wined3d: Use dummy textures for all the texture targets.
This commit is contained in:
parent
0386b44bad
commit
7c6bd2f287
|
@ -1252,6 +1252,40 @@ static int context_choose_pixel_format(struct wined3d_device *device, HDC hdc,
|
||||||
return iPixelFormat;
|
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. */
|
/* Do not call while under the GL lock. */
|
||||||
struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
|
struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
|
||||||
struct wined3d_surface *target, const struct wined3d_format *ds_format)
|
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);
|
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();
|
LEAVE_GL();
|
||||||
|
|
||||||
TRACE("Created context %p.\n", ret);
|
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)
|
void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name)
|
||||||
{
|
{
|
||||||
glBindTexture(target, name);
|
DWORD unit = context->active_texture;
|
||||||
checkGLcall("glBindTexture");
|
DWORD old_texture_type = context->texture_type[unit];
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
context->texture_type[context->active_texture] = target;
|
{
|
||||||
|
glBindTexture(target, name);
|
||||||
|
checkGLcall("glBindTexture");
|
||||||
|
}
|
||||||
else
|
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)
|
static void context_set_render_offscreen(struct wined3d_context *context, BOOL offscreen)
|
||||||
|
|
|
@ -970,7 +970,7 @@ out:
|
||||||
static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context)
|
static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context)
|
||||||
{
|
{
|
||||||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
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
|
/* Under DirectX you can sample even if no texture is bound, whereas
|
||||||
* OpenGL will only allow that when a valid texture is bound.
|
* OpenGL will only allow that when a valid texture is bound.
|
||||||
* We emulate this by creating dummy textures and binding them
|
* 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)");
|
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;
|
DWORD color = 0x000000ff;
|
||||||
|
|
||||||
/* Make appropriate texture active */
|
/* Make appropriate texture active */
|
||||||
context_active_texture(context, gl_info, i);
|
context_active_texture(context, gl_info, i);
|
||||||
|
|
||||||
/* Generate an opengl texture name */
|
|
||||||
glGenTextures(1, &device->dummyTextureName[i]);
|
glGenTextures(1, &device->dummyTextureName[i]);
|
||||||
checkGLcall("glGenTextures");
|
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]);
|
glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[i]);
|
||||||
checkGLcall("glBindTexture");
|
checkGLcall("glBindTexture");
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
|
||||||
checkGLcall("glTexImage2D");
|
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])
|
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. */
|
/* Context activation is done by the caller. */
|
||||||
static void destroy_dummy_textures(struct wined3d_device *device, const struct wined3d_gl_info *gl_info)
|
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();
|
ENTER_GL();
|
||||||
glDeleteTextures(gl_info->limits.textures, device->dummyTextureName);
|
if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
|
||||||
checkGLcall("glDeleteTextures(gl_info->limits.textures, device->dummyTextureName)");
|
{
|
||||||
|
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();
|
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));
|
memset(device->dummyTextureName, 0, gl_info->limits.textures * sizeof(*device->dummyTextureName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3566,7 +3566,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
|
||||||
if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
|
if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
|
||||||
device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
|
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)
|
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);
|
state_alpha(context, state, WINED3DRS_COLORKEYENABLE);
|
||||||
}
|
}
|
||||||
} /* Otherwise tex_colorop disables the stage */
|
} /* Otherwise tex_colorop disables the stage */
|
||||||
context_bind_texture(context, GL_TEXTURE_2D, device->dummyTextureName[sampler]);
|
context_bind_texture(context, GL_NONE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1722,7 +1722,10 @@ struct wined3d_device
|
||||||
struct wined3d_surface *logo_surface;
|
struct wined3d_surface *logo_surface;
|
||||||
|
|
||||||
/* Textures for when no other textures are mapped */
|
/* 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 */
|
/* DirectDraw stuff */
|
||||||
DWORD ddraw_width, ddraw_height;
|
DWORD ddraw_width, ddraw_height;
|
||||||
|
|
Loading…
Reference in New Issue