From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/preshader.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c index 8a7dfd76935..c19c30d428b 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,12 +1111,14 @@ 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;
+ magic = *ptr; + TRACE("Preshader version %#x.\n", *ptr & 0xffff);
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 | 82 +++++++++++++++++++---------------- dlls/d3dx9_36/shader.c | 18 ++++++++ dlls/d3dx9_36/tests/texture.c | 32 +++++++++----- 4 files changed, 86 insertions(+), 48 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..d1946812cfb 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,17 +6345,14 @@ 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; + }
+ if (effect->params.count) + { for (i = 0; i < effect->params.count; ++i) { param_set_magic_number(&effect->params.parameters[i].param); @@ -6427,15 +6443,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 e8a57fc609e..2fb05d57856 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2471,21 +2471,20 @@ 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)) - { - 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); + if (SUCCEEDED(hr)) + { + size = ID3DXBuffer_GetBufferSize(buffer); + ok(!size, "Unexpected buffer size %u.\n", size);
- ID3DXBuffer_Release(buffer); + ID3DXBuffer_Release(buffer); + }
hr = tx->lpVtbl->GetDesc(tx, &ctab_desc); + todo_wine ok(hr == S_OK, "Failed to get constant description, hr %#x.\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 +2527,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = D3DXFillTextureTX(texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY); @@ -2541,6 +2541,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 +2561,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = D3DXFillCubeTextureTX(cube_texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
for (z = 0; z < 6; ++z) @@ -2599,6 +2601,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 +2622,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = D3DXFillVolumeTextureTX(volume_texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVolumeTexture9_LockBox(volume_texture, 0, &lb, NULL, D3DLOCK_READONLY); @@ -2633,6 +2637,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 +2651,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 %#x.\n", hr); + if (FAILED(hr)) + goto cleanup;
hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer); todo_wine @@ -2768,7 +2777,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 | 2 -- dlls/d3dx9_36/texture.c | 6 ----- 4 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c index c19c30d428b..5f40c34bcb4 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 2fb05d57856..0f7c6c45ef2 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2527,7 +2527,6 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = D3DXFillTextureTX(texture, tx); - todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY); @@ -2541,7 +2540,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 | 192 ++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 88 deletions(-)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 0f7c6c45ef2..0e426b80a9e 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 %#x, expected %#x\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 %#x\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 & 0x1f) << 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 %u (%u, %u) doesn't match: %#x, expected %#x\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 %#x, expected %#x\n", hr, D3D_OK); + hr = IDirect3DCubeTexture9_GetLevelDesc(texture, m, &desc); + ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr); + + size = desc.Width; + for (f = 0; f < 6; f++) { - hr = IDirect3DCubeTexture9_LockRect(tex, f, 0, &lock_rect, NULL, D3DLOCK_READONLY); + 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 %#x\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 %u (%u, %u) doesn't match: %#x, expected %#x\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 %u (%u, %u) doesn't match: %08x, expected %08x.\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, "Failed to create a cube texture, hr %#x.\n", hr); + hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL); + ok(hr == D3D_OK, "Unexpected hr %#x.\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, "Failed to create a cube texture, hr %#x.\n", hr); + hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL); + ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr); + compare_cube_texture(tex, fillfunc_cube, 2); + IDirect3DCubeTexture9_Release(tex); }
static void WINAPI fillfunc_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/tests/texture.c | 29 +++++++++++++++++++++++++---- dlls/d3dx9_36/texture.c | 2 +- 2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 0e426b80a9e..5f491b89a72 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,15 +1397,21 @@ 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); + + 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 @@ -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, "Failed to create a cube texture, hr %#x.\n", hr); + hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL); ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr); compare_cube_texture(tex, fillfunc_cube, 1); + + hr = D3DXFillCubeTexture(tex, fillfunc_cube_coord, NULL); + ok(hr == D3D_OK, "Unexpected hr %#x.\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 5f491b89a72..dddccd1728d 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2596,55 +2596,8 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = D3DXFillCubeTextureTX(cube_texture, tx); - todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\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 %#x.\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 %#x.\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;