Commit 604caf0c authored by Roderick Colenbrander's avatar Roderick Colenbrander Committed by Alexandre Julliard

wined3d: Remove oversize texture support.

parent 74bf524a
...@@ -719,11 +719,10 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, ...@@ -719,11 +719,10 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,
if (gl_info->supported[APPLE_CLIENT_STORAGE]) if (gl_info->supported[APPLE_CLIENT_STORAGE])
{ {
if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_OVERSIZE | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) { if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) {
/* In some cases we want to disable client storage. /* In some cases we want to disable client storage.
* SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches
* SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues... * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues...
* SFLAG_OVERSIZE: The gl texture is smaller than the allocated memory
* SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface * SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface
* allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively * allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively
*/ */
...@@ -1419,7 +1418,7 @@ void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb) ...@@ -1419,7 +1418,7 @@ void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb)
if(convert != NO_CONVERSION) surface->Flags |= SFLAG_CONVERTED; if(convert != NO_CONVERSION) surface->Flags |= SFLAG_CONVERTED;
else surface->Flags &= ~SFLAG_CONVERTED; else surface->Flags &= ~SFLAG_CONVERTED;
if ((surface->Flags & SFLAG_NONPOW2) && !(surface->Flags & SFLAG_OVERSIZE)) if (surface->Flags & SFLAG_NONPOW2)
{ {
width = surface->pow2Width; width = surface->pow2Width;
height = surface->pow2Height; height = surface->pow2Height;
...@@ -4420,9 +4419,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { ...@@ -4420,9 +4419,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
3: WARN and return WINED3DERR_NOTAVAILABLE; 3: WARN and return WINED3DERR_NOTAVAILABLE;
4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target. 4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target.
*/ */
WARN("(%p) Creating an oversized surface: %ux%u (texture is %ux%u)\n", if(This->resource.pool == WINED3DPOOL_DEFAULT || This->resource.pool == WINED3DPOOL_MANAGED)
This, This->pow2Width, This->pow2Height, This->currentDesc.Width, This->currentDesc.Height); {
This->Flags |= SFLAG_OVERSIZE; WARN("(%p) Unable to allocate a surface which exceeds the maximum OpenGL texture size\n", This);
return WINED3DERR_NOTAVAILABLE;
}
/* We should never use this surface in combination with OpenGL! */
TRACE("(%p) Creating an oversized surface: %ux%u\n", This, This->pow2Width, This->pow2Height);
/* This will be initialized on the first blt */ /* This will be initialized on the first blt */
This->glRect.left = 0; This->glRect.left = 0;
...@@ -4430,8 +4434,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { ...@@ -4430,8 +4434,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
This->glRect.right = 0; This->glRect.right = 0;
This->glRect.bottom = 0; This->glRect.bottom = 0;
} else { } else {
/* Check this after the oversize check - do not make an oversized surface a texture_rectangle one. /* Don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE
doesn't work in combination with ARB_TEXTURE_RECTANGLE. doesn't work in combination with ARB_TEXTURE_RECTANGLE.
*/ */
...@@ -4446,8 +4449,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { ...@@ -4446,8 +4449,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
This->Flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD); This->Flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD);
} }
/* No oversize, gl rect is the full texture size */
This->Flags &= ~SFLAG_OVERSIZE;
This->glRect.left = 0; This->glRect.left = 0;
This->glRect.top = 0; This->glRect.top = 0;
This->glRect.right = This->pow2Width; This->glRect.right = This->pow2Width;
...@@ -5001,7 +5002,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -5001,7 +5002,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
glPixelStorei(GL_UNPACK_ROW_LENGTH, width); glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
LEAVE_GL(); LEAVE_GL();
if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) { if (This->Flags & SFLAG_NONPOW2) {
TRACE("non power of two support\n"); TRACE("non power of two support\n");
if (mem || (This->Flags & SFLAG_PBO)) { if (mem || (This->Flags & SFLAG_PBO)) {
surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem); surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem);
......
...@@ -570,7 +570,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT ...@@ -570,7 +570,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT
/* Use the callback to create the texture surface. */ /* Use the callback to create the texture surface. */
hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_h, format_desc->format, hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_h, format_desc->format,
usage, pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &texture->surfaces[i]); usage, pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &texture->surfaces[i]);
if (FAILED(hr) || ((IWineD3DSurfaceImpl *)texture->surfaces[i])->Flags & SFLAG_OVERSIZE) if (FAILED(hr))
{ {
FIXME("Failed to create surface %p, hr %#x\n", texture, hr); FIXME("Failed to create surface %p, hr %#x\n", texture, hr);
texture->surfaces[i] = NULL; texture->surfaces[i] = NULL;
......
...@@ -2276,10 +2276,8 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { ...@@ -2276,10 +2276,8 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
*********************************************************************/ *********************************************************************/
BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4])
{ {
const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
int x1 = Rect->left, x2 = Rect->right; int x1 = Rect->left, x2 = Rect->right;
int y1 = Rect->top, y2 = Rect->bottom; int y1 = Rect->top, y2 = Rect->bottom;
GLint maxSize = gl_info->limits.texture_size;
TRACE("(%p)->(%d,%d)-(%d,%d)\n", This, TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
Rect->left, Rect->top, Rect->right, Rect->bottom); Rect->left, Rect->top, Rect->right, Rect->bottom);
...@@ -2294,107 +2292,18 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4] ...@@ -2294,107 +2292,18 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]
y2 = Rect->top; y2 = Rect->top;
} }
/* No oversized texture? This is easy */ /* Which rect from the texture do I need? */
if(!(This->Flags & SFLAG_OVERSIZE)) { if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
/* Which rect from the texture do I need? */ {
if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB) glTexCoord[0] = (float) Rect->left;
{ glTexCoord[2] = (float) Rect->top;
glTexCoord[0] = (float) Rect->left; glTexCoord[1] = (float) Rect->right;
glTexCoord[2] = (float) Rect->top; glTexCoord[3] = (float) Rect->bottom;
glTexCoord[1] = (float) Rect->right;
glTexCoord[3] = (float) Rect->bottom;
} else {
glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
}
return TRUE;
} else { } else {
/* Check if we can succeed at all */ glTexCoord[0] = (float) Rect->left / (float) This->pow2Width;
if( (x2 - x1) > maxSize || glTexCoord[2] = (float) Rect->top / (float) This->pow2Height;
(y2 - y1) > maxSize ) { glTexCoord[1] = (float) Rect->right / (float) This->pow2Width;
TRACE("Requested rectangle is too large for gl\n"); glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height;
return FALSE;
}
/* A part of the texture has to be picked. First, check if
* some texture part is loaded already, if yes try to re-use it.
* If the texture is dirty, or the part can't be used,
* re-position the part to load
*/
if(This->Flags & SFLAG_INTEXTURE) {
if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
/* Ok, the rectangle is ok, re-use it */
TRACE("Using existing gl Texture\n");
} else {
/* Rectangle is not ok, dirtify the texture to reload it */
TRACE("Dirtifying texture to force reload\n");
This->Flags &= ~SFLAG_INTEXTURE;
}
}
/* Now if we are dirty(no else if!) */
if(!(This->Flags & SFLAG_INTEXTURE)) {
/* Set the new rectangle. Use the following strategy:
* 1) Use as big textures as possible.
* 2) Place the texture part in the way that the requested
* part is in the middle of the texture(well, almost)
* 3) If the texture is moved over the edges of the
* surface, replace it nicely
* 4) If the coord is not limiting the texture size,
* use the whole size
*/
if((This->pow2Width) > maxSize) {
This->glRect.left = x1 - maxSize / 2;
if(This->glRect.left < 0) {
This->glRect.left = 0;
}
This->glRect.right = This->glRect.left + maxSize;
if(This->glRect.right > This->currentDesc.Width) {
This->glRect.right = This->currentDesc.Width;
This->glRect.left = This->glRect.right - maxSize;
}
} else {
This->glRect.left = 0;
This->glRect.right = This->pow2Width;
}
if (This->pow2Height > maxSize)
{
This->glRect.top = x1 - gl_info->limits.texture_size / 2;
if(This->glRect.top < 0) This->glRect.top = 0;
This->glRect.bottom = This->glRect.left + maxSize;
if(This->glRect.bottom > This->currentDesc.Height) {
This->glRect.bottom = This->currentDesc.Height;
This->glRect.top = This->glRect.bottom - maxSize;
}
} else {
This->glRect.top = 0;
This->glRect.bottom = This->pow2Height;
}
TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This,
This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom);
}
/* Re-calculate the rect to draw */
Rect->left -= This->glRect.left;
Rect->right -= This->glRect.left;
Rect->top -= This->glRect.top;
Rect->bottom -= This->glRect.top;
/* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size,
* or the pow2Width / pow2Height of the surface.
*
* Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up
* as regular GL_TEXTURE_2D.
*/
glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left);
glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);
glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left);
glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top);
} }
return TRUE; return TRUE;
} }
......
...@@ -2159,7 +2159,6 @@ void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *h ...@@ -2159,7 +2159,6 @@ void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *h
void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPEC_HIDDEN; void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPEC_HIDDEN;
/* Surface flags: */ /* Surface flags: */
#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
#define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */ #define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */
#define SFLAG_DIBSECTION 0x00000004 /* Has a DIB section attached for GetDC */ #define SFLAG_DIBSECTION 0x00000004 /* Has a DIB section attached for GetDC */
#define SFLAG_LOCKABLE 0x00000008 /* Surface can be locked */ #define SFLAG_LOCKABLE 0x00000008 /* Surface can be locked */
...@@ -2186,7 +2185,6 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE ...@@ -2186,7 +2185,6 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE
#define SFLAG_SWAPCHAIN 0x01000000 /* The surface is part of a swapchain */ #define SFLAG_SWAPCHAIN 0x01000000 /* The surface is part of a swapchain */
/* In some conditions the surface memory must not be freed: /* In some conditions the surface memory must not be freed:
* SFLAG_OVERSIZE: Not all data can be kept in GL
* SFLAG_CONVERTED: Converting the data back would take too long * SFLAG_CONVERTED: Converting the data back would take too long
* SFLAG_DIBSECTION: The dib code manages the memory * SFLAG_DIBSECTION: The dib code manages the memory
* SFLAG_LOCKED: The app requires access to the surface data * SFLAG_LOCKED: The app requires access to the surface data
...@@ -2194,8 +2192,7 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE ...@@ -2194,8 +2192,7 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE
* SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL. * SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL.
* SFLAG_CLIENT: OpenGL uses our memory as backup * SFLAG_CLIENT: OpenGL uses our memory as backup
*/ */
#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \ #define SFLAG_DONOTFREE (SFLAG_CONVERTED | \
SFLAG_CONVERTED | \
SFLAG_DIBSECTION | \ SFLAG_DIBSECTION | \
SFLAG_LOCKED | \ SFLAG_LOCKED | \
SFLAG_DYNLOCK | \ SFLAG_DYNLOCK | \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment