isl: avoid gfx version switch cases on the hot path

Some of the surface state packing functions are called from the hot
path in Anv. We can use function pointers to avoid repeatedly going
through switch/case.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19050>
This commit is contained in:
Lionel Landwerlin 2022-10-02 19:20:30 +03:00 committed by Marge Bot
parent 06d955ab21
commit 2db45f713a
7 changed files with 162 additions and 119 deletions

View file

@ -36,6 +36,12 @@
#include "isl_gfx12.h"
#include "isl_priv.h"
isl_genX_declare_get_func(surf_fill_state_s)
isl_genX_declare_get_func(buffer_fill_state_s)
isl_genX_declare_get_func(emit_depth_stencil_hiz_s)
isl_genX_declare_get_func(null_fill_state_s)
isl_genX_declare_get_func(emit_cpb_control_s)
void
isl_memcpy_linear_to_tiled(uint32_t xt1, uint32_t xt2,
uint32_t yt1, uint32_t yt2,
@ -315,6 +321,12 @@ isl_device_init(struct isl_device *dev,
_3DSTATE_CPSIZE_CONTROL_BUFFER_SurfaceBaseAddress_start(info) / 8;
isl_device_setup_mocs(dev);
dev->surf_fill_state_s = isl_surf_fill_state_s_get_func(dev);
dev->buffer_fill_state_s = isl_buffer_fill_state_s_get_func(dev);
dev->emit_depth_stencil_hiz_s = isl_emit_depth_stencil_hiz_s_get_func(dev);
dev->null_fill_state_s = isl_null_fill_state_s_get_func(dev);
dev->emit_cpb_control_s = isl_emit_cpb_control_s_get_func(dev);
}
/**
@ -2410,98 +2422,6 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
assert(!"Unknown hardware generation"); \
}
void
isl_surf_fill_state_s(const struct isl_device *dev, void *state,
const struct isl_surf_fill_state_info *restrict info)
{
#ifndef NDEBUG
isl_surf_usage_flags_t _base_usage =
info->view->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT |
ISL_SURF_USAGE_TEXTURE_BIT |
ISL_SURF_USAGE_STORAGE_BIT);
/* They may only specify one of the above bits at a time */
assert(__builtin_popcount(_base_usage) == 1);
/* The only other allowed bit is ISL_SURF_USAGE_CUBE_BIT */
assert((info->view->usage & ~ISL_SURF_USAGE_CUBE_BIT) == _base_usage);
#endif
if (info->surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->surf->logical_level0_px.array_len);
}
isl_genX_call(dev, surf_fill_state_s, dev, state, info);
}
void
isl_buffer_fill_state_s(const struct isl_device *dev, void *state,
const struct isl_buffer_fill_state_info *restrict info)
{
isl_genX_call(dev, buffer_fill_state_s, dev, state, info);
}
void
isl_null_fill_state_s(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info)
{
isl_genX_call(dev, null_fill_state, dev, state, info);
}
void
isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info)
{
if (info->depth_surf && info->stencil_surf) {
if (!dev->info->has_hiz_and_separate_stencil) {
assert(info->depth_surf == info->stencil_surf);
assert(info->depth_address == info->stencil_address);
}
assert(info->depth_surf->dim == info->stencil_surf->dim);
}
if (info->depth_surf) {
assert((info->depth_surf->usage & ISL_SURF_USAGE_DEPTH_BIT));
if (info->depth_surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->depth_surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->depth_surf->logical_level0_px.array_len);
}
}
if (info->stencil_surf) {
assert((info->stencil_surf->usage & ISL_SURF_USAGE_STENCIL_BIT));
if (info->stencil_surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->stencil_surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->stencil_surf->logical_level0_px.array_len);
}
}
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.

View file

@ -1230,6 +1230,12 @@ typedef enum {
ISL_MEMCPY_INVALID,
} isl_memcpy_type;
struct isl_surf_fill_state_info;
struct isl_buffer_fill_state_info;
struct isl_depth_stencil_hiz_emit_info;
struct isl_null_fill_state_info;
struct isl_cpb_emit_info;
struct isl_device {
const struct intel_device_info *info;
bool use_separate_stencil;
@ -1285,6 +1291,21 @@ struct isl_device {
uint32_t blitter_src;
uint32_t blitter_dst;
} mocs;
void (*surf_fill_state_s)(const struct isl_device *dev, void *state,
const struct isl_surf_fill_state_info *restrict info);
void (*buffer_fill_state_s)(const struct isl_device *dev, void *state,
const struct isl_buffer_fill_state_info *restrict info);
void (*emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void (*null_fill_state_s)(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info);
void (*emit_cpb_control_s)(const struct isl_device *dev, void *batch,
const struct isl_cpb_emit_info *restrict info);
};
struct isl_extent2d {
@ -2469,40 +2490,35 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
uint32_t row_pitch_B);
#define isl_surf_fill_state(dev, state, ...) \
isl_surf_fill_state_s((dev), (state), \
(dev)->surf_fill_state_s(dev, state, \
&(struct isl_surf_fill_state_info) { __VA_ARGS__ });
void
isl_surf_fill_state_s(const struct isl_device *dev, void *state,
const struct isl_surf_fill_state_info *restrict info);
#define isl_surf_fill_state_s(dev, state, info) \
(dev)->surf_fill_state_s(dev, state, info)
#define isl_buffer_fill_state(dev, state, ...) \
isl_buffer_fill_state_s((dev), (state), \
&(struct isl_buffer_fill_state_info) { __VA_ARGS__ });
(dev)->buffer_fill_state_s(dev, state, \
&(struct isl_buffer_fill_state_info) { __VA_ARGS__ });
void
isl_buffer_fill_state_s(const struct isl_device *dev, void *state,
const struct isl_buffer_fill_state_info *restrict info);
void
isl_null_fill_state_s(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info);
#define isl_buffer_fill_state_s(dev, state, info) \
(dev)->buffer_fill_state_s(dev, state, info);
#define isl_null_fill_state(dev, state, ...) \
isl_null_fill_state_s((dev), (state), \
&(struct isl_null_fill_state_info) { __VA_ARGS__ });
(dev)->null_fill_state_s(dev, state, \
&(struct isl_null_fill_state_info) { __VA_ARGS__ });
#define isl_null_fill_state_s(dev, state, info) \
(dev)->null_fill_state_s(dev, state, info);
#define isl_emit_depth_stencil_hiz(dev, batch, ...) \
isl_emit_depth_stencil_hiz_s((dev), (batch), \
&(struct isl_depth_stencil_hiz_emit_info) { __VA_ARGS__ })
(dev)->emit_depth_stencil_hiz_s(dev, batch, \
&(struct isl_depth_stencil_hiz_emit_info) { __VA_ARGS__ })
void
isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
#define isl_emit_depth_stencil_hiz_s(dev, batch, info) \
(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);
#define isl_emit_cpb_control_s(dev, batch, info) \
(dev)->emit_cpb_control_s(dev, batch, info)
void
isl_surf_fill_image_param(const struct isl_device *dev,

View file

@ -51,6 +51,14 @@ 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
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);
}
struct GENX(3DSTATE_CPSIZE_CONTROL_BUFFER) cpb = {
GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_header),
};

