diff --git a/src/freedreno/ir3/ir3_context.c b/src/freedreno/ir3/ir3_context.c index bf08f844803..24fead918b0 100644 --- a/src/freedreno/ir3/ir3_context.c +++ b/src/freedreno/ir3/ir3_context.c @@ -39,7 +39,8 @@ ir3_context_init(struct ir3_compiler *compiler, struct ir3_shader_variant *so) if (so->type == MESA_SHADER_VERTEX) { ctx->astc_srgb = so->key.vastc_srgb; memcpy(ctx->sampler_swizzles, so->key.vsampler_swizzles, sizeof(ctx->sampler_swizzles)); - } else if (so->type == MESA_SHADER_FRAGMENT) { + } else if (so->type == MESA_SHADER_FRAGMENT || + so->type == MESA_SHADER_COMPUTE) { ctx->astc_srgb = so->key.fastc_srgb; memcpy(ctx->sampler_swizzles, so->key.fsampler_swizzles, sizeof(ctx->sampler_swizzles)); } diff --git a/src/freedreno/ir3/ir3_shader.c b/src/freedreno/ir3/ir3_shader.c index 8a4cd23b7bc..002ad27c1f0 100644 --- a/src/freedreno/ir3/ir3_shader.c +++ b/src/freedreno/ir3/ir3_shader.c @@ -471,7 +471,7 @@ ir3_setup_used_key(struct ir3_shader *shader) * ucp_enables to determine whether to lower legacy clip planes to * gl_ClipDistance. */ - if (info->stage != MESA_SHADER_FRAGMENT || !shader->compiler->has_clip_cull) + if (info->stage != MESA_SHADER_COMPUTE && (info->stage != MESA_SHADER_FRAGMENT || !shader->compiler->has_clip_cull)) key->ucp_enables = 0xff; if (info->stage == MESA_SHADER_FRAGMENT) { @@ -501,6 +501,10 @@ ir3_setup_used_key(struct ir3_shader *shader) SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID) || BITSET_TEST(info->system_values_read, SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID))); + } else if (info->stage == MESA_SHADER_COMPUTE) { + key->fastc_srgb = ~0; + key->fsamples = ~0; + memset(key->fsampler_swizzles, 0xff, sizeof(key->fsampler_swizzles)); } else { key->tessellation = ~0; key->has_gs = true; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_compute.c b/src/gallium/drivers/freedreno/a4xx/fd4_compute.c index b9c52ad5e29..9de32eeb4cc 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_compute.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_compute.c @@ -118,13 +118,23 @@ static void fd4_launch_grid(struct fd_context *ctx, const struct pipe_grid_info *info) assert_dt { - struct ir3_shader_key key = {}; + struct fd4_context *fd4_ctx = fd4_context(ctx); + struct ir3_shader_key key = { + .has_per_samp = fd4_ctx->castc_srgb, + .fastc_srgb = fd4_ctx->castc_srgb, + }; + struct ir3_shader *shader = ir3_get_shader(ctx->compute); struct ir3_shader_variant *v; struct fd_ringbuffer *ring = ctx->batch->draw; unsigned nglobal = 0; - v = - ir3_shader_variant(ir3_get_shader(ctx->compute), key, false, &ctx->debug); + if (ir3_get_shader_info(ctx->compute)->uses_texture_gather) { + key.has_per_samp = true; + memcpy(key.fsampler_swizzles, fd4_ctx->csampler_swizzles, + sizeof(key.fsampler_swizzles)); + } + + v = ir3_shader_variant(shader, key, false, &ctx->debug); if (!v) return; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_context.c b/src/gallium/drivers/freedreno/a4xx/fd4_context.c index 0cfe5926863..c4ea172b305 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_context.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_context.c @@ -115,6 +115,7 @@ fd4_context_create(struct pipe_screen *pscreen, void *priv, for (int i = 0; i < 16; i++) { fd4_ctx->vsampler_swizzles[i] = 0x688; fd4_ctx->fsampler_swizzles[i] = 0x688; + fd4_ctx->csampler_swizzles[i] = 0x688; } return pctx; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_context.h b/src/gallium/drivers/freedreno/a4xx/fd4_context.h index 194c424768f..6d9e6f7e565 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_context.h +++ b/src/gallium/drivers/freedreno/a4xx/fd4_context.h @@ -49,10 +49,10 @@ struct fd4_context { struct pipe_resource *border_color_buf; /* bitmask of samplers which need astc srgb workaround: */ - uint16_t vastc_srgb, fastc_srgb; + uint16_t vastc_srgb, fastc_srgb, castc_srgb; /* samplers swizzles, needed for tg4 workaround: */ - uint16_t vsampler_swizzles[16], fsampler_swizzles[16]; + uint16_t vsampler_swizzles[16], fsampler_swizzles[16], csampler_swizzles[16]; /* storage for ctx->last.key: */ struct ir3_shader_key last_key; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index 5b00245bea0..2263009aa89 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -923,6 +923,9 @@ fd4_emit_cs_state(struct fd_context *ctx, struct fd_ringbuffer *ring, struct ir3_shader_variant *cp) { enum fd_dirty_shader_state dirty = ctx->dirty_shader[PIPE_SHADER_COMPUTE]; + unsigned num_textures = ctx->tex[PIPE_SHADER_COMPUTE].num_textures + + cp->astc_srgb.count + + cp->tg4.count; if (dirty & FD_DIRTY_SHADER_TEX) { emit_textures(ctx, ring, SB4_CS_TEX, &ctx->tex[PIPE_SHADER_COMPUTE], cp); @@ -933,9 +936,7 @@ fd4_emit_cs_state(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_PKT0(ring, REG_A4XX_TPL1_TP_FS_TEX_COUNT, 1); OUT_RING(ring, A4XX_TPL1_TP_FS_TEX_COUNT_CS( - ctx->shaderimg[PIPE_SHADER_COMPUTE].enabled_mask - ? 0x80 - : ctx->tex[PIPE_SHADER_COMPUTE].num_textures)); + ctx->shaderimg[PIPE_SHADER_COMPUTE].enabled_mask ? 0x80 : num_textures)); if (dirty & FD_DIRTY_SHADER_SSBO) emit_ssbos(ctx, ring, SB4_CS_SSBO, &ctx->shaderbuf[PIPE_SHADER_COMPUTE]); diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c index 98e3811265e..9e58cbe72ef 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c @@ -247,9 +247,11 @@ fd4_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader, sampler_swizzles = fd4_ctx->fsampler_swizzles; } else if (shader == PIPE_SHADER_VERTEX) { sampler_swizzles = fd4_ctx->vsampler_swizzles; + } else if (shader == PIPE_SHADER_COMPUTE) { + sampler_swizzles = fd4_ctx->csampler_swizzles; } else { debug_assert(0); - sampler_swizzles = fd4_ctx->fsampler_swizzles; + sampler_swizzles = fd4_ctx->csampler_swizzles; } for (i = 0; i < nr; i++) { @@ -295,6 +297,8 @@ fd4_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader, fd4_ctx->fastc_srgb = astc_srgb; } else if (shader == PIPE_SHADER_VERTEX) { fd4_ctx->vastc_srgb = astc_srgb; + } else if (shader == PIPE_SHADER_COMPUTE) { + fd4_ctx->castc_srgb = astc_srgb; } }