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 <robdclark@gmail.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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: */
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
enum fd_dirty_3d_state dirty;
|
||||
|
||||
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;
|
||||
/* 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 *
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user