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 || if (ctx->last.dirty ||
(ctx->last.primitive_restart != emit->primitive_restart)) { (ctx->last.primitive_restart != emit->primitive_restart)) {
/* rasterizer state is effected by 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; 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; 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: */ /* mark all state dirty: */
static inline void static inline void
fd_context_all_dirty(struct fd_context *ctx) 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); struct fd_context *ctx = fd_context(pctx);
ctx->prog.vs = hwcso; ctx->prog.vs = hwcso;
ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG; fd_context_dirty_shader(ctx, PIPE_SHADER_VERTEX, FD_DIRTY_SHADER_PROG);
ctx->dirty |= FD_DIRTY_PROG;
} }
static void static void
@ -48,8 +47,7 @@ fd_tcs_state_bind(struct pipe_context *pctx, void *hwcso)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->prog.hs = hwcso; ctx->prog.hs = hwcso;
ctx->dirty_shader[PIPE_SHADER_TESS_CTRL] |= FD_DIRTY_SHADER_PROG; fd_context_dirty_shader(ctx, PIPE_SHADER_TESS_CTRL, FD_DIRTY_SHADER_PROG);
ctx->dirty |= FD_DIRTY_PROG;
} }
static void static void
@ -58,8 +56,7 @@ fd_tes_state_bind(struct pipe_context *pctx, void *hwcso)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->prog.ds = hwcso; ctx->prog.ds = hwcso;
ctx->dirty_shader[PIPE_SHADER_TESS_EVAL] |= FD_DIRTY_SHADER_PROG; fd_context_dirty_shader(ctx, PIPE_SHADER_TESS_EVAL, FD_DIRTY_SHADER_PROG);
ctx->dirty |= FD_DIRTY_PROG;
} }
static void static void
@ -68,8 +65,7 @@ fd_gs_state_bind(struct pipe_context *pctx, void *hwcso)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->prog.gs = hwcso; ctx->prog.gs = hwcso;
ctx->dirty_shader[PIPE_SHADER_GEOMETRY] |= FD_DIRTY_SHADER_PROG; fd_context_dirty_shader(ctx, PIPE_SHADER_GEOMETRY, FD_DIRTY_SHADER_PROG);
ctx->dirty |= FD_DIRTY_PROG;
} }
static void static void
@ -78,8 +74,7 @@ fd_fs_state_bind(struct pipe_context *pctx, void *hwcso)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->prog.fs = hwcso; ctx->prog.fs = hwcso;
ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG; fd_context_dirty_shader(ctx, PIPE_SHADER_FRAGMENT, FD_DIRTY_SHADER_PROG);
ctx->dirty |= FD_DIRTY_PROG;
} }
static const char *solid_fs = 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; struct fd_vertexbuf_stateobj *vb = &ctx->vtx.vertexbuf;
for (unsigned i = 0; i < vb->count && !(ctx->dirty & FD_DIRTY_VTXBUF); i++) { for (unsigned i = 0; i < vb->count && !(ctx->dirty & FD_DIRTY_VTXBUF); i++) {
if (vb->vb[i].buffer.resource == prsc) 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); const unsigned num_ubos = util_last_bit(cb->enabled_mask);
for (unsigned i = 0; i < num_ubos; i++) { for (unsigned i = 0; i < num_ubos; i++) {
if (cb->cb[i].buffer == prsc) { if (cb->cb[i].buffer == prsc) {
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_CONST; fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_CONST);
ctx->dirty |= FD_DIRTY_CONST;
break; 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]; struct fd_texture_stateobj *tex = &ctx->tex[stage];
for (unsigned i = 0; i < tex->num_textures; i++) { for (unsigned i = 0; i < tex->num_textures; i++) {
if (tex->textures[i] && (tex->textures[i]->texture == prsc)) { if (tex->textures[i] && (tex->textures[i]->texture == prsc)) {
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_TEX; fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_TEX);
ctx->dirty |= FD_DIRTY_TEX;
break; 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); const unsigned num_images = util_last_bit(si->enabled_mask);
for (unsigned i = 0; i < num_images; i++) { for (unsigned i = 0; i < num_images; i++) {
if (si->si[i].resource == prsc) { if (si->si[i].resource == prsc) {
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_IMAGE; fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_IMAGE);
ctx->dirty |= FD_DIRTY_IMAGE;
break; 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); const unsigned num_ssbos = util_last_bit(sb->enabled_mask);
for (unsigned i = 0; i < num_ssbos; i++) { for (unsigned i = 0; i < num_ssbos; i++) {
if (sb->sb[i].buffer == prsc) { if (sb->sb[i].buffer == prsc) {
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_SSBO; fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_SSBO);
ctx->dirty |= FD_DIRTY_SSBO;
break; break;
} }
} }
@ -1393,13 +1389,13 @@ fd_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
if (pfb->zsbuf && pfb->zsbuf->texture == prsc) { if (pfb->zsbuf && pfb->zsbuf->texture == prsc) {
batch->resolve &= ~(FD_BUFFER_DEPTH | FD_BUFFER_STENCIL); 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++) { for (unsigned i = 0; i < pfb->nr_cbufs; i++) {
if (pfb->cbufs[i] && pfb->cbufs[i]->texture == prsc) { if (pfb->cbufs[i] && pfb->cbufs[i]->texture == prsc) {
batch->resolve &= ~(PIPE_CLEAR_COLOR0 << i); 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); struct fd_context *ctx = fd_context(pctx);
ctx->blend_color = *blend_color; ctx->blend_color = *blend_color;
ctx->dirty |= FD_DIRTY_BLEND_COLOR; fd_context_dirty(ctx, FD_DIRTY_BLEND_COLOR);
} }
static void static void
@ -60,7 +60,7 @@ fd_set_stencil_ref(struct pipe_context *pctx,
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->stencil_ref = stencil_ref; ctx->stencil_ref = stencil_ref;
ctx->dirty |= FD_DIRTY_STENCIL_REF; fd_context_dirty(ctx, FD_DIRTY_STENCIL_REF);
} }
static void static void
@ -70,7 +70,7 @@ fd_set_clip_state(struct pipe_context *pctx,
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->ucp = *clip; ctx->ucp = *clip;
ctx->dirty |= FD_DIRTY_UCP; fd_context_dirty(ctx, FD_DIRTY_UCP);
} }
static void static void
@ -79,7 +79,7 @@ fd_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->sample_mask = (uint16_t)sample_mask; ctx->sample_mask = (uint16_t)sample_mask;
ctx->dirty |= FD_DIRTY_SAMPLE_MASK; fd_context_dirty(ctx, FD_DIRTY_SAMPLE_MASK);
} }
static void static void
@ -88,7 +88,7 @@ fd_set_min_samples(struct pipe_context *pctx, unsigned min_samples)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->min_samples = min_samples; 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: /* notes from calim on #dri-devel:
@ -120,9 +120,8 @@ fd_set_constant_buffer(struct pipe_context *pctx,
} }
so->enabled_mask |= 1 << index; 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); 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; fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_SSBO);
ctx->dirty |= FD_DIRTY_SSBO;
} }
void void
@ -220,8 +218,7 @@ fd_set_shader_images(struct pipe_context *pctx,
so->enabled_mask &= ~(BITFIELD_MASK(unbind_num_trailing_slots) << (start + count)); so->enabled_mask &= ~(BITFIELD_MASK(unbind_num_trailing_slots) << (start + count));
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_IMAGE; fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_IMAGE);
ctx->dirty |= FD_DIRTY_IMAGE;
} }
static void static void
@ -282,14 +279,14 @@ fd_set_framebuffer_state(struct pipe_context *pctx,
fd_batch_flush(ctx->batch); 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.minx = 0;
ctx->disabled_scissor.miny = 0; ctx->disabled_scissor.miny = 0;
ctx->disabled_scissor.maxx = cso->width; ctx->disabled_scissor.maxx = cso->width;
ctx->disabled_scissor.maxy = cso->height; ctx->disabled_scissor.maxy = cso->height;
ctx->dirty |= FD_DIRTY_SCISSOR; fd_context_dirty(ctx, FD_DIRTY_SCISSOR);
} }
static void static void
@ -299,7 +296,7 @@ fd_set_polygon_stipple(struct pipe_context *pctx,
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->stipple = *stipple; ctx->stipple = *stipple;
ctx->dirty |= FD_DIRTY_STIPPLE; fd_context_dirty(ctx, FD_DIRTY_STIPPLE);
} }
static void static void
@ -312,7 +309,7 @@ fd_set_scissor_states(struct pipe_context *pctx,
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->scissor = *scissor; ctx->scissor = *scissor;
ctx->dirty |= FD_DIRTY_SCISSOR; fd_context_dirty(ctx, FD_DIRTY_SCISSOR);
} }
static void static void
@ -352,7 +349,7 @@ fd_set_viewport_states(struct pipe_context *pctx,
scissor->maxx = CLAMP(ceilf(maxx), 0.f, max_dims); scissor->maxx = CLAMP(ceilf(maxx), 0.f, max_dims);
scissor->maxy = CLAMP(ceilf(maxy), 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 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 new_stride = vb ? vb[i].stride : 0;
uint32_t old_stride = so->vb[i].stride; uint32_t old_stride = so->vb[i].stride;
if ((new_enabled != old_enabled) || (new_stride != old_stride)) { if ((new_enabled != old_enabled) || (new_stride != old_stride)) {
ctx->dirty |= FD_DIRTY_VTXSTATE; fd_context_dirty(ctx, FD_DIRTY_VTXSTATE);
break; break;
} }
} }
@ -392,7 +389,7 @@ fd_set_vertex_buffers(struct pipe_context *pctx,
if (!vb) if (!vb)
return; return;
ctx->dirty |= FD_DIRTY_VTXBUF; fd_context_dirty(ctx, FD_DIRTY_VTXBUF);
for (unsigned i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
assert(!vb[i].is_user_buffer); 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) : cso->rt[0].blend_enable && util_blend_state_is_dual(cso, 0) :
false; false;
ctx->blend = hwcso; ctx->blend = hwcso;
ctx->dirty |= FD_DIRTY_BLEND; fd_context_dirty(ctx, FD_DIRTY_BLEND);
if (old_is_dual != new_is_dual) if (old_is_dual != new_is_dual)
ctx->dirty |= FD_DIRTY_BLEND_DUAL; fd_context_dirty(ctx, FD_DIRTY_BLEND_DUAL);
} }
static void static void
@ -434,7 +431,7 @@ fd_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)
bool discard = ctx->rasterizer && ctx->rasterizer->rasterizer_discard; bool discard = ctx->rasterizer && ctx->rasterizer->rasterizer_discard;
ctx->rasterizer = hwcso; ctx->rasterizer = hwcso;
ctx->dirty |= FD_DIRTY_RASTERIZER; fd_context_dirty(ctx, FD_DIRTY_RASTERIZER);
if (ctx->rasterizer && ctx->rasterizer->scissor) { if (ctx->rasterizer && ctx->rasterizer->scissor) {
ctx->current_scissor = &ctx->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 it changed to/from &ctx->disable_scissor
*/ */
if (old_scissor != fd_context_get_scissor(ctx)) 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)) if (ctx->rasterizer && (discard != ctx->rasterizer->rasterizer_discard))
ctx->dirty |= FD_DIRTY_RASTERIZER_DISCARD; fd_context_dirty(ctx, FD_DIRTY_RASTERIZER_DISCARD);
} }
static void static void
@ -467,7 +464,7 @@ fd_zsa_state_bind(struct pipe_context *pctx, void *hwcso)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->zsa = hwcso; ctx->zsa = hwcso;
ctx->dirty |= FD_DIRTY_ZSA; fd_context_dirty(ctx, FD_DIRTY_ZSA);
} }
static void static void
@ -505,7 +502,7 @@ fd_vertex_state_bind(struct pipe_context *pctx, void *hwcso)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->vtx.vtx = hwcso; ctx->vtx.vtx = hwcso;
ctx->dirty |= FD_DIRTY_VTXSTATE; fd_context_dirty(ctx, FD_DIRTY_VTXSTATE);
} }
static struct pipe_stream_output_target * static struct pipe_stream_output_target *
@ -582,7 +579,7 @@ fd_set_stream_output_targets(struct pipe_context *pctx,
so->num_targets = num_targets; so->num_targets = num_targets;
ctx->dirty |= FD_DIRTY_STREAMOUT; fd_context_dirty(ctx, FD_DIRTY_STREAMOUT);
} }
static void static void
@ -591,6 +588,7 @@ fd_bind_compute_state(struct pipe_context *pctx, void *state)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
ctx->compute = state; ctx->compute = state;
/* NOTE: Don't mark FD_DIRTY_PROG for compute specific state */
ctx->dirty_shader[PIPE_SHADER_COMPUTE] |= FD_DIRTY_SHADER_PROG; 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); struct fd_context *ctx = fd_context(pctx);
bind_sampler_states(&ctx->tex[shader], start, nr, hwcso); bind_sampler_states(&ctx->tex[shader], start, nr, hwcso);
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX; fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_TEX);
ctx->dirty |= FD_DIRTY_TEX;
} }
void 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); struct fd_context *ctx = fd_context(pctx);
set_sampler_views(&ctx->tex[shader], start, nr, unbind_num_trailing_slots, views); set_sampler_views(&ctx->tex[shader], start, nr, unbind_num_trailing_slots, views);
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX; fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_TEX);
ctx->dirty |= FD_DIRTY_TEX;
} }
void 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_equal(ctx->last.key, key)) {
if (ir3_shader_key_changes_fs(ctx->last.key, key)) { if (ir3_shader_key_changes_fs(ctx->last.key, key)) {
ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG; fd_context_dirty_shader(ctx, PIPE_SHADER_FRAGMENT, FD_DIRTY_SHADER_PROG);
ctx->dirty |= FD_DIRTY_PROG;
} }
if (ir3_shader_key_changes_vs(ctx->last.key, key)) { if (ir3_shader_key_changes_vs(ctx->last.key, key)) {
ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG; fd_context_dirty_shader(ctx, PIPE_SHADER_VERTEX, FD_DIRTY_SHADER_PROG);
ctx->dirty |= FD_DIRTY_PROG;
} }
/* NOTE: currently only a6xx has gs/tess, but needs no /* NOTE: currently only a6xx has gs/tess, but needs no