Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/d3d9/tests/visual.c | 240 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index f51e334a68..45c6e03dd9 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -26249,6 +26249,245 @@ static void test_desktop_window(void) IDirect3D9_Release(d3d); }
+static void test_mismatched_sample_types_fill_texture(DWORD *bits, unsigned int pitch, D3DCOLOR colour, + unsigned int size) +{ + unsigned int x, y; + + for (y = 0; y < size; ++y) + { + DWORD *ptr = (DWORD *)(((BYTE *)bits) + (y * pitch)); + + for (x = 0; x < size; ++x) + *ptr++ = colour; + } +} + +static void test_mismatched_sample_types(void) +{ + /* MSDN suggests that sampling a texture with fewer dimensions than sampler has + * is allowed while the opposite is not. + * AMD, Intel, WARP return sampled texture values in both cases. The use of W + * coordinate when sampling 3d texture with 2d sampler looks not entirely consistent. + * Nvidia returns zero texture values for both cases while that is different + * from unbound texture result (0, 0, 0, 1): it is (0, 0, 0, 0) for RGBA texture or, + * in a general case, result of a fixup of zero texture color, e. g., (0, 0, 1, 1) + * for D3DFMT_G16R16 texture. */ + + IDirect3DVertexDeclaration9 *vertex_declaration; + static IDirect3DPixelShader9 *ps_2d, *ps_3d; + static IDirect3DVolumeTexture9 *volume; + IDirect3DVertexShader9 *vertex_shader; + static IDirect3DTexture9 *tex_2d; + D3DLOCKED_RECT locked_rect; + D3DLOCKED_BOX locked_box; + IDirect3DDevice9 *device; + IDirect3D9 *d3d; + D3DCOLOR colour; + unsigned int i; + ULONG refcount; + D3DCAPS9 caps; + HWND window; + HRESULT hr; + + static const D3DVERTEXELEMENT9 decl_elements[] = + { + {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, + {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, + D3DDECL_END() + }; + static const struct + { + struct vec3 position; + struct vec3 t0; + } + quad[] = + { + {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f, 0.0f}}, + {{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f, 0.5f}}, + {{ 1.0f, -1.0f, 0.1f}, {1.0f, 0.0f, 0.5f}}, + {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}}, + }; + + static const DWORD vs_code[] = + { + 0xfffe0300, /* vs_3_0 */ + 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */ + 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */ + 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */ + 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */ + 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */ + 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */ + 0x0000ffff, /* end */ + }; + + static const DWORD ps_header[] = + { + 0xffff0300, /* ps_3_0 */ + 0x05000051, 0xa00f0000, 0x3f333333, 0x3f4ccccd, 0x3f666666, 0x00000000, + /* def c0, 0.7, 0.8, 0.9, 0.0 */ + }; + static const DWORD ps_footer[] = + { + 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40800, /* texld r1, v0, s0 */ + 0x02020029, 0x80ff0001, 0xa0ff0000, /* if_eq r1.w, c0.w */ + 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */ + 0x0000002b, /* endif */ + 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */ + 0x0000ffff, /* end */ + }; + + #define TEST_MISMATCHED_SAMPLE_BODY_WORDS 6 + + static const DWORD ps_tex_2d[TEST_MISMATCHED_SAMPLE_BODY_WORDS] = + { + 0x0200001f, 0x80000005, 0x90030000, /* dcl_texcoord0 v0.xy */ + 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */ + }; + static const DWORD ps_tex_3d[TEST_MISMATCHED_SAMPLE_BODY_WORDS] = + { + 0x0200001f, 0x80000005, 0x90070000, /* dcl_texcoord0 v0.xyz */ + 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */ + }; + + static DWORD ps_code[ARRAY_SIZE(ps_header) + TEST_MISMATCHED_SAMPLE_BODY_WORDS + ARRAY_SIZE(ps_footer)]; + + static const struct + { + const char *name; + IDirect3DBaseTexture9 **texture; + IDirect3DPixelShader9 **pixel_shader; + D3DCOLOR expected_colour; + D3DCOLOR expected_broken; + BOOL todo; + D3DCOLOR expected_broken2; + } + tests[] = + { + {"2d_2d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_2d, 0x00707070}, + {"3d_3d", (IDirect3DBaseTexture9 **)&volume, &ps_3d, 0x00303030}, + {"2d_3d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_3d, 0x00707070, 0x00b2cce5, TRUE}, + {"3d_2d", (IDirect3DBaseTexture9 **)&volume, &ps_2d, 0x00303030, 0x00b2cce5, TRUE, 0x00202020}, + }; + + window = create_window(); + ok(!!window, "Failed to create a window.\n"); + + d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + if (!(device = create_device(d3d, window, window, TRUE))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D9_Release(d3d); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice9_GetDeviceCaps(device, &caps); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0)) + { + skip("No shader model 3 support, skipping tests.\n"); + goto done; + } + if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)) + { + skip("No volume texture support, skipping tests.\n"); + goto done; + } + + hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8, + D3DPOOL_MANAGED, &volume, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &locked_box, NULL, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + test_mismatched_sample_types_fill_texture(locked_box.pBits, locked_box.RowPitch, 0x20202020, 2); + test_mismatched_sample_types_fill_texture((DWORD *)((BYTE *)locked_box.pBits + locked_box.SlicePitch), + locked_box.RowPitch, 0x40404040, 2); + hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, + D3DPOOL_MANAGED, &tex_2d, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DTexture9_LockRect(tex_2d, 0, &locked_rect, NULL, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + test_mismatched_sample_types_fill_texture(locked_rect.pBits, locked_rect.Pitch, 0x70707070, 2); + hr = IDirect3DTexture9_UnlockRect(tex_2d, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertex_shader); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + memcpy(ps_code, ps_header, sizeof(ps_header)); + memcpy(ps_code + ARRAY_SIZE(ps_header) + TEST_MISMATCHED_SAMPLE_BODY_WORDS, ps_footer, sizeof(ps_footer)); + + memcpy(ps_code + ARRAY_SIZE(ps_header), ps_tex_2d, + sizeof(*ps_code) * TEST_MISMATCHED_SAMPLE_BODY_WORDS); + hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps_2d); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + memcpy(ps_code + ARRAY_SIZE(ps_header), ps_tex_3d, + sizeof(*ps_code) * TEST_MISMATCHED_SAMPLE_BODY_WORDS); + hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps_3d); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirect3DDevice9_BeginScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80808080, 0.0f, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetTexture(device, 0, *tests[i].texture); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_SetPixelShader(device, *tests[i].pixel_shader); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad)); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + colour = getPixelColor(device, 320, 240); + + todo_wine_if(tests[i].todo) ok(color_match(colour, tests[i].expected_colour, 1) + || broken(tests[i].expected_broken && color_match(colour, tests[i].expected_broken, 1)) + || broken(tests[i].expected_broken2 && color_match(colour, tests[i].expected_broken2, 1)), + "test %s, expected 0x%08x, got 0x%08x.\n", + tests[i].name, tests[i].expected_colour, colour); + } + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + IDirect3DPixelShader9_Release(ps_2d); + IDirect3DPixelShader9_Release(ps_3d); + + IDirect3DVertexShader9_Release(vertex_shader); + IDirect3DVertexDeclaration9_Release(vertex_declaration); + IDirect3DVolumeTexture9_Release(volume); + IDirect3DTexture9_Release(tex_2d); + +done: + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D9_Release(d3d); + DestroyWindow(window); +} + START_TEST(visual) { D3DADAPTER_IDENTIFIER9 identifier; @@ -26393,4 +26632,5 @@ START_TEST(visual) test_sysmem_draw(); test_nrm_instruction(); test_desktop_window(); + test_mismatched_sample_types(); }
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/wined3d/arb_program_shader.c | 31 +++++++++++++++--------- dlls/wined3d/glsl_shader.c | 33 ++++++++++++++++++------- dlls/wined3d/shader.c | 40 +++++++++++++------------------ dlls/wined3d/wined3d_private.h | 3 ++- 4 files changed, 62 insertions(+), 45 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index c07b23ae71..15d13a234b 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1407,18 +1407,28 @@ static const char *shader_arb_get_modifier(const struct wined3d_shader_instructi static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx, const char *dst_str, const char *coord_reg, WORD flags, const char *dsx, const char *dsy) { - enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[sampler_idx].type; + BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type); + struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; struct wined3d_string_buffer *buffer = ins->ctx->buffer; - const char *tex_type; + enum wined3d_shader_resource_type resource_type; + struct color_fixup_masks masks; + const char *tex_dst = dst_str; BOOL np2_fixup = FALSE; - struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; + const char *tex_type; const char *mod; - BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type); - const char *tex_dst = dst_str; - struct color_fixup_masks masks;
- /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */ - if(!pshader) sampler_idx += WINED3D_MAX_FRAGMENT_SAMPLERS; + if (pshader) + { + resource_type = pixelshader_get_resource_type(ins->ctx->reg_maps, sampler_idx, + priv->cur_ps_args->super.tex_types); + } + else + { + resource_type = ins->ctx->reg_maps->resource_info[sampler_idx].type; + + /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */ + sampler_idx += WINED3D_MAX_FRAGMENT_SAMPLERS; + }
switch (resource_type) { @@ -1432,7 +1442,8 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD tex_type = "RECT"; else tex_type = "2D"; - if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)) + + if (pshader) { if (priv->cur_np2fixup_info->super.active & (1u << sampler_idx)) { @@ -4297,8 +4308,6 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_context_gl
shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
- pixelshader_update_resource_types(shader, args->super.tex_types); - if (!string_buffer_init(&buffer)) { ERR("Failed to initialize shader buffer.\n"); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 53169b8e46..452f5d15d9 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -2282,6 +2282,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c const struct wined3d_gl_info *gl_info = context_gl->c.gl_info; const struct wined3d_shader_indexable_temp *idx_temp_reg; unsigned int uniform_block_base, uniform_block_count; + enum wined3d_shader_resource_type resource_type; const struct wined3d_shader_lconst *lconst; const char *prefix; unsigned int i; @@ -2446,7 +2447,11 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c }
shadow_sampler = glsl_is_shadow_sampler(shader, ps_args, entry->resource_idx, entry->sampler_idx); - switch (reg_maps->resource_info[entry->resource_idx].type) + resource_type = version->type == WINED3D_SHADER_TYPE_PIXEL + ? pixelshader_get_resource_type(reg_maps, entry->resource_idx, ps_args->tex_types) + : reg_maps->resource_info[entry->resource_idx].type; + + switch (resource_type) { case WINED3D_SHADER_RESOURCE_BUFFER: sampler_type = "samplerBuffer"; @@ -2523,7 +2528,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c
default: sampler_type = "unsupported_sampler"; - FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[entry->resource_idx].type); + FIXME("Unhandled resource type %#x.\n", resource_type); break; }
@@ -3469,7 +3474,7 @@ static void shader_glsl_get_coord_size(enum wined3d_shader_resource_type resourc static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx, DWORD resource_idx, DWORD sampler_idx, DWORD flags, struct glsl_sample_function *sample_function) { - enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type; + enum wined3d_shader_resource_type resource_type; struct shader_glsl_ctx_priv *priv = ctx->backend_data; const struct wined3d_gl_info *gl_info = ctx->gl_info; BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx); @@ -3483,6 +3488,10 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context const char *base = "texture", *type_part = "", *suffix = ""; unsigned int coord_size, deriv_size;
+ resource_type = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL + ? pixelshader_get_resource_type(ctx->reg_maps, resource_idx, priv->cur_ps_args->tex_types) + : ctx->reg_maps->resource_info[resource_idx].type; + sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type;
if (resource_type >= ARRAY_SIZE(resource_type_info)) @@ -5201,6 +5210,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) DWORD resource_idx; DWORD mask = 0, swizzle; const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + enum wined3d_shader_resource_type resource_type;
/* 1.0-1.4: Use destination register as sampler source. * 2.0+: Use provided sampler source. */ @@ -5209,11 +5219,14 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) else resource_idx = ins->src[1].reg.idx[0].offset;
+ resource_type = ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL + ? pixelshader_get_resource_type(ins->ctx->reg_maps, resource_idx, priv->cur_ps_args->tex_types) + : ins->ctx->reg_maps->resource_info[resource_idx].type; + if (shader_version < WINED3D_SHADER_VERSION(1,4)) { DWORD flags = (priv->cur_ps_args->tex_transform >> resource_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT) & WINED3D_PSARGS_TEXTRANSFORM_MASK; - enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type;
/* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */ if (flags & WINED3D_PSARGS_PROJECTED && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) @@ -5252,7 +5265,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) else { if ((ins->flags & WINED3DSI_TEXLD_PROJECT) - && ins->ctx->reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) + && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) { /* ps 2.0 texldp instruction always divides by the fourth component. */ sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; @@ -7735,10 +7748,14 @@ static GLuint shader_glsl_generate_fragment_shader(const struct wined3d_context_
for (i = 0; i < shader->limits->sampler; ++i) { - if (!reg_maps->resource_info[i].type || !(args->np2_fixup & (1u << i))) + enum wined3d_shader_resource_type resource_type; + + resource_type = pixelshader_get_resource_type(reg_maps, i, args->tex_types); + + if (!resource_type || !(args->np2_fixup & (1u << i))) continue;
- if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D) + if (resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_2D) { FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n"); continue; @@ -8586,8 +8603,6 @@ static GLuint find_glsl_fragment_shader(const struct wined3d_context_gl *context memset(np2fixup, 0, sizeof(*np2fixup)); *np2fixup_info = args->np2_fixup ? np2fixup : NULL;
- pixelshader_update_resource_types(shader, args->tex_types); - string_buffer_clear(buffer); ret = shader_glsl_generate_fragment_shader(context_gl, buffer, string_buffers, shader, args, np2fixup); gl_shaders[shader_data->num_gl_shaders++].id = ret; diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 68cea78778..73acb65a19 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -4220,35 +4220,27 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d return WINED3D_OK; }
-void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types) +enum wined3d_shader_resource_type pixelshader_get_resource_type(const struct wined3d_shader_reg_maps *reg_maps, + unsigned int resource_idx, WORD tex_types) { - struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; - struct wined3d_shader_resource_info *resource_info = reg_maps->resource_info; - unsigned int i; - - if (reg_maps->shader_version.major != 1) return; - - for (i = 0; i < shader->limits->sampler; ++i) + static enum wined3d_shader_resource_type shader_resource_type_from_shader_tex_types[] = { - /* We don't sample from this sampler. */ - if (!resource_info[i].type) - continue; + WINED3D_SHADER_RESOURCE_TEXTURE_2D, /* WINED3D_SHADER_TEX_2D */ + WINED3D_SHADER_RESOURCE_TEXTURE_3D, /* WINED3D_SHADER_TEX_3D */ + WINED3D_SHADER_RESOURCE_TEXTURE_CUBE, /* WINED3D_SHADER_TEX_CUBE */ + };
- switch ((tex_types >> i * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK) - { - case WINED3D_SHADER_TEX_2D: - resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D; - break; + unsigned int idx;
- case WINED3D_SHADER_TEX_3D: - resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_3D; - break; + if (reg_maps->shader_version.major != 1) + return reg_maps->resource_info[resource_idx].type;
- case WINED3D_SHADER_TEX_CUBE: - resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_CUBE; - break; - } - } + if (!reg_maps->resource_info[resource_idx].type) + return 0; + + idx = (tex_types >> resource_idx * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK; + assert(idx < ARRAY_SIZE(shader_resource_type_from_shader_tex_types)); + return shader_resource_type_from_shader_tex_types[idx]; }
HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const struct wined3d_shader_desc *desc, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 77813515b4..f9596e9c85 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4455,7 +4455,8 @@ struct wined3d_shader } u; };
-void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN; +enum wined3d_shader_resource_type pixelshader_get_resource_type(const struct wined3d_shader_reg_maps *reg_maps, + unsigned int resource_idx, WORD tex_types) DECLSPEC_HIDDEN; void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context) DECLSPEC_HIDDEN;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/d3d9/tests/visual.c | 2 +- dlls/wined3d/shader.c | 37 ++++++++++++++++++++++++++++++++-- dlls/wined3d/wined3d_private.h | 6 ++++-- 3 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 45c6e03dd9..747750f81c 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -26366,7 +26366,7 @@ static void test_mismatched_sample_types(void) { {"2d_2d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_2d, 0x00707070}, {"3d_3d", (IDirect3DBaseTexture9 **)&volume, &ps_3d, 0x00303030}, - {"2d_3d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_3d, 0x00707070, 0x00b2cce5, TRUE}, + {"2d_3d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_3d, 0x00707070, 0x00b2cce5}, {"3d_2d", (IDirect3DBaseTexture9 **)&volume, &ps_2d, 0x00303030, 0x00b2cce5, TRUE, 0x00202020}, };
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 73acb65a19..4561eb95ff 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -4023,6 +4023,39 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 } } } + else if (shader->reg_maps.shader_version.major <= 3) + { + for (i = 0; i < shader->limits->sampler; ++i) + { + enum wined3d_shader_resource_type resource_type; + enum wined3d_shader_tex_types tex_type; + + if (!(resource_type = shader->reg_maps.resource_info[i].type)) + continue; + + switch (resource_type) + { + case WINED3D_SHADER_RESOURCE_TEXTURE_3D: + tex_type = WINED3D_SHADER_TEX_3D; + break; + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + tex_type = WINED3D_SHADER_TEX_CUBE; + break; + default: + tex_type = WINED3D_SHADER_TEX_2D; + break; + } + + if ((texture = state->textures[i])) + { + if (texture->resource.type == WINED3D_RTYPE_TEXTURE_2D + && resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_3D + && !(texture->resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP)) + tex_type = WINED3D_SHADER_TEX_2D; + } + args->tex_types |= tex_type << i * WINED3D_PSARGS_TEXTYPE_SHIFT; + } + }
if (shader->reg_maps.shader_version.major >= 4) { @@ -4221,7 +4254,7 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d }
enum wined3d_shader_resource_type pixelshader_get_resource_type(const struct wined3d_shader_reg_maps *reg_maps, - unsigned int resource_idx, WORD tex_types) + unsigned int resource_idx, DWORD tex_types) { static enum wined3d_shader_resource_type shader_resource_type_from_shader_tex_types[] = { @@ -4232,7 +4265,7 @@ enum wined3d_shader_resource_type pixelshader_get_resource_type(const struct win
unsigned int idx;
- if (reg_maps->shader_version.major != 1) + if (reg_maps->shader_version.major > 3) return reg_maps->resource_info[resource_idx].type;
if (!reg_maps->resource_info[resource_idx].type) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f9596e9c85..08cd723478 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1372,6 +1372,7 @@ enum wined3d_shader_tex_types WINED3D_SHADER_TEX_2D = 0, WINED3D_SHADER_TEX_3D = 1, WINED3D_SHADER_TEX_CUBE = 2, + WINED3D_SHADER_TEX_ERR = 3, };
struct ps_compile_args @@ -1379,8 +1380,8 @@ struct ps_compile_args struct color_fixup_desc color_fixup[WINED3D_MAX_FRAGMENT_SAMPLERS]; enum wined3d_vertex_processing_mode vp_mode; enum wined3d_ffp_ps_fog_mode fog; + DWORD tex_types; /* ps 1 - 3, 16 textures */ WORD tex_transform; /* ps 1.0-1.3, 4 textures */ - WORD tex_types; /* ps 1.0 - 1.4, 6 textures */ WORD srgb_correction; /* Bitmap for NP2 texcoord fixups (16 samplers max currently). D3D9 has a limit of 16 samplers and the fixup is superfluous @@ -1388,6 +1389,7 @@ struct ps_compile_args WORD np2_fixup; WORD shadow; /* WINED3D_MAX_FRAGMENT_SAMPLERS, 16 */ WORD texcoords_initialized; /* WINED3D_MAX_TEXTURES, 8 */ + WORD padding_to_dword; DWORD pointsprite : 1; DWORD flatshading : 1; DWORD alpha_test_func : 3; @@ -4456,7 +4458,7 @@ struct wined3d_shader };
enum wined3d_shader_resource_type pixelshader_get_resource_type(const struct wined3d_shader_reg_maps *reg_maps, - unsigned int resource_idx, WORD tex_types) DECLSPEC_HIDDEN; + unsigned int resource_idx, DWORD tex_types) DECLSPEC_HIDDEN; void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context) DECLSPEC_HIDDEN;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/d3d9/tests/visual.c | 5 ++--- dlls/wined3d/shader.c | 3 +++ 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 747750f81c..4af6146cf9 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -26359,7 +26359,6 @@ static void test_mismatched_sample_types(void) IDirect3DPixelShader9 **pixel_shader; D3DCOLOR expected_colour; D3DCOLOR expected_broken; - BOOL todo; D3DCOLOR expected_broken2; } tests[] = @@ -26367,7 +26366,7 @@ static void test_mismatched_sample_types(void) {"2d_2d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_2d, 0x00707070}, {"3d_3d", (IDirect3DBaseTexture9 **)&volume, &ps_3d, 0x00303030}, {"2d_3d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_3d, 0x00707070, 0x00b2cce5}, - {"3d_2d", (IDirect3DBaseTexture9 **)&volume, &ps_2d, 0x00303030, 0x00b2cce5, TRUE, 0x00202020}, + {"3d_2d", (IDirect3DBaseTexture9 **)&volume, &ps_2d, 0x00303030, 0x00b2cce5, 0x00202020}, };
window = create_window(); @@ -26464,7 +26463,7 @@ static void test_mismatched_sample_types(void)
colour = getPixelColor(device, 320, 240);
- todo_wine_if(tests[i].todo) ok(color_match(colour, tests[i].expected_colour, 1) + ok(color_match(colour, tests[i].expected_colour, 1) || broken(tests[i].expected_broken && color_match(colour, tests[i].expected_broken, 1)) || broken(tests[i].expected_broken2 && color_match(colour, tests[i].expected_broken2, 1)), "test %s, expected 0x%08x, got 0x%08x.\n", diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 4561eb95ff..7c040ef7c8 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -4052,6 +4052,9 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 && resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_3D && !(texture->resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP)) tex_type = WINED3D_SHADER_TEX_2D; + else if (texture->resource.type == WINED3D_RTYPE_TEXTURE_3D + && resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2D) + tex_type = WINED3D_SHADER_TEX_3D; } args->tex_types |= tex_type << i * WINED3D_PSARGS_TEXTYPE_SHIFT; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=54421
Your paranoid android.
=== w8 (32 bit report) ===
d3d9: visual.c:8771: Test failed: Input test: Quad 3(2crd-wrongidx) returned color 0x00ff00ff, expected 0x00ff0080
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com