wined3d: Always use np2 repacking if no native np2 support is available.
This commit is contained in:
parent
21172f1dec
commit
b48dfb3c54
|
@ -136,9 +136,9 @@ static void test_surface_alignment(IDirect3DDevice9 *device_ptr)
|
|||
ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
|
||||
ok(!(lockedRect.Pitch & 3), "Surface pitch %d is not 32-bit aligned\n", lockedRect.Pitch);
|
||||
/* Some applications also depend on the exact pitch, rather than just
|
||||
* the alignment. However, this test will fail or succeed depending
|
||||
* on the NP2 mode we're using. */
|
||||
if (0) ok(lockedRect.Pitch == 12, "Got pitch %d, expected 12\n", lockedRect.Pitch);
|
||||
* the alignment.
|
||||
*/
|
||||
ok(lockedRect.Pitch == 12, "Got pitch %d, expected 12\n", lockedRect.Pitch);
|
||||
hr = IDirect3DSurface9_UnlockRect(surface_ptr);
|
||||
IDirect3DSurface9_Release(surface_ptr);
|
||||
}
|
||||
|
|
|
@ -760,7 +760,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
|
|||
*******************************/
|
||||
|
||||
/* Non-power2 support */
|
||||
if (wined3d_settings.nonpower2_mode == NP2_NATIVE) {
|
||||
if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
|
||||
pow2Width = Width;
|
||||
pow2Height = Height;
|
||||
} else {
|
||||
|
@ -788,15 +788,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
|
|||
Size = 0;
|
||||
} else if (Format == WINED3DFMT_DXT1) {
|
||||
/* DXT1 is half byte per pixel */
|
||||
Size = ((max(pow2Width,4) * tableEntry->bpp) * max(pow2Height,4)) >> 1;
|
||||
Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4)) >> 1;
|
||||
|
||||
} else if (Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 ||
|
||||
Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5) {
|
||||
Size = ((max(pow2Width,4) * tableEntry->bpp) * max(pow2Height,4));
|
||||
Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4));
|
||||
} else {
|
||||
/* The pitch is a multiple of 4 bytes */
|
||||
Size = ((pow2Width * tableEntry->bpp) + SURFACE_ALIGNMENT - 1) & ~(SURFACE_ALIGNMENT - 1);
|
||||
Size *= pow2Height;
|
||||
Size = ((Width * tableEntry->bpp) + SURFACE_ALIGNMENT - 1) & ~(SURFACE_ALIGNMENT - 1);
|
||||
Size *= Height;
|
||||
}
|
||||
|
||||
/** Create and initialise the surface resource **/
|
||||
|
@ -937,7 +937,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
|
|||
object->height = Height;
|
||||
|
||||
/** Non-power2 support **/
|
||||
if (wined3d_settings.nonpower2_mode == NP2_NATIVE) {
|
||||
if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
|
||||
pow2Width = Width;
|
||||
pow2Height = Height;
|
||||
} else {
|
||||
|
@ -5120,13 +5120,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
|
|||
|
||||
|
||||
} else {
|
||||
if (NP2_REPACK == wined3d_settings.nonpower2_mode) {
|
||||
|
||||
/* some applications cannot handle odd pitches returned by soft non-power2, so we have
|
||||
to repack the data from pow2Width/Height to expected Width,Height, this makes the
|
||||
data returned by GetData non-power2 width/height with hardware non-power2
|
||||
pow2Width/height are set to surface width height, repacking isn't needed so it
|
||||
doesn't matter which function gets called. */
|
||||
glTexSubImage2D(glDescription->target
|
||||
,glDescription->level
|
||||
,destLeft
|
||||
|
@ -5137,21 +5130,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
|
|||
,glDescription->glType
|
||||
,IWineD3DSurface_GetData(pSourceSurface)
|
||||
);
|
||||
} else {
|
||||
|
||||
/* not repacked, the data returned by IWineD3DSurface_GetData is pow2Width x pow2Height */
|
||||
glTexSubImage2D(glDescription->target
|
||||
,glDescription->level
|
||||
,destLeft
|
||||
,destTop
|
||||
,((IWineD3DSurfaceImpl *)pSourceSurface)->pow2Width
|
||||
,((IWineD3DSurfaceImpl *)pSourceSurface)->pow2Height
|
||||
,glDescription->glFormat
|
||||
,glDescription->glType
|
||||
,IWineD3DSurface_GetData(pSourceSurface)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
checkGLcall("glTexSubImage2D");
|
||||
|
@ -5632,6 +5610,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice*
|
|||
}
|
||||
|
||||
void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) {
|
||||
IWineD3DDeviceImpl *This = surface->resource.wineD3DDevice; /* for GL_SUPPORT */
|
||||
|
||||
/* Reallocate proper memory for the front and back buffer and adjust their sizes */
|
||||
if(surface->Flags & SFLAG_DIBSECTION) {
|
||||
/* Release the DC */
|
||||
|
@ -5645,7 +5625,7 @@ void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, WINED3DPRESENT_PARAMETERS*
|
|||
}
|
||||
surface->currentDesc.Width = *pPresentationParameters->BackBufferWidth;
|
||||
surface->currentDesc.Height = *pPresentationParameters->BackBufferHeight;
|
||||
if (wined3d_settings.nonpower2_mode == NP2_NATIVE) {
|
||||
if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
|
||||
surface->pow2Width = *pPresentationParameters->BackBufferWidth;
|
||||
surface->pow2Height = *pPresentationParameters->BackBufferHeight;
|
||||
} else {
|
||||
|
|
|
@ -792,12 +792,6 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
|
|||
* shaders), but 8 texture stages (register combiners). */
|
||||
gl_info->max_sampler_stages = max(gl_info->max_samplers, gl_info->max_texture_stages);
|
||||
|
||||
/* We can only use NP2_NATIVE when the hardware supports it. */
|
||||
if (wined3d_settings.nonpower2_mode == NP2_NATIVE && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) {
|
||||
WARN_(d3d_caps)("GL_ARB_texture_non_power_of_two not supported, falling back to NP2_NONE NPOT mode.\n");
|
||||
wined3d_settings.nonpower2_mode = NP2_NONE;
|
||||
}
|
||||
|
||||
/* We can only use ORM_FBO when the hardware supports it. */
|
||||
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
|
||||
WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
|
||||
|
|
|
@ -1824,7 +1824,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
|
|||
* IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
|
||||
* scaling is reapplied or removed, the texture matrix has to be reapplied
|
||||
*/
|
||||
if(wined3d_settings.nonpower2_mode != NP2_NATIVE && sampler < MAX_TEXTURES) {
|
||||
if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
|
||||
if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
|
||||
if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
|
||||
((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
|
||||
|
|
|
@ -67,18 +67,33 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
|
|||
LEAVE_GL();
|
||||
}
|
||||
} else {
|
||||
void *mem;
|
||||
int src_pitch = 0;
|
||||
int dst_pitch = 0;
|
||||
|
||||
if (This->Flags & SFLAG_NONPOW2) {
|
||||
src_pitch = This->bytesPerPixel * This->pow2Width;
|
||||
dst_pitch = IWineD3DSurface_GetPitch((IWineD3DSurface *) This);
|
||||
src_pitch = (src_pitch + SURFACE_ALIGNMENT - 1) & ~(SURFACE_ALIGNMENT - 1);
|
||||
mem = HeapAlloc(GetProcessHeap(), 0, src_pitch * This->pow2Height);
|
||||
} else {
|
||||
mem = This->resource.allocatedMemory;
|
||||
}
|
||||
|
||||
TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n", This, This->glDescription.level,
|
||||
This->glDescription.glFormat, This->glDescription.glType, This->resource.allocatedMemory);
|
||||
This->glDescription.glFormat, This->glDescription.glType, mem);
|
||||
|
||||
ENTER_GL();
|
||||
|
||||
glGetTexImage(This->glDescription.target, This->glDescription.level, This->glDescription.glFormat,
|
||||
This->glDescription.glType, This->resource.allocatedMemory);
|
||||
This->glDescription.glType, mem);
|
||||
checkGLcall("glGetTexImage()");
|
||||
|
||||
LEAVE_GL();
|
||||
|
||||
if (wined3d_settings.nonpower2_mode == NP2_REPACK) {
|
||||
if (This->Flags & SFLAG_NONPOW2) {
|
||||
LPBYTE src_data, dst_data;
|
||||
int y;
|
||||
/*
|
||||
* Some games (e.g. warhammer 40k) don't work properly with the odd pitches, preventing
|
||||
* the surface pitch from being used to box non-power2 textures. Instead we have to use a hack to
|
||||
|
@ -124,23 +139,22 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
|
|||
*
|
||||
* internally the texture is still stored in a boxed format so any references to textureName will
|
||||
* get a boxed texture with width pow2width and not a texture of width currentDesc.Width.
|
||||
*
|
||||
* Performance should not be an issue, because applications normally do not lock the surfaces when
|
||||
* rendering. If an app does, the SFLAG_DYNLOCK flag will kick in and the memory copy won't be released,
|
||||
* and doesn't have to be re-read.
|
||||
*/
|
||||
|
||||
if (This->Flags & SFLAG_NONPOW2) {
|
||||
LPBYTE src_data, dst_data;
|
||||
int src_pitch = This->bytesPerPixel * This->pow2Width;
|
||||
int dst_pitch = This->bytesPerPixel * This->currentDesc.Width;
|
||||
int y;
|
||||
|
||||
src_data = dst_data = This->resource.allocatedMemory;
|
||||
FIXME("(%p) : Repacking the surface data from pitch %d to pitch %d\n", This, src_pitch, dst_pitch);
|
||||
src_data = mem;
|
||||
dst_data = This->resource.allocatedMemory;
|
||||
TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", This, src_pitch, dst_pitch);
|
||||
for (y = 1 ; y < This->currentDesc.Height; y++) {
|
||||
/* skip the first row */
|
||||
src_data += src_pitch;
|
||||
dst_data += dst_pitch;
|
||||
memcpy(dst_data, src_data, dst_pitch);
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, mem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1152,18 +1166,9 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
|
|||
}
|
||||
|
||||
b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
if( (NP2_REPACK == wined3d_settings.nonpower2_mode || This->resource.usage & WINED3DUSAGE_RENDERTARGET)) {
|
||||
b_info->bmiHeader.biWidth = This->currentDesc.Width;
|
||||
b_info->bmiHeader.biHeight = -This->currentDesc.Height -extraline;
|
||||
b_info->bmiHeader.biSizeImage = ( This->currentDesc.Height + extraline) * IWineD3DSurface_GetPitch(iface);
|
||||
/* Use the full pow2 image size(assigned below) because LockRect
|
||||
* will need it for a full glGetTexImage call
|
||||
*/
|
||||
} else {
|
||||
b_info->bmiHeader.biWidth = This->pow2Width;
|
||||
b_info->bmiHeader.biHeight = -This->pow2Height -extraline;
|
||||
b_info->bmiHeader.biSizeImage = This->resource.size + extraline * IWineD3DSurface_GetPitch(iface);
|
||||
}
|
||||
b_info->bmiHeader.biPlanes = 1;
|
||||
b_info->bmiHeader.biBitCount = This->bytesPerPixel * 8;
|
||||
|
||||
|
@ -1654,11 +1659,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
|
|||
d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp);
|
||||
|
||||
/* The width is in 'length' not in bytes */
|
||||
if (NP2_REPACK == wined3d_settings.nonpower2_mode || This->resource.usage & WINED3DUSAGE_RENDERTARGET)
|
||||
width = This->currentDesc.Width;
|
||||
else
|
||||
width = This->pow2Width;
|
||||
|
||||
pitch = IWineD3DSurface_GetPitch(iface);
|
||||
|
||||
if((convert != NO_CONVERSION) && This->resource.allocatedMemory) {
|
||||
|
@ -1688,11 +1689,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
|
|||
/* Make sure the correct pitch is used */
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
|
||||
|
||||
if (NP2_REPACK == wined3d_settings.nonpower2_mode && (This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) {
|
||||
if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) {
|
||||
TRACE("non power of two support\n");
|
||||
surface_allocate_surface(This, internal, This->pow2Width, This->pow2Height, format, type);
|
||||
if (mem) {
|
||||
surface_upload_data(This, This->pow2Width, This->pow2Height, format, type, mem);
|
||||
surface_upload_data(This, This->currentDesc.Width, This->currentDesc.Height, format, type, mem);
|
||||
}
|
||||
} else {
|
||||
surface_allocate_surface(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type);
|
||||
|
@ -2995,12 +2996,7 @@ DWORD WINAPI IWineD3DSurfaceImpl_GetPitch(IWineD3DSurface *iface) {
|
|||
This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) /* DXT2/3/4/5 is 16 bytes per block */
|
||||
ret = ((This->currentDesc.Width + 3) >> 2) << 4;
|
||||
else {
|
||||
if (NP2_REPACK == wined3d_settings.nonpower2_mode || This->resource.usage & WINED3DUSAGE_RENDERTARGET) {
|
||||
/* Front and back buffers are always lockes/unlocked on currentDesc.Width */
|
||||
ret = This->bytesPerPixel * This->currentDesc.Width; /* Bytes / row */
|
||||
} else {
|
||||
ret = This->bytesPerPixel * This->pow2Width;
|
||||
}
|
||||
/* Surfaces are 32 bit aligned */
|
||||
ret = (ret + SURFACE_ALIGNMENT - 1) & ~(SURFACE_ALIGNMENT - 1);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ wined3d_settings_t wined3d_settings =
|
|||
PS_HW, /* Hardware by default */
|
||||
VBO_HW, /* Hardware by default */
|
||||
FALSE, /* Use of GLSL disabled by default */
|
||||
NP2_NATIVE, /* Use native NPOT textures, when available */
|
||||
ORM_BACKBUFFER, /* Use the backbuffer to do offscreen rendering */
|
||||
RTL_AUTO, /* Automatically determine best locking method */
|
||||
64*1024*1024 /* 64MB texture memory by default */
|
||||
|
@ -188,21 +187,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||
TRACE("Use of GL Shading Language disabled\n");
|
||||
}
|
||||
}
|
||||
if ( !get_config_key( hkey, appkey, "Nonpower2Mode", buffer, size) )
|
||||
{
|
||||
if (!strcmp(buffer,"none"))
|
||||
{
|
||||
TRACE("Using default non-power2 textures\n");
|
||||
wined3d_settings.nonpower2_mode = NP2_NONE;
|
||||
|
||||
}
|
||||
else if (!strcmp(buffer,"repack"))
|
||||
{
|
||||
TRACE("Repacking non-power2 textures\n");
|
||||
wined3d_settings.nonpower2_mode = NP2_REPACK;
|
||||
}
|
||||
/* There will be a couple of other choices for nonpow2, they are: TextureRecrangle and OpenGL 2 */
|
||||
}
|
||||
if ( !get_config_key( hkey, appkey, "OffscreenRenderingMode", buffer, size) )
|
||||
{
|
||||
if (!strcmp(buffer,"backbuffer"))
|
||||
|
@ -271,8 +255,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||
TRACE("Disable Vertex Buffer Hardware support\n");
|
||||
if (wined3d_settings.glslRequested)
|
||||
TRACE("If supported by your system, GL Shading Language will be used\n");
|
||||
if (wined3d_settings.nonpower2_mode == NP2_REPACK)
|
||||
TRACE("Repacking non-power2 textures\n");
|
||||
|
||||
if (appkey) RegCloseKey( appkey );
|
||||
if (hkey) RegCloseKey( hkey );
|
||||
|
|
|
@ -161,8 +161,6 @@ typedef struct wined3d_settings_s {
|
|||
we should use it. However, until it's fully implemented, we'll leave it as a registry
|
||||
setting for developers. */
|
||||
BOOL glslRequested;
|
||||
/* nonpower 2 function */
|
||||
int nonpower2_mode;
|
||||
int offscreen_rendering_mode;
|
||||
int rendertargetlock_mode;
|
||||
/* Memory tracking and object counting */
|
||||
|
|
Loading…
Reference in New Issue