diff --git a/src/gallium/drivers/lima/lima_context.h b/src/gallium/drivers/lima/lima_context.h index 400fa0e979c..128127f9dfd 100644 --- a/src/gallium/drivers/lima/lima_context.h +++ b/src/gallium/drivers/lima/lima_context.h @@ -57,7 +57,10 @@ struct lima_fs_bind_state { struct lima_fs_key { struct lima_fs_bind_state *shader_state; - uint8_t swizzles[PIPE_MAX_SAMPLERS][4]; + struct { + enum pipe_format format; + uint8_t swizzle[4]; + } tex[PIPE_MAX_SAMPLERS]; }; #define LIMA_MAX_VARYING_NUM 13 diff --git a/src/gallium/drivers/lima/lima_program.c b/src/gallium/drivers/lima/lima_program.c index 5a04274a9cf..8d60c6d14ed 100644 --- a/src/gallium/drivers/lima/lima_program.c +++ b/src/gallium/drivers/lima/lima_program.c @@ -280,18 +280,26 @@ lima_fs_compile_shader(struct lima_context *ctx, struct nir_lower_tex_options tex_options = { .lower_txp = ~0u, - .swizzle_result = 0, + .swizzle_result = ~0u, }; - uint8_t identity[4] = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, - PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W }; - + /* Lower the format swizzle and ARB_texture_swizzle-style swizzle. */ for (int i = 0; i < PIPE_MAX_SAMPLERS; i++) { - for (int j = 0; j < 4; j++) - tex_options.swizzles[i][j] = key->swizzles[i][j]; + enum pipe_format format = key->tex[i].format; + if (!format) + continue; - if (memcmp(tex_options.swizzles[i], identity, 4) != 0) - tex_options.swizzle_result |= (1 << i); + const uint8_t *format_swizzle = lima_format_get_texel_swizzle(format); + + for (int j = 0; j < 4; j++) { + uint8_t arb_swiz = key->tex[i].swizzle[j]; + + if (arb_swiz <= 3) { + tex_options.swizzles[i][j] = format_swizzle[arb_swiz]; + } else { + tex_options.swizzles[i][j] = arb_swiz; + } + } } lima_program_optimize_fs_nir(nir, &tex_options); @@ -514,10 +522,12 @@ lima_update_fs_state(struct lima_context *ctx) lima_tex->num_samplers && lima_tex->num_textures)) { for (int i = 0; i < lima_tex->num_samplers; i++) { - struct lima_sampler_view *texture = lima_sampler_view(lima_tex->textures[i]); - struct pipe_resource *prsc = texture->base.texture; - const uint8_t *swizzle = lima_format_get_texel_swizzle(prsc->format); - memcpy(key->swizzles[i], swizzle, 4); + struct pipe_sampler_view *sampler = lima_tex->textures[i]; + key->tex[i].format = sampler->format; + key->tex[i].swizzle[0] = sampler->swizzle_r; + key->tex[i].swizzle[1] = sampler->swizzle_g; + key->tex[i].swizzle[2] = sampler->swizzle_b; + key->tex[i].swizzle[3] = sampler->swizzle_a; } } @@ -525,7 +535,7 @@ lima_update_fs_state(struct lima_context *ctx) uint8_t identity[4] = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W }; for (int i = lima_tex->num_samplers; i < PIPE_MAX_SAMPLERS; i++) - memcpy(key->swizzles[i], identity, 4); + memcpy(key->tex[i].swizzle, identity, 4); struct lima_fs_shader_state *old_fs = ctx->fs; diff --git a/src/gallium/drivers/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c index a5285d36eaa..d5221542c36 100644 --- a/src/gallium/drivers/lima/lima_screen.c +++ b/src/gallium/drivers/lima/lima_screen.c @@ -101,6 +101,7 @@ lima_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_UMA: case PIPE_CAP_NATIVE_FENCE_FD: case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: + case PIPE_CAP_TEXTURE_SWIZZLE: return 1; /* Unimplemented, but for exporting OpenGL 2.0 */