wined3d: Remove oversize texture support.
This commit is contained in:
parent
74bf524a99
commit
604caf0caa
|
@ -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)
|
||||||
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) {
|
||||||
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) {
|
||||||
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) {
|
||||||
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
|
||||||
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
|
||||||
/* 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) {
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
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]
|
||||||
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
|
||||||
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
|
||||||
#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
|
||||||
* 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 | \
|
||||||
|
|
Loading…
Reference in New Issue