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(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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 | \
|
||||
|
|
Loading…
Reference in New Issue