wined3d: Always use np2 repacking if no native np2 support is available.
diff --git a/dlls/d3d9/tests/surface.c b/dlls/d3d9/tests/surface.c
index 06a5716..42ebf2d 100644
--- a/dlls/d3d9/tests/surface.c
+++ b/dlls/d3d9/tests/surface.c
@@ -136,9 +136,9 @@
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);
}
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 51caef6..5804df8 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -760,7 +760,7 @@
*******************************/
/* 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 @@
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 @@
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,38 +5120,16 @@
} 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
- ,destTop
- ,srcWidth
- ,srcHeight
- ,glDescription->glFormat
- ,glDescription->glType
- ,IWineD3DSurface_GetData(pSourceSurface)
- );
- } else {
-
- /* not repacked, the data returned by IWineD3DSurface_GetData is pow2Width x pow2Height */
- glTexSubImage2D(glDescription->target
+ glTexSubImage2D(glDescription->target
,glDescription->level
,destLeft
,destTop
- ,((IWineD3DSurfaceImpl *)pSourceSurface)->pow2Width
- ,((IWineD3DSurfaceImpl *)pSourceSurface)->pow2Height
+ ,srcWidth
+ ,srcHeight
,glDescription->glFormat
,glDescription->glType
,IWineD3DSurface_GetData(pSourceSurface)
);
- }
-
}
}
checkGLcall("glTexSubImage2D");
@@ -5632,6 +5610,8 @@
}
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 @@
}
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 {
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 7bd04bb..d7f8d6d 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -792,12 +792,6 @@
* 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");
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 61ab215..ef1d3a6 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -1824,7 +1824,7 @@
* 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 ) {
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index fe957d4..54a5214 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -67,18 +67,33 @@
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 @@
*
* 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);
- 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);
- }
+ 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 @@
}
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.biWidth = This->currentDesc.Width;
+ b_info->bmiHeader.biHeight = -This->currentDesc.Height -extraline;
+ b_info->bmiHeader.biSizeImage = ( This->currentDesc.Height + extraline) * IWineD3DSurface_GetPitch(iface);
b_info->bmiHeader.biPlanes = 1;
b_info->bmiHeader.biBitCount = This->bytesPerPixel * 8;
@@ -1654,11 +1659,7 @@
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;
-
+ width = This->currentDesc.Width;
pitch = IWineD3DSurface_GetPitch(iface);
if((convert != NO_CONVERSION) && This->resource.allocatedMemory) {
@@ -1688,11 +1689,11 @@
/* 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 @@
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;
- }
+ ret = This->bytesPerPixel * This->currentDesc.Width; /* Bytes / row */
/* Surfaces are 32 bit aligned */
ret = (ret + SURFACE_ALIGNMENT - 1) & ~(SURFACE_ALIGNMENT - 1);
}
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index a3fc80b..719f176 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -40,7 +40,6 @@
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 @@
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 @@
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 );
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9c5cf33..c59764b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -161,8 +161,6 @@
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 */