- Add flag to indicate FETCH4 support in textures - FIXME: 3D textures and fetch4 - Tested under W10+Intel, when Fetch4 is enabled, projection is ignored - The swizzle fix has been checked against windows since it does not match with the one in gather4
Signed-off-by: Daniel Ansorregui mailszeros@gmail.com --- dlls/wined3d/glsl_shader.c | 25 ++++++++++++++++++++++++- dlls/wined3d/utils.c | 9 +++++++++ dlls/wined3d/wined3d_private.h | 4 +++- 3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 5f1a86608b..d9eb26762c 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -9703,6 +9703,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n"); if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n"); + if (gl_info->supported[ARB_TEXTURE_GATHER]) + shader_addline(buffer, "#extension GL_ARB_texture_gather : enable\n");
if (!needs_legacy_glsl_syntax(gl_info)) { @@ -9843,6 +9845,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage) { const char *texture_function, *coord_mask; + BOOL fetch4 = settings->op[stage].fetch4; BOOL proj;
if (!(tex_map & (1u << stage))) @@ -9862,7 +9865,6 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * FIXME("Unexpected projection mode %d\n", settings->op[stage].projected); proj = TRUE; } - if (settings->op[stage].tex_type == WINED3D_GL_RES_TYPE_TEX_CUBE) proj = FALSE;
@@ -9871,6 +9873,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * case WINED3D_GL_RES_TYPE_TEX_1D: texture_function = "texture1D"; coord_mask = "x"; + fetch4 = FALSE; break; case WINED3D_GL_RES_TYPE_TEX_2D: texture_function = "texture2D"; @@ -9879,6 +9882,11 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * case WINED3D_GL_RES_TYPE_TEX_3D: texture_function = "texture3D"; coord_mask = "xyz"; + /* 3D + Fetch4 should return textureGather(sampler2DArray, t.xy0) + unfortunately, we cant convert 3D to 2DArray */ + if (fetch4) + FIXME("Unsupported Fetch4 and texture3D sampling"); + fetch4 = FALSE; break; case WINED3D_GL_RES_TYPE_TEX_CUBE: texture_function = "textureCube"; @@ -9887,17 +9895,28 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * case WINED3D_GL_RES_TYPE_TEX_RECT: texture_function = "texture2DRect"; coord_mask = "xy"; + if (fetch4) + FIXME("Unsupported Fetch4 and texture2DRect sampling"); + fetch4 = FALSE; break; default: FIXME("Unhandled texture type %#x.\n", settings->op[stage].tex_type); texture_function = ""; coord_mask = "xyzw"; proj = FALSE; + fetch4 = FALSE; break; } if (!legacy_syntax) texture_function = "texture";
+ if (fetch4) + { + texture_function = "textureGather"; + /* Tested on W10+Intel, fetch4 enabled disables projection */ + proj = FALSE; + } + if (stage > 0 && (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP || settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)) @@ -9946,6 +9965,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * stage, texture_function, proj ? "Proj" : "", stage, stage, coord_mask, proj ? "w" : ""); }
+ /* Match FETCH4 swizzle with textureGather swizzle */ + if (fetch4) + shader_addline(buffer, "tex%u = tex%u.xwyz;\n", stage, stage); + string_buffer_sprintf(tex_reg_name, "tex%u", stage); shader_glsl_color_correction_ext(buffer, tex_reg_name->buffer, WINED3DSP_WRITEMASK_ALL, settings->op[stage].color_fixup); diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index f8da256b07..24e08df377 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -340,6 +340,11 @@ static const struct wined3d_format_base_flags format_base_flags[] = {WINED3DFMT_NULL, WINED3DFMT_FLAG_EXTENSION}, {WINED3DFMT_NVDB, WINED3DFMT_FLAG_EXTENSION}, {WINED3DFMT_RESZ, WINED3DFMT_FLAG_EXTENSION}, + {WINED3DFMT_L8_UNORM, WINED3DFMT_FLAG_ALLOW_FETCH4}, + {WINED3DFMT_L16_UNORM, WINED3DFMT_FLAG_ALLOW_FETCH4}, + {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_ALLOW_FETCH4}, + {WINED3DFMT_R16, WINED3DFMT_FLAG_ALLOW_FETCH4}, + {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_ALLOW_FETCH4}, };
static void rgb888_from_rgb565(WORD rgb565, BYTE *r, BYTE *g, BYTE *b) @@ -5783,6 +5788,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d settings->op[i].tmp_dst = 0; settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D; settings->op[i].projected = WINED3D_PROJECTION_NONE; + settings->op[i].fetch4 = FALSE; i++; break; } @@ -5926,6 +5932,9 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d settings->op[i].aarg1 = aarg1; settings->op[i].aarg2 = aarg2; settings->op[i].tmp_dst = state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP; + settings->op[i].fetch4 = (state->textures[i] && gl_info->supported[ARB_TEXTURE_GATHER] && + state->textures[i]->resource.format_flags & WINED3DFMT_FLAG_ALLOW_FETCH4 && + state->sampler_states[i][WINED3D_SAMP_MIPMAP_LOD_BIAS] == MAKEFOURCC('G','E','T','4')); }
/* Clear unsupported stages */ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0df3f2ab2a..60edb9bac1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2747,7 +2747,8 @@ struct texture_stage_op unsigned tex_type : 3; unsigned tmp_dst : 1; unsigned projected : 2; - unsigned padding : 10; + unsigned fetch4 : 1; + unsigned padding : 9; };
struct ffp_frag_settings @@ -4412,6 +4413,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN #define WINED3DFMT_FLAG_VERTEX_ATTRIBUTE 0x01000000 #define WINED3DFMT_FLAG_BLIT 0x02000000 #define WINED3DFMT_FLAG_MAPPABLE 0x04000000 +#define WINED3DFMT_FLAG_ALLOW_FETCH4 0x08000000
struct wined3d_rational {