wined3d: Move the 8-bit palette shader code over to the blit_shader backend.

This commit is contained in:
Roderick Colenbrander 2010-03-02 18:46:43 +01:00 committed by Alexandre Julliard
parent 922ad80f42
commit c0ef7a1a93
5 changed files with 90 additions and 42 deletions

View File

@ -6229,6 +6229,7 @@ struct arbfp_blit_priv {
GLenum yuy2_rect_shader, yuy2_2d_shader;
GLenum uyvy_rect_shader, uyvy_2d_shader;
GLenum yv12_rect_shader, yv12_2d_shader;
GLenum p8_rect_shader, p8_2d_shader;
};
static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) {
@ -6253,7 +6254,9 @@ static void arbfp_blit_free(IWineD3DDevice *iface) {
GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_2d_shader));
GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_rect_shader));
GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_2d_shader));
checkGLcall("Delete yuv programs");
GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_rect_shader));
GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_2d_shader));
checkGLcall("Delete yuv and p8 programs");
LEAVE_GL();
HeapFree(GetProcessHeap(), 0, device->blit_priv);
@ -6494,6 +6497,72 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype,
return TRUE;
}
static GLuint gen_p8_shader(IWineD3DDeviceImpl *device, GLenum textype)
{
GLenum shader;
struct wined3d_shader_buffer buffer;
struct arbfp_blit_priv *priv = device->blit_priv;
GLint pos;
/* Shader header */
if (!shader_buffer_init(&buffer))
{
ERR("Failed to initialize shader buffer.\n");
return 0;
}
ENTER_GL();
GL_EXTCALL(glGenProgramsARB(1, &shader));
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader));
LEAVE_GL();
if(!shader) {
shader_buffer_free(&buffer);
return 0;
}
shader_addline(&buffer, "!!ARBfp1.0\n");
shader_addline(&buffer, "TEMP index;\n");
/* { 255/256, 0.5/255*255/256, 0, 0 } */
shader_addline(&buffer, "PARAM constants = { 0.996, 0.00195, 0, 0 };\n");
/* The alpha-component contains the palette index */
if(textype == GL_TEXTURE_RECTANGLE_ARB)
shader_addline(&buffer, "TXP index, fragment.texcoord[0], texture[0], RECT;\n");
else
shader_addline(&buffer, "TEX index, fragment.texcoord[0], texture[0], 2D;\n");
/* Scale the index by 255/256 and add a bias of '0.5' in order to sample in the middle */
shader_addline(&buffer, "MAD index.a, index.a, constants.x, constants.y;\n");
/* Use the alpha-component as an index in the palette to get the final color */
shader_addline(&buffer, "TEX result.color, index.a, texture[1], 1D;\n");
shader_addline(&buffer, "END\n");
ENTER_GL();
GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
strlen(buffer.buffer), buffer.buffer));
checkGLcall("glProgramStringARB()");
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
if (pos != -1)
{
FIXME("Fragment program error at position %d: %s\n\n", pos,
debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
shader_arb_dump_program_source(buffer.buffer);
}
if (textype == GL_TEXTURE_RECTANGLE_ARB)
priv->p8_rect_shader = shader;
else
priv->p8_2d_shader = shader;
shader_buffer_free(&buffer);
LEAVE_GL();
return shader;
}
/* Context activation is done by the caller. */
static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum complex_fixup yuv_fixup, GLenum textype)
{
@ -6643,6 +6712,8 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum complex_fixup yuv_
if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yv12_rect_shader = shader;
else priv->yv12_2d_shader = shader;
break;
default:
ERR("Unsupported complex fixup: %d\n", yuv_fixup);
}
return shader;
@ -6686,8 +6757,13 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD
shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yv12_rect_shader : priv->yv12_2d_shader;
break;
case COMPLEX_FIXUP_P8:
shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->p8_rect_shader : priv->p8_2d_shader;
if (!shader) shader = gen_p8_shader(device, textype);
break;
default:
FIXME("Unsupported YUV fixup %#x, not setting a shader\n", fixup);
FIXME("Unsupported complex fixup %#x, not setting a shader\n", fixup);
ENTER_GL();
glEnable(textype);
checkGLcall("glEnable(textype)");
@ -6761,6 +6837,7 @@ static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup)
case COMPLEX_FIXUP_YUY2:
case COMPLEX_FIXUP_UYVY:
case COMPLEX_FIXUP_YV12:
case COMPLEX_FIXUP_P8:
TRACE("[OK]\n");
return TRUE;

