[3/6] wined3d: Use dummy textures for all the texture targets when the texture is unset.

Matteo Bruni matteo.mystral at gmail.com
Mon Jul 4 15:32:44 CDT 2011


-------------- next part --------------
From 9e1f2a0a574fb083af712290da587b1a2bd8a8f0 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <mbruni at codeweavers.com>
Date: Fri, 1 Jul 2011 19:59:04 +0200
Subject: wined3d: Use dummy textures for all the texture targets when the texture is unset.

---
 dlls/wined3d/device.c          |   78 ++++++++++++++++++++++++++++++++++-----
 dlls/wined3d/state.c           |   44 +++++++++++++++++++---
 dlls/wined3d/wined3d_private.h |    6 +++-
 3 files changed, 111 insertions(+), 17 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 334319e..5b6b9fc 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -970,7 +970,7 @@ out:
 static void create_dummy_textures(struct wined3d_device *device)
 {
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
-    unsigned int i;
+    unsigned int i, j, count;
     /* Under DirectX you can sample even if no texture is bound, whereas
      * OpenGL will only allow that when a valid texture is bound.
      * We emulate this by creating dummy textures and binding them
@@ -984,7 +984,8 @@ static void create_dummy_textures(struct wined3d_device *device)
         checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
     }
 
-    for (i = 0; i < gl_info->limits.textures; ++i)
+    count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers);
+    for (i = 0; i < count; ++i)
     {
         DWORD color = 0x000000ff;
 
@@ -992,18 +993,57 @@ static void create_dummy_textures(struct wined3d_device *device)
         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
         checkGLcall("glActiveTextureARB");
 
-        /* Generate an opengl texture name */
         glGenTextures(1, &device->dummyTextureName[i]);
         checkGLcall("glGenTextures");
-        TRACE("Dummy Texture %d given name %d.\n", i, device->dummyTextureName[i]);
+        TRACE("Dummy 2D texture %d given name %d.\n", i, device->dummyTextureName[i]);
 
-        /* Generate a dummy 2d texture (not using 1d because they cause many
-        * DRI drivers fall back to sw) */
         glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[i]);
         checkGLcall("glBindTexture");
 
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
         checkGLcall("glTexImage2D");
+
+        if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+        {
+            glGenTextures(1, &device->dummy_texture_rect[i]);
+            checkGLcall("glGenTextures");
+            TRACE("Dummy rectangle texture %d given name %d.\n", i, device->dummy_texture_rect[i]);
+
+            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[i]);
+            checkGLcall("glBindTexture");
+
+            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+            checkGLcall("glTexImage2D");
+        }
+
+        if (gl_info->supported[EXT_TEXTURE3D])
+        {
+            glGenTextures(1, &device->dummy_texture_3d[i]);
+            checkGLcall("glGenTextures");
+            TRACE("Dummy 3D texture %d given name %d.\n", i, device->dummy_texture_3d[i]);
+
+            glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]);
+            checkGLcall("glBindTexture");
+
+            GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
+            checkGLcall("glTexImage3D");
+        }
+
+        if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+        {
+            glGenTextures(1, &device->dummy_texture_cube[i]);
+            checkGLcall("glGenTextures");
+            TRACE("Dummy cube texture %d given name %d.\n", i, device->dummy_texture_cube[i]);
+
+            glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[i]);
+            checkGLcall("glBindTexture");
+
+            for (j = GL_TEXTURE_CUBE_MAP_POSITIVE_X; j <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++j)
+            {
+                glTexImage2D(j, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+                checkGLcall("glTexImage2D");
+            }
+        }
     }
 
     if (gl_info->supported[APPLE_CLIENT_STORAGE])
@@ -1019,12 +1059,30 @@ static void create_dummy_textures(struct wined3d_device *device)
 /* Context activation is done by the caller. */
 static void destroy_dummy_textures(struct wined3d_device *device, const struct wined3d_gl_info *gl_info)
 {
+    unsigned int count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers);
+
     ENTER_GL();
-    glDeleteTextures(gl_info->limits.textures, device->dummyTextureName);
-    checkGLcall("glDeleteTextures(gl_info->limits.textures, device->dummyTextureName)");
-    LEAVE_GL();
+    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+    {
+        glDeleteTextures(count, device->dummy_texture_cube);
+        checkGLcall("glDeleteTextures(count, device->dummy_texture_cube)");
+    }
+
+    if (gl_info->supported[EXT_TEXTURE3D])
+    {
+        glDeleteTextures(count, device->dummy_texture_3d);
+        checkGLcall("glDeleteTextures(count, device->dummy_texture_3d)");
+    }
 
-    memset(device->dummyTextureName, 0, gl_info->limits.textures * sizeof(*device->dummyTextureName));
+    if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+    {
+        glDeleteTextures(count, device->dummy_texture_rect);
+        checkGLcall("glDeleteTextures(count, device->dummy_texture_rect)");
+    }
+
+    glDeleteTextures(count, device->dummyTextureName);
+    checkGLcall("glDeleteTextures(count, device->dummyTextureName)");
+    LEAVE_GL();
 }
 
 static LONG fullscreen_style(LONG style)
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index bb2b292..0dd1211 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3540,10 +3540,12 @@ static void sampler_texmatrix(DWORD state, struct wined3d_stateblock *stateblock
 static void sampler(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD sampler = state_id - STATE_SAMPLER(0);
-    struct wined3d_device *device = stateblock->device;
+    const struct wined3d_device *device = stateblock->device;
     DWORD mapped_stage = device->texUnitMap[sampler];
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    const struct wined3d_state *state = &stateblock->state;
+    struct wined3d_state *state = &stateblock->state;
+    struct wined3d_texture *texture = state->textures[sampler];
+    DWORD old_texture_type = state->texture_type[sampler];
     union {
         float f;
         DWORD d;
@@ -3567,9 +3569,41 @@ static void sampler(DWORD state_id, struct wined3d_stateblock *stateblock, struc
     GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
     checkGLcall("glActiveTextureARB");
 
-    if (state->textures[sampler])
+    if ((!texture && old_texture_type != GL_NONE) || (texture && texture->target != old_texture_type))
+    {
+        switch (old_texture_type)
+        {
+            case GL_NONE:
+                /* nothing to do */
+                break;
+            case GL_TEXTURE_2D:
+                glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler]);
+                checkGLcall("glBindTexture()");
+                break;
+            case GL_TEXTURE_RECTANGLE_ARB:
+                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[sampler]);
+                checkGLcall("glBindTexture()");
+                break;
+            case GL_TEXTURE_CUBE_MAP:
+                glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[sampler]);
+                checkGLcall("glBindTexture()");
+                break;
+            case GL_TEXTURE_3D:
+                glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[sampler]);
+                checkGLcall("glBindTexture()");
+                break;
+            default:
+                ERR("Unexpected texture type %x\n", old_texture_type);
+        }
+
+        if (texture)
+            state->texture_type[sampler] = texture->target;
+        else
+            state->texture_type[sampler] = GL_NONE;
+    }
+
+    if (texture)
     {
-        struct wined3d_texture *texture = state->textures[sampler];
         BOOL srgb = state->sampler_states[sampler][WINED3DSAMP_SRGBTEXTURE];
 
         texture->texture_ops->texture_bind(texture, gl_info, srgb);
@@ -3612,8 +3646,6 @@ static void sampler(DWORD state_id, struct wined3d_stateblock *stateblock, struc
                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
             }
         } /* Otherwise tex_colorop disables the stage */
-        glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler]);
-        checkGLcall("glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler])");
     }
 }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f4947f1..00a7dbe 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1711,7 +1711,10 @@ struct wined3d_device
     struct wined3d_surface *logo_surface;
 
     /* Textures for when no other textures are mapped */
-    UINT                          dummyTextureName[MAX_TEXTURES];
+    UINT                          dummyTextureName[MAX_COMBINED_SAMPLERS];
+    UINT dummy_texture_rect[MAX_COMBINED_SAMPLERS];
+    UINT dummy_texture_3d[MAX_COMBINED_SAMPLERS];
+    UINT dummy_texture_cube[MAX_COMBINED_SAMPLERS];
 
     /* DirectDraw stuff */
     DWORD ddraw_width, ddraw_height;
@@ -2251,6 +2254,7 @@ struct wined3d_state
     float *ps_consts_f;
 
     struct wined3d_texture *textures[MAX_COMBINED_SAMPLERS];
+    DWORD texture_type[MAX_COMBINED_SAMPLERS];
     DWORD sampler_states[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
     DWORD texture_states[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
     DWORD lowest_disabled_stage;
-- 
1.7.3.4


More information about the wine-patches mailing list