Stefan Dösinger : wined3d: Fix D3DFMT_R32F, R16F, G16R16F, ... in the pixel shader.
Alexandre Julliard
julliard at winehq.org
Thu Dec 4 09:02:09 CST 2008
Module: wine
Branch: master
Commit: e04556bb166804edc5c6cb16e6001b25aab9563e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e04556bb166804edc5c6cb16e6001b25aab9563e
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Wed Dec 3 14:53:43 2008 +0100
wined3d: Fix D3DFMT_R32F, R16F, G16R16F, ... in the pixel shader.
This allows us to drop the load time conversion and the clear
readback hack and replaces it with a color fixup in the fixed
function pipeline replacement.
---
dlls/d3d9/tests/visual.c | 2 +-
dlls/wined3d/surface.c | 130 ----------------------------------------
dlls/wined3d/utils.c | 20 ++++++
dlls/wined3d/wined3d_private.h | 3 -
4 files changed, 21 insertions(+), 134 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 32031e4..d9399fe 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -8679,7 +8679,7 @@ struct formats {
};
const struct formats test_formats[] = {
- { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
+ { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
{ "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
{ "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
{ "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index b34ab49..3e72ad6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -36,7 +36,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey);
static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert);
-static inline void clear_unused_channels(IWineD3DSurfaceImpl *This);
static void surface_remove_pbo(IWineD3DSurfaceImpl *This);
void surface_force_reload(IWineD3DSurface *iface)
@@ -945,8 +944,6 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This)
This->pow2Height, format, type);
}
- clear_unused_channels(This);
-
ENTER_GL();
/* If !SrcIsUpsideDown we should flip the surface.
* This can be done using glCopyTexSubImage2D but this
@@ -1703,38 +1700,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
*target_bpp = 2;
break;
- case WINED3DFMT_R32F:
- /* Can be loaded in theory with fmt=GL_RED, type=GL_FLOAT, but this fails. The reason
- * is that D3D expects the undefined green, blue and alpha channels to return 1.0
- * when sampling, but OpenGL sets green and blue to 0.0 instead. Thus we have to inject
- * 1.0 instead.
- *
- * The alpha channel defaults to 1.0 in opengl, so nothing has to be done about it.
- */
- *convert = CONVERT_R32F;
- *format = GL_RGB;
- *internal = GL_RGB32F_ARB;
- *type = GL_FLOAT;
- *target_bpp = 12;
- break;
-
- case WINED3DFMT_R16F:
- /* Similar to R32F */
- *convert = CONVERT_R16F;
- *format = GL_RGB;
- *internal = GL_RGB16F_ARB;
- *type = GL_HALF_FLOAT_ARB;
- *target_bpp = 6;
- break;
-
- case WINED3DFMT_G16R16:
- *convert = CONVERT_G16R16;
- *format = GL_RGB;
- *internal = GL_RGB16_EXT;
- *type = GL_UNSIGNED_SHORT;
- *target_bpp = 6;
- break;
-
default:
break;
}
@@ -2062,66 +2027,6 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
break;
}
- case CONVERT_R32F:
- {
- unsigned int x, y;
- const float *Source;
- float *Dest;
- for(y = 0; y < height; y++) {
- Source = (const float *)(src + y * pitch);
- Dest = (float *) (dst + y * outpitch);
- for (x = 0; x < width; x++ ) {
- float color = (*Source++);
- Dest[0] = color;
- Dest[1] = 1.0;
- Dest[2] = 1.0;
- Dest += 3;
- }
- }
- break;
- }
-
- case CONVERT_R16F:
- {
- unsigned int x, y;
- const WORD *Source;
- WORD *Dest;
- const WORD one = 0x3c00;
- for(y = 0; y < height; y++) {
- Source = (const WORD *)(src + y * pitch);
- Dest = (WORD *) (dst + y * outpitch);
- for (x = 0; x < width; x++ ) {
- WORD color = (*Source++);
- Dest[0] = color;
- Dest[1] = one;
- Dest[2] = one;
- Dest += 3;
- }
- }
- break;
- }
-
- case CONVERT_G16R16:
- {
- unsigned int x, y;
- const WORD *Source;
- WORD *Dest;
-
- for(y = 0; y < height; y++) {
- Source = (const WORD *)(src + y * pitch);
- Dest = (WORD *) (dst + y * outpitch);
- for (x = 0; x < width; x++ ) {
- WORD green = (*Source++);
- WORD red = (*Source++);
- Dest[0] = green;
- Dest[1] = red;
- Dest[2] = 0xffff;
- Dest += 3;
- }
- }
- break;
- }
-
default:
ERR("Unsupported conversation type %d\n", convert);
}
@@ -2273,41 +2178,6 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) {
return TRUE;
}
-static inline void clear_unused_channels(IWineD3DSurfaceImpl *This) {
- GLboolean oldwrite[4];
-
- /* Some formats have only some color channels, and the others are 1.0.
- * since our rendering renders to all channels, and those pixel formats
- * are emulated by using a full texture with the other channels set to 1.0
- * manually, clear the unused channels.
- *
- * This could be done with hacking colorwriteenable to mask the colors,
- * but before drawing the buffer would have to be cleared too, so there's
- * no gain in that
- */
- switch(This->resource.format) {
- case WINED3DFMT_R16F:
- case WINED3DFMT_R32F:
- TRACE("R16F or R32F format, clearing green, blue and alpha to 1.0\n");
- /* Do not activate a context, the correct drawable is active already
- * though just the read buffer is set, make sure to have the correct draw
- * buffer too
- */
- glDrawBuffer(This->resource.wineD3DDevice->offscreenBuffer);
- glDisable(GL_SCISSOR_TEST);
- glGetBooleanv(GL_COLOR_WRITEMASK, oldwrite);
- glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
- glClearColor(0.0, 1.0, 1.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
- glColorMask(oldwrite[0], oldwrite[1], oldwrite[2], oldwrite[3]);
- if(!This->resource.wineD3DDevice->render_offscreen) glDrawBuffer(GL_BACK);
- checkGLcall("Unused channel clear\n");
- break;
-
- default: break;
- }
-}
-
static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BOOL srgb_mode) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index cd7ff06..fd4f4ee 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -363,6 +363,26 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
}
}
+ dst = getFmtIdx(WINED3DFMT_R16F);
+ gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ dst = getFmtIdx(WINED3DFMT_R32F);
+ gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ dst = getFmtIdx(WINED3DFMT_G16R16);
+ gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ dst = getFmtIdx(WINED3DFMT_G16R16F);
+ gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ dst = getFmtIdx(WINED3DFMT_G32R32F);
+ gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
/* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
* V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
* their extensions are not available. GL_ATI_envmap_bumpmap is not used because
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2aa74e7..36ba563 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1693,9 +1693,6 @@ typedef enum {
CONVERT_Q8W8V8U8,
CONVERT_V16U16,
CONVERT_A4L4,
- CONVERT_R32F,
- CONVERT_R16F,
- CONVERT_G16R16,
} CONVERT_TYPES;
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);
More information about the wine-cvs
mailing list