View File

@ -1720,14 +1720,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface,
}
}
/* Delete the palette conversion shader if it is around */
if(This->paletteConversionShader) {
ENTER_GL();
GL_EXTCALL(glDeleteProgramsARB(1, &This->paletteConversionShader));
LEAVE_GL();
This->paletteConversionShader = 0;
}
/* Delete the pbuffer context if there is any */
if(This->pbufferContext) context_destroy(This, This->pbufferContext);

View File

@ -1853,7 +1853,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
* in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which
* conflicts with this.
*/
if (!(gl_info->supported[EXT_PALETTED_TEXTURE] || (gl_info->supported[ARB_FRAGMENT_PROGRAM]
if (!(gl_info->supported[EXT_PALETTED_TEXTURE] || (device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup)
&& device->render_targets && This == (IWineD3DSurfaceImpl*)device->render_targets[0]))
|| colorkey_active || !use_texturing)
{
@ -1867,7 +1867,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
*convert = CONVERT_PALETTED;
}
}
else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && gl_info->supported[ARB_FRAGMENT_PROGRAM])
else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup))
{
*format = GL_ALPHA;
*type = GL_UNSIGNED_BYTE;
@ -2584,34 +2584,10 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
* The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */
TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n");
device->blitter->set_shader((IWineD3DDevice *) device, This->resource.format_desc,
This->texture_target, This->pow2Width, This->pow2Height);
ENTER_GL();
/* Create the fragment program if we don't have it */
if(!device->paletteConversionShader)
{
const char *fragment_palette_conversion =
"!!ARBfp1.0\n"
"TEMP index;\n"
/* { 255/256, 0.5/255*255/256, 0, 0 } */
"PARAM constants = { 0.996, 0.00195, 0, 0 };\n"
/* The alpha-component contains the palette index */
"TEX index, fragment.texcoord[0], texture[0], 2D;\n"
/* Scale the index by 255/256 and add a bias of '0.5' in order to sample in the middle */
"MAD index.a, index.a, constants.x, constants.y;\n"
/* Use the alpha-component as an index in the palette to get the final color */
"TEX result.color, index.a, texture[1], 1D;\n"
"END";
glEnable(GL_FRAGMENT_PROGRAM_ARB);
GL_EXTCALL(glGenProgramsARB(1, &device->paletteConversionShader));
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader));
GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fragment_palette_conversion), fragment_palette_conversion));
glDisable(GL_FRAGMENT_PROGRAM_ARB);
}
glEnable(GL_FRAGMENT_PROGRAM_ARB);
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader));
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1));
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -2625,7 +2601,6 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
/* Rebind the texture because it isn't bound anymore */
glBindTexture(This->texture_target, This->texture_name);
LEAVE_GL();
}
}
@ -5065,7 +5040,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This);
}
else if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
&& (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM]))
&& (gl_info->supported[EXT_PALETTED_TEXTURE] || device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup)))
{
d3dfmt_p8_upload_palette(iface, convert);
mem = This->resource.allocatedMemory;

View File

@ -1098,6 +1098,9 @@ static void apply_format_fixups(struct wined3d_gl_info *gl_info)
gl_info->gl_formats[idx].heightscale = 1.5f;
gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
idx = getFmtIdx(WINED3DFMT_P8_UINT);
gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
@ -1930,6 +1933,7 @@ static const char *debug_complex_fixup(enum complex_fixup fixup)
WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
WINED3D_TO_STR(COMPLEX_FIXUP_P8);
#undef WINED3D_TO_STR
default:
FIXME("Unrecognized complex fixup %#x\n", fixup);

View File

@ -70,6 +70,7 @@ enum complex_fixup
COMPLEX_FIXUP_YUY2 = 0,
COMPLEX_FIXUP_UYVY = 1,
COMPLEX_FIXUP_YV12 = 2,
COMPLEX_FIXUP_P8 = 3,
};
#include <pshpack2.h>
@ -1644,7 +1645,6 @@ struct IWineD3DDeviceImpl
UINT NumberOfPalettes;
PALETTEENTRY **palettes;
UINT currentPalette;
UINT paletteConversionShader;
/* For rendering to a texture using glCopyTexImage */
GLenum *draw_buffers;