[D3D9 3/6] Add a test for textures and sampler states

Ivan Gyurdiev ivg231 at gmail.com
Sat Oct 28 18:53:25 CDT 2006


Note: Vertex and dmap textures are included in the test, but disabled. 
That's because there's no good way to mark things todo in this 
framework. It should be fixed first, before the test is added, and I 
think that it would be more appropriate to fix this after Stefan's 
changes to state management.

Note 2: Vertex textures (the ones disabled above) have their release 
call disabled, because it hangs on native. This results in a small 
memory leak in the test, but there's nothing I can do about that - I 
don't have access to the native code to see why it hangs. It is not a 
refcounting problem, since the refcount is shown to be correct before 
release. Furthermore, the test shows all other vertex texture 
functionality working, other than the release call. If someone figures 
out the problem, we can reenable it.

-------------- next part --------------
---
 dlls/d3d9/tests/stateblock.c |  272 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 270 insertions(+), 2 deletions(-)

diff --git a/dlls/d3d9/tests/stateblock.c b/dlls/d3d9/tests/stateblock.c
index bfed524..c8337c4 100644
--- a/dlls/d3d9/tests/stateblock.c
+++ b/dlls/d3d9/tests/stateblock.c
@@ -1390,6 +1390,268 @@ static void render_states_queue_test(
     test->test_arg = test_arg;
 }
 