View file

@ -69,6 +69,36 @@ void
isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info)
{
if (info->depth_surf && info->stencil_surf) {
if (!dev->info->has_hiz_and_separate_stencil) {
assert(info->depth_surf == info->stencil_surf);
assert(info->depth_address == info->stencil_address);
}
assert(info->depth_surf->dim == info->stencil_surf->dim);
}
if (info->depth_surf) {
assert((info->depth_surf->usage & ISL_SURF_USAGE_DEPTH_BIT));
if (info->depth_surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->depth_surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->depth_surf->logical_level0_px.array_len);
}
}
if (info->stencil_surf) {
assert((info->stencil_surf->usage & ISL_SURF_USAGE_STENCIL_BIT));
if (info->stencil_surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->stencil_surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->stencil_surf->logical_level0_px.array_len);
}
}
struct GENX(3DSTATE_DEPTH_BUFFER) db = {
GENX(3DSTATE_DEPTH_BUFFER_header),
#if GFX_VER >= 6

View file

@ -45,8 +45,8 @@ isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_genX(null_fill_state)(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info);
isl_genX(null_fill_state_s)(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,

View file

@ -33,6 +33,56 @@
#include "isl.h"
typedef void (*isl_surf_fill_state_s_func)(
const struct isl_device *dev, void *state,
const struct isl_surf_fill_state_info *restrict info);
typedef void (*isl_buffer_fill_state_s_func)(
const struct isl_device *dev, void *state,
const struct isl_buffer_fill_state_info *restrict info);
typedef void (*isl_emit_depth_stencil_hiz_s_func)(
const struct isl_device *dev, void *state,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
typedef void (*isl_null_fill_state_s_func)(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info);
typedef void (*isl_emit_cpb_control_s_func)(const struct isl_device *dev, void *batch,
const struct isl_cpb_emit_info *restrict info);
#define isl_genX_declare_get_func(func) \
static inline isl_##func##_func \
isl_##func##_get_func(const struct isl_device *dev) { \
switch (ISL_GFX_VERX10(dev)) { \
case 40: \
return isl_gfx4_##func; \
case 45: \
/* G45 surface state is the same as gfx5 */ \
case 50: \
return isl_gfx5_##func; \
case 60: \
return isl_gfx6_##func; \
case 70: \
return isl_gfx7_##func; \
case 75: \
return isl_gfx75_##func; \
case 80: \
return isl_gfx8_##func; \
case 90: \
return isl_gfx9_##func; \
case 110: \
return isl_gfx11_##func; \
case 120: \
return isl_gfx12_##func; \
case 125: \
return isl_gfx125_##func; \
default: \
assert(!"Unknown hardware generation"); \
return NULL; \
} \
}
#define isl_finishme(format, ...) \
do { \
static bool reported = false; \

View file

@ -158,6 +158,25 @@ void
isl_genX(surf_fill_state_s)(const struct isl_device *dev, void *state,
const struct isl_surf_fill_state_info *restrict info)
{
#ifndef NDEBUG
isl_surf_usage_flags_t _base_usage =
info->view->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT |
ISL_SURF_USAGE_TEXTURE_BIT |
ISL_SURF_USAGE_STORAGE_BIT);
/* They may only specify one of the above bits at a time */
assert(__builtin_popcount(_base_usage) == 1);
/* The only other allowed bit is ISL_SURF_USAGE_CUBE_BIT */
assert((info->view->usage & ~ISL_SURF_USAGE_CUBE_BIT) == _base_usage);
#endif
if (info->surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->surf->logical_level0_px.array_len);
}
struct GENX(RENDER_SURFACE_STATE) s = { 0 };
s.SurfaceType = get_surftype(info->surf->dim, info->view->usage);
@ -933,8 +952,8 @@ isl_genX(buffer_fill_state_s)(const struct isl_device *dev, void *state,
}
void
isl_genX(null_fill_state)(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info)
isl_genX(null_fill_state_s)(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info)
{
struct GENX(RENDER_SURFACE_STATE) s = {
.SurfaceType = SURFTYPE_NULL,