-- v6: d3dx9: Partially implement D3DXFillCubeTextureTX(). d3dx9: Fix ARGB texture fills with negative component values. d3dx9/tests: Add a helper to compare filled cube textures. d3dx9: Partially implement D3DXFillTextureTX(). d3dx9: Create parameter evaluator for texture shaders. d3dx9/preshader: Set input table size for texture shaders.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/preshader.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c index 8a7dfd76935..316019ffe4c 100644 --- a/dlls/d3dx9_36/preshader.c +++ b/dlls/d3dx9_36/preshader.c @@ -144,6 +144,7 @@ static double pres_div(double *args, int n) {return 0.0;} #define FOURCC_CLIT 0x54494c43 #define FOURCC_FXLC 0x434c5846 #define FOURCC_PRSI 0x49535250 +#define FOURCC_TX_1 0x54580100 #define PRES_SIGN 0x46580000
struct op_info @@ -1110,13 +1111,15 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u struct d3dx_parameters_store *parameters) { unsigned int *p; - unsigned int i, j, const_count; + unsigned int i, j, const_count, magic; double *dconst; HRESULT hr; unsigned int saved_word; unsigned int section_size;
- TRACE("Preshader version %#x.\n", *ptr & 0xffff); + magic = *ptr; + + TRACE("Preshader magic %#x.\n", magic);
if (!count) { @@ -1186,6 +1189,8 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u return D3DXERR_INVALIDDATA; } pres->regs.table_sizes[PRES_REGTAB_IMMED] = get_reg_offset(PRES_REGTAB_IMMED, const_count); + if (magic == FOURCC_TX_1) + pres->regs.table_sizes[PRES_REGTAB_INPUT] = 2;
update_table_sizes_consts(pres->regs.table_sizes, &pres->inputs); for (i = 0; i < pres->ins_count; ++i)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 2 + dlls/d3dx9_36/effect.c | 99 ++++++++++++++++++----------------- dlls/d3dx9_36/shader.c | 18 +++++++ dlls/d3dx9_36/tests/texture.c | 27 +++++++--- 4 files changed, 93 insertions(+), 53 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index d22415b1f69..ce5abfcc735 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -396,6 +396,8 @@ struct d3dx_parameters_store unsigned int full_name_tmp_size; };
+HRESULT d3dx_init_parameters_store(struct d3dx_parameters_store *store, unsigned int count) DECLSPEC_HIDDEN; +void d3dx_parameters_store_cleanup(struct d3dx_parameters_store *store) DECLSPEC_HIDDEN; struct d3dx_parameter *get_parameter_by_name(struct d3dx_parameters_store *store, struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index c5e1f6ed348..db40bc249cd 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -745,6 +745,40 @@ static void free_parameter_block(struct d3dx_parameter_block *block) heap_free(block); }
+static int param_rb_compare(const void *key, const struct wine_rb_entry *entry) +{ + const char *name = key; + struct d3dx_parameter *param = WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry); + + return strcmp(name, param->full_name); +} + +HRESULT d3dx_init_parameters_store(struct d3dx_parameters_store *store, unsigned int count) +{ + store->count = count; + wine_rb_init(&store->tree, param_rb_compare); + + if (store->count && !(store->parameters = heap_alloc_zero(sizeof(*store->parameters) * store->count))) + return E_OUTOFMEMORY; + + return S_OK; +} + +void d3dx_parameters_store_cleanup(struct d3dx_parameters_store *store) +{ + unsigned int i; + + heap_free(store->full_name_tmp); + + if (store->parameters) + { + for (i = 0; i < store->count; ++i) + free_top_level_parameter(&store->parameters[i]); + heap_free(store->parameters); + store->parameters = NULL; + } +} + static void d3dx_effect_cleanup(struct d3dx_effect *effect) { struct d3dx_parameter_block *block, *cursor; @@ -760,14 +794,7 @@ static void d3dx_effect_cleanup(struct d3dx_effect *effect) free_parameter_block(block); }
- heap_free(effect->params.full_name_tmp); - - if (effect->params.parameters) - { - for (i = 0; i < effect->params.count; ++i) - free_top_level_parameter(&effect->params.parameters[i]); - heap_free(effect->params.parameters); - } + d3dx_parameters_store_cleanup(&effect->params);
if (effect->techniques) { @@ -5371,14 +5398,6 @@ static void param_set_magic_number(struct d3dx_parameter *param) memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string)); }
-static int param_rb_compare(const void *key, const struct wine_rb_entry *entry) -{ - const char *name = key; - struct d3dx_parameter *param = WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry); - - return strcmp(name, param->full_name); -} - static void add_param_to_tree(struct d3dx_effect *effect, struct d3dx_parameter *param, struct d3dx_parameter *parent, char separator, unsigned int element) { @@ -6301,13 +6320,13 @@ static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_paramet static HRESULT d3dx_parse_effect(struct d3dx_effect *effect, const char *data, UINT data_size, uint32_t start, const char **skip_constants, unsigned int skip_constants_count) { - unsigned int string_count, resource_count; + unsigned int string_count, resource_count, params_count; const char *ptr = data + start; unsigned int i; HRESULT hr;
- effect->params.count = read_u32(&ptr); - TRACE("Parameter count: %u.\n", effect->params.count); + params_count = read_u32(&ptr); + TRACE("Parameter count: %u.\n", params_count);
effect->technique_count = read_u32(&ptr); TRACE("Technique count: %u.\n", effect->technique_count); @@ -6326,29 +6345,23 @@ static HRESULT d3dx_parse_effect(struct d3dx_effect *effect, const char *data, U goto err_out; }
- wine_rb_init(&effect->params.tree, param_rb_compare); - if (effect->params.count) + if (FAILED(hr = d3dx_init_parameters_store(&effect->params, params_count))) { - effect->params.parameters = heap_alloc_zero(sizeof(*effect->params.parameters) * effect->params.count); - if (!effect->params.parameters) - { - ERR("Out of memory.\n"); - hr = E_OUTOFMEMORY; - goto err_out; - } + hr = E_OUTOFMEMORY; + goto err_out; + }
- for (i = 0; i < effect->params.count; ++i) + for (i = 0; i < effect->params.count; ++i) + { + param_set_magic_number(&effect->params.parameters[i].param); + hr = d3dx_parse_effect_parameter(effect, &effect->params.parameters[i], data, &ptr, effect->objects); + if (hr != D3D_OK) { - param_set_magic_number(&effect->params.parameters[i].param); - hr = d3dx_parse_effect_parameter(effect, &effect->params.parameters[i], data, &ptr, effect->objects); - if (hr != D3D_OK) - { - WARN("Failed to parse parameter %u.\n", i); - goto err_out; - } - walk_parameter_tree(&effect->params.parameters[i].param, param_set_top_level_param, &effect->params.parameters[i]); - add_param_to_tree(effect, &effect->params.parameters[i].param, NULL, 0, 0); + WARN("Failed to parse parameter %u.\n", i); + goto err_out; } + walk_parameter_tree(&effect->params.parameters[i].param, param_set_top_level_param, &effect->params.parameters[i]); + add_param_to_tree(effect, &effect->params.parameters[i].param, NULL, 0, 0); }
if (effect->technique_count) @@ -6427,15 +6440,7 @@ err_out: effect->techniques = NULL; }
- if (effect->params.parameters) - { - for (i = 0; i < effect->params.count; ++i) - { - free_top_level_parameter(&effect->params.parameters[i]); - } - heap_free(effect->params.parameters); - effect->params.parameters = NULL; - } + d3dx_parameters_store_cleanup(&effect->params);
if (effect->objects) { diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index 3663eacf6da..a776a1d9a94 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -2361,6 +2361,9 @@ struct d3dx9_texture_shader LONG ref;
ID3DXBuffer *byte_code; + ULONG64 version_counter; + struct d3dx_parameters_store parameters; + struct d3dx_param_eval *eval; };
static inline struct d3dx9_texture_shader *impl_from_ID3DXTextureShader(ID3DXTextureShader *iface) @@ -2406,6 +2409,8 @@ static ULONG WINAPI d3dx9_texture_shader_Release(ID3DXTextureShader *iface) { if (texture_shader->byte_code) ID3DXBuffer_Release(texture_shader->byte_code); + d3dx_free_param_eval(texture_shader->eval); + d3dx_parameters_store_cleanup(&texture_shader->parameters); HeapFree(GetProcessHeap(), 0, texture_shader); }
@@ -2637,6 +2642,19 @@ HRESULT WINAPI D3DXCreateTextureShader(const DWORD *function, ID3DXTextureShader } memcpy(ID3DXBuffer_GetBufferPointer(object->byte_code), function, size);
+ if (FAILED(hr = d3dx_init_parameters_store(&object->parameters, 0))) + { + IUnknown_Release(&object->ID3DXTextureShader_iface); + return hr; + } + + if (FAILED(hr = d3dx_create_param_eval(&object->parameters, ID3DXBuffer_GetBufferPointer(object->byte_code), + size, D3DXPT_FLOAT, &object->eval, &object->version_counter, NULL, 0))) + { + IUnknown_Release(&object->ID3DXTextureShader_iface); + return hr; + } + *texture_shader = &object->ID3DXTextureShader_iface;
return D3D_OK; diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 20970a93dcd..00a09831ec9 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2471,11 +2471,13 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer); todo_wine ok(SUCCEEDED(hr), "Failed to get texture shader constant buffer.\n"); - if (FAILED(hr)) + + if (SUCCEEDED(hr)) { - skip("Texture shaders not supported, skipping further tests.\n"); - IUnknown_Release(tx); - return; + size = ID3DXBuffer_GetBufferSize(buffer); + ok(!size, "Unexpected buffer size %u.\n", size); + + ID3DXBuffer_Release(buffer); }
size = ID3DXBuffer_GetBufferSize(buffer); @@ -2484,8 +2486,10 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ID3DXBuffer_Release(buffer);
hr = tx->lpVtbl->GetDesc(tx, &ctab_desc); + todo_wine ok(hr == S_OK, "Failed to get constant description, hr %#lx.\n", hr); - ok(!ctab_desc.Constants, "Unexpected number of constants %u.\n", ctab_desc.Constants); + if (SUCCEEDED(hr)) + ok(!ctab_desc.Constants, "Unexpected number of constants %u.\n", ctab_desc.Constants);
/* Constant table access calls, without constant table. */ h = tx->lpVtbl->GetConstant(tx, NULL, 0); @@ -2528,6 +2532,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = D3DXFillTextureTX(texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY); @@ -2541,6 +2546,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR /* The third position coordinate is apparently undefined for 2D textures. */ unsigned int color = data[y * lr.Pitch / sizeof(*data) + x] & 0xffffff00;
+ todo_wine ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u).\n", color, x, y); } } @@ -2560,6 +2566,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = D3DXFillCubeTextureTX(cube_texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
for (z = 0; z < 6; ++z) @@ -2599,6 +2606,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR component = -component; expected |= max(component, 0) << i * 8; } + todo_wine ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n", color, x, y, z); } @@ -2619,6 +2627,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = D3DXFillVolumeTextureTX(volume_texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = IDirect3DVolumeTexture9_LockBox(volume_texture, 0, &lb, NULL, D3DLOCK_READONLY); @@ -2633,6 +2642,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR unsigned int expected = 0xff000000 | ((x * 4 + 2) << 16) | ((y * 4 + 2) << 8) | (z * 4 + 2); unsigned int color = data[z * lb.SlicePitch / sizeof(*data) + y * lb.RowPitch / sizeof(*data) + x];
+ todo_wine ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n", color, x, y, z); } @@ -2646,8 +2656,12 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR IUnknown_Release(tx);
/* With constant table */ + tx = NULL; hr = D3DXCreateTextureShader(shader_code2, &tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + goto cleanup;
hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer); todo_wine @@ -2768,7 +2782,8 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR IDirect3DDevice9_Release(device); IDirect3D9_Release(d3d); DestroyWindow(wnd); - IUnknown_Release(tx); + if (tx) + IUnknown_Release(tx); }
START_TEST(texture)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/preshader.c | 10 +++++--- dlls/d3dx9_36/shader.c | 43 +++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/tests/texture.c | 1 - dlls/d3dx9_36/texture.c | 6 ----- 4 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c index 316019ffe4c..a98b75b3e52 100644 --- a/dlls/d3dx9_36/preshader.c +++ b/dlls/d3dx9_36/preshader.c @@ -1728,16 +1728,20 @@ HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, const struct d3dx HRESULT hr; unsigned int i; unsigned int elements, elements_param, elements_table; + BOOL is_dirty; float *oc;
TRACE("peval %p, param %p, param_value %p.\n", peval, param, param_value);
- if (is_const_tab_input_dirty(&peval->pres.inputs, ULONG64_MAX)) + if ((is_dirty = is_const_tab_input_dirty(&peval->pres.inputs, ULONG64_MAX))) { set_constants(&peval->pres.regs, &peval->pres.inputs, - next_update_version(peval->version_counter), - NULL, NULL, peval->param_type, FALSE, FALSE); + next_update_version(peval->version_counter), NULL, NULL, + peval->param_type, FALSE, FALSE); + }
+ if (is_dirty || peval->pres.regs.table_sizes[PRES_REGTAB_INPUT]) + { if (FAILED(hr = execute_preshader(&peval->pres))) return hr; } diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index a776a1d9a94..3ed7bcc5b70 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <assert.h>
#include "d3dx9_private.h" #include "d3dcommon.h" @@ -2615,6 +2616,15 @@ static const struct ID3DXTextureShaderVtbl d3dx9_texture_shader_vtbl = d3dx9_texture_shader_SetMatrixTransposePointerArray };
+static inline struct d3dx9_texture_shader *unsafe_impl_from_ID3DXTextureShader(ID3DXTextureShader *iface) +{ + if (!iface) + return NULL; + + assert(iface->lpVtbl == &d3dx9_texture_shader_vtbl); + return impl_from_ID3DXTextureShader(iface); +} + HRESULT WINAPI D3DXCreateTextureShader(const DWORD *function, ID3DXTextureShader **texture_shader) { struct d3dx9_texture_shader *object; @@ -2660,6 +2670,39 @@ HRESULT WINAPI D3DXCreateTextureShader(const DWORD *function, ID3DXTextureShader return D3D_OK; }
+void WINAPI texture_shader_fill_2d(D3DXVECTOR4 *out, const D3DXVECTOR2 *texcoord, + const D3DXVECTOR2 *texelsize, void *data) +{ + struct d3dx9_texture_shader *shader = data; + struct d3dx_parameter param = { 0 }; + float *inputs; + + inputs = (float *)shader->eval->pres.regs.tables[PRES_REGTAB_INPUT]; + + *(inputs++) = texcoord->x; + *(inputs++) = texcoord->y; + *(inputs++) = 0.0f; + *(inputs++) = 0.0f; + + *(inputs++) = texelsize->x; + *(inputs++) = texelsize->y; + *(inputs++) = 0.0f; + *(inputs++) = 0.0f; + + param.type = D3DXPT_FLOAT; + param.bytes = 4 * sizeof(float); + d3dx_evaluate_parameter(shader->eval, ¶m, out); +} + +HRESULT WINAPI D3DXFillTextureTX(struct IDirect3DTexture9 *texture, ID3DXTextureShader *texture_shader) +{ + struct d3dx9_texture_shader *shader = unsafe_impl_from_ID3DXTextureShader(texture_shader); + + TRACE("texture %p, texture_shader %p.\n", texture, texture_shader); + + return D3DXFillTexture(texture, texture_shader_fill_2d, shader); +} + static unsigned int get_instr_length(const DWORD *byte_code, unsigned int major, unsigned int minor) { DWORD opcode = *byte_code & 0xffff; diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 00a09831ec9..8ae9f71b8b8 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2546,7 +2546,6 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR /* The third position coordinate is apparently undefined for 2D textures. */ unsigned int color = data[y * lr.Pitch / sizeof(*data) + x] & 0xffffff00;
- todo_wine ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u).\n", color, x, y); } } diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 46bca5eb4e6..04df331c79a 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1382,12 +1382,6 @@ HRESULT WINAPI D3DXFillTexture(struct IDirect3DTexture9 *texture, LPD3DXFILL2D f return D3D_OK; }
-HRESULT WINAPI D3DXFillTextureTX(struct IDirect3DTexture9 *texture, ID3DXTextureShader *texture_shader) -{ - FIXME("texture %p, texture_shader %p stub.\n", texture, texture_shader); - return E_NOTIMPL; -} - HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, const void *src_data, UINT src_data_size, UINT size, UINT mip_levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, DWORD filter, DWORD mip_filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info,
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/tests/texture.c | 196 ++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 90 deletions(-)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 8ae9f71b8b8..8caab1218fd 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -1362,119 +1362,135 @@ static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int } }
-static void test_D3DXFillCubeTexture(IDirect3DDevice9 *device) +static DWORD get_argb_color(D3DFORMAT format, DWORD x, DWORD y, const D3DLOCKED_RECT *lock_rect) { - IDirect3DCubeTexture9 *tex; - HRESULT hr; - D3DLOCKED_RECT lock_rect; - DWORD x, y, f, m; - DWORD v[4], e[4]; - DWORD value, expected, size, pitch; - enum cube_coord coordmap[6][3] = - { - {ONE, YCOORDINV, XCOORDINV}, - {ZERO, YCOORDINV, XCOORD}, - {XCOORD, ONE, YCOORD}, - {XCOORD, ZERO, YCOORDINV}, - {XCOORD, YCOORDINV, ONE}, - {XCOORDINV, YCOORDINV, ZERO} - }; - - size = 4; - hr = IDirect3DDevice9_CreateCubeTexture(device, size, 0, 0, D3DFMT_A8R8G8B8, - D3DPOOL_MANAGED, &tex, NULL); + DWORD value, ret; + int pitch;
- if (SUCCEEDED(hr)) + switch (format) { - hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL); - ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#lx, expected %#lx\n", hr, D3D_OK); + case D3DFMT_A8R8G8B8: + pitch = lock_rect->Pitch / sizeof(DWORD); + return ((DWORD *)lock_rect->pBits)[y * pitch + x]; + case D3DFMT_A1R5G5B5: + pitch = lock_rect->Pitch / sizeof(WORD); + value = ((WORD *)lock_rect->pBits)[y * pitch + x];
- for (m = 0; m < 3; m++) - { - for (f = 0; f < 6; f++) - { - hr = IDirect3DCubeTexture9_LockRect(tex, f, m, &lock_rect, NULL, D3DLOCK_READONLY); - ok(hr == D3D_OK, "Couldn't lock the texture, error %#lx\n", hr); - if (SUCCEEDED(hr)) - { - pitch = lock_rect.Pitch / sizeof(DWORD); - for (y = 0; y < size; y++) - { - for (x = 0; x < size; x++) - { - value = ((DWORD *)lock_rect.pBits)[y * pitch + x]; - v[0] = (value >> 24) & 0xff; - v[1] = (value >> 16) & 0xff; - v[2] = (value >> 8) & 0xff; - v[3] = value & 0xff; + ret = (value >> 15 & 0x1) << 16 + | (value >> 10 & 0x1f) << 16 + | (value >> 5 & 0x1f) << 8 + | (value & 0x1f);
- e[0] = (f == 0) || (f == 1) ? - 0 : (BYTE)(255.0f / size * 2.0f + 0.5f); - e[1] = get_cube_coord(coordmap[f][0], x, y, size) / size * 255.0f + 0.5f; - e[2] = get_cube_coord(coordmap[f][1], x, y, size) / size * 255.0f + 0.5f; - e[3] = get_cube_coord(coordmap[f][2], x, y, size) / size * 255.0f + 0.5f; - expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3]; + return ret;
- ok(color_match(v, e), - "Texel at face %lu (%lu, %lu) doesn't match: %#lx, expected %#lx\n", - f, x, y, value, expected); - } - } - IDirect3DCubeTexture9_UnlockRect(tex, f, m); - } - } - size >>= 1; - } + default: + return 0; + } +}
- IDirect3DCubeTexture9_Release(tex); +static DWORD get_expected_argb_color(D3DFORMAT format, const D3DXVECTOR4 *v) +{ + switch (format) + { + case D3DFMT_A8R8G8B8: + return (BYTE)(v->w * 255 + 0.5f) << 24 + | (BYTE)(v->x * 255 + 0.5f) << 16 + | (BYTE)(v->y * 255 + 0.5f) << 8 + | (BYTE)(v->z * 255 + 0.5f); + case D3DFMT_A1R5G5B5: + + return (BYTE)(v->w + 0.5f) << 24 + | (BYTE)(v->x * 31 + 0.5f) << 16 + | (BYTE)(v->y * 31 + 0.5f) << 8 + | (BYTE)(v->z * 31 + 0.5f); + default: + return 0; } - else - skip("Failed to create texture\n"); +}
- hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 1, 0, D3DFMT_A1R5G5B5, - D3DPOOL_MANAGED, &tex, NULL); +#define compare_cube_texture(t,f,d) compare_cube_texture_(t,f,d,__LINE__) +static void compare_cube_texture_(IDirect3DCubeTexture9 *texture, + LPD3DXFILL3D func, BYTE diff, unsigned int line) +{ + static const enum cube_coord coordmap[6][3] = + { + {ONE, YCOORDINV, XCOORDINV}, + {ZERO, YCOORDINV, XCOORD}, + {XCOORD, ONE, YCOORD}, + {XCOORD, ZERO, YCOORDINV}, + {XCOORD, YCOORDINV, ONE}, + {XCOORDINV, YCOORDINV, ZERO} + };
- if (SUCCEEDED(hr)) + DWORD x, y, m, f, levels, size, value, expected; + D3DXVECTOR3 coord, texelsize; + D3DLOCKED_RECT lock_rect; + D3DSURFACE_DESC desc; + D3DXVECTOR4 out; + HRESULT hr; + + levels = IDirect3DCubeTexture9_GetLevelCount(texture); + + for (m = 0; m < levels; ++m) { - hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL); - ok(hr == D3D_OK, "D3DXFillTexture returned %#lx, expected %#lx\n", hr, D3D_OK); + hr = IDirect3DCubeTexture9_GetLevelDesc(texture, m, &desc); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + size = desc.Width; + for (f = 0; f < 6; f++) { - hr = IDirect3DCubeTexture9_LockRect(tex, f, 0, &lock_rect, NULL, D3DLOCK_READONLY); - ok(hr == D3D_OK, "Couldn't lock the texture, error %#lx\n", hr); + texelsize.x = (f == 0) || (f == 1) ? 0.0f : 2.0f / size; + texelsize.y = (f == 2) || (f == 3) ? 0.0f : 2.0f / size; + texelsize.z = (f == 4) || (f == 5) ? 0.0f : 2.0f / size; + + hr = IDirect3DCubeTexture9_LockRect(texture, f, m, &lock_rect, NULL, D3DLOCK_READONLY); + ok(hr == D3D_OK, "Couldn't lock the texture, error %#lx.\n", hr); if (SUCCEEDED(hr)) { - pitch = lock_rect.Pitch / sizeof(WORD); - for (y = 0; y < 4; y++) + for (y = 0; y < size; y++) { - for (x = 0; x < 4; x++) + for (x = 0; x < size; x++) { - value = ((WORD *)lock_rect.pBits)[y * pitch + x]; - v[0] = value >> 15; - v[1] = value >> 10 & 0x1f; - v[2] = value >> 5 & 0x1f; - v[3] = value & 0x1f; + coord.x = get_cube_coord(coordmap[f][0], x, y, size) / size * 2.0f - 1.0f; + coord.y = get_cube_coord(coordmap[f][1], x, y, size) / size * 2.0f - 1.0f; + coord.z = get_cube_coord(coordmap[f][2], x, y, size) / size * 2.0f - 1.0f;
- e[0] = (f == 0) || (f == 1) ? - 0 : (BYTE)(1.0f / size * 2.0f + 0.5f); - e[1] = get_cube_coord(coordmap[f][0], x, y, 4) / 4 * 31.0f + 0.5f; - e[2] = get_cube_coord(coordmap[f][1], x, y, 4) / 4 * 31.0f + 0.5f; - e[3] = get_cube_coord(coordmap[f][2], x, y, 4) / 4 * 31.0f + 0.5f; - expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3]; + func(&out, &coord, &texelsize, NULL);
- ok(color_match(v, e), - "Texel at face %lu (%lu, %lu) doesn't match: %#lx, expected %#lx\n", - f, x, y, value, expected); + value = get_argb_color(desc.Format, x, y, &lock_rect); + expected = get_expected_argb_color(desc.Format, &out); + + ok_(__FILE__, line)(compare_color(value, expected, diff), + "Texel at face %lu (%lu, %lu) doesn't match: %08lx, expected %08lx.\n", + f, x, y, value, expected); } } - IDirect3DCubeTexture9_UnlockRect(tex, f, 0); + IDirect3DCubeTexture9_UnlockRect(texture, f, m); } } - - IDirect3DCubeTexture9_Release(tex); } - else - skip("Failed to create texture\n"); +} + +static void test_D3DXFillCubeTexture(IDirect3DDevice9 *device) +{ + IDirect3DCubeTexture9 *tex; + HRESULT hr; + + hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + compare_cube_texture(tex, fillfunc_cube, 1); + IDirect3DCubeTexture9_Release(tex); + + hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 1, 0, D3DFMT_A1R5G5B5, + D3DPOOL_MANAGED, &tex, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + compare_cube_texture(tex, fillfunc_cube, 2); + IDirect3DCubeTexture9_Release(tex); }
static void WINAPI fillfunc_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord, @@ -2475,7 +2491,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR if (SUCCEEDED(hr)) { size = ID3DXBuffer_GetBufferSize(buffer); - ok(!size, "Unexpected buffer size %u.\n", size); + ok(!size, "Unexpected buffer size %lu.\n", size);
ID3DXBuffer_Release(buffer); }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/tests/texture.c | 31 ++++++++++++++++++++++++++----- dlls/d3dx9_36/texture.c | 2 +- 2 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 8caab1218fd..2b3e1895700 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -1330,6 +1330,15 @@ static void WINAPI fillfunc_cube(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord value->w = texelsize->x; }
+static void WINAPI fillfunc_cube_coord(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord, + const D3DXVECTOR3 *texelsize, void *data) +{ + value->x = texcoord->x; + value->y = texcoord->y; + value->z = texcoord->z; + value->w = 1.0f; +} + enum cube_coord { XCOORD = 0, @@ -1388,21 +1397,27 @@ static DWORD get_argb_color(D3DFORMAT format, DWORD x, DWORD y, const D3DLOCKED_ } }
+static BYTE get_s8_clipped(float v) +{ + return (BYTE)(v >= 0.0f ? v * 255 + 0.5f : 0.0f); +} + static DWORD get_expected_argb_color(D3DFORMAT format, const D3DXVECTOR4 *v) { switch (format) { case D3DFMT_A8R8G8B8: - return (BYTE)(v->w * 255 + 0.5f) << 24 - | (BYTE)(v->x * 255 + 0.5f) << 16 - | (BYTE)(v->y * 255 + 0.5f) << 8 - | (BYTE)(v->z * 255 + 0.5f); - case D3DFMT_A1R5G5B5: + return get_s8_clipped(v->w) << 24 + | get_s8_clipped(v->x) << 16 + | get_s8_clipped(v->y) << 8 + | get_s8_clipped(v->z);
+ case D3DFMT_A1R5G5B5: return (BYTE)(v->w + 0.5f) << 24 | (BYTE)(v->x * 31 + 0.5f) << 16 | (BYTE)(v->y * 31 + 0.5f) << 8 | (BYTE)(v->z * 31 + 0.5f); + default: return 0; } @@ -1479,9 +1494,15 @@ static void test_D3DXFillCubeTexture(IDirect3DDevice9 *device)
hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL); ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL); ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); compare_cube_texture(tex, fillfunc_cube, 1); + + hr = D3DXFillCubeTexture(tex, fillfunc_cube_coord, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + compare_cube_texture(tex, fillfunc_cube_coord, 1); + IDirect3DCubeTexture9_Release(tex);
hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 1, 0, D3DFMT_A1R5G5B5, diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 04df331c79a..def7e41070b 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1288,7 +1288,7 @@ static inline void fill_texture(const struct pixel_format_desc *format, BYTE *po else if (format->type == FORMAT_ARGBF) v = *(DWORD *)&comp_value; else if (format->type == FORMAT_ARGB) - v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f; + v = max(comp_value * ((1 << format->bits[c]) - 1) + 0.5f, 0); else FIXME("Unhandled format type %#x\n", format->type);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/shader.c | 33 +++++++++++++++++++++++ dlls/d3dx9_36/tests/texture.c | 49 +---------------------------------- dlls/d3dx9_36/texture.c | 6 ----- 3 files changed, 34 insertions(+), 54 deletions(-)
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index 3ed7bcc5b70..1aa75d64dc5 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -2694,6 +2694,30 @@ void WINAPI texture_shader_fill_2d(D3DXVECTOR4 *out, const D3DXVECTOR2 *texcoord d3dx_evaluate_parameter(shader->eval, ¶m, out); }
+void WINAPI texture_shader_fill_3d(D3DXVECTOR4 *out, const D3DXVECTOR3 *texcoord, + const D3DXVECTOR3 *texelsize, void *data) +{ + struct d3dx9_texture_shader *shader = data; + struct d3dx_parameter param = { 0 }; + float *inputs; + + inputs = (float *)shader->eval->pres.regs.tables[PRES_REGTAB_INPUT]; + + *(inputs++) = texcoord->x; + *(inputs++) = texcoord->y; + *(inputs++) = texcoord->z; + *(inputs++) = 0.0f; + + *(inputs++) = texelsize->x; + *(inputs++) = texelsize->y; + *(inputs++) = texelsize->z; + *(inputs++) = 0.0f; + + param.type = D3DXPT_FLOAT; + param.bytes = 4 * sizeof(float); + d3dx_evaluate_parameter(shader->eval, ¶m, out); +} + HRESULT WINAPI D3DXFillTextureTX(struct IDirect3DTexture9 *texture, ID3DXTextureShader *texture_shader) { struct d3dx9_texture_shader *shader = unsafe_impl_from_ID3DXTextureShader(texture_shader); @@ -2703,6 +2727,15 @@ HRESULT WINAPI D3DXFillTextureTX(struct IDirect3DTexture9 *texture, ID3DXTexture return D3DXFillTexture(texture, texture_shader_fill_2d, shader); }
+HRESULT WINAPI D3DXFillCubeTextureTX(struct IDirect3DCubeTexture9 *cube, ID3DXTextureShader *texture_shader) +{ + struct d3dx9_texture_shader *shader = unsafe_impl_from_ID3DXTextureShader(texture_shader); + + TRACE("cube %p, texture_shader %p.\n", cube, texture_shader); + + return D3DXFillCubeTexture(cube, texture_shader_fill_3d, shader); +} + static unsigned int get_instr_length(const DWORD *byte_code, unsigned int major, unsigned int minor) { DWORD opcode = *byte_code & 0xffff; diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 2b3e1895700..fa2bba3df65 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2602,55 +2602,8 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = D3DXFillCubeTextureTX(cube_texture, tx); - todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); - - for (z = 0; z < 6; ++z) - { - static const char * const mapping[6][3] = - { - {"-x", "-y", "1"}, - {"+x", "-y", "0"}, - {"+y", "1", "+x"}, - {"-y", "0", "+x"}, - {"1", "-y", "+x"}, - {"0", "-y", "-x"}, - }; - - hr = IDirect3DCubeTexture9_LockRect(cube_texture, z, 0, &lr, NULL, D3DLOCK_READONLY); - ok(SUCCEEDED(hr), "Locking texture failed, hr %#lx.\n", hr); - data = lr.pBits; - for (y = 0; y < 256; ++y) - { - for (x = 0; x < 256; ++x) - { - unsigned int color = data[y * lr.Pitch / sizeof(*data) + x]; - unsigned int expected = 0xff000000; - unsigned int i; - - for (i = 0; i < 3; ++i) - { - int component; - - if (mapping[z][i][0] == '0') - component = 0; - else if (mapping[z][i][0] == '1') - component = 255; - else - component = mapping[z][i][1] == 'x' ? x * 2 - 255 : y * 2 - 255; - if (mapping[z][i][0] == '-') - component = -component; - expected |= max(component, 0) << i * 8; - } - todo_wine - ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n", - color, x, y, z); - } - } - hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, z, 0); - ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#lx.\n", hr); - } - + compare_cube_texture(cube_texture, fillfunc_cube_coord, 1); IDirect3DCubeTexture9_Release(cube_texture);
if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) || caps.MaxVolumeExtent < 64) diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index def7e41070b..2ee79b51f79 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1723,12 +1723,6 @@ HRESULT WINAPI D3DXFillCubeTexture(struct IDirect3DCubeTexture9 *texture, LPD3DX return D3D_OK; }
-HRESULT WINAPI D3DXFillCubeTextureTX(struct IDirect3DCubeTexture9 *texture, ID3DXTextureShader *texture_shader) -{ - FIXME("texture %p, texture_shader %p stub.\n", texture, texture_shader); - return E_NOTIMPL; -} - HRESULT WINAPI D3DXFillVolumeTexture(struct IDirect3DVolumeTexture9 *texture, LPD3DXFILL3D function, void *funcdata) { DWORD miplevels;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=128810
Your paranoid android.
=== w8 (32 bit report) ===
d3dx9_36: 0b20:texture: unhandled exception c0000005 at 00800588
=== w8adm (32 bit report) ===
d3dx9_36: 0abc:texture: unhandled exception c0000005 at 00720588
=== w864 (32 bit report) ===
d3dx9_36: 04b4:texture: unhandled exception c0000005 at 003C0588
=== w1064v1809 (32 bit report) ===
d3dx9_36: 17d8:texture: unhandled exception c0000005 at 00960540
=== w1064_tsign (32 bit report) ===
d3dx9_36: 1f2c:texture: unhandled exception c0000005 at 05280CF8
=== w10pro64 (32 bit report) ===
d3dx9_36: 03dc:texture: unhandled exception c0000005 at 00CF12E8
=== w864 (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w1064v1809 (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w1064_2qxl (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w1064_adm (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w1064_tsign (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w10pro64 (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w10pro64_en_AE_u8 (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w10pro64_ar (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w10pro64_ja (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== w10pro64_zh_CN (64 bit report) ===
Report validation errors: d3dx9_36:texture crashed (c0000374)
=== debian11 (32 bit report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on read access to 0x0000000a in 32-bit code (0x6a04618b).
=== debian11 (32 bit ar:MA report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on execute access to 0x04740278 in 32-bit code (0x04740278).
=== debian11 (32 bit de report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on execute access to 0x04740278 in 32-bit code (0x04740278).
=== debian11 (32 bit fr report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on execute access to 0x04740278 in 32-bit code (0x04740278).
=== debian11 (32 bit he:IL report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on read access to 0x0000000a in 32-bit code (0x6a04618b).
=== debian11 (32 bit hi:IN report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on read access to 0x0000000a in 32-bit code (0x6a04618b).
=== debian11 (32 bit ja:JP report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on execute access to 0x04740278 in 32-bit code (0x04740278).
=== debian11 (32 bit zh:CN report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on execute access to 0x04740278 in 32-bit code (0x04740278).
=== debian11b (32 bit WoW report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on read access to 0x0000000a in 32-bit code (0x6a04618b).
=== debian11b (64 bit WoW report) ===
d3dx9_36: texture.c:2521: Test failed: Unexpected buffer size 224. texture.c:2573: Test succeeded inside todo block: Got unexpected hr 0. Unhandled exception: page fault on execute access to 0x00000000008ada80 in 64-bit code (0x000000008ada80).
Should be good for another review now.