[PATCH 2/5] wined3d: Use dummy textures for all the texture targets.

Matteo Bruni mbruni at codeweavers.com
Fri Aug 26 06:33:58 CDT 2011


---
 dlls/wined3d/context.c         |   86 ++++++++++++++++++++++++++++++++++++++--
 dlls/wined3d/device.c          |   79 +++++++++++++++++++++++++++++++++----
 dlls/wined3d/state.c           |    4 +-
 dlls/wined3d/wined3d_private.h |    5 ++-
 4 files changed, 159 insertions(+), 15 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 2bef879..c50e670 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1252,6 +1252,40 @@ static int context_choose_pixel_format(struct wined3d_device *device, HDC hdc,
     return iPixelFormat;
 }
 
+/* GL locking is done by the caller */
+static void bind_dummy_textures(const struct wined3d_device *device, struct wined3d_context *context)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned int i, count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers);
+
+    for (i = 0; i < count; ++i)
+    {
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
+        checkGLcall("glActiveTextureARB");
+
+        glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[i]);
+        checkGLcall("glBindTexture");
+
+        if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+        {
+            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[i]);
+            checkGLcall("glBindTexture");
+        }
+
+        if (gl_info->supported[EXT_TEXTURE3D])
+        {
+            glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]);
+            checkGLcall("glBindTexture");
+        }
+
+        if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+        {
+            glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[i]);
+            checkGLcall("glBindTexture");
+        }
+    }
+}
+
 /* Do not call while under the GL lock. */
 struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
         struct wined3d_surface *target, const struct wined3d_format *ds_format)
@@ -1564,6 +1598,12 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     }
     device->frag_pipe->enable_extension(TRUE);
 
+    /* If this happens to be the first context for the device, dummy textures
+     * are not created yet. In that case, they will be created (and bound) by
+     * create_dummy_textures right after this context is initialized. */
+    if (device->dummyTextureName[0])
+        bind_dummy_textures(device, ret);
+
     LEAVE_GL();
 
     TRACE("Created context %p.\n", ret);
@@ -1911,12 +1951,50 @@ void context_active_texture(struct wined3d_context *context, const struct wined3
 
 void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name)
 {
-    glBindTexture(target, name);
-    checkGLcall("glBindTexture");
+    DWORD unit = context->active_texture;
+    DWORD old_texture_type = context->texture_type[unit];
+
     if (name)
-        context->texture_type[context->active_texture] = target;
+    {
+        glBindTexture(target, name);
+        checkGLcall("glBindTexture");
+    }
     else
-        context->texture_type[context->active_texture] = GL_NONE;
+    {
+        target = GL_NONE;
+    }
+
+    if (old_texture_type != target)
+    {
+        const struct wined3d_device *device = context->swapchain->device;
+
+        switch (old_texture_type)
+        {
+            case GL_NONE:
+                /* nothing to do */
+                break;
+            case GL_TEXTURE_2D:
+                glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[unit]);
+                checkGLcall("glBindTexture");
+                break;
+            case GL_TEXTURE_RECTANGLE_ARB:
+                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[unit]);
+                checkGLcall("glBindTexture");
+                break;
+            case GL_TEXTURE_CUBE_MAP:
+                glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[unit]);
+                checkGLcall("glBindTexture");
+                break;
+            case GL_TEXTURE_3D:
+                glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[unit]);
+                checkGLcall("glBindTexture");
+                break;
+            default:
+                ERR("Unexpected texture target %#x\n", old_texture_type);
+        }
+
+        context->texture_type[unit] = target;
+    }
 }
 
 static void context_set_render_offscreen(struct wined3d_context *context, BOOL offscreen)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 6b1a48a..8727ec0 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, struct wined3d_context *context)
 {
     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,25 +984,65 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
         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;
 
         /* Make appropriate texture active */
         context_active_texture(context, gl_info, i);
 
-        /* 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 %u given name %u.\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 %u given name %u.\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 %u given name %u.\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 %u given name %u.\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])
@@ -1018,11 +1058,34 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
 /* 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)");
+    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)");
+    }
+
+    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();
 
+    memset(device->dummy_texture_cube, 0, gl_info->limits.textures * sizeof(*device->dummy_texture_cube));
+    memset(device->dummy_texture_3d, 0, gl_info->limits.textures * sizeof(*device->dummy_texture_3d));
+    memset(device->dummy_texture_rect, 0, gl_info->limits.textures * sizeof(*device->dummy_texture_rect));
     memset(device->dummyTextureName, 0, gl_info->limits.textures * sizeof(*device->dummyTextureName));
 }
 
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index b777432..1535e3a 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3566,7 +3566,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
         if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
             device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
     }
-    else if (mapped_stage < gl_info->limits.textures)
+    else
     {
         if (sampler < state->lowest_disabled_stage)
         {
@@ -3578,7 +3578,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
                 state_alpha(context, state, WINED3DRS_COLORKEYENABLE);
             }
         } /* Otherwise tex_colorop disables the stage */
-        context_bind_texture(context, GL_TEXTURE_2D, device->dummyTextureName[sampler]);
+        context_bind_texture(context, GL_NONE, 0);
     }
 }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0fe5712..56c939a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1722,7 +1722,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;
-- 
1.7.3.4




More information about the wine-patches mailing list