freedreno: Add helpers to mark dirty state

Doesn't change anything yet, but this will let us more easily add
mapping from dirty gallium state to dirty gen-specific state-groups.

Note that the mapping from shader-state to global state in
fd_context_dirty_shader() optimizes out for release builds.  This
is kind of important, in the next patch we'll want ffs(SOME_CONST)
to optimize away even more.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9581>
This commit is contained in:
Rob Clark 2021-03-12 11:38:59 -08:00
parent 9aef029635
commit 0cb989d71f
7 changed files with 77 additions and 56 deletions

View File

@ -135,7 +135,7 @@ fixup_draw_state(struct fd_context *ctx, struct fd6_emit *emit)
if (ctx->last.dirty ||
(ctx->last.primitive_restart != emit->primitive_restart)) {
/* rasterizer state is effected by primitive-restart: */
ctx->dirty |= FD_DIRTY_RASTERIZER;
fd_context_dirty(ctx, FD_DIRTY_RASTERIZER);
ctx->last.primitive_restart = emit->primitive_restart;
}
}

View File

@ -496,6 +496,42 @@ fd_stream_output_target(struct pipe_stream_output_target *target)
return (struct fd_stream_output_target *)target;
}
/* Mark specified non-shader-stage related state as dirty: */
static inline void
fd_context_dirty(struct fd_context *ctx, enum fd_dirty_3d_state dirty)
assert_dt
{
assert(util_is_power_of_two_nonzero(dirty));
ctx->dirty |= dirty;
}
static inline void
fd_context_dirty_shader(struct fd_context *ctx, enum pipe_shader_type shader,
enum fd_dirty_shader_state dirty)
assert_dt
{
const enum fd_dirty_3d_state map[] = {
FD_DIRTY_PROG,
FD_DIRTY_CONST,
FD_DIRTY_TEX,
FD_DIRTY_SSBO,
FD_DIRTY_IMAGE,
};
/* Need to update the table above if these shift: */
STATIC_ASSERT(FD_DIRTY_SHADER_PROG == BIT(0));
STATIC_ASSERT(FD_DIRTY_SHADER_CONST == BIT(1));
STATIC_ASSERT(FD_DIRTY_SHADER_TEX == BIT(2));
STATIC_ASSERT(FD_DIRTY_SHADER_SSBO == BIT(3));
STATIC_ASSERT(FD_DIRTY_SHADER_IMAGE == BIT(4));
assert(util_is_power_of_two_nonzero(dirty));
assert(ffs(dirty) <= ARRAY_SIZE(map));
ctx->dirty_shader[shader] |= dirty;
fd_context_dirty(ctx, map[ffs(dirty) - 1]);
}
/* mark all state dirty: */
static inline void
fd_context_all_dirty(struct fd_context *ctx)

View File

@ -38,8 +38,7 @@ fd_vs_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->prog.vs = hwcso;
ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
ctx->dirty |= FD_DIRTY_PROG;
fd_context_dirty_shader(ctx, PIPE_SHADER_VERTEX, FD_DIRTY_SHADER_PROG);
}
static void
@ -48,8 +47,7 @@ fd_tcs_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->prog.hs = hwcso;
ctx->dirty_shader[PIPE_SHADER_TESS_CTRL] |= FD_DIRTY_SHADER_PROG;
ctx->dirty |= FD_DIRTY_PROG;
fd_context_dirty_shader(ctx, PIPE_SHADER_TESS_CTRL, FD_DIRTY_SHADER_PROG);
}
static void
@ -58,8 +56,7 @@ fd_tes_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->prog.ds = hwcso;
ctx->dirty_shader[PIPE_SHADER_TESS_EVAL] |= FD_DIRTY_SHADER_PROG;
ctx->dirty |= FD_DIRTY_PROG;
fd_context_dirty_shader(ctx, PIPE_SHADER_TESS_EVAL, FD_DIRTY_SHADER_PROG);
}
static void
@ -68,8 +65,7 @@ fd_gs_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->prog.gs = hwcso;
ctx->dirty_shader[PIPE_SHADER_GEOMETRY] |= FD_DIRTY_SHADER_PROG;
ctx->dirty |= FD_DIRTY_PROG;
fd_context_dirty_shader(ctx, PIPE_SHADER_GEOMETRY, FD_DIRTY_SHADER_PROG);
}
static void
@ -78,8 +74,7 @@ fd_fs_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->prog.fs = hwcso;
ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
ctx->dirty |= FD_DIRTY_PROG;
fd_context_dirty_shader(ctx, PIPE_SHADER_FRAGMENT, FD_DIRTY_SHADER_PROG);
}
static const char *solid_fs =

