diff options
author | Lionel Landwerlin <lionel.g.landwerlin@intel.com> | 2020-11-06 17:03:33 +0200 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-02-02 17:09:46 +0000 |
commit | dff08cbf8e7f9d9656b3c260b115ae9951a0b99c (patch) | |
tree | b5107a25a5dfdaeb4d4a48329e0ffb20de238674 | |
parent | 8d90fe587fdb54517d90e03e3095dea83e2a2f84 (diff) |
isl: add support for coarse pixel control surfaces
Those surfaces are used as attachment to rendering passes and describe
the rate of coarse pixel shading for the pass.
v2: Move CPB_BIT tile filtering to isl_gfx125_filter_tiling() (Nanley)
v3: Drop unused macro (Nanley)
s/isl_to_gen/isl_encode/ (Nanley)
Remove pitch alignment 128B constraint already covered by tiling (Nanley)
Move some asserts together (Nanley)
v4: Disable miptail for now (Nanley)
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13739>
-rw-r--r-- | src/intel/genxml/meson.build | 2 | ||||
-rw-r--r-- | src/intel/isl/isl.c | 33 | ||||
-rw-r--r-- | src/intel/isl/isl.h | 42 | ||||
-rw-r--r-- | src/intel/isl/isl_emit_cpb.c | 110 | ||||
-rw-r--r-- | src/intel/isl/isl_genX_priv.h | 4 | ||||
-rw-r--r-- | src/intel/isl/isl_gfx12.c | 9 | ||||
-rw-r--r-- | src/intel/isl/meson.build | 1 |
7 files changed, 201 insertions, 0 deletions
diff --git a/src/intel/genxml/meson.build b/src/intel/genxml/meson.build index 4202c138a36..0932e2c0179 100644 --- a/src/intel/genxml/meson.build +++ b/src/intel/genxml/meson.build @@ -56,6 +56,8 @@ genX_bits_included_symbols = [ '3DSTATE_CLEAR_PARAMS', '3DSTATE_SO_BUFFER::Surface Base Address', '3DSTATE_SO_BUFFER::Stream Offset', + '3DSTATE_CPSIZE_CONTROL_BUFFER::Surface Base Address', + '3DSTATE_CPSIZE_CONTROL_BUFFER::Surface Pitch', # structures 'RENDER_SURFACE_STATE::Surface Base Address', 'RENDER_SURFACE_STATE::Surface Pitch', diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index b2de1544f76..e16661dcc15 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -198,6 +198,9 @@ isl_mocs(const struct isl_device *dev, isl_surf_usage_flags_t usage, if (usage & ISL_SURF_USAGE_STAGING_BIT) return dev->mocs.internal; + if (usage & ISL_SURF_USAGE_CPB_BIT) + return dev->mocs.internal; + /* Using L1:HDC for storage buffers breaks Vulkan memory model * tests that use shader atomics. This isn't likely to work out, * and we can't know a priori whether they'll be used. So just @@ -307,6 +310,10 @@ isl_device_init(struct isl_device *dev, dev->max_buffer_size = 1ull << 27; } + dev->cpb.size = _3DSTATE_CPSIZE_CONTROL_BUFFER_length(info) * 4; + dev->cpb.offset = + _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfaceBaseAddress_start(info) / 8; + isl_device_setup_mocs(dev); } @@ -1599,6 +1606,9 @@ isl_calc_row_pitch_alignment(const struct isl_device *dev, return tile_info->phys_extent_B.width; } + /* We only support tiled fragment shading rate buffers. */ + assert((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) == 0); + /* From the Broadwel PRM >> Volume 2d: Command Reference: Structures >> * RENDER_SURFACE_STATE Surface Pitch (p349): * @@ -1782,6 +1792,10 @@ isl_calc_row_pitch(const struct isl_device *dev, !pitch_in_range(row_pitch_B, stencil_pitch_bits)) return false; + if ((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) && + !pitch_in_range(row_pitch_B, _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfacePitch_bits(dev->info))) + return false; + done: *out_row_pitch_B = row_pitch_B; return true; @@ -1792,6 +1806,10 @@ isl_surf_init_s(const struct isl_device *dev, struct isl_surf *surf, const struct isl_surf_init_info *restrict info) { + /* Some sanity checks */ + assert(!(info->usage & ISL_SURF_USAGE_CPB_BIT) || + dev->info->has_coarse_pixel_primitive_and_cb); + const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); const struct isl_extent4d logical_level0_px = { @@ -2459,6 +2477,21 @@ isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch, isl_genX_call(dev, emit_depth_stencil_hiz_s, dev, batch, info); } +void +isl_emit_cpb_control_s(const struct isl_device *dev, void *batch, + const struct isl_cpb_emit_info *restrict info) +{ + if (info->surf) { + assert((info->surf->usage & ISL_SURF_USAGE_CPB_BIT)); + assert(info->surf->dim != ISL_SURF_DIM_3D); + assert(info->surf->tiling == ISL_TILING_4 || + info->surf->tiling == ISL_TILING_64); + assert(info->surf->format == ISL_FORMAT_R8_UINT); + } + + isl_genX_call(dev, emit_cpb_control_s, dev, batch, info); +} + /** * A variant of isl_surf_get_image_offset_sa() specific to * ISL_DIM_LAYOUT_GFX4_2D. diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h index 799b5e035dd..3f84a3a5988 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -1115,6 +1115,7 @@ typedef uint64_t isl_surf_usage_flags_t; #define ISL_SURF_USAGE_INDEX_BUFFER_BIT (1u << 12) #define ISL_SURF_USAGE_CONSTANT_BUFFER_BIT (1u << 13) #define ISL_SURF_USAGE_STAGING_BIT (1u << 14) +#define ISL_SURF_USAGE_CPB_BIT (1u << 15) /** @} */ /** @@ -1269,6 +1270,15 @@ struct isl_device { uint8_t hiz_offset; } ds; + /** + * Describes the layout of the coarse pixel control commands as emitted by + * isl_emit_cpb_control. + */ + struct { + uint8_t size; + uint8_t offset; + } cpb; + struct { uint32_t internal; uint32_t external; @@ -1770,6 +1780,28 @@ struct isl_null_fill_state_info { uint32_t minimum_array_element; }; +struct isl_cpb_emit_info { + /** + * The coarse pixel shading control surface. + */ + const struct isl_surf *surf; + + /** + * The view into the control surface. + */ + const struct isl_view *view; + + /** + * The address of the control surface in GPU memory. + */ + uint64_t address; + + /** + * The Memory Object Control state for the surface. + */ + uint32_t mocs; +}; + extern const struct isl_format_layout isl_format_layouts[]; extern const char isl_format_names[]; extern const uint16_t isl_format_name_offsets[]; @@ -2237,6 +2269,12 @@ isl_surf_usage_is_depth_or_stencil(isl_surf_usage_flags_t usage) } static inline bool +isl_surf_usage_is_cpb(isl_surf_usage_flags_t usage) +{ + return usage & ISL_SURF_USAGE_CPB_BIT; +} + +static inline bool isl_surf_info_is_z16(const struct isl_surf_init_info *info) { return (info->usage & ISL_SURF_USAGE_DEPTH_BIT) && @@ -2424,6 +2462,10 @@ isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch, const struct isl_depth_stencil_hiz_emit_info *restrict info); void +isl_emit_cpb_control_s(const struct isl_device *dev, void *batch, + const struct isl_cpb_emit_info *restrict info); + +void isl_surf_fill_image_param(const struct isl_device *dev, struct brw_image_param *param, const struct isl_surf *surf, diff --git a/src/intel/isl/isl_emit_cpb.c b/src/intel/isl/isl_emit_cpb.c new file mode 100644 index 00000000000..024fba9e478 --- /dev/null +++ b/src/intel/isl/isl_emit_cpb.c @@ -0,0 +1,110 @@ +/* + * Copyright 2020 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <stdint.h> + +#define __gen_address_type uint64_t +#define __gen_user_data void + +static uint64_t +__gen_combine_address(__attribute__((unused)) void *data, + __attribute__((unused)) void *loc, uint64_t addr, + uint32_t delta) +{ + return addr + delta; +} + +#include "genxml/gen_macros.h" +#include "genxml/genX_pack.h" + +#include "isl_priv.h" + +#if GFX_VERx10 >= 125 +static const uint8_t isl_encode_tiling[] = { + [ISL_TILING_4] = TILE4, + [ISL_TILING_64] = TILE64, +}; +#endif + +void +isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch, + const struct isl_cpb_emit_info *restrict info) +{ +#if GFX_VERx10 >= 125 + struct GENX(3DSTATE_CPSIZE_CONTROL_BUFFER) cpb = { + GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_header), + }; + + if (info->surf) { + /* BSpec 46962 has a number of restriction on the fields of this packet + * like : + * + * "The Width specified by this field must be less than or equal to + * the surface pitch (specified in bytes via the Surface Pitch field). + * For cube maps, Width must be set equal to Height. + * + * 1. The Width ofthis buffer must be the same as the Width of the + * render target(s) (defined in SURFACE_STATE), unless Surface + * Type is SURFTYPE_1D or SURFTYPE_2D with Depth = 0 (non-array) + * and LOD = 0 (non-mip mapped). + * + * 2. Depth buffer (defined in 3DSTATE_DEPTH_BUFFER) unless either + * the depth buffer or this buffer surf_typeare SURFTYPE_NULL" + * + * Unfortunately APIs like Vulkan do not give guarantees that every + * framebuffer attachment will match in size (RT & CPB surfaces for + * example). But at least it gives a guarantee that all the attachments + * of a render pass will be at least be large enough to handle the + * rendered area. So here we use the CPB surface values, even if they + * don't strictly match the various BSpec restrictions. + */ + cpb.Width = (info->surf->logical_level0_px.width * 8) - 1; + cpb.Height = (info->surf->logical_level0_px.height * 8) - 1; + cpb.Depth = info->view->array_len - 1; + cpb.RenderTargetViewExtent = cpb.Depth; + + cpb.SurfLOD = info->view->base_level; + cpb.MinimumArrayElement = info->view->base_array_layer; + cpb.SurfaceType = SURFTYPE_2D; + cpb.SurfacePitch = info->surf->row_pitch_B - 1; + cpb.MOCS = info->mocs; + cpb.SurfaceQPitch = isl_surf_get_array_pitch_sa_rows(info->surf) >> 2; + cpb.TiledMode = isl_encode_tiling[info->surf->tiling]; + cpb.SurfaceBaseAddress = info->address; + + /* We don't use miptails yet. The PRM recommends that you set "Mip Tail + * Start LOD" to 15 to prevent the hardware from trying to use them. + */ + cpb.MipTailStartLOD = 15; + } else { + cpb.SurfaceType = SURFTYPE_NULL; + cpb.TiledMode = TILE64; + } + + /* Pack everything into the batch */ + uint32_t *dw = batch; + GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_pack)(NULL, dw, &cpb); +#else + unreachable("Coarse pixel shading not supported"); +#endif +} diff --git a/src/intel/isl/isl_genX_priv.h b/src/intel/isl/isl_genX_priv.h index 5fa545a501c..258dd8db740 100644 --- a/src/intel/isl/isl_genX_priv.h +++ b/src/intel/isl/isl_genX_priv.h @@ -47,3 +47,7 @@ isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch, void isl_genX(null_fill_state)(const struct isl_device *dev, void *state, const struct isl_null_fill_state_info *restrict info); + +void +isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch, + const struct isl_cpb_emit_info *restrict info); diff --git a/src/intel/isl/isl_gfx12.c b/src/intel/isl/isl_gfx12.c index df541e6504a..959139ca923 100644 --- a/src/intel/isl/isl_gfx12.c +++ b/src/intel/isl/isl_gfx12.c @@ -88,6 +88,15 @@ isl_gfx125_filter_tiling(const struct isl_device *dev, /* Tile64 is not defined for format sizes that are 24, 48, and 96 bpb. */ if (isl_format_get_layout(info->format)->bpb % 3 == 0) *flags &= ~ISL_TILING_64_BIT; + + /* BSpec 46962: 3DSTATE_CPSIZE_CONTROL_BUFFER::Tiled Mode : TILE4 & TILE64 + * are the only 2 valid values. + * + * TODO: For now we only TILE64 as we need to figure out potential + * additional requirements for TILE4. + */ + if (info->usage & ISL_SURF_USAGE_CPB_BIT) + *flags &= ISL_TILING_64_BIT; } void diff --git a/src/intel/isl/meson.build b/src/intel/isl/meson.build index 891360fdd6d..50c60f87511 100644 --- a/src/intel/isl/meson.build +++ b/src/intel/isl/meson.build @@ -19,6 +19,7 @@ # SOFTWARE. isl_per_hw_ver_files = files( + 'isl_emit_cpb.c', 'isl_emit_depth_stencil.c', 'isl_surface_state.c', 'isl_genX_helpers.h', |