From e04556bb166804edc5c6cb16e6001b25aab9563e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Wed, 3 Dec 2008 14:53:43 +0100 Subject: [PATCH] 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 32031e4e4c4..d9399fe7e29 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 b34ab49bd1a..3e72ad60318 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 cd7ff065310..fd4f4ee1987 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 2aa74e72f5c..36ba5630704 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);