From cd9b1812754126284bc319d155d4f20f947a5b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 8 Mar 2016 17:46:51 +0100 Subject: [PATCH] wined3d: Extend shader_glsl_gen_sample_code() to support offsets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/glsl_shader.c | 121 +++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 39 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index a3e000037d1..ab4a51107a8 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -49,6 +49,7 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); #define WINED3D_GLSL_SAMPLE_LOD 0x04 #define WINED3D_GLSL_SAMPLE_GRAD 0x08 #define WINED3D_GLSL_SAMPLE_LOAD 0x10 +#define WINED3D_GLSL_SAMPLE_OFFSET 0x20 struct glsl_dst_param { @@ -68,6 +69,7 @@ struct glsl_sample_function DWORD coord_mask; enum wined3d_data_type data_type; BOOL output_single_component; + unsigned int offset_size; }; enum heap_node_op @@ -318,6 +320,31 @@ static void shader_glsl_append_imm_vec4(struct wined3d_string_buffer *buffer, co shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]); } +static void shader_glsl_append_imm_ivec(struct wined3d_string_buffer *buffer, + const int *values, unsigned int size) +{ + const char *fmt = "%#x"; + char str[4][17] = {{0}}; + int i; + + if (1 > size || size > 4) + { + ERR("Invalid vector size %u.\n", size); + return; + } + + for (i = size - 1; i >= 0; --i) + { + sprintf(str[i], fmt, values[i]); + fmt = "%#x, "; + } + + if (size > 1) + shader_addline(buffer, "ivec%u(%s%s%s%s)", size, str[0], str[1], str[2], str[3]); + else + shader_addline(buffer, str[0]); +} + static const char *get_info_log_line(const char **ptr) { const char *p, *q; @@ -2655,20 +2682,21 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context static const struct { unsigned int coord_size; + unsigned int offset_size; const char *type_part; } resource_types[] = { - {0, ""}, /* WINED3D_SHADER_RESOURCE_NONE */ - {1, ""}, /* WINED3D_SHADER_RESOURCE_BUFFER */ - {1, "1D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1D */ - {2, "2D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2D */ - {2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMS */ - {3, "3D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_3D */ - {3, "Cube"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBE */ - {2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ - {3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ - {3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ + {0, 0, ""}, /* WINED3D_SHADER_RESOURCE_NONE */ + {1, 0, ""}, /* WINED3D_SHADER_RESOURCE_BUFFER */ + {1, 1, "1D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1D */ + {2, 2, "2D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2D */ + {2, 0, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMS */ + {3, 3, "3D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_3D */ + {3, 0, "Cube"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBE */ + {2, 1, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ + {3, 2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ + {3, 0, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ }; struct shader_glsl_ctx_priv *priv = ctx->backend_data; enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type; @@ -2679,6 +2707,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context BOOL texrect = flags & WINED3D_GLSL_SAMPLE_NPOT && gl_info->supported[ARB_TEXTURE_RECTANGLE]; BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD; BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD; + BOOL offset = flags & WINED3D_GLSL_SAMPLE_OFFSET; const char *base = "texture", *type_part = "", *suffix = ""; unsigned int coord_size; @@ -2716,16 +2745,24 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context if (flags & WINED3D_GLSL_SAMPLE_LOAD) { - if (flags != WINED3D_GLSL_SAMPLE_LOAD) - ERR("Unexpected flags for texelFetch %#x.\n", flags & ~WINED3D_GLSL_SAMPLE_LOAD); + static const DWORD texel_fetch_flags = WINED3D_GLSL_SAMPLE_LOAD | WINED3D_GLSL_SAMPLE_OFFSET; + if (flags & ~texel_fetch_flags) + ERR("Unexpected flags for texelFetch %#x.\n", flags & ~texel_fetch_flags); base = "texelFetch"; type_part = ""; } + sample_function->offset_size = offset ? resource_types[resource_type].offset_size : 0; + if (offset && !sample_function->offset_size) + { + FIXME("Offset not supported for resource type %#x.\n", resource_type); + offset = FALSE; + } + sample_function->name = string_buffer_get(priv->string_buffers); - string_buffer_sprintf(sample_function->name, "%s%s%s%s%s", base, type_part, projected ? "Proj" : "", - lod ? "Lod" : grad ? "Grad" : "", suffix); + string_buffer_sprintf(sample_function->name, "%s%s%s%s%s%s", base, type_part, projected ? "Proj" : "", + lod ? "Lod" : grad ? "Grad" : "", offset ? "Offset" : "", suffix); coord_size = resource_types[resource_type].coord_size; if (shadow) @@ -2847,9 +2884,10 @@ static void shader_glsl_color_correction(const struct wined3d_shader_instruction shader_glsl_color_correction_ext(ins->ctx->buffer, reg_name, ins->dst[0].write_mask, fixup); } -static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins, +static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins, unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function, DWORD swizzle, - const char *dx, const char *dy, const char *bias, const char *coord_reg_fmt, ...) + const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset, + const char *coord_reg_fmt, ...) { const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version; char dst_swizzle[6]; @@ -2921,11 +2959,16 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s } } if (dx && dy) - shader_addline(ins->ctx->buffer, ", %s, %s)", dx, dy); + shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy); else if (bias) - shader_addline(ins->ctx->buffer, ", %s)", bias); - else - shader_addline(ins->ctx->buffer, ")"); + shader_addline(ins->ctx->buffer, ", %s", bias); + if (sample_function->offset_size) + { + int offset_immdata[4] = {offset->u, offset->v, offset->w}; + shader_addline(ins->ctx->buffer, ", "); + shader_glsl_append_imm_ivec(ins->ctx->buffer, offset_immdata, sample_function->offset_size); + } + shader_addline(ins->ctx->buffer, ")"); if (sample_function->output_single_component) shader_addline(ins->ctx->buffer, ")"); @@ -4211,7 +4254,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) { char coord_mask[6]; shader_glsl_write_mask_to_str(mask, coord_mask); - shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, NULL, "T%u%s", resource_idx, coord_mask); } else @@ -4223,9 +4266,9 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) struct glsl_src_param bias; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias); shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, bias.param_str, - "%s", coord_param.param_str); + NULL, "%s", coord_param.param_str); } else { - shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, NULL, "%s", coord_param.param_str); } } @@ -4258,8 +4301,8 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param); shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, NULL, - "%s", coord_param.param_str); + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, + NULL, NULL, "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4291,7 +4334,7 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins) * even without the appropriate extension. */ WARN("Using %s in fragment shader.\n", sample_function.name->buffer); } - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str, + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str, NULL, "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4398,7 +4441,7 @@ static void shader_glsl_ld(const struct wined3d_shader_instruction *ins) sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, ins->src[1].reg.idx[0].offset, WINED3D_SAMPLER_DEFAULT); shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle, - NULL, NULL, lod_param.param_str, "%s", coord_param.param_str); + NULL, NULL, lod_param.param_str, NULL, "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4446,7 +4489,7 @@ static void shader_glsl_sample(const struct wined3d_shader_instruction *ins) sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx, sampler_idx); shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle, - dx_param_str, dy_param_str, lod_param_str, "%s", coord_param.param_str); + dx_param_str, dy_param_str, lod_param_str, NULL, "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4517,17 +4560,17 @@ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins) { case 1: shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, - "dot(ffp_texcoord[%u].xyz, %s)", sampler_idx, src0_param.param_str); + NULL, "dot(ffp_texcoord[%u].xyz, %s)", sampler_idx, src0_param.param_str); break; case 2: shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, - "vec2(dot(ffp_texcoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str); + NULL, "vec2(dot(ffp_texcoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str); break; case 3: shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, - "vec3(dot(ffp_texcoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str); + NULL, "vec3(dot(ffp_texcoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str); break; default: @@ -4635,7 +4678,7 @@ static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins) shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ - shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy"); + shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "tmp0.xy"); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4656,7 +4699,7 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins) shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ - shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz"); + shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "tmp0.xyz"); shader_glsl_release_sample_function(ins->ctx, &sample_function); tex_mx->current_row = 0; @@ -4708,7 +4751,7 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins /* Sample the texture */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, - NULL, NULL, NULL, "tmp0%s", coord_mask); + NULL, NULL, NULL, NULL, "tmp0%s", coord_mask); shader_glsl_release_sample_function(ins->ctx, &sample_function); tex_mx->current_row = 0; @@ -4742,7 +4785,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, - NULL, NULL, NULL, "tmp0%s", coord_mask); + NULL, NULL, NULL, NULL, "tmp0%s", coord_mask); shader_glsl_release_sample_function(ins->ctx, &sample_function); tex_mx->current_row = 0; @@ -4800,7 +4843,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "T%u%s + vec4(bumpenv_mat%u * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx, coord_param.param_str, coord_mask); @@ -4843,7 +4886,7 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "%s.wx", src0_param.reg_name); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4859,7 +4902,7 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "%s.yz", src0_param.reg_name); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4876,7 +4919,7 @@ static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins) shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, + shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "%s", src0_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); }