summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>2020-11-06 17:03:33 +0200
committerMarge Bot <emma+marge@anholt.net>2022-02-02 17:09:46 +0000
commitdff08cbf8e7f9d9656b3c260b115ae9951a0b99c (patch)
treeb5107a25a5dfdaeb4d4a48329e0ffb20de238674
parent8d90fe587fdb54517d90e03e3095dea83e2a2f84 (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.build2
-rw-r--r--src/intel/isl/isl.c33
-rw-r--r--src/intel/isl/isl.h42
-rw-r--r--src/intel/isl/isl_emit_cpb.c110
-rw-r--r--src/intel/isl/isl_genX_priv.h4
-rw-r--r--src/intel/isl/isl_gfx12.c9
-rw-r--r--src/intel/isl/meson.build1
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',