+/* =================== State test: Textures, Sampler States ================== */
+
+/* There are 16 pixel samplers, 4 vertex one, and 1 dmap */
+#define MAX_PIXEL_SAMPLERS   16
+
+/* Disable VTF tests for now, since there's no good way to mark them todo.
+ * Once fixed, turn on the tests to prevent regressions */
+#if 0
+#define MAX_VERTEX_SAMPLERS   4
+#define ENABLE_DMAP_SAMPLER   1
+#else
+#define MAX_VERTEX_SAMPLERS   0
+#define ENABLE_DMAP_SAMPLER   0
+#endif
+
+#define MAX_SAMPLERS (MAX_PIXEL_SAMPLERS + MAX_VERTEX_SAMPLERS + ENABLE_DMAP_SAMPLER)
+#define D3D9_SAMPLER_STATES 13
+
+typedef struct texture_data {
+    IDirect3DBaseTexture9* texture[MAX_SAMPLERS];
+    DWORD sampler_state[MAX_SAMPLERS][D3D9_SAMPLER_STATES];
+} texture_data;
+
+typedef struct texture_arg {
+    IDirect3DDevice9* device;
+} texture_arg;
+
+typedef struct texture_context {
+    texture_data return_data_buffer;
+    texture_data default_data_buffer;
+    texture_data test_data_buffer;
+    texture_data poison_data_buffer;
+    DWORD sampler_indices[MAX_SAMPLERS];
+} texture_context;
+
+static void texture_default_data_init(
+    texture_data* data) {
+
+    unsigned int i;
+    for (i = 0; i < MAX_SAMPLERS; i++) {
+        data->texture[i] = NULL;
+        data->sampler_state[i][D3DSAMP_ADDRESSU - 1] = D3DTADDRESS_WRAP;
+        data->sampler_state[i][D3DSAMP_ADDRESSV - 1] = D3DTADDRESS_WRAP;
+        data->sampler_state[i][D3DSAMP_ADDRESSW - 1] = D3DTADDRESS_WRAP;
+        data->sampler_state[i][D3DSAMP_BORDERCOLOR - 1] = 0x00000000;
+        data->sampler_state[i][D3DSAMP_MAGFILTER - 1] = D3DTEXF_POINT;
+        data->sampler_state[i][D3DSAMP_MINFILTER - 1] = D3DTEXF_POINT;
+        data->sampler_state[i][D3DSAMP_MIPFILTER - 1] = D3DTEXF_NONE;
+        data->sampler_state[i][D3DSAMP_MIPMAPLODBIAS - 1] = 0;
+        data->sampler_state[i][D3DSAMP_MAXMIPLEVEL - 1] = 0;
+        data->sampler_state[i][D3DSAMP_MAXANISOTROPY - 1] = 1;
+        data->sampler_state[i][D3DSAMP_SRGBTEXTURE - 1] = 0;
+        data->sampler_state[i][D3DSAMP_ELEMENTINDEX - 1] = 0;
+        data->sampler_state[i][D3DSAMP_DMAPOFFSET - 1] = 0;
+    }
+}
+
+static void texture_poison_data_init(
+    texture_data* data) {
+
+    unsigned int i, j;
+    for (i = 0; i < MAX_SAMPLERS; i++) {
+        data->texture[i] = (void*) 0x1337c0de;
+        for (j = 0; j < D3D9_SAMPLER_STATES; j++)
+            data->sampler_state[i][j] = 0x1337c0de;
+    }
+}
+
+static IDirect3DBaseTexture9* texture_make_default(
+    IDirect3DDevice9* device) {
+
+    HRESULT hret;
+    IDirect3DTexture9* texture = NULL;
+
+    UINT default_width = 8;
+    UINT default_height = 8;
+    UINT default_levels = 1;
+    DWORD default_usage = 0;
+    D3DFORMAT default_fmt = D3DFMT_A8R8G8B8;
+    D3DPOOL default_pool = D3DPOOL_DEFAULT;
+    
+    hret = IDirect3DDevice9_CreateTexture(device, default_width, default_height, default_levels,
+       default_usage, default_fmt, default_pool, &texture, NULL);
+    ok (hret == D3D_OK, "CreateTexture returned %#x.\n", hret);  
+
+    return (IDirect3DBaseTexture9*) texture;
+}
+
+static void texture_test_data_init(
+    IDirect3DDevice9* device,
+    texture_data* data) {
+
+    unsigned int i;
+    for (i = 0; i < MAX_SAMPLERS; i++) {
+        data->texture[i] = texture_make_default(device);
+        data->sampler_state[i][D3DSAMP_ADDRESSU - 1] = D3DTADDRESS_MIRROR;
+        data->sampler_state[i][D3DSAMP_ADDRESSV - 1] = D3DTADDRESS_BORDER;
+        data->sampler_state[i][D3DSAMP_ADDRESSW - 1] = D3DTADDRESS_CLAMP;
+        data->sampler_state[i][D3DSAMP_BORDERCOLOR - 1] = 0x01010101;
+        data->sampler_state[i][D3DSAMP_MAGFILTER - 1] = D3DTEXF_PYRAMIDALQUAD;
+        data->sampler_state[i][D3DSAMP_MINFILTER - 1] = D3DTEXF_GAUSSIANQUAD;
+        data->sampler_state[i][D3DSAMP_MIPFILTER - 1] = D3DTEXF_LINEAR;
+        data->sampler_state[i][D3DSAMP_MIPMAPLODBIAS - 1] = 0.4;
+        data->sampler_state[i][D3DSAMP_MAXMIPLEVEL - 1] = 2;
+        data->sampler_state[i][D3DSAMP_MAXANISOTROPY - 1] = 2;
+        data->sampler_state[i][D3DSAMP_SRGBTEXTURE - 1] = 0.3;
+        data->sampler_state[i][D3DSAMP_ELEMENTINDEX - 1] = 1;
+        data->sampler_state[i][D3DSAMP_DMAPOFFSET - 1] = 1;
+   }
+}
+
+static void texture_test_data_release(
+    DWORD* sampler_indices,
+    texture_data* data) {
+
+    unsigned int i;
+    for (i = 0; i < MAX_SAMPLERS; i++) {
+        if (data->texture[i]) {
+
+            /* Releasing vertex samplers hangs on native.
+             * Leak some memory until the cause for that is established.
+             * It seems like a possible bug in the native dll */
+
+            if (sampler_indices[i] >= D3DVERTEXTEXTURESAMPLER0)
+                continue;
+
+            IUnknown_Release(data->texture[i]);
+         }
+    }
+}
+
+static void texture_set_handler(
+    IDirect3DDevice9* device, const state_test* test, const void* data) {
+
+    HRESULT hret;
+    unsigned int i, j;
+    const texture_data* tdata = data;
+    const texture_context* tcontext = test->test_context;
+
+    for (i = 0; i < MAX_SAMPLERS; i++) {
+
+        DWORD sampler_idx = tcontext->sampler_indices[i];
+
+        hret = IDirect3DDevice9_SetTexture(device, sampler_idx, tdata->texture[i]);
+        ok(hret == D3D_OK, "SetTexture returned %#x for sampler %u.\n", hret, sampler_idx);
+
+        for (j = 0; j < D3D9_SAMPLER_STATES; j++) {
+
+            /* Note: The indices are 1-based, and none are skipped */
+            unsigned int state_idx = j + 1;
+
+            hret = IDirect3DDevice9_SetSamplerState(device, sampler_idx, state_idx, tdata->sampler_state[i][j]);
+            ok (hret == D3D_OK, "SetSamplerState returned %#x for sampler %u.\n", hret, i);
+        }
+    }
+}
+
+static void texture_get_handler(
+    IDirect3DDevice9* device, const state_test* test, void* data) {
+
+    HRESULT hret;
+    unsigned int i, j;
+    texture_data* tdata = data;
+    const texture_context* tcontext = test->test_context;
+
+    for (i = 0; i < MAX_SAMPLERS; i++) {
+    
+        DWORD sampler_idx = tcontext->sampler_indices[i];
+
+        hret = IDirect3DDevice9_GetTexture(device, sampler_idx, &tdata->texture[i]);
+        ok(hret == D3D_OK, "GetTexture returned %#x for sampler %u.\n", hret, sampler_idx);
+        if (hret == D3D_OK && tdata->texture[i])
+            IUnknown_Release(tdata->texture[i]);
+
+        for (j = 0; j < D3D9_SAMPLER_STATES; j++) {
+
+            /* Note: The indices are 1-based, and none are skipped */
+            unsigned int state_idx = j + 1;
+
+            hret = IDirect3DDevice9_GetSamplerState(device, sampler_idx, state_idx, &tdata->sampler_state[i][j]);
+            ok (hret == D3D_OK, "GetSamplerState returned %#x for sampler %u.\n", hret, sampler_idx);
+        }
+    }
+}
+
+static void texture_print_handler(
+    const state_test* test,
+    const void* data) {
+
+    unsigned int i, j;
+    const texture_data* tdata = data;
+    const texture_context* tcontext = test->test_context;
+
+    for (i = 0; i < MAX_SAMPLERS; i++) {
+
+        DWORD sampler_idx = tcontext->sampler_indices[i];
+        trace("Sampler = %u, Texture = %p\n", sampler_idx, tdata->texture[i]);
+        for (j = 0; j < D3D9_SAMPLER_STATES; j++) {
+
+            /* Note: The indices are 1-based, and none are skipped */
+            DWORD state_idx = j + 1;
+            trace("    Sampler State %u, Value = %#x\n", state_idx, tdata->sampler_state[i][j]);
+        }
+    }
+}
+
+static HRESULT texture_setup_handler(
+    state_test* test) {
+
+    unsigned int i, count = 0;
+    const texture_arg* targ = test->test_arg;
+
+    texture_context *ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(texture_context));
+    if (ctx == NULL) return E_FAIL;
+    test->test_context = ctx;
+
+    test->return_data = &ctx->return_data_buffer;
+    test->default_data = &ctx->default_data_buffer;
+    test->initial_data = &ctx->default_data_buffer;
+    test->test_data_in = &ctx->test_data_buffer;
+    test->test_data_out = &ctx->test_data_buffer;
+    test->poison_data = &ctx->poison_data_buffer;
+
+    texture_default_data_init(&ctx->default_data_buffer);
+    texture_test_data_init(targ->device, &ctx->test_data_buffer);
+    texture_poison_data_init(&ctx->poison_data_buffer);
+
+    /* Sampler layout in the data array */
+    for (i = 0; i < MAX_PIXEL_SAMPLERS; i++)
+        ctx->sampler_indices[count++] = i;
+    for (i = 0; i < MAX_VERTEX_SAMPLERS; i++)
+        ctx->sampler_indices[count++] = D3DVERTEXTEXTURESAMPLER0 + i;
+    if (ENABLE_DMAP_SAMPLER)
+        ctx->sampler_indices[count++] = D3DDMAPSAMPLER;
+
+    test->data_size = sizeof(texture_data);
+
+    return D3D_OK;
+}
+
+static void texture_teardown_handler(
+    state_test* test) {
+
+    texture_context *ctx = (test->test_context);
+
+    texture_test_data_release(ctx->sampler_indices, &ctx->test_data_buffer);
+    HeapFree(GetProcessHeap(), 0, ctx);
+}
+
+static void textures_queue_test(
+    state_test* test,
+    texture_arg* test_arg) {
+
+    test->setup_handler = texture_setup_handler;
+    test->teardown_handler = texture_teardown_handler;
+    test->set_handler = texture_set_handler;
+    test->get_handler = texture_get_handler;
+    test->print_handler = texture_print_handler;
+    test->test_name = "set_get_texture";
+    test->test_arg = test_arg;
+}
+
 /* =================== Main state tests function =============================== */
 
 static void test_state_management(
@@ -1403,15 +1665,17 @@ static void test_state_management(
                    1 for lights
                    1 for transforms
                    1 for render states
+                   1 for textures
      */
-    const int max_tests = 5;
-    state_test tests[5];
+    const int max_tests = 6;
+    state_test tests[6];
     unsigned int tcount = 0;
 
     shader_constant_arg pshader_constant_arg;
     shader_constant_arg vshader_constant_arg;
     render_state_arg render_state_arg;
     light_arg light_arg;
+    texture_arg texture_arg;
 
     hret = IDirect3DDevice9_GetDeviceCaps(device, &caps);
     ok(hret == D3D_OK, "GetDeviceCaps returned %#x.\n", hret);
@@ -1447,6 +1711,10 @@ static void test_state_management(
     render_states_queue_test(&tests[tcount], &render_state_arg);
     tcount++;
 
+    texture_arg.device = device;
+    textures_queue_test(&tests[tcount], &texture_arg);
+    tcount++;
+
     execute_test_chain_all(device, tests, tcount);
 }
 
-- 
1.4.2.4



More information about the wine-patches mailing list