blorp: add support for cached dynamic states
Of the dynamic states we have blorp reemit for each operations, a few actually never change : * BLEND_STATE (it looks like it does, but actually for anv no) * COLOR_CALC_STATE * CC_VIEWPORT * SAMPLER_STATE We add infrastructure here to upload into the driver and retrieve the state offset later. Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Tapani Pälli <tapani.palli@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28368>
This commit is contained in:
committed by
Marge Bot
parent
bdc3d75431
commit
a147ccaa5c
@@ -134,6 +134,13 @@ blorp_get_surface_base_address(UNUSED struct blorp_batch *blorp_batch)
|
||||
return (struct blorp_address) { .offset = IRIS_MEMZONE_BINDER_START };
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
blorp_get_dynamic_state(struct blorp_batch *batch,
|
||||
enum blorp_dynamic_state name)
|
||||
{
|
||||
unreachable("Not implemented");
|
||||
}
|
||||
|
||||
static void *
|
||||
blorp_alloc_dynamic_state(struct blorp_batch *blorp_batch,
|
||||
uint32_t size,
|
||||
|
||||
+23
-5
@@ -59,6 +59,16 @@ struct blorp_params;
|
||||
struct blorp_config {
|
||||
bool use_mesh_shading;
|
||||
bool use_unrestricted_depth_range;
|
||||
bool use_cached_dynamic_states;
|
||||
};
|
||||
|
||||
enum blorp_dynamic_state {
|
||||
BLORP_DYNAMIC_STATE_BLEND,
|
||||
BLORP_DYNAMIC_STATE_CC_VIEWPORT,
|
||||
BLORP_DYNAMIC_STATE_COLOR_CALC,
|
||||
BLORP_DYNAMIC_STATE_SAMPLER,
|
||||
|
||||
BLORP_DYNAMIC_STATE_COUNT,
|
||||
};
|
||||
|
||||
struct blorp_context {
|
||||
@@ -70,6 +80,11 @@ struct blorp_context {
|
||||
|
||||
bool enable_tbimr;
|
||||
|
||||
void (*upload_dynamic_state)(struct blorp_context *context,
|
||||
const void *data, uint32_t size,
|
||||
uint32_t alignment,
|
||||
enum blorp_dynamic_state name);
|
||||
|
||||
bool (*lookup_shader)(struct blorp_batch *batch,
|
||||
const void *key, uint32_t key_size,
|
||||
uint32_t *kernel_out, void *prog_data_out);
|
||||
@@ -103,23 +118,26 @@ enum blorp_batch_flags {
|
||||
* and stencil images passed in will match what is currently set in the
|
||||
* hardware.
|
||||
*/
|
||||
BLORP_BATCH_NO_EMIT_DEPTH_STENCIL = (1 << 0),
|
||||
BLORP_BATCH_NO_EMIT_DEPTH_STENCIL = BITFIELD_BIT(0),
|
||||
|
||||
/* This flag indicates that the blorp call should be predicated. */
|
||||
BLORP_BATCH_PREDICATE_ENABLE = (1 << 1),
|
||||
BLORP_BATCH_PREDICATE_ENABLE = BITFIELD_BIT(1),
|
||||
|
||||
/* This flag indicates that blorp should *not* update the indirect clear
|
||||
* color buffer.
|
||||
*/
|
||||
BLORP_BATCH_NO_UPDATE_CLEAR_COLOR = (1 << 2),
|
||||
BLORP_BATCH_NO_UPDATE_CLEAR_COLOR = BITFIELD_BIT(2),
|
||||
|
||||
/* This flag indicates that blorp should use a compute program for the
|
||||
* operation.
|
||||
*/
|
||||
BLORP_BATCH_USE_COMPUTE = (1 << 3),
|
||||
BLORP_BATCH_USE_COMPUTE = BITFIELD_BIT(3),
|
||||
|
||||
/** Use the hardware blitter to perform any operations in this batch */
|
||||
BLORP_BATCH_USE_BLITTER = (1 << 4),
|
||||
BLORP_BATCH_USE_BLITTER = BITFIELD_BIT(4),
|
||||
|
||||
/** Reuse dynamic states */
|
||||
BLORP_BATCH_REUSE_DYNAMIC_STATES = BITFIELD_BIT(5),
|
||||
};
|
||||
|
||||
struct blorp_batch {
|
||||
|
||||
@@ -73,6 +73,10 @@ blorp_alloc_general_state(struct blorp_batch *batch,
|
||||
uint32_t alignment,
|
||||
uint32_t *offset);
|
||||
|
||||
static uint32_t
|
||||
blorp_get_dynamic_state(struct blorp_batch *batch,
|
||||
enum blorp_dynamic_state name);
|
||||
|
||||
static void *
|
||||
blorp_alloc_vertex_buffer(struct blorp_batch *batch, uint32_t size,
|
||||
struct blorp_address *addr);
|
||||
@@ -193,7 +197,20 @@ _blorp_combine_address(struct blorp_batch *batch, void *location,
|
||||
|
||||
#define STRUCT_ZERO(S) ({ struct S t; memset(&t, 0, sizeof(t)); t; })
|
||||
|
||||
#define blorp_emit_dynamic(batch, state, name, align, offset) \
|
||||
#define blorp_context_upload_dynamic(context, state, name, \
|
||||
align, dynamic_name) \
|
||||
for (struct state name = STRUCT_ZERO(state), *_dst = &name; \
|
||||
_dst != NULL; \
|
||||
({ \
|
||||
uint32_t _dw[_blorp_cmd_length(state)]; \
|
||||
_blorp_cmd_pack(state)(NULL, (void *)_dw, &name); \
|
||||
context->upload_dynamic_state(context, _dw, \
|
||||
_blorp_cmd_length(state) * 4, \
|
||||
align, dynamic_name); \
|
||||
_dst = NULL; \
|
||||
}))
|
||||
|
||||
#define blorp_emit_dynamic(batch, state, name, align, offset) \
|
||||
for (struct state name = STRUCT_ZERO(state), \
|
||||
*_dst = blorp_alloc_dynamic_state(batch, \
|
||||
_blorp_cmd_length(state) * 4, \
|
||||
@@ -574,11 +591,16 @@ static uint32_t
|
||||
blorp_emit_cc_viewport(struct blorp_batch *batch)
|
||||
{
|
||||
uint32_t cc_vp_offset;
|
||||
blorp_emit_dynamic(batch, GENX(CC_VIEWPORT), vp, 32, &cc_vp_offset) {
|
||||
vp.MinimumDepth = batch->blorp->config.use_unrestricted_depth_range ?
|
||||
|
||||
if (batch->blorp->config.use_cached_dynamic_states) {
|
||||
cc_vp_offset = blorp_get_dynamic_state(batch, BLORP_DYNAMIC_STATE_CC_VIEWPORT);
|
||||
} else {
|
||||
blorp_emit_dynamic(batch, GENX(CC_VIEWPORT), vp, 32, &cc_vp_offset) {
|
||||
vp.MinimumDepth = batch->blorp->config.use_unrestricted_depth_range ?
|
||||
-FLT_MAX : 0.0;
|
||||
vp.MaximumDepth = batch->blorp->config.use_unrestricted_depth_range ?
|
||||
vp.MaximumDepth = batch->blorp->config.use_unrestricted_depth_range ?
|
||||
FLT_MAX : 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
blorp_emit(batch, GENX(3DSTATE_VIEWPORT_STATE_POINTERS_CC), vsp) {
|
||||
@@ -617,7 +639,9 @@ blorp_emit_sampler_state(struct blorp_batch *batch)
|
||||
UNUSED static uint32_t
|
||||
blorp_emit_sampler_state_ps(struct blorp_batch *batch)
|
||||
{
|
||||
uint32_t offset = blorp_emit_sampler_state(batch);
|
||||
uint32_t offset = batch->blorp->config.use_cached_dynamic_states ?
|
||||
blorp_get_dynamic_state(batch, BLORP_DYNAMIC_STATE_SAMPLER) :
|
||||
blorp_emit_sampler_state(batch);
|
||||
|
||||
blorp_emit(batch, GENX(3DSTATE_SAMPLER_STATE_POINTERS_PS), ssp) {
|
||||
ssp.PointertoPSSamplerState = offset;
|
||||
@@ -858,36 +882,42 @@ static void
|
||||
blorp_emit_blend_state(struct blorp_batch *batch,
|
||||
const struct blorp_params *params)
|
||||
{
|
||||
struct GENX(BLEND_STATE) blend = { };
|
||||
|
||||
uint32_t offset;
|
||||
int size = GENX(BLEND_STATE_length) * 4;
|
||||
size += GENX(BLEND_STATE_ENTRY_length) * 4 * params->num_draw_buffers;
|
||||
uint32_t *state = blorp_alloc_dynamic_state(batch, size, 64, &offset);
|
||||
if (state == NULL)
|
||||
return;
|
||||
uint32_t *pos = state;
|
||||
if (!batch->blorp->config.use_cached_dynamic_states) {
|
||||
struct GENX(BLEND_STATE) blend = { };
|
||||
|
||||
GENX(BLEND_STATE_pack)(NULL, pos, &blend);
|
||||
pos += GENX(BLEND_STATE_length);
|
||||
int size = GENX(BLEND_STATE_length) * 4;
|
||||
size += GENX(BLEND_STATE_ENTRY_length) * 4 * params->num_draw_buffers;
|
||||
uint32_t *state = blorp_alloc_dynamic_state(batch, size, 64, &offset);
|
||||
if (state == NULL)
|
||||
return;
|
||||
uint32_t *pos = state;
|
||||
|
||||
for (unsigned i = 0; i < params->num_draw_buffers; ++i) {
|
||||
struct GENX(BLEND_STATE_ENTRY) entry = {
|
||||
.PreBlendColorClampEnable = true,
|
||||
.PostBlendColorClampEnable = true,
|
||||
.ColorClampRange = COLORCLAMP_RTFORMAT,
|
||||
GENX(BLEND_STATE_pack)(NULL, pos, &blend);
|
||||
pos += GENX(BLEND_STATE_length);
|
||||
|
||||
.WriteDisableRed = params->color_write_disable & 1,
|
||||
.WriteDisableGreen = params->color_write_disable & 2,
|
||||
.WriteDisableBlue = params->color_write_disable & 4,
|
||||
.WriteDisableAlpha = params->color_write_disable & 8,
|
||||
};
|
||||
GENX(BLEND_STATE_ENTRY_pack)(NULL, pos, &entry);
|
||||
pos += GENX(BLEND_STATE_ENTRY_length);
|
||||
for (unsigned i = 0; i < params->num_draw_buffers; ++i) {
|
||||
struct GENX(BLEND_STATE_ENTRY) entry = {
|
||||
.PreBlendColorClampEnable = true,
|
||||
.PostBlendColorClampEnable = true,
|
||||
.ColorClampRange = COLORCLAMP_RTFORMAT,
|
||||
|
||||
.WriteDisableRed = params->color_write_disable & 1,
|
||||
.WriteDisableGreen = params->color_write_disable & 2,
|
||||
.WriteDisableBlue = params->color_write_disable & 4,
|
||||
.WriteDisableAlpha = params->color_write_disable & 8,
|
||||
};
|
||||
GENX(BLEND_STATE_ENTRY_pack)(NULL, pos, &entry);
|
||||
pos += GENX(BLEND_STATE_ENTRY_length);
|
||||
}
|
||||
|
||||
blorp_flush_range(batch, state, size);
|
||||
} else {
|
||||
/* We only cached this case. */
|
||||
assert(params->color_write_disable == 0);
|
||||
offset = blorp_get_dynamic_state(batch, BLORP_DYNAMIC_STATE_BLEND);
|
||||
}
|
||||
|
||||
blorp_flush_range(batch, state, size);
|
||||
|
||||
blorp_emit(batch, GENX(3DSTATE_BLEND_STATE_POINTERS), sp) {
|
||||
sp.BlendStatePointer = offset;
|
||||
sp.BlendStatePointerValid = true;
|
||||
@@ -903,7 +933,11 @@ blorp_emit_color_calc_state(struct blorp_batch *batch,
|
||||
UNUSED const struct blorp_params *params)
|
||||
{
|
||||
uint32_t offset;
|
||||
blorp_emit_dynamic(batch, GENX(COLOR_CALC_STATE), cc, 64, &offset) {}
|
||||
|
||||
if (batch->blorp->config.use_cached_dynamic_states)
|
||||
offset = blorp_get_dynamic_state(batch, BLORP_DYNAMIC_STATE_COLOR_CALC);
|
||||
else
|
||||
blorp_emit_dynamic(batch, GENX(COLOR_CALC_STATE), cc, 64, &offset) {}
|
||||
|
||||
blorp_emit(batch, GENX(3DSTATE_CC_STATE_POINTERS), sp) {
|
||||
sp.ColorCalcStatePointer = offset;
|
||||
@@ -2151,4 +2185,65 @@ blorp_exec(struct blorp_batch *batch, const struct blorp_params *params)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blorp_init_dynamic_states(struct blorp_context *context)
|
||||
{
|
||||
{
|
||||
struct GENX(BLEND_STATE) blend = { };
|
||||
|
||||
uint32_t dws[GENX(BLEND_STATE_length) * 4 +
|
||||
GENX(BLEND_STATE_ENTRY_length) * 4 * 8 /* MAX_RTS */];
|
||||
uint32_t *pos = dws;
|
||||
|
||||
GENX(BLEND_STATE_pack)(NULL, pos, &blend);
|
||||
pos += GENX(BLEND_STATE_length);
|
||||
|
||||
for (unsigned i = 0; i < 8; ++i) {
|
||||
struct GENX(BLEND_STATE_ENTRY) entry = {
|
||||
.PreBlendColorClampEnable = true,
|
||||
.PostBlendColorClampEnable = true,
|
||||
.ColorClampRange = COLORCLAMP_RTFORMAT,
|
||||
};
|
||||
GENX(BLEND_STATE_ENTRY_pack)(NULL, pos, &entry);
|
||||
pos += GENX(BLEND_STATE_ENTRY_length);
|
||||
}
|
||||
|
||||
context->upload_dynamic_state(context, dws, sizeof(dws), 64,
|
||||
BLORP_DYNAMIC_STATE_BLEND);
|
||||
}
|
||||
|
||||
blorp_context_upload_dynamic(context, GENX(CC_VIEWPORT), vp, 32,
|
||||
BLORP_DYNAMIC_STATE_CC_VIEWPORT) {
|
||||
vp.MinimumDepth = context->config.use_unrestricted_depth_range ?
|
||||
-FLT_MAX : 0.0;
|
||||
vp.MaximumDepth = context->config.use_unrestricted_depth_range ?
|
||||
FLT_MAX : 1.0;
|
||||
}
|
||||
|
||||
blorp_context_upload_dynamic(context, GENX(COLOR_CALC_STATE), cc, 64,
|
||||
BLORP_DYNAMIC_STATE_COLOR_CALC) {
|
||||
/* Nothing */
|
||||
}
|
||||
|
||||
blorp_context_upload_dynamic(context, GENX(SAMPLER_STATE), sampler, 32,
|
||||
BLORP_DYNAMIC_STATE_SAMPLER) {
|
||||
sampler.MipModeFilter = MIPFILTER_NONE;
|
||||
sampler.MagModeFilter = MAPFILTER_LINEAR;
|
||||
sampler.MinModeFilter = MAPFILTER_LINEAR;
|
||||
sampler.MinLOD = 0;
|
||||
sampler.MaxLOD = 0;
|
||||
sampler.TCXAddressControlMode = TCM_CLAMP;
|
||||
sampler.TCYAddressControlMode = TCM_CLAMP;
|
||||
sampler.TCZAddressControlMode = TCM_CLAMP;
|
||||
sampler.MaximumAnisotropy = RATIO21;
|
||||
sampler.RAddressMinFilterRoundingEnable = true;
|
||||
sampler.RAddressMagFilterRoundingEnable = true;
|
||||
sampler.VAddressMinFilterRoundingEnable = true;
|
||||
sampler.VAddressMagFilterRoundingEnable = true;
|
||||
sampler.UAddressMinFilterRoundingEnable = true;
|
||||
sampler.UAddressMagFilterRoundingEnable = true;
|
||||
sampler.NonnormalizedCoordinateEnable = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BLORP_GENX_EXEC_BRW_H */
|
||||
|
||||
@@ -116,6 +116,13 @@ blorp_get_surface_base_address(struct blorp_batch *batch)
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t
|
||||
blorp_get_dynamic_state(struct blorp_batch *batch,
|
||||
enum blorp_dynamic_state name)
|
||||
{
|
||||
unreachable("Not implemented");
|
||||
}
|
||||
|
||||
static void *
|
||||
blorp_alloc_dynamic_state(struct blorp_batch *batch,
|
||||
uint32_t size,
|
||||
|
||||
Reference in New Issue
Block a user