wined3d: Implented signed texture formats via NV_TEXTURE_SHADER
Fabian Bieler
der.fabe at gmx.net
Sun Mar 11 18:30:19 CDT 2007
The same patch as before, but with GL_DSDT_NV instead of GL_HILO8_NV as
suggested by Frank Richter.
On Saturday 10 March 2007 15:02, Fabian Bieler wrote:
> This patch implements D3DFMT_V8U8 and D3DFMT_Q8W8V8U8 via
> NV_TEXTURE_SHADER. This fixes some renderissues in Half-Life 2 with the
> DirectX9 path and the DirectX8 path via GLSL.
>
> Pavel Troller described these issues as:
> "there is too much
> shine all over the game. Not only barrels and weapons, but also faces,
> dresses,
> walls.. It looks like covered by the oil film. There are also some strange
> shadow effects - like that the top of the hand is dark and the bottom is
> bright,
> like if the light would come from the ground."
>
> There are still some issues in the closing cutscene. I'm not sure if this
> is due to different handling of RGBA and QWVU textures by the driver or
> some other bug.
>
> Somebody should probably do the same with ATI_envmap_bumpmap for ATI cards.
-------------- next part --------------
From af015cb7fde5ab338701e260eceb13686c10dcc7 Mon Sep 17 00:00:00 2001
From: Fabian Bieler <der.fabe at gmx.net>
Date: Mon, 12 Mar 2007 00:25:16 +0100
Subject: [PATCH] wined3d: Implented signed texture formats via NV_TEXTURE_SHADER
---
dlls/wined3d/arb_program_shader.c | 8 +++++---
dlls/wined3d/device.c | 6 +++---
dlls/wined3d/state.c | 4 ++--
dlls/wined3d/surface.c | 11 ++++++-----
dlls/wined3d/surface_gdi.c | 15 ++++++++-------
dlls/wined3d/utils.c | 32 +++++++++++++++++++++++++++-----
dlls/wined3d/volume.c | 2 +-
dlls/wined3d/wined3d_private.h | 2 +-
8 files changed, 53 insertions(+), 27 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 79148e5..2e636ad 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -694,6 +694,7 @@ void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg) {
void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
+ WineD3D_GL_Info *gl_info = &((IWineD3DImpl *)(((IWineD3DDeviceImpl *)(This->baseShader.device))->wineD3D))->gl_info;
DWORD dst = arg->dst;
DWORD src = arg->src[0] & WINED3DSP_REGNUM_MASK;
@@ -714,11 +715,12 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
* So the surface loading code converts the -128 ... 127 signed integers to
* 0 ... 255 unsigned ones. The following line undoes that.
*
- * TODO: Both GL_NV_texture_shader and GL_ATI_envmap_bumpmap provide pixel formats
- * suitable for loading the Direct3D perturbation data. If one of them is used, do
+ * TODO: GL_ATI_envmap_bumpmap provides pixel formats
+ * suitable for loading the Direct3D perturbation data. If it is used, do
* not correct the signedness
*/
- shader_addline(buffer, "MAD T%u, T%u, coefmul.x, -one;\n", src, src);
+ if(!GL_SUPPORT(NV_TEXTURE_SHADER3))
+ shader_addline(buffer, "MAD T%u, T%u, coefmul.x, -one;\n", src, src);
shader_addline(buffer, "SWZ TMP2, bumpenvmat, x, z, 0, 0;\n");
shader_addline(buffer, "DP3 TMP.r, TMP2, T%u;\n", src);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index cff0f19..1f745d8 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -587,7 +587,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
unsigned int pow2Width, pow2Height;
unsigned int Size = 1;
- const PixelFormatDesc *tableEntry = getFormatDescEntry(Format);
+ const PixelFormatDesc *tableEntry = getFormatDescEntry(&GLINFO_LOCATION, Format);
TRACE("(%p) Create surface\n",This);
/** FIXME: Check ranges on the inputs are valid
@@ -951,7 +951,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVolumeImpl *object; /** NOTE: impl ref allowed since this is a create function **/
- const PixelFormatDesc *formatDesc = getFormatDescEntry(Format);
+ const PixelFormatDesc *formatDesc = getFormatDescEntry(&GLINFO_LOCATION, Format);
D3DCREATERESOURCEOBJECTINSTANCE(object, Volume, WINED3DRTYPE_VOLUME, ((Width * formatDesc->bpp) * Height * Depth))
@@ -1835,7 +1835,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, U
DEVMODEW devmode;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
LONG ret;
- const PixelFormatDesc *formatDesc = getFormatDescEntry(pMode->Format);
+ const PixelFormatDesc *formatDesc = getFormatDescEntry(&GLINFO_LOCATION, pMode->Format);
RECT clip_rc;
TRACE("(%p)->(%d,%p) Mode=%dx%dx@%d, %s\n", This, iSwapChain, pMode, pMode->Width, pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index cf1b7f4..059e6f6 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -349,7 +349,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
if(surf->CKeyFlags & DDSD_CKSRCBLT) {
- const PixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format);
+ const PixelFormatDesc *fmt = getFormatDescEntry(&GLINFO_LOCATION, surf->resource.format);
/* The surface conversion does not do color keying conversion for surfaces that have an alpha
* channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
* surface has alpha bits
@@ -1595,7 +1595,7 @@ static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
if(surf->CKeyFlags & DDSD_CKSRCBLT &&
- getFormatDescEntry(surf->resource.format)->alphaMask == 0x00000000) {
+ getFormatDescEntry(&GLINFO_LOCATION, surf->resource.format)->alphaMask == 0x00000000) {
/* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
* On the other hand applications can still use texture combiners apparently. This code takes care that apps
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index c8d39f6..d1142ca 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1168,7 +1168,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
DWORD *masks;
HRESULT hr;
RGBQUAD col[256];
- const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format);
+ const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
TRACE("(%p)->(%p)\n",This,pHDC);
@@ -1383,7 +1383,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC) {
HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp) {
BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & DDSD_CKSRCBLT);
- const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format);
+ const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
/* Default values: From the surface */
*format = formatEntry->glFormat;
@@ -1455,10 +1455,11 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
break;
case WINED3DFMT_V8U8:
- /* TODO: GL_NV_texture_shader and GL_ATI_envmap_bumpmap provide suitable formats.
- * use one of them instead of converting
+ /* TODO: GL_ATI_envmap_bumpmap provides suitable formats.
+ * use it instead of converting
* Remember to adjust the texbem instruction in the shader
*/
+ if(GL_SUPPORT(NV_TEXTURE_SHADER3)) break;
*convert = CONVERT_V8U8;
*format = GL_BGR;
*internal = GL_RGB8;
@@ -2035,7 +2036,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3D
HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- const PixelFormatDesc *formatEntry = getFormatDescEntry(format);
+ const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, format);
if (This->resource.format != WINED3DFMT_UNKNOWN) {
FIXME("(%p) : The foramt of the surface must be WINED3DFORMAT_UNKNOWN\n", This);
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index 4565f72..638e305 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -35,6 +35,7 @@
/* Use the d3d_surface debug channel to have one channel for all surfaces */
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
WINE_DECLARE_DEBUG_CHANNEL(fps);
+#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
/*****************************************************************************
* x11_copy_to_screen
@@ -534,7 +535,7 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface,
dfmt = This->resource.format;
slock = dlock;
sfmt = dfmt;
- sEntry = getFormatDescEntry(sfmt);
+ sEntry = getFormatDescEntry(&GLINFO_LOCATION, sfmt);
dEntry = sEntry;
}
else
@@ -544,9 +545,9 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface,
IWineD3DSurface_LockRect(SrcSurface, &slock, NULL, WINED3DLOCK_READONLY);
sfmt = Src->resource.format;
}
- sEntry = getFormatDescEntry(sfmt);
+ sEntry = getFormatDescEntry(&GLINFO_LOCATION, sfmt);
dfmt = This->resource.format;
- dEntry = getFormatDescEntry(dfmt);
+ dEntry = getFormatDescEntry(&GLINFO_LOCATION, dfmt);
IWineD3DSurface_LockRect(iface, &dlock,NULL,0);
}
@@ -1224,7 +1225,7 @@ IWineGDISurfaceImpl_BltFast(IWineD3DSurface *iface,
assert(This->resource.allocatedMemory != NULL);
sbuf = (BYTE *)This->resource.allocatedMemory + lock_src.top * pitch + lock_src.left * bpp;
dbuf = (BYTE *)This->resource.allocatedMemory + lock_dst.top * pitch + lock_dst.left * bpp;
- sEntry = getFormatDescEntry(Src->resource.format);
+ sEntry = getFormatDescEntry(&GLINFO_LOCATION, Src->resource.format);
dEntry = sEntry;
}
else
@@ -1238,8 +1239,8 @@ IWineGDISurfaceImpl_BltFast(IWineD3DSurface *iface,
dbuf = dlock.pBits;
TRACE("Dst is at %p, Src is at %p\n", dbuf, sbuf);
- sEntry = getFormatDescEntry(Src->resource.format);
- dEntry = getFormatDescEntry(This->resource.format);
+ sEntry = getFormatDescEntry(&GLINFO_LOCATION, Src->resource.format);
+ dEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
}
/* Handle first the FOURCC surfaces... */
@@ -1417,7 +1418,7 @@ const char* filename)
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
static char *output = NULL;
static int size = 0;
- const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format);
+ const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
if (This->pow2Width > size) {
output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pow2Width * 3);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 9c82ef0..d609624 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -27,8 +27,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
-
/*****************************************************************************
* Pixel format array
*/
@@ -107,14 +105,31 @@ static const PixelFormatDesc formats[] = {
{WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT }
};
-const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt)
+static const PixelFormatDesc NV_texture_shader_formats[] = {
+ {WINED3DFMT_V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_DSDT8_NV ,GL_DSDT_NV ,GL_BYTE },
+ {WINED3DFMT_X8L8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_DSDT8_MAG8_INTENSITY8_NV,GL_DSDT_MAG_INTENSITY_NV,GL_BYTE},
+ {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_RGBA8_NV ,GL_RGBA ,GL_BYTE },
+ {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SIGNED_HILO16_NV ,GL_HILO_NV ,GL_SHORT }
+};
+
+#define GLINFO_LOCATION (*gl_info)
+
+const PixelFormatDesc *getFormatDescEntry(WineD3D_GL_Info *gl_info, WINED3DFORMAT fmt)
{
/* First check if the format is at the position of its value.
* This will catch the argb formats before the loop is entered
*/
if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
return &formats[fmt];
- } else {
+ }
+ if(GL_SUPPORT(NV_TEXTURE_SHADER3)) {
+ unsigned int i;
+ for(i = 0; i < (sizeof(NV_texture_shader_formats) / sizeof(NV_texture_shader_formats[0])); i++) {
+ if(NV_texture_shader_formats[i].format == fmt) {
+ return &NV_texture_shader_formats[i];
+ }
+ }
+ } {
unsigned int i;
for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
if(formats[i].format == fmt) {
@@ -122,15 +137,18 @@ const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt)
}
}
}
+
FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
if(fmt == WINED3DFMT_UNKNOWN) {
ERR("Format table corrupt - Can't find WINED3DFMT_UNKNOWN\n");
return NULL;
}
/* Get the caller a valid pointer */
- return getFormatDescEntry(WINED3DFMT_UNKNOWN);
+ return getFormatDescEntry(gl_info, WINED3DFMT_UNKNOWN);
}
+#undef GLINFO_LOCATION
+
/*****************************************************************************
* Trace formatting of useful values
*/
@@ -787,6 +805,8 @@ static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP
return FALSE;
}
+#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
+
void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
tex_op_args tex_op_args = {{0}, {0}, {0}};
@@ -1085,6 +1105,8 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX
LEAVE_GL();
}
+#undef GLINFO_LOCATION
+
static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
/* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
* input should be used for all input components. The WINED3DTA_COMPLEMENT
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 3fb3036..3ad9c00 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -264,7 +264,7 @@ static HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWi
static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, GLenum gl_level) {
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
- const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format);
+ const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
if(GL_SUPPORT(EXT_TEXTURE3D)) {
TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n",
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index df0ff6a..5670c83 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1936,5 +1936,5 @@ typedef struct {
GLint glInternal, glFormat, glType;
} PixelFormatDesc;
-const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt);
+const PixelFormatDesc *getFormatDescEntry(WineD3D_GL_Info *gl_info, WINED3DFORMAT fmt);
#endif
--
1.4.4.1
More information about the wine-patches
mailing list