summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2017-04-15 10:04:55 -0400
committerRob Clark <[email protected]>2017-04-18 16:32:00 -0400
commit4299849ec7a873edf46a3a366749282fdec020fe (patch)
treed1fdc58b6fc65ad2c9fdbe096a4c3acd4eea3a6b /src/gallium/drivers
parentd7fa7f5e7eafed8bb88f7e0b9ba4261a76ad9c95 (diff)
freedreno: refactor dirty state handling
In particular, move per-shader-stage info out to a seperate array of enum's indexed by shader stage. This will make it easier to add more shader stages as well as new per-stage state (like SSBOs). Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_draw.c5
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_emit.c6
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_emit.h2
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_program.c6
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_draw.c6
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c8
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.h2
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_draw.c8
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_emit.c6
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_emit.h2
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_draw.c6
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_emit.c6
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_emit.h2
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.h72
-rw-r--r--src/gallium/drivers/freedreno/freedreno_program.c6
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c40
-rw-r--r--src/gallium/drivers/freedreno/freedreno_state.c3
-rw-r--r--src/gallium/drivers/freedreno/freedreno_texture.c22
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_shader.c12
19 files changed, 119 insertions, 101 deletions
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c
index feec59fa5de..f360ec2f6e2 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c
@@ -284,9 +284,12 @@ fd2_clear(struct fd_context *ctx, unsigned buffers,
FD_DIRTY_RASTERIZER |
FD_DIRTY_SAMPLE_MASK |
FD_DIRTY_PROG |
- FD_DIRTY_CONSTBUF |
+ FD_DIRTY_CONST |
FD_DIRTY_BLEND |
FD_DIRTY_FRAMEBUFFER;
+
+ ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG | FD_DIRTY_SHADER_CONST;
}
void
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c
index fe2750ba10b..d745e44b0ad 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c
@@ -182,7 +182,7 @@ fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
}
void
-fd2_emit_state(struct fd_context *ctx, const uint32_t dirty)
+fd2_emit_state(struct fd_context *ctx, const enum fd_dirty_3d_state dirty)
{
struct fd2_blend_stateobj *blend = fd2_blend_stateobj(ctx->blend);
struct fd2_zsa_stateobj *zsa = fd2_zsa_stateobj(ctx->zsa);
@@ -284,7 +284,7 @@ fd2_emit_state(struct fd_context *ctx, const uint32_t dirty)
fd2_program_emit(ring, &ctx->prog);
}
- if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+ if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONST)) {
emit_constants(ring, VS_CONST_BASE * 4,
&ctx->constbuf[PIPE_SHADER_VERTEX],
(dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL);
@@ -309,7 +309,7 @@ fd2_emit_state(struct fd_context *ctx, const uint32_t dirty)
OUT_RING(ring, blend->rb_colormask);
}
- if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX | FD_DIRTY_PROG))
+ if (dirty & (FD_DIRTY_TEX | FD_DIRTY_PROG))
emit_textures(ring, ctx);
}
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_emit.h b/src/gallium/drivers/freedreno/a2xx/fd2_emit.h
index 6a26c85c142..d908b113514 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_emit.h
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_emit.h
@@ -42,7 +42,7 @@ struct fd2_vertex_buf {
void fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
struct fd2_vertex_buf *vbufs, uint32_t n);
-void fd2_emit_state(struct fd_context *ctx, uint32_t dirty);
+void fd2_emit_state(struct fd_context *ctx, enum fd_dirty_3d_state dirty);
void fd2_emit_restore(struct fd_context *ctx, struct fd_ringbuffer *ring);
void fd2_emit_init(struct pipe_context *pctx);
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_program.c b/src/gallium/drivers/freedreno/a2xx/fd2_program.c
index 8dcbb979383..9a774572514 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_program.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_program.c
@@ -241,16 +241,18 @@ void
fd2_program_validate(struct fd_context *ctx)
{
struct fd_program_stateobj *prog = &ctx->prog;
+ bool dirty_fp = !!(ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_PROG);
+ bool dirty_vp = !!(ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_PROG);
/* if vertex or frag shader is dirty, we may need to recompile. Compile
* frag shader first, as that assigns the register slots for exports
* from the vertex shader. And therefore if frag shader has changed we
* need to recompile both vert and frag shader.
*/
- if (ctx->dirty & FD_SHADER_DIRTY_FP)
+ if (dirty_fp)
compile(prog, prog->fp);
- if (ctx->dirty & (FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP))
+ if (dirty_fp || dirty_vp)
compile(prog, prog->vp);
/* if necessary, fix up vertex fetch instructions: */
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
index c36e5071660..b3e42f37a2a 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
@@ -101,11 +101,13 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
if (!ir3_shader_key_equal(last_key, key)) {
if (ir3_shader_key_changes_fs(last_key, key)) {
- ctx->dirty |= FD_SHADER_DIRTY_FP;
+ ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty |= FD_DIRTY_PROG;
}
if (ir3_shader_key_changes_vs(last_key, key)) {
- ctx->dirty |= FD_SHADER_DIRTY_VP;
+ ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty |= FD_DIRTY_PROG;
}
fd3_ctx->last_key = *key;
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 04e3300efde..ca97a08d544 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -490,7 +490,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
{
const struct ir3_shader_variant *vp = fd3_emit_get_vp(emit);
const struct ir3_shader_variant *fp = fd3_emit_get_fp(emit);
- const uint32_t dirty = emit->dirty;
+ const enum fd_dirty_3d_state dirty = emit->dirty;
emit_marker(ring, 5);
@@ -783,13 +783,13 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
A3XX_RB_BLEND_ALPHA_FLOAT(bcolor->color[3]));
}
- if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX))
+ if (dirty & FD_DIRTY_TEX)
fd_wfi(ctx->batch, ring);
- if (dirty & FD_DIRTY_VERTTEX)
+ if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX)
emit_textures(ctx, ring, SB_VERT_TEX, &ctx->tex[PIPE_SHADER_VERTEX]);
- if (dirty & FD_DIRTY_FRAGTEX)
+ if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX)
emit_textures(ctx, ring, SB_FRAG_TEX, &ctx->tex[PIPE_SHADER_FRAGMENT]);
}
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
index 6e7dee25daa..5e574da199d 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h
@@ -48,7 +48,7 @@ struct fd3_emit {
const struct fd_program_stateobj *prog;
const struct pipe_draw_info *info;
struct ir3_shader_key key;
- uint32_t dirty;
+ enum fd_dirty_3d_state dirty;
uint32_t sprite_coord_enable;
bool sprite_coord_mode;
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
index 869c69b25b3..a76f9e8c434 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
@@ -85,11 +85,13 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
if (!ir3_shader_key_equal(last_key, key)) {
if (ir3_shader_key_changes_fs(last_key, key)) {
- ctx->dirty |= FD_SHADER_DIRTY_FP;
+ ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty |= FD_DIRTY_PROG;
}
if (ir3_shader_key_changes_vs(last_key, key)) {
- ctx->dirty |= FD_SHADER_DIRTY_VP;
+ ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty |= FD_DIRTY_PROG;
}
fd4_ctx->last_key = *key;
@@ -131,7 +133,7 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
fixup_shader_state(ctx, &emit.key);
- unsigned dirty = ctx->dirty;
+ enum fd_dirty_3d_state dirty = ctx->dirty;
/* do regular pass first, since that is more likely to fail compiling: */
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
index 4c79a67ba59..f0a1fdea0df 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
@@ -499,7 +499,7 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
{
const struct ir3_shader_variant *vp = fd4_emit_get_vp(emit);
const struct ir3_shader_variant *fp = fd4_emit_get_fp(emit);
- const uint32_t dirty = emit->dirty;
+ const enum fd_dirty_3d_state dirty = emit->dirty;
emit_marker(ring, 5);
@@ -740,10 +740,10 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, A4XX_RB_BLEND_ALPHA_F32(bcolor->color[3]));
}
- if (dirty & FD_DIRTY_VERTTEX)
+ if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX)
emit_textures(ctx, ring, SB4_VS_TEX, &ctx->tex[PIPE_SHADER_VERTEX], vp);
- if (dirty & FD_DIRTY_FRAGTEX)
+ if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX)
emit_textures(ctx, ring, SB4_FS_TEX, &ctx->tex[PIPE_SHADER_FRAGMENT], fp);
}
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.h b/src/gallium/drivers/freedreno/a4xx/fd4_emit.h
index 00f92faaf35..a724caedc29 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.h
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.h
@@ -48,7 +48,7 @@ struct fd4_emit {
const struct fd_program_stateobj *prog;
const struct pipe_draw_info *info;
struct ir3_shader_key key;
- uint32_t dirty;
+ enum fd_dirty_3d_state dirty;
uint32_t sprite_coord_enable; /* bitmask */
bool sprite_coord_mode;
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
index 147f7070039..4ef0c7303d2 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
@@ -78,11 +78,13 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
if (!ir3_shader_key_equal(last_key, key)) {
if (ir3_shader_key_changes_fs(last_key, key)) {
- ctx->dirty |= FD_SHADER_DIRTY_FP;
+ ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty |= FD_DIRTY_PROG;
}
if (ir3_shader_key_changes_vs(last_key, key)) {
- ctx->dirty |= FD_SHADER_DIRTY_VP;
+ ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty |= FD_DIRTY_PROG;
}
fd5_ctx->last_key = *key;
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
index 1e5b6dbc292..f2c9a6b85d5 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
@@ -398,7 +398,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
{
const struct ir3_shader_variant *vp = fd5_emit_get_vp(emit);
const struct ir3_shader_variant *fp = fd5_emit_get_fp(emit);
- const uint32_t dirty = emit->dirty;
+ const enum fd_dirty_3d_state dirty = emit->dirty;
bool needs_border = false;
emit_marker5(ring, 5);
@@ -647,14 +647,14 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, A5XX_RB_BLEND_ALPHA_F32(bcolor->color[3]));
}
- if (dirty & FD_DIRTY_VERTTEX) {
+ if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX) {
needs_border |= emit_textures(ctx, ring, SB4_VS_TEX,
&ctx->tex[PIPE_SHADER_VERTEX]);
OUT_PKT4(ring, REG_A5XX_TPL1_VS_TEX_COUNT, 1);
OUT_RING(ring, ctx->tex[PIPE_SHADER_VERTEX].num_textures);
}
- if (dirty & FD_DIRTY_FRAGTEX) {
+ if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX) {
needs_border |= emit_textures(ctx, ring, SB4_FS_TEX,
&ctx->tex[PIPE_SHADER_FRAGMENT]);
OUT_PKT4(ring, REG_A5XX_TPL1_FS_TEX_COUNT, 1);
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.h b/src/gallium/drivers/freedreno/a5xx/fd5_emit.h
index 0525b3e7326..b18c0a8cb66 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.h
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.h
@@ -44,7 +44,7 @@ struct fd5_emit {
const struct fd_program_stateobj *prog;
const struct pipe_draw_info *info;
struct ir3_shader_key key;
- uint32_t dirty;
+ enum fd_dirty_3d_state dirty;
uint32_t sprite_coord_enable; /* bitmask */
bool sprite_coord_mode;
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index 7f47eaf2a71..733c64b1807 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -107,6 +107,42 @@ struct fd_vertex_state {
struct fd_vertexbuf_stateobj vertexbuf;
};
+/* global 3d pipeline dirty state: */
+enum fd_dirty_3d_state {
+ FD_DIRTY_BLEND = BIT(0),
+ FD_DIRTY_RASTERIZER = BIT(1),
+ FD_DIRTY_ZSA = BIT(2),
+ FD_DIRTY_BLEND_COLOR = BIT(3),
+ FD_DIRTY_STENCIL_REF = BIT(4),
+ FD_DIRTY_SAMPLE_MASK = BIT(5),
+ FD_DIRTY_FRAMEBUFFER = BIT(6),
+ FD_DIRTY_STIPPLE = BIT(7),
+ FD_DIRTY_VIEWPORT = BIT(8),
+ FD_DIRTY_VTXSTATE = BIT(9),
+ FD_DIRTY_VTXBUF = BIT(10),
+ FD_DIRTY_INDEXBUF = BIT(11),
+ FD_DIRTY_SCISSOR = BIT(12),
+ FD_DIRTY_STREAMOUT = BIT(13),
+ FD_DIRTY_UCP = BIT(14),
+ FD_DIRTY_BLEND_DUAL = BIT(15),
+
+ /* These are a bit redundent with fd_dirty_shader_state, and possibly
+ * should be removed. (But OTOH kinda convenient in some places)
+ */
+ FD_DIRTY_PROG = BIT(16),
+ FD_DIRTY_CONST = BIT(17),
+ FD_DIRTY_TEX = BIT(18),
+
+ /* only used by a2xx.. possibly can be removed.. */
+ FD_DIRTY_TEXSTATE = BIT(19),
+};
+
+/* per shader-stage dirty state: */
+enum fd_dirty_shader_state {
+ FD_DIRTY_SHADER_PROG = BIT(0),
+ FD_DIRTY_SHADER_CONST = BIT(1),
+ FD_DIRTY_SHADER_TEX = BIT(2),
+};
struct fd_context {
struct pipe_context base;
@@ -196,34 +232,10 @@ struct fd_context {
struct fd_tile tile[512];
/* which state objects need to be re-emit'd: */
- enum {
- FD_DIRTY_BLEND = (1 << 0),
- FD_DIRTY_RASTERIZER = (1 << 1),
- FD_DIRTY_ZSA = (1 << 2),
- FD_DIRTY_FRAGTEX = (1 << 3),
- FD_DIRTY_VERTTEX = (1 << 4),
- FD_DIRTY_TEXSTATE = (1 << 5),
-
- FD_SHADER_DIRTY_VP = (1 << 6),
- FD_SHADER_DIRTY_FP = (1 << 7),
- /* skip geom/tcs/tes/compute */
- FD_DIRTY_PROG = FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP,
-
- FD_DIRTY_BLEND_COLOR = (1 << 12),
- FD_DIRTY_STENCIL_REF = (1 << 13),
- FD_DIRTY_SAMPLE_MASK = (1 << 14),
- FD_DIRTY_FRAMEBUFFER = (1 << 15),
- FD_DIRTY_STIPPLE = (1 << 16),
- FD_DIRTY_VIEWPORT = (1 << 17),
- FD_DIRTY_CONSTBUF = (1 << 18),
- FD_DIRTY_VTXSTATE = (1 << 19),
- FD_DIRTY_VTXBUF = (1 << 20),
- FD_DIRTY_INDEXBUF = (1 << 21),
- FD_DIRTY_SCISSOR = (1 << 22),
- FD_DIRTY_STREAMOUT = (1 << 23),
- FD_DIRTY_UCP = (1 << 24),
- FD_DIRTY_BLEND_DUAL = (1 << 25),
- } dirty;
+ enum fd_dirty_3d_state dirty;
+
+ /* per shader-stage dirty status: */
+ enum fd_dirty_shader_state dirty_shader[PIPE_SHADER_TYPES];
struct pipe_blend_state *blend;
struct pipe_rasterizer_state *rasterizer;
@@ -330,12 +342,16 @@ static inline void
fd_context_all_dirty(struct fd_context *ctx)
{
ctx->dirty = ~0;
+ for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++)
+ ctx->dirty_shader[i] = ~0;
}
static inline void
fd_context_all_clean(struct fd_context *ctx)
{
ctx->dirty = 0;
+ for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++)
+ ctx->dirty_shader[i] = 0;
}
static inline struct pipe_scissor_state *
diff --git a/src/gallium/drivers/freedreno/freedreno_program.c b/src/gallium/drivers/freedreno/freedreno_program.c
index db6b258e21c..0bb5d68752c 100644
--- a/src/gallium/drivers/freedreno/freedreno_program.c
+++ b/src/gallium/drivers/freedreno/freedreno_program.c
@@ -37,7 +37,8 @@ fd_fp_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->prog.fp = hwcso;
- ctx->dirty |= FD_SHADER_DIRTY_FP;
+ ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty |= FD_DIRTY_PROG;
}
static void
@@ -45,7 +46,8 @@ fd_vp_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
ctx->prog.vp = hwcso;
- ctx->dirty |= FD_SHADER_DIRTY_VP;
+ ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+ ctx->dirty |= FD_DIRTY_PROG;
}
static const char *solid_fp =
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 427ada8b667..3b067095523 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -51,23 +51,13 @@
static void
fd_invalidate_resource(struct fd_context *ctx, struct pipe_resource *prsc)
{
- int i;
-
/* Go through the entire state and see if the resource is bound
* anywhere. If it is, mark the relevant state as dirty. This is called on
* realloc_bo.
*/
- /* Constbufs */
- for (i = 1; i < PIPE_MAX_CONSTANT_BUFFERS && !(ctx->dirty & FD_DIRTY_CONSTBUF); i++) {
- if (ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer == prsc)
- ctx->dirty |= FD_DIRTY_CONSTBUF;
- if (ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer == prsc)
- ctx->dirty |= FD_DIRTY_CONSTBUF;
- }
-
/* VBOs */
- for (i = 0; i < ctx->vtx.vertexbuf.count && !(ctx->dirty & FD_DIRTY_VTXBUF); i++) {
+ for (unsigned i = 0; i < ctx->vtx.vertexbuf.count && !(ctx->dirty & FD_DIRTY_VTXBUF); i++) {
if (ctx->vtx.vertexbuf.vb[i].buffer == prsc)
ctx->dirty |= FD_DIRTY_VTXBUF;
}
@@ -76,14 +66,26 @@ fd_invalidate_resource(struct fd_context *ctx, struct pipe_resource *prsc)
if (ctx->indexbuf.buffer == prsc)
ctx->dirty |= FD_DIRTY_INDEXBUF;
- /* Textures */
- for (i = 0; i < ctx->tex[PIPE_SHADER_VERTEX].num_textures && !(ctx->dirty & FD_DIRTY_VERTTEX); i++) {
- if (ctx->tex[PIPE_SHADER_VERTEX].textures[i] && (ctx->tex[PIPE_SHADER_VERTEX].textures[i]->texture == prsc))
- ctx->dirty |= FD_DIRTY_VERTTEX;
- }
- for (i = 0; i < ctx->tex[PIPE_SHADER_FRAGMENT].num_textures && !(ctx->dirty & FD_DIRTY_FRAGTEX); i++) {
- if (ctx->tex[PIPE_SHADER_FRAGMENT].textures[i] && (ctx->tex[PIPE_SHADER_FRAGMENT].textures[i]->texture == prsc))
- ctx->dirty |= FD_DIRTY_FRAGTEX;
+ /* per-shader-stage resources: */
+ for (unsigned stage = 0; stage < PIPE_SHADER_TYPES; stage++) {
+ /* Constbufs.. note that constbuf[0] is normal uniforms emitted in
+ * cmdstream rather than by pointer..
+ */
+ const unsigned num_ubos = util_last_bit(ctx->constbuf[stage].enabled_mask);
+ for (unsigned i = 1; i < num_ubos; i++) {
+ if (ctx->dirty_shader[stage] & FD_DIRTY_SHADER_CONST)
+ break;
+ if (ctx->constbuf[stage].cb[i].buffer == prsc)
+ ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_CONST;
+ }
+
+ /* Textures */
+ for (unsigned i = 0; i < ctx->tex[stage].num_textures; i++) {
+ if (ctx->dirty_shader[stage] & FD_DIRTY_SHADER_TEX)
+ break;
+ if (ctx->tex[stage].textures[i] && (ctx->tex[stage].textures[i]->texture == prsc))
+ ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_TEX;
+ }
}
}
diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c
index 06dfd228dcc..3b02e630646 100644
--- a/src/gallium/drivers/freedreno/freedreno_state.c
+++ b/src/gallium/drivers/freedreno/freedreno_state.c
@@ -109,7 +109,8 @@ fd_set_constant_buffer(struct pipe_context *pctx,
so->enabled_mask |= 1 << index;
so->dirty_mask |= 1 << index;
- ctx->dirty |= FD_DIRTY_CONSTBUF;
+ ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_CONST;
+ ctx->dirty |= FD_DIRTY_CONST;
}
static void
diff --git a/src/gallium/drivers/freedreno/freedreno_texture.c b/src/gallium/drivers/freedreno/freedreno_texture.c
index e9d90aa3a77..1487f7441c9 100644
--- a/src/gallium/drivers/freedreno/freedreno_texture.c
+++ b/src/gallium/drivers/freedreno/freedreno_texture.c
@@ -92,13 +92,8 @@ fd_sampler_states_bind(struct pipe_context *pctx,
struct fd_context *ctx = fd_context(pctx);
bind_sampler_states(&ctx->tex[shader], start, nr, hwcso);
-
- if (shader == PIPE_SHADER_FRAGMENT) {
- ctx->dirty |= FD_DIRTY_FRAGTEX;
- }
- else if (shader == PIPE_SHADER_VERTEX) {
- ctx->dirty |= FD_DIRTY_VERTTEX;
- }
+ ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX;
+ ctx->dirty |= FD_DIRTY_TEX;
}
void
@@ -109,17 +104,8 @@ 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, views);
-
- switch (shader) {
- case PIPE_SHADER_FRAGMENT:
- ctx->dirty |= FD_DIRTY_FRAGTEX;
- break;
- case PIPE_SHADER_VERTEX:
- ctx->dirty |= FD_DIRTY_VERTTEX;
- break;
- default:
- break;
- }
+ ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX;
+ ctx->dirty |= FD_DIRTY_TEX;
}
void
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c
index 402d12a205c..1d54d5330ad 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c
@@ -658,16 +658,16 @@ void
ir3_emit_vs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
struct fd_context *ctx, const struct pipe_draw_info *info)
{
- uint32_t dirty = ctx->dirty;
+ enum fd_dirty_shader_state dirty = ctx->dirty_shader[PIPE_SHADER_VERTEX];
debug_assert(v->type == SHADER_VERTEX);
- if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+ if (dirty & (FD_DIRTY_SHADER_PROG | FD_DIRTY_SHADER_CONST)) {
struct fd_constbuf_stateobj *constbuf;
bool shader_dirty;
constbuf = &ctx->constbuf[PIPE_SHADER_VERTEX];
- shader_dirty = !!(dirty & FD_SHADER_DIRTY_VP);
+ shader_dirty = !!(dirty & FD_DIRTY_SHADER_PROG);
emit_user_consts(ctx, v, ring, constbuf);
emit_ubos(ctx, v, ring, constbuf);
@@ -718,16 +718,16 @@ void
ir3_emit_fs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
struct fd_context *ctx)
{
- uint32_t dirty = ctx->dirty;
+ enum fd_dirty_shader_state dirty = ctx->dirty_shader[PIPE_SHADER_FRAGMENT];
debug_assert(v->type == SHADER_FRAGMENT);
- if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+ if (dirty & (FD_DIRTY_SHADER_PROG | FD_DIRTY_SHADER_CONST)) {
struct fd_constbuf_stateobj *constbuf;
bool shader_dirty;
constbuf = &ctx->constbuf[PIPE_SHADER_FRAGMENT];
- shader_dirty = !!(dirty & FD_SHADER_DIRTY_FP);
+ shader_dirty = !!(dirty & FD_DIRTY_SHADER_PROG);
emit_user_consts(ctx, v, ring, constbuf);
emit_ubos(ctx, v, ring, constbuf);