Commit e04556bb authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

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.
parent 89139b75
...@@ -8679,7 +8679,7 @@ struct formats { ...@@ -8679,7 +8679,7 @@ struct formats {
}; };
const struct formats test_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_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
{ "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff }, { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
{ "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 }, { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
......
...@@ -36,7 +36,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); ...@@ -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_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey);
static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert); 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); static void surface_remove_pbo(IWineD3DSurfaceImpl *This);
void surface_force_reload(IWineD3DSurface *iface) void surface_force_reload(IWineD3DSurface *iface)
...@@ -945,8 +944,6 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This) ...@@ -945,8 +944,6 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This)
This->pow2Height, format, type); This->pow2Height, format, type);
} }
clear_unused_channels(This);
ENTER_GL(); ENTER_GL();
/* If !SrcIsUpsideDown we should flip the surface. /* If !SrcIsUpsideDown we should flip the surface.
* This can be done using glCopyTexSubImage2D but this * This can be done using glCopyTexSubImage2D but this
...@@ -1703,38 +1700,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ ...@@ -1703,38 +1700,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
*target_bpp = 2; *target_bpp = 2;
break; 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: default:
break; break;
} }
...@@ -2062,66 +2027,6 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI ...@@ -2062,66 +2027,6 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
break; 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: default:
ERR("Unsupported conversation type %d\n", convert); ERR("Unsupported conversation type %d\n", convert);
} }
...@@ -2273,41 +2178,6 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) { ...@@ -2273,41 +2178,6 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) {
return TRUE; 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) { static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BOOL srgb_mode) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
......
...@@ -363,6 +363,26 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info) ...@@ -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. /* 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 * 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 * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
......
...@@ -1693,9 +1693,6 @@ typedef enum { ...@@ -1693,9 +1693,6 @@ typedef enum {
CONVERT_Q8W8V8U8, CONVERT_Q8W8V8U8,
CONVERT_V16U16, CONVERT_V16U16,
CONVERT_A4L4, CONVERT_A4L4,
CONVERT_R32F,
CONVERT_R16F,
CONVERT_G16R16,
} CONVERT_TYPES; } 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); 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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment