[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