diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 5606c7f..d9f4b7b 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -2144,6 +2144,21 @@ static inline GLenum to_gl_swizzle(int swizzle) } } +static inline int to_pipe_swizzle(GLenum swizzle) +{ + switch (swizzle) { + case GL_RED: return PIPE_SWIZZLE_RED; + case GL_GREEN: return PIPE_SWIZZLE_GREEN; + case GL_BLUE: return PIPE_SWIZZLE_BLUE; + case GL_ALPHA: return PIPE_SWIZZLE_ALPHA; + case GL_ZERO: return PIPE_SWIZZLE_ZERO; + case GL_ONE: return PIPE_SWIZZLE_ONE; + default: + assert(0); + return 0; + } +} + int vrend_create_sampler_view(struct vrend_context *ctx, uint32_t handle, uint32_t res_handle, uint32_t format, @@ -3533,6 +3548,18 @@ static inline void vrend_fill_shader_key(struct vrend_sub_context *sub_ctx, if (type != PIPE_SHADER_COMPUTE) vrend_sync_shader_io(sub_ctx, sel, key); + + for (int i = 0; i < sub_ctx->views->num_views; i++) { + struct vrend_sampler_view *view = sub_ctx->views[type].views[i]; + if (view && view->texture->target == GL_TEXTURE_BUFFER && + view->format != tex_conv_table[view->format].internalformat) { + key->sampler_views_lower_swizzle_mask |= 1 << i; + key->tex_swizzle[i] = to_pipe_swizzle(view->gl_swizzle[0]) | + to_pipe_swizzle(view->gl_swizzle[1]) << 3 | + to_pipe_swizzle(view->gl_swizzle[2]) << 6 | + to_pipe_swizzle(view->gl_swizzle[3]) << 9 ; + } + } } static int vrend_shader_create(struct vrend_context *ctx, diff --git a/src/vrend_shader.c b/src/vrend_shader.c index 2a6a41d..c9c0228 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -441,6 +441,21 @@ static inline const char *get_wm_string(unsigned wm) } } +static inline const char *get_swizzle_string(uint8_t swizzle) +{ + switch (swizzle) { + case PIPE_SWIZZLE_RED: return ".x"; + case PIPE_SWIZZLE_GREEN: return ".y"; + case PIPE_SWIZZLE_BLUE: return ".z"; + case PIPE_SWIZZLE_ALPHA: return ".w"; + case PIPE_SWIZZLE_ZERO: + case PIPE_SWIZZLE_ONE: return ".0"; + default: + assert(0); + return ""; + } +} + const char *get_internalformat_string(int virgl_format, enum tgsi_return_type *stype); static inline const char *tgsi_proc_to_prefix(int shader_type) @@ -2903,6 +2918,17 @@ static void translate_tex(struct dump_ctx *ctx, tex_ext, srcs[sampler_index], get_string(txfi), srcs[0], get_wm_string(twm), bias, offset, dinfo->dst_override_no_wm[0] ? "" : writemask); + if (ctx->key->sampler_views_lower_swizzle_mask & (1 << sinfo->sreg_index)) { + uint8_t swizzle_r = ctx->key->tex_swizzle[sinfo->sreg_index] & 7; + uint8_t swizzle_g = (ctx->key->tex_swizzle[sinfo->sreg_index] & (7 << 3)) >> 3; + uint8_t swizzle_b = (ctx->key->tex_swizzle[sinfo->sreg_index] & (7 << 6)) >> 6; + uint8_t swizzle_a = (ctx->key->tex_swizzle[sinfo->sreg_index] & (7 << 9)) >> 9; + emit_buff(&ctx->glsl_strbufs, "%s = vec4(%s%s, %s%s, %s%s, %s%s);\n", dst, + swizzle_r == PIPE_SWIZZLE_ZERO ? "0" : (swizzle_r == PIPE_SWIZZLE_ONE ? "1" : dst), get_swizzle_string(swizzle_r), + swizzle_g == PIPE_SWIZZLE_ZERO ? "0" : (swizzle_g == PIPE_SWIZZLE_ONE ? "1" : dst), get_swizzle_string(swizzle_g), + swizzle_b == PIPE_SWIZZLE_ZERO ? "0" : (swizzle_b == PIPE_SWIZZLE_ONE ? "1" : dst), get_swizzle_string(swizzle_b), + swizzle_a == PIPE_SWIZZLE_ZERO ? "0" : (swizzle_a == PIPE_SWIZZLE_ONE ? "1" : dst), get_swizzle_string(swizzle_a)); + } } } else if (ctx->cfg->glsl_version < 140 && (ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT)) { /* rect is special in GLSL 1.30 */ diff --git a/src/vrend_shader.h b/src/vrend_shader.h index de84ca4..1e56282 100644 --- a/src/vrend_shader.h +++ b/src/vrend_shader.h @@ -168,6 +168,9 @@ struct vrend_shader_key { uint32_t compiled_fs_uid; + uint32_t sampler_views_lower_swizzle_mask; + uint16_t tex_swizzle[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + uint8_t alpha_test; uint8_t clip_plane_enable; uint8_t num_cull : 4;