wined3d: Remove oversize texture support.

This commit is contained in:
Roderick Colenbrander 2010-03-11 15:03:50 +01:00 committed by Alexandre Julliard
parent 74bf524a99
commit 604caf0caa
4 changed files with 25 additions and 118 deletions

View File

@ -719,11 +719,10 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,
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.
* 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_OVERSIZE: The gl texture is smaller than the allocated memory
* 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
*/
@ -1419,7 +1418,7 @@ void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb)
if(convert != NO_CONVERSION) 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;
height = surface->pow2Height;
@ -4420,9 +4419,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
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.
*/
WARN("(%p) Creating an oversized surface: %ux%u (texture is %ux%u)\n",
This, This->pow2Width, This->pow2Height, This->currentDesc.Width, This->currentDesc.Height);
This->Flags |= SFLAG_OVERSIZE;
if(This->resource.pool == WINED3DPOOL_DEFAULT || This->resource.pool == WINED3DPOOL_MANAGED)
{
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->glRect.left = 0;
@ -4430,8 +4434,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
This->glRect.right = 0;
This->glRect.bottom = 0;
} else {
/* Check this after the oversize check - do not make an oversized surface a texture_rectangle one.
Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
/* 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
doesn't work in combination with ARB_TEXTURE_RECTANGLE.
*/
@ -4446,8 +4449,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
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.top = 0;
This->glRect.right = This->pow2Width;
@ -5001,7 +5002,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
LEAVE_GL();
if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) {
if (This->Flags & SFLAG_NONPOW2) {
TRACE("non power of two support\n");
if (mem || (This->Flags & SFLAG_PBO)) {
surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem);

View File

@ -570,7 +570,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT
/* Use the callback to create the texture surface. */
hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_h, format_desc->format,
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);
texture->surfaces[i] = NULL;

View File

@ -2276,10 +2276,8 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
*********************************************************************/
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 y1 = Rect->top, y2 = Rect->bottom;
GLint maxSize = gl_info->limits.texture_size;
TRACE("(%p)->(%d,%d)-(%d,%d)\n", This,
Rect->left, Rect->top, Rect->right, Rect->bottom);
@ -2294,107 +2292,18 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]
y2 = Rect->top;
}
/* No oversized texture? This is easy */
if(!(This->Flags & SFLAG_OVERSIZE)) {
/* 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[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;
/* 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[1] = (float) Rect->right;
glTexCoord[3] = (float) Rect->bottom;
} else {
/* Check if we can succeed at all */
if( (x2 - x1) > maxSize ||
(y2 - y1) > maxSize ) {
TRACE("Requested rectangle is too large for gl\n");
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);
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;
}

View File

@ -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;
/* 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_DIBSECTION 0x00000004 /* Has a DIB section attached for GetDC */
#define SFLAG_LOCKABLE 0x00000008 /* Surface can be locked */
@ -2186,7 +2185,6 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE
#define SFLAG_SWAPCHAIN 0x01000000 /* The surface is part of a swapchain */
/* 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_DIBSECTION: The dib code manages the memory
* SFLAG_LOCKED: The app requires access to the surface data
@ -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_CLIENT: OpenGL uses our memory as backup
*/
#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \
SFLAG_CONVERTED | \
#define SFLAG_DONOTFREE (SFLAG_CONVERTED | \
SFLAG_DIBSECTION | \
SFLAG_LOCKED | \
SFLAG_DYNLOCK | \