View File

@ -80,7 +80,7 @@ rebind_resource_in_ctx(struct fd_context *ctx, struct fd_resource *rsc)
struct fd_vertexbuf_stateobj *vb = &ctx->vtx.vertexbuf;
for (unsigned i = 0; i < vb->count && !(ctx->dirty & FD_DIRTY_VTXBUF); i++) {
if (vb->vb[i].buffer.resource == prsc)
ctx->dirty |= FD_DIRTY_VTXBUF;
fd_context_dirty(ctx, FD_DIRTY_VTXBUF);
}
}
@ -101,8 +101,7 @@ rebind_resource_in_ctx(struct fd_context *ctx, struct fd_resource *rsc)
const unsigned num_ubos = util_last_bit(cb->enabled_mask);
for (unsigned i = 0; i < num_ubos; i++) {
if (cb->cb[i].buffer == prsc) {
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_CONST;
ctx->dirty |= FD_DIRTY_CONST;
fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_CONST);
break;
}
}
@ -114,8 +113,7 @@ rebind_resource_in_ctx(struct fd_context *ctx, struct fd_resource *rsc)
struct fd_texture_stateobj *tex = &ctx->tex[stage];
for (unsigned i = 0; i < tex->num_textures; i++) {
if (tex->textures[i] && (tex->textures[i]->texture == prsc)) {
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_TEX;
ctx->dirty |= FD_DIRTY_TEX;
fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_TEX);
break;
}
}
@ -128,8 +126,7 @@ rebind_resource_in_ctx(struct fd_context *ctx, struct fd_resource *rsc)
const unsigned num_images = util_last_bit(si->enabled_mask);
for (unsigned i = 0; i < num_images; i++) {
if (si->si[i].resource == prsc) {
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_IMAGE;
ctx->dirty |= FD_DIRTY_IMAGE;
fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_IMAGE);
break;
}
}
@ -142,8 +139,7 @@ rebind_resource_in_ctx(struct fd_context *ctx, struct fd_resource *rsc)
const unsigned num_ssbos = util_last_bit(sb->enabled_mask);
for (unsigned i = 0; i < num_ssbos; i++) {
if (sb->sb[i].buffer == prsc) {
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_SSBO;
ctx->dirty |= FD_DIRTY_SSBO;
fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_SSBO);
break;
}
}
@ -1393,13 +1389,13 @@ fd_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
if (pfb->zsbuf && pfb->zsbuf->texture == prsc) {
batch->resolve &= ~(FD_BUFFER_DEPTH | FD_BUFFER_STENCIL);
ctx->dirty |= FD_DIRTY_ZSA;
fd_context_dirty(ctx, FD_DIRTY_ZSA);
}
for (unsigned i = 0; i < pfb->nr_cbufs; i++) {
if (pfb->cbufs[i] && pfb->cbufs[i]->texture == prsc) {
batch->resolve &= ~(PIPE_CLEAR_COLOR0 << i);
ctx->dirty |= FD_DIRTY_FRAMEBUFFER;
fd_context_dirty(ctx, FD_DIRTY_FRAMEBUFFER);
}
}
}

View File

@ -50,7 +50,7 @@ fd_set_blend_color(struct pipe_context *pctx,
{
struct fd_context *ctx = fd_context(pctx);
ctx->blend_color = *blend_color;
ctx->dirty |= FD_DIRTY_BLEND_COLOR;
fd_context_dirty(ctx, FD_DIRTY_BLEND_COLOR);
}
static void
@ -60,7 +60,7 @@ fd_set_stencil_ref(struct pipe_context *pctx,
{
struct fd_context *ctx = fd_context(pctx);
ctx->stencil_ref = stencil_ref;
ctx->dirty |= FD_DIRTY_STENCIL_REF;
fd_context_dirty(ctx, FD_DIRTY_STENCIL_REF);
}
static void
@ -70,7 +70,7 @@ fd_set_clip_state(struct pipe_context *pctx,
{
struct fd_context *ctx = fd_context(pctx);
ctx->ucp = *clip;
ctx->dirty |= FD_DIRTY_UCP;
fd_context_dirty(ctx, FD_DIRTY_UCP);
}
static void
@ -79,7 +79,7 @@ fd_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
{
struct fd_context *ctx = fd_context(pctx);
ctx->sample_mask = (uint16_t)sample_mask;
ctx->dirty |= FD_DIRTY_SAMPLE_MASK;
fd_context_dirty(ctx, FD_DIRTY_SAMPLE_MASK);
}
static void
@ -88,7 +88,7 @@ fd_set_min_samples(struct pipe_context *pctx, unsigned min_samples)
{
struct fd_context *ctx = fd_context(pctx);
ctx->min_samples = min_samples;
ctx->dirty |= FD_DIRTY_MIN_SAMPLES;
fd_context_dirty(ctx, FD_DIRTY_MIN_SAMPLES);
}
/* notes from calim on #dri-devel:
@ -120,9 +120,8 @@ fd_set_constant_buffer(struct pipe_context *pctx,
}
so->enabled_mask |= 1 << index;
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_CONST;
ctx->dirty |= FD_DIRTY_CONST;
fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_CONST);
fd_resource_set_usage(cb->buffer, FD_DIRTY_CONST);
}
@ -164,8 +163,7 @@ fd_set_shader_buffers(struct pipe_context *pctx,
}
}
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_SSBO;
ctx->dirty |= FD_DIRTY_SSBO;
fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_SSBO);
}
void
@ -220,8 +218,7 @@ fd_set_shader_images(struct pipe_context *pctx,
so->enabled_mask &= ~(BITFIELD_MASK(unbind_num_trailing_slots) << (start + count));
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_IMAGE;
ctx->dirty |= FD_DIRTY_IMAGE;
fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_IMAGE);
}
static void
@ -282,14 +279,14 @@ fd_set_framebuffer_state(struct pipe_context *pctx,
fd_batch_flush(ctx->batch);
}
ctx->dirty |= FD_DIRTY_FRAMEBUFFER;
fd_context_dirty(ctx, FD_DIRTY_FRAMEBUFFER);
ctx->disabled_scissor.minx = 0;
ctx->disabled_scissor.miny = 0;
ctx->disabled_scissor.maxx = cso->width;
ctx->disabled_scissor.maxy = cso->height;
ctx->dirty |= FD_DIRTY_SCISSOR;
fd_context_dirty(ctx, FD_DIRTY_SCISSOR);
}
static void
@ -299,7 +296,7 @@ fd_set_polygon_stipple(struct pipe_context *pctx,
{
struct fd_context *ctx = fd_context(pctx);
ctx->stipple = *stipple;
ctx->dirty |= FD_DIRTY_STIPPLE;
fd_context_dirty(ctx, FD_DIRTY_STIPPLE);
}
static void
@ -312,7 +309,7 @@ fd_set_scissor_states(struct pipe_context *pctx,
struct fd_context *ctx = fd_context(pctx);
ctx->scissor = *scissor;
ctx->dirty |= FD_DIRTY_SCISSOR;
fd_context_dirty(ctx, FD_DIRTY_SCISSOR);
}
static void
@ -352,7 +349,7 @@ fd_set_viewport_states(struct pipe_context *pctx,
scissor->maxx = CLAMP(ceilf(maxx), 0.f, max_dims);
scissor->maxy = CLAMP(ceilf(maxy), 0.f, max_dims);
ctx->dirty |= FD_DIRTY_VIEWPORT;
fd_context_dirty(ctx, FD_DIRTY_VIEWPORT);
}
static void
@ -378,7 +375,7 @@ fd_set_vertex_buffers(struct pipe_context *pctx,
uint32_t new_stride = vb ? vb[i].stride : 0;
uint32_t old_stride = so->vb[i].stride;
if ((new_enabled != old_enabled) || (new_stride != old_stride)) {
ctx->dirty |= FD_DIRTY_VTXSTATE;
fd_context_dirty(ctx, FD_DIRTY_VTXSTATE);
break;
}
}
@ -392,7 +389,7 @@ fd_set_vertex_buffers(struct pipe_context *pctx,
if (!vb)
return;
ctx->dirty |= FD_DIRTY_VTXBUF;
fd_context_dirty(ctx, FD_DIRTY_VTXBUF);
for (unsigned i = 0; i < count; i++) {
assert(!vb[i].is_user_buffer);
@ -413,9 +410,9 @@ fd_blend_state_bind(struct pipe_context *pctx, void *hwcso)
cso->rt[0].blend_enable && util_blend_state_is_dual(cso, 0) :
false;
ctx->blend = hwcso;
ctx->dirty |= FD_DIRTY_BLEND;
fd_context_dirty(ctx, FD_DIRTY_BLEND);
if (old_is_dual != new_is_dual)
ctx->dirty |= FD_DIRTY_BLEND_DUAL;
fd_context_dirty(ctx, FD_DIRTY_BLEND_DUAL);
}
static void
@ -434,7 +431,7 @@ fd_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)
bool discard = ctx->rasterizer && ctx->rasterizer->rasterizer_discard;
ctx->rasterizer = hwcso;
ctx->dirty |= FD_DIRTY_RASTERIZER;
fd_context_dirty(ctx, FD_DIRTY_RASTERIZER);
if (ctx->rasterizer && ctx->rasterizer->scissor) {
ctx->current_scissor = &ctx->scissor;
@ -448,10 +445,10 @@ fd_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)
* if it changed to/from &ctx->disable_scissor
*/
if (old_scissor != fd_context_get_scissor(ctx))
ctx->dirty |= FD_DIRTY_SCISSOR;
fd_context_dirty(ctx, FD_DIRTY_SCISSOR);
if (ctx->rasterizer && (discard != ctx->rasterizer->rasterizer_discard))
ctx->dirty |= FD_DIRTY_RASTERIZER_DISCARD;
fd_context_dirty(ctx, FD_DIRTY_RASTERIZER_DISCARD);
}
static void
@ -467,7 +464,7 @@ fd_zsa_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->zsa = hwcso;
ctx->dirty |= FD_DIRTY_ZSA;
fd_context_dirty(ctx, FD_DIRTY_ZSA);
}
static void
@ -505,7 +502,7 @@ fd_vertex_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->vtx.vtx = hwcso;
ctx->dirty |= FD_DIRTY_VTXSTATE;
fd_context_dirty(ctx, FD_DIRTY_VTXSTATE);
}
static struct pipe_stream_output_target *
@ -582,7 +579,7 @@ fd_set_stream_output_targets(struct pipe_context *pctx,
so->num_targets = num_targets;
ctx->dirty |= FD_DIRTY_STREAMOUT;
fd_context_dirty(ctx, FD_DIRTY_STREAMOUT);
}
static void
@ -591,6 +588,7 @@ fd_bind_compute_state(struct pipe_context *pctx, void *state)
{
struct fd_context *ctx = fd_context(pctx);
ctx->compute = state;
/* NOTE: Don't mark FD_DIRTY_PROG for compute specific state */
ctx->dirty_shader[PIPE_SHADER_COMPUTE] |= FD_DIRTY_SHADER_PROG;
}

View File

@ -109,8 +109,7 @@ fd_sampler_states_bind(struct pipe_context *pctx,
struct fd_context *ctx = fd_context(pctx);
bind_sampler_states(&ctx->tex[shader], start, nr, hwcso);
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX;
ctx->dirty |= FD_DIRTY_TEX;
fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_TEX);
}
void
@ -122,8 +121,7 @@ fd_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader,
struct fd_context *ctx = fd_context(pctx);
set_sampler_views(&ctx->tex[shader], start, nr, unbind_num_trailing_slots, views);
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX;
ctx->dirty |= FD_DIRTY_TEX;
fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_TEX);
}
void

View File

@ -454,13 +454,11 @@ ir3_fixup_shader_state(struct pipe_context *pctx, struct ir3_shader_key *key)
if (!ir3_shader_key_equal(ctx->last.key, key)) {
if (ir3_shader_key_changes_fs(ctx->last.key, key)) {
ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
ctx->dirty |= FD_DIRTY_PROG;
fd_context_dirty_shader(ctx, PIPE_SHADER_FRAGMENT, FD_DIRTY_SHADER_PROG);
}
if (ir3_shader_key_changes_vs(ctx->last.key, key)) {
ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
ctx->dirty |= FD_DIRTY_PROG;
fd_context_dirty_shader(ctx, PIPE_SHADER_VERTEX, FD_DIRTY_SHADER_PROG);
}
/* NOTE: currently only a6xx has gs/tess, but needs no