[PATCH] WineD3D: Fix D3DFMT_R32F, R16F, G16R16F, ... in the =
Stefan Doesinger
stefan at codeweavers.com
Wed Nov 26 21:47:50 CST 2008
pixel shader=0A=
=0A=
This allows us to drop the load time conversion and the clear=0A=
readback hack and replaces it with a color fixup in the fixed=0A=
function pipeline replacement.=0A=
=0A=
We can safely assume that GLSL or at least=0A=
GL_ARB_fragment_program is supported if float textures are=0A=
available because those formats are only really useable with the=0A=
programmable pipeline. (They work with fixed function, but lose=0A=
their advantages, so there's no point in implementing them on a=0A=
card that doesn't do shaders)=0A=
=0A=
I changed an expected result in the d3d9 visual shader. On=0A=
Windows, this format doesn't support post pixel shader blending,=0A=
so it was never tested by that test at least on my hardware. A=0A=
different test also shows that blue =3D 0xff, so I think the change=0A=
to the test is correct. Unfortunately I do not have any directx=0A=
10 hardware to verify this.=0A=
---=0A=
dlls/d3d9/tests/visual.c | 2 +-=0A=
dlls/wined3d/arb_program_shader.c | 10 +++=0A=
dlls/wined3d/glsl_shader.c | 11 +++=0A=
dlls/wined3d/surface.c | 130 =
-------------------------------------=0A=
dlls/wined3d/utils.c | 11 +++=0A=
dlls/wined3d/wined3d_gl.h | 23 ++++---=0A=
dlls/wined3d/wined3d_private.h | 3 -=0A=
7 files changed, 45 insertions(+), 145 deletions(-)=0A=
=0A=
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c=0A=
index 32031e4..d9399fe 100644=0A=
--- a/dlls/d3d9/tests/visual.c=0A=
+++ b/dlls/d3d9/tests/visual.c=0A=
@@ -8679,7 +8679,7 @@ struct formats {=0A=
};=0A=
=0A=
const struct formats test_formats[] =3D {=0A=
- { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},=0A=
+ { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},=0A=
{ "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },=0A=
{ "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },=0A=
{ "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, =
0x00201000 },=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 5d3a546..f386666 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -606,6 +606,16 @@ static void gen_color_correction(SHADER_BUFFER =
*buffer, const char *reg, const c=0A=
}=0A=
break;=0A=
=0A=
+ case set_green_blue_1:=0A=
+ /* D3DFMT_R16F and D3DFMT_R32F */=0A=
+ if(strlen(writemask) >=3D 4) {=0A=
+ shader_addline(buffer, "MOV %s.%c, %s;\n", reg, =
writemask[3], one);=0A=
+ }=0A=
+ if(strlen(writemask) >=3D 3) {=0A=
+ shader_addline(buffer, "MOV %s.%c, %s;\n", reg, =
writemask[2], one);=0A=
+ }=0A=
+ break;=0A=
+=0A=
case signed_2_no_ba:=0A=
/* Applies to V8U8, V16U16. Input blue and alpha are 1.0, =
so the output=0A=
* is 1.0 as well=0A=
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c=0A=
index 7f30888..239dfff 100644=0A=
--- a/dlls/wined3d/glsl_shader.c=0A=
+++ b/dlls/wined3d/glsl_shader.c=0A=
@@ -1251,6 +1251,17 @@ static void shader_glsl_color_correction(const =
SHADER_OPCODE_ARG *arg)=0A=
}=0A=
break;=0A=
=0A=
+ case set_green_blue_1:=0A=
+ /* D3DFMT_R16F and D3DFMT_R32F */=0A=
+ mask =3D shader_glsl_add_dst_param(arg, arg->dst, =
WINED3DSP_WRITEMASK_2, &dst_param);=0A=
+ mask_size =3D shader_glsl_get_write_mask_size(mask);=0A=
+ if(mask_size >=3D 3) {=0A=
+ shader_addline(arg->buffer, "%s.%c%c =3D vec2(1.0);\n", =
dst_param.reg_name, dst_param.mask_str[2], dst_param.mask_str[3]);=0A=
+ } else if(mask_size >=3D 2) {=0A=
+ shader_addline(arg->buffer, "%s.%c =3D 1.0;\n", =
dst_param.reg_name, dst_param.mask_str[2]);=0A=
+ }=0A=
+ break;=0A=
+=0A=
case signed_2_no_ba:=0A=
/* Correct the sign, but leave the blue as it is - it was =
loaded correctly already=0A=
* V8U8 and V16U16 without GL_NV_texture_shader or =
GL_ATI_envmap_bumpmap=0A=
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c=0A=
index 20bc73b..73e0a2a 100644=0A=
--- a/dlls/wined3d/surface.c=0A=
+++ b/dlls/wined3d/surface.c=0A=
@@ -35,7 +35,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);=0A=
=0A=
static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE =
table[256][4], BOOL colorkey);=0A=
static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, =
CONVERT_TYPES convert);=0A=
-static inline void clear_unused_channels(IWineD3DSurfaceImpl *This);=0A=
static void surface_remove_pbo(IWineD3DSurfaceImpl *This);=0A=
=0A=
void surface_force_reload(IWineD3DSurface *iface)=0A=
@@ -944,8 +943,6 @@ static void =
read_from_framebuffer_texture(IWineD3DSurfaceImpl *This)=0A=
This->pow2Height, format, type);=0A=
}=0A=
=0A=
- clear_unused_channels(This);=0A=
-=0A=
ENTER_GL();=0A=
/* If !SrcIsUpsideDown we should flip the surface.=0A=
* This can be done using glCopyTexSubImage2D but this=0A=
@@ -1702,38 +1699,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl =
*This, BOOL need_alpha_ck, BOOL use_=0A=
*target_bpp =3D 2;=0A=
break;=0A=
=0A=
- case WINED3DFMT_R32F:=0A=
- /* Can be loaded in theory with fmt=3DGL_RED, =
type=3DGL_FLOAT, but this fails. The reason=0A=
- * is that D3D expects the undefined green, blue and alpha =
channels to return 1.0=0A=
- * when sampling, but OpenGL sets green and blue to 0.0 =
instead. Thus we have to inject=0A=
- * 1.0 instead.=0A=
- *=0A=
- * The alpha channel defaults to 1.0 in opengl, so nothing =
has to be done about it.=0A=
- */=0A=
- *convert =3D CONVERT_R32F;=0A=
- *format =3D GL_RGB;=0A=
- *internal =3D GL_RGB32F_ARB;=0A=
- *type =3D GL_FLOAT;=0A=
- *target_bpp =3D 12;=0A=
- break;=0A=
-=0A=
- case WINED3DFMT_R16F:=0A=
- /* Similar to R32F */=0A=
- *convert =3D CONVERT_R16F;=0A=
- *format =3D GL_RGB;=0A=
- *internal =3D GL_RGB16F_ARB;=0A=
- *type =3D GL_HALF_FLOAT_ARB;=0A=
- *target_bpp =3D 6;=0A=
- break;=0A=
-=0A=
- case WINED3DFMT_G16R16:=0A=
- *convert =3D CONVERT_G16R16;=0A=
- *format =3D GL_RGB;=0A=
- *internal =3D GL_RGB16_EXT;=0A=
- *type =3D GL_UNSIGNED_SHORT;=0A=
- *target_bpp =3D 6;=0A=
- break;=0A=
-=0A=
default:=0A=
break;=0A=
}=0A=
@@ -2061,66 +2026,6 @@ static HRESULT d3dfmt_convert_surface(const BYTE =
*src, BYTE *dst, UINT pitch, UI=0A=
break;=0A=
}=0A=
=0A=
- case CONVERT_R32F:=0A=
- {=0A=
- unsigned int x, y;=0A=
- const float *Source;=0A=
- float *Dest;=0A=
- for(y =3D 0; y < height; y++) {=0A=
- Source =3D (const float *)(src + y * pitch);=0A=
- Dest =3D (float *) (dst + y * outpitch);=0A=
- for (x =3D 0; x < width; x++ ) {=0A=
- float color =3D (*Source++);=0A=
- Dest[0] =3D color;=0A=
- Dest[1] =3D 1.0;=0A=
- Dest[2] =3D 1.0;=0A=
- Dest +=3D 3;=0A=
- }=0A=
- }=0A=
- break;=0A=
- }=0A=
-=0A=
- case CONVERT_R16F:=0A=
- {=0A=
- unsigned int x, y;=0A=
- const WORD *Source;=0A=
- WORD *Dest;=0A=
- const WORD one =3D 0x3c00;=0A=
- for(y =3D 0; y < height; y++) {=0A=
- Source =3D (const WORD *)(src + y * pitch);=0A=
- Dest =3D (WORD *) (dst + y * outpitch);=0A=
- for (x =3D 0; x < width; x++ ) {=0A=
- WORD color =3D (*Source++);=0A=
- Dest[0] =3D color;=0A=
- Dest[1] =3D one;=0A=
- Dest[2] =3D one;=0A=
- Dest +=3D 3;=0A=
- }=0A=
- }=0A=
- break;=0A=
- }=0A=
-=0A=
- case CONVERT_G16R16:=0A=
- {=0A=
- unsigned int x, y;=0A=
- const WORD *Source;=0A=
- WORD *Dest;=0A=
-=0A=
- for(y =3D 0; y < height; y++) {=0A=
- Source =3D (const WORD *)(src + y * pitch);=0A=
- Dest =3D (WORD *) (dst + y * outpitch);=0A=
- for (x =3D 0; x < width; x++ ) {=0A=
- WORD green =3D (*Source++);=0A=
- WORD red =3D (*Source++);=0A=
- Dest[0] =3D green;=0A=
- Dest[1] =3D red;=0A=
- Dest[2] =3D 0xffff;=0A=
- Dest +=3D 3;=0A=
- }=0A=
- }=0A=
- break;=0A=
- }=0A=
-=0A=
default:=0A=
ERR("Unsupported conversation type %d\n", convert);=0A=
}=0A=
@@ -2272,41 +2177,6 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) {=0A=
return TRUE;=0A=
}=0A=
=0A=
-static inline void clear_unused_channels(IWineD3DSurfaceImpl *This) {=0A=
- GLboolean oldwrite[4];=0A=
-=0A=
- /* Some formats have only some color channels, and the others are =
1.0.=0A=
- * since our rendering renders to all channels, and those pixel =
formats=0A=
- * are emulated by using a full texture with the other channels set =
to 1.0=0A=
- * manually, clear the unused channels.=0A=
- *=0A=
- * This could be done with hacking colorwriteenable to mask the =
colors,=0A=
- * but before drawing the buffer would have to be cleared too, so =
there's=0A=
- * no gain in that=0A=
- */=0A=
- switch(This->resource.format) {=0A=
- case WINED3DFMT_R16F:=0A=
- case WINED3DFMT_R32F:=0A=
- TRACE("R16F or R32F format, clearing green, blue and alpha =
to 1.0\n");=0A=
- /* Do not activate a context, the correct drawable is =
active already=0A=
- * though just the read buffer is set, make sure to have =
the correct draw=0A=
- * buffer too=0A=
- */=0A=
- glDrawBuffer(This->resource.wineD3DDevice->offscreenBuffer);=0A=
- glDisable(GL_SCISSOR_TEST);=0A=
- glGetBooleanv(GL_COLOR_WRITEMASK, oldwrite);=0A=
- glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);=0A=
- glClearColor(0.0, 1.0, 1.0, 1.0);=0A=
- glClear(GL_COLOR_BUFFER_BIT);=0A=
- glColorMask(oldwrite[0], oldwrite[1], oldwrite[2], =
oldwrite[3]);=0A=
- if(!This->resource.wineD3DDevice->render_offscreen) =
glDrawBuffer(GL_BACK);=0A=
- checkGLcall("Unused channel clear\n");=0A=
- break;=0A=
-=0A=
- default: break;=0A=
- }=0A=
-}=0A=
-=0A=
static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface =
*iface, BOOL srgb_mode) {=0A=
IWineD3DSurfaceImpl *This =3D (IWineD3DSurfaceImpl *)iface;=0A=
=0A=
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c=0A=
index 7845b8a..e7949b7 100644=0A=
--- a/dlls/wined3d/utils.c=0A=
+++ b/dlls/wined3d/utils.c=0A=
@@ -363,6 +363,17 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)=0A=
}=0A=
}=0A=
=0A=
+ dst =3D getFmtIdx(WINED3DFMT_R16F);=0A=
+ gl_info->gl_formats[dst].conversion_group =3D set_green_blue_1;=0A=
+ dst =3D getFmtIdx(WINED3DFMT_R32F);=0A=
+ gl_info->gl_formats[dst].conversion_group =3D set_green_blue_1;=0A=
+ dst =3D getFmtIdx(WINED3DFMT_G16R16);=0A=
+ gl_info->gl_formats[dst].conversion_group =3D set_blue_1;=0A=
+ dst =3D getFmtIdx(WINED3DFMT_G16R16F);=0A=
+ gl_info->gl_formats[dst].conversion_group =3D set_blue_1;=0A=
+ dst =3D getFmtIdx(WINED3DFMT_G32R32F);=0A=
+ gl_info->gl_formats[dst].conversion_group =3D set_blue_1;=0A=
+=0A=
/* V8U8 is supported natively by GL_ATI_envmap_bumpmap and =
GL_NV_texture_shader.=0A=
* V16U16 is only supported by GL_NV_texture_shader. The formats =
need fixup if=0A=
* their extensions are not available. GL_ATI_envmap_bumpmap is not =
used because=0A=
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h=0A=
index efd55e0..0194e52 100644=0A=
--- a/dlls/wined3d/wined3d_gl.h=0A=
+++ b/dlls/wined3d/wined3d_gl.h=0A=
@@ -3815,17 +3815,18 @@ typedef BOOL (WINAPI * =
WINED3D_PFNWGLSETPIXELFORMATWINE) (HDC hdc, int iPixelFor=0A=
=0A=
enum shader_color_conv=0A=
{=0A=
- fmtconv_none =3D 1,=0A=
- set_blue_1 =3D 2,=0A=
- signed_2_no_ba =3D 3,=0A=
- signed_2 =3D 4,=0A=
- signed_4 =3D 5,=0A=
- signed_l6v5u5 =3D 6,=0A=
- swap_rg_blue_1 =3D 7,=0A=
- a_to_g_ba_1 =3D 8,=0A=
- yuv_yuy2 =3D 9,=0A=
- yuv_uyvy =3D 10,=0A=
- yuv_yv12 =3D 11,=0A=
+ fmtconv_none =3D 1,=0A=
+ set_blue_1 =3D 2,=0A=
+ set_green_blue_1 =3D 3,=0A=
+ signed_2_no_ba =3D 4,=0A=
+ signed_2 =3D 5,=0A=
+ signed_4 =3D 6,=0A=
+ signed_l6v5u5 =3D 7,=0A=
+ swap_rg_blue_1 =3D 8,=0A=
+ a_to_g_ba_1 =3D 9,=0A=
+ yuv_yuy2 =3D 10,=0A=
+ yuv_uyvy =3D 11,=0A=
+ yuv_yv12 =3D 12,=0A=
force_dword =3D 0x7ffffff=0A=
};=0A=
=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index 77579a1..d6ad1fd 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -1575,9 +1575,6 @@ typedef enum {=0A=
CONVERT_Q8W8V8U8,=0A=
CONVERT_V16U16,=0A=
CONVERT_A4L4,=0A=
- CONVERT_R32F,=0A=
- CONVERT_R16F,=0A=
- CONVERT_G16R16,=0A=
} CONVERT_TYPES;=0A=
=0A=
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 srgb_mode);=0A=
-- =0A=
1.5.6.4=0A=
=0A=
------=_NextPart_000_000D_01C9502F.C39C86B0--
More information about the wine-patches
mailing list