Commit 89139b75 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Make shader texture format fixups more generic.

Based on a patch by Stefan Dösinger. This is more flexible, and allows the shader backend implementation to be simpler, since it doesn't have to know about specific formats. The next patch makes use of this.
parent 9f2fa8ba
......@@ -26,6 +26,7 @@
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
/* Some private defines, Constant associations, etc.
* Env bump matrix and per stage constant should be independent,
......@@ -343,21 +344,30 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
/* Pass 2: Generate perturbation calculations */
for(stage = 0; stage < GL_LIMITS(textures); stage++) {
GLuint argmodextra_x, argmodextra_y;
struct color_fixup_desc fixup;
if(op[stage].cop == WINED3DTOP_DISABLE) break;
if(op[stage].cop != WINED3DTOP_BUMPENVMAP &&
op[stage].cop != WINED3DTOP_BUMPENVMAPLUMINANCE) continue;
/* Nice thing, we get the color correction for free :-) */
if(op[stage].color_correction == WINED3DFMT_V8U8) {
argmodextra = GL_2X_BIT_ATI | GL_BIAS_BIT_ATI;
} else {
argmodextra = 0;
if (fixup.x_source != CHANNEL_SOURCE_X || fixup.y_source != CHANNEL_SOURCE_Y)
{
FIXME("Swizzles not implemented\n");
argmodextra_x = GL_NONE;
argmodextra_y = GL_NONE;
}
else
{
/* Nice thing, we get the color correction for free :-) */
argmodextra_x = fixup.x_sign_fixup ? GL_2X_BIT_ATI | GL_BIAS_BIT_ATI : GL_NONE;
argmodextra_y = fixup.y_sign_fixup ? GL_2X_BIT_ATI | GL_BIAS_BIT_ATI : GL_NONE;
}
TRACE("glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, GL_REG_%d_ATI, GL_RED_BIT_ATI, GL_NONE, GL_REG_%d_ATI, GL_NONE, %s, ATI_FFP_CONST_BUMPMAT(%d), GL_NONE, GL_NONE, GL_REG_%d_ATI, GL_RED, GL_NONE)\n",
stage + 1, stage, debug_argmod(argmodextra), stage, stage + 1);
stage + 1, stage, debug_argmod(argmodextra_x), stage, stage + 1);
GL_EXTCALL(glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_RED_BIT_ATI, GL_NONE,
GL_REG_0_ATI + stage, GL_NONE, argmodextra,
GL_REG_0_ATI + stage, GL_NONE, argmodextra_x,
ATI_FFP_CONST_BUMPMAT(stage), GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
GL_REG_0_ATI + stage + 1, GL_RED, GL_NONE));
......@@ -376,9 +386,9 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
GL_EXTCALL(glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_5_ATI, GL_GREEN_BIT_ATI, GL_NONE,
ATI_FFP_CONST_BUMPMAT(stage), GL_ALPHA, GL_NONE));
TRACE("glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, GL_REG_%d_ATI, GL_GREEN_BIT_ATI, GL_NONE, GL_REG_%d_ATI, GL_NONE, %s, GL_REG_5_ATI, GL_NONE, GL_NONE, GL_REG_%d_ATI, GL_GREEN, GL_NONE)\n",
stage + 1, stage, debug_argmod(argmodextra), stage + 1);
stage + 1, stage, debug_argmod(argmodextra_y), stage + 1);
GL_EXTCALL(glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_GREEN_BIT_ATI, GL_NONE,
GL_REG_0_ATI + stage, GL_NONE, argmodextra,
GL_REG_0_ATI + stage, GL_NONE, argmodextra_y,
GL_REG_5_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
GL_REG_0_ATI + stage + 1, GL_GREEN, GL_NONE));
}
......@@ -1108,17 +1118,25 @@ static void atifs_free(IWineD3DDevice *iface) {
}
#undef GLINFO_LOCATION
static BOOL atifs_conv_supported(WINED3DFORMAT fmt) {
TRACE("Checking shader format support for format %s:", debug_d3dformat(fmt));
switch(fmt) {
case WINED3DFMT_V8U8:
case WINED3DFMT_V16U16:
TRACE("[OK]\n");
return TRUE;
default:
TRACE("[FAILED\n");
return FALSE;
static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(fixup);
}
/* We only support sign fixup of the first two channels. */
if (fixup.x_source == CHANNEL_SOURCE_X && fixup.y_source == CHANNEL_SOURCE_Y
&& fixup.z_source == CHANNEL_SOURCE_Z && fixup.w_source == CHANNEL_SOURCE_W
&& !fixup.z_sign_fixup && !fixup.w_sign_fixup)
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
}
const struct fragment_pipeline atifs_fragment_pipeline = {
......@@ -1126,7 +1144,7 @@ const struct fragment_pipeline atifs_fragment_pipeline = {
atifs_get_caps,
atifs_alloc,
atifs_free,
atifs_conv_supported,
atifs_color_fixup_supported,
atifs_fragmentstate_template,
TRUE /* We can disable projected textures */
};
......@@ -29,6 +29,7 @@
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
#define GLNAME_REQUIRE_GLSL ((const char *)1)
......@@ -768,6 +769,67 @@ static void shader_dump_param(IWineD3DBaseShader *iface, const DWORD param, cons
}
}
static void shader_color_correction(IWineD3DBaseShaderImpl *shader,
IWineD3DDeviceImpl *device, const struct SHADER_OPCODE_ARG *arg)
{
DWORD hex_version = shader->baseShader.hex_version;
IWineD3DBaseTextureImpl *texture;
struct color_fixup_desc fixup;
BOOL recorded = FALSE;
DWORD sampler_idx;
UINT i;
switch(arg->opcode->opcode)
{
case WINED3DSIO_TEX:
if (hex_version < WINED3DPS_VERSION(2,0)) sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
else sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
break;
case WINED3DSIO_TEXLDL:
FIXME("Add color fixup for vertex texture WINED3DSIO_TEXLDL\n");
return;
case WINED3DSIO_TEXDP3TEX:
case WINED3DSIO_TEXM3x3TEX:
case WINED3DSIO_TEXM3x3SPEC:
case WINED3DSIO_TEXM3x3VSPEC:
case WINED3DSIO_TEXBEM:
case WINED3DSIO_TEXREG2AR:
case WINED3DSIO_TEXREG2GB:
case WINED3DSIO_TEXREG2RGB:
sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
break;
default:
/* Not a texture sampling instruction, nothing to do */
return;
};
texture = (IWineD3DBaseTextureImpl *)device->stateBlock->textures[sampler_idx];
if (texture) fixup = texture->baseTexture.shader_color_fixup;
else fixup = COLOR_FIXUP_IDENTITY;
/* before doing anything, record the sampler with the format in the format conversion list,
* but check if it's not there already */
for (i = 0; i < shader->baseShader.num_sampled_samplers; ++i)
{
if (shader->baseShader.sampled_samplers[i] == sampler_idx)
{
recorded = TRUE;
break;
}
}
if (!recorded)
{
shader->baseShader.sampled_samplers[shader->baseShader.num_sampled_samplers] = sampler_idx;
++shader->baseShader.num_sampled_samplers;
}
device->shader_backend->shader_color_correction(arg, fixup);
}
/** Shared code in order to generate the bulk of the shader string.
Use the shader_header_fct & shader_footer_fct to add strings
that are specific to pixel or vertex functions
......@@ -866,7 +928,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
hw_fct(&hw_arg);
/* Add color correction if needed */
device->shader_backend->shader_color_correction(&hw_arg);
shader_color_correction(This, device, &hw_arg);
/* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
/* FIXME: This should be internal to the shader backend.
......@@ -1083,7 +1145,7 @@ static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types t
static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
static void shader_none_cleanup(IWineD3DDevice *iface) {}
static void shader_none_color_correction(const SHADER_OPCODE_ARG *arg) {}
static void shader_none_color_correction(const struct SHADER_OPCODE_ARG *arg, struct color_fixup_desc fixup) {}
static void shader_none_destroy(IWineD3DBaseShader *iface) {}
static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;}
static void shader_none_free(IWineD3DDevice *iface) {}
......@@ -1105,21 +1167,23 @@ static void shader_none_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *
pCaps->PixelShader1xMaxValue = 0.0;
}
#undef GLINFO_LOCATION
static BOOL shader_none_conv_supported(WINED3DFORMAT fmt) {
TRACE("Checking shader format support for format %s", debug_d3dformat(fmt));
switch(fmt) {
/* Faked to make some apps happy. */
case WINED3DFMT_V8U8:
case WINED3DFMT_V16U16:
case WINED3DFMT_L6V5U5:
case WINED3DFMT_X8L8V8U8:
case WINED3DFMT_Q8W8V8U8:
TRACE("[OK]\n");
return TRUE;
default:
TRACE("[FAILED]\n");
return FALSE;
static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(fixup);
}
/* Faked to make some apps happy. */
if (!is_yuv_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
}
const shader_backend_t none_shader_backend = {
......@@ -1137,7 +1201,7 @@ const shader_backend_t none_shader_backend = {
shader_none_generate_pshader,
shader_none_generate_vshader,
shader_none_get_caps,
shader_none_conv_supported
shader_none_color_fixup_supported,
};
/* *******************************************
......
......@@ -891,7 +891,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
tmpW = max(1, tmpW >> 1);
tmpH = max(1, tmpH >> 1);
}
object->baseTexture.shader_conversion_group = glDesc->conversion_group;
object->baseTexture.shader_color_fixup = glDesc->color_fixup;
TRACE("(%p) : Created texture %p\n", This, object);
return WINED3D_OK;
......@@ -998,7 +998,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
tmpH = max(1, tmpH >> 1);
tmpD = max(1, tmpD >> 1);
}
object->baseTexture.shader_conversion_group = glDesc->conversion_group;
object->baseTexture.shader_color_fixup = glDesc->color_fixup;
*ppVolumeTexture = (IWineD3DVolumeTexture *) object;
TRACE("(%p) : Created volume texture %p\n", This, object);
......@@ -1168,7 +1168,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
}
tmpW = max(1, tmpW >> 1);
}
object->baseTexture.shader_conversion_group = glDesc->conversion_group;
object->baseTexture.shader_color_fixup = glDesc->color_fixup;
TRACE("(%p) : Created Cube Texture %p\n", This, object);
*ppCubeTexture = (IWineD3DCubeTexture *) object;
......
......@@ -1994,24 +1994,18 @@ static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
case WINED3DFMT_L6V5U5:
case WINED3DFMT_X8L8V8U8:
case WINED3DFMT_Q8W8V8U8:
/* Ask the fixed function pipeline implementation if it can deal
* with the conversion. If we've got a GL extension giving native
* support this will be an identity conversion. */
getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
if(glDesc->conversion_group == WINED3DFMT_UNKNOWN) {
/* We have a GL extension giving native support */
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
/* No native support: Ask the fixed function pipeline implementation if it
* can deal with the conversion
*/
fp = select_fragment_implementation(Adapter, DeviceType);
if(fp->conv_supported(CheckFormat)) {
if (fp->color_fixup_supported(glDesc->color_fixup))
{
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
} else {
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
}
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
default:
TRACE_(d3d_caps)("[FAILED]\n");
......@@ -2281,25 +2275,18 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
case WINED3DFMT_L6V5U5:
case WINED3DFMT_Q8W8V8U8:
case WINED3DFMT_V16U16:
case WINED3DFMT_W11V11U10:
/* Ask the shader backend if it can deal with the conversion. If
* we've got a GL extension giving native support this will be an
* identity conversion. */
getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
if(glDesc->conversion_group == WINED3DFMT_UNKNOWN) {
/* We have a GL extension giving native support */
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
/* No native support: Ask the fixed function pipeline implementation if it
* can deal with the conversion
*/
shader_backend = select_shader_backend(Adapter, DeviceType);
if(shader_backend->shader_conv_supported(CheckFormat)) {
if (shader_backend->shader_color_fixup_supported(glDesc->color_fixup))
{
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
} else {
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
}
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
case WINED3DFMT_DXT1:
case WINED3DFMT_DXT2:
......@@ -2322,6 +2309,7 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
case WINED3DFMT_INDEX32:
case WINED3DFMT_Q16W16V16U16:
case WINED3DFMT_A2W10V10U10:
case WINED3DFMT_W11V11U10:
TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
return FALSE;
......@@ -2404,10 +2392,12 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
/* Vendor specific formats */
case WINED3DFMT_ATI2N:
if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
shader_backend = select_shader_backend(Adapter, DeviceType);
fp = select_fragment_implementation(Adapter, DeviceType);
if(shader_backend->shader_conv_supported(CheckFormat) &&
fp->conv_supported(CheckFormat)) {
if (shader_backend->shader_color_fixup_supported(glDesc->color_fixup)
&& fp->color_fixup_supported(glDesc->color_fixup))
{
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
......@@ -2440,6 +2430,7 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
}
static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType) {
const struct GlPixelFormatDesc *format_desc;
const struct blit_shader *blitter;
if(SurfaceType == SURFACE_GDI) {
......@@ -2476,8 +2467,10 @@ static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WI
if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) return TRUE;
/* If opengl can't process the format natively, the blitter may be able to convert it */
getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &format_desc);
blitter = select_blit_implementation(Adapter, DeviceType);
if(blitter->conv_supported(CheckFormat)) {
if (blitter->color_fixup_supported(format_desc->color_fixup))
{
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
......
......@@ -673,8 +673,22 @@ static void nvrc_fragment_free(IWineD3DDevice *iface) {}
* register combiners extension(Pre-GF3).
*/
static BOOL nvts_conv_supported(WINED3DFORMAT fmt) {
TRACE("Checking shader format support for format %s: [FAILED]\n", debug_d3dformat(fmt));
static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(fixup);
}
/* We only support identity conversions. */
if (is_identity_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
}
......@@ -810,7 +824,7 @@ const struct fragment_pipeline nvts_fragment_pipeline = {
nvrc_fragment_get_caps,
nvrc_fragment_alloc,
nvrc_fragment_free,
nvts_conv_supported,
nvts_color_fixup_supported,
nvrc_fragmentstate_template,
FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
};
......@@ -820,7 +834,7 @@ const struct fragment_pipeline nvrc_fragment_pipeline = {
nvrc_fragment_get_caps,
nvrc_fragment_alloc,
nvrc_fragment_free,
nvts_conv_supported,
nvts_color_fixup_supported,
nvrc_fragmentstate_template,
FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
};
......@@ -435,15 +435,15 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
args->srgb_correction = stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;
memset(args->format_conversion, 0, sizeof(args->format_conversion));
memset(args->color_fixup, 0, sizeof(args->color_fixup));
for(i = 0; i < shader->baseShader.num_sampled_samplers; i++) {
sampler = shader->baseShader.sampled_samplers[i];
tex = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
if(!tex) {
args->format_conversion[sampler] = WINED3DFMT_UNKNOWN;
args->color_fixup[sampler] = COLOR_FIXUP_IDENTITY;
continue;
}
args->format_conversion[sampler] = tex->baseTexture.shader_conversion_group;
args->color_fixup[sampler] = tex->baseTexture.shader_color_fixup;
}
if(shader->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
if(((IWineD3DDeviceImpl *) shader->baseShader.device)->strided_streams.u.s.position_transformed) {
......
......@@ -5471,8 +5471,22 @@ static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info
static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
static void ffp_fragment_free(IWineD3DDevice *iface) {}
static BOOL ffp_conv_supported(WINED3DFORMAT fmt) {
TRACE("Checking shader format support for format %s: [FAILED]\n", debug_d3dformat(fmt));
static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(fixup);
}
/* We only support identity conversions. */
if (is_identity_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
}
......@@ -5481,7 +5495,7 @@ const struct fragment_pipeline ffp_fragment_pipeline = {
ffp_fragment_get_caps,
ffp_fragment_alloc,
ffp_fragment_free,
ffp_conv_supported,
ffp_color_fixup_supported,
ffp_fragmentstate_template,
FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
};
......
......@@ -31,6 +31,7 @@
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey);
......@@ -4847,8 +4848,22 @@ static void ffp_blit_unset(IWineD3DDevice *iface) {
}
}
static BOOL ffp_blit_conv_supported(WINED3DFORMAT fmt) {
TRACE("Checking blit format support for format %s: [FAILED]\n", debug_d3dformat(fmt));
static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d_surface) && TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(fixup);
}
/* We only support identity conversions. */
if (is_identity_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
}
......@@ -4857,5 +4872,5 @@ const struct blit_shader ffp_blit = {
ffp_blit_free,
ffp_blit_set,
ffp_blit_unset,
ffp_blit_conv_supported
ffp_blit_color_fixup_supported
};
......@@ -318,7 +318,7 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
gl_info->gl_formats[dst].glGammaInternal = gl_formats_template[src].glGammaInternal;
gl_info->gl_formats[dst].glFormat = gl_formats_template[src].glFormat;
gl_info->gl_formats[dst].glType = gl_formats_template[src].glType;
gl_info->gl_formats[dst].conversion_group= WINED3DFMT_UNKNOWN;
gl_info->gl_formats[dst].color_fixup = COLOR_FIXUP_IDENTITY;
gl_info->gl_formats[dst].Flags = gl_formats_template[src].Flags;
gl_info->gl_formats[dst].heightscale = 1.0;
......@@ -372,21 +372,38 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
* returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
* conversion for this format.
*/
dst = getFmtIdx(WINED3DFMT_V8U8);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
dst = getFmtIdx(WINED3DFMT_V16U16);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_V8U8;
if (!GL_SUPPORT(NV_TEXTURE_SHADER))
{
dst = getFmtIdx(WINED3DFMT_V8U8);
gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
dst = getFmtIdx(WINED3DFMT_V16U16);
gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
else
{
dst = getFmtIdx(WINED3DFMT_V8U8);
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_ONE);
dst = getFmtIdx(WINED3DFMT_V16U16);
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_ONE);
}
if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
/* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
* with each other
*/
dst = getFmtIdx(WINED3DFMT_L6V5U5);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_L6V5U5;
gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
dst = getFmtIdx(WINED3DFMT_X8L8V8U8);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_X8L8V8U8;
gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
dst = getFmtIdx(WINED3DFMT_Q8W8V8U8);
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_Q8W8V8U8;
gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
} else {
/* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
* are converted at surface loading time, but they do not need any modification in
......@@ -399,12 +416,14 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
dst = getFmtIdx(WINED3DFMT_ATI2N);
gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
gl_info->gl_formats[dst].conversion_group= WINED3DFMT_ATI2N;
gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
} else if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
dst = getFmtIdx(WINED3DFMT_ATI2N);
gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
gl_info->gl_formats[dst].conversion_group= WINED3DFMT_ATI2N;
gl_info->gl_formats[dst].color_fixup= create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
if(!GL_SUPPORT(APPLE_YCBCR_422)) {
......@@ -413,19 +432,19 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_YUY2;
gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
dst = getFmtIdx(WINED3DFMT_UYVY);
gl_info->gl_formats[dst].glInternal = GL_LUMINANCE_ALPHA;
gl_info->gl_formats[dst].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
gl_info->gl_formats[dst].glFormat = GL_LUMINANCE_ALPHA;
gl_info->gl_formats[dst].glType = GL_UNSIGNED_BYTE;
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_UYVY;
gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
}
dst = getFmtIdx(WINED3DFMT_YV12);
gl_info->gl_formats[dst].heightscale = 1.5;
gl_info->gl_formats[dst].conversion_group = WINED3DFMT_YV12;
gl_info->gl_formats[dst].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
return TRUE;
}
......@@ -1115,6 +1134,55 @@ const char *debug_d3ddegree(WINED3DDEGREETYPE degree) {
}
}
const char *debug_fixup_channel_source(enum fixup_channel_source source)
{
switch(source)
{
#define WINED3D_TO_STR(x) case x: return #x
WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
WINED3D_TO_STR(CHANNEL_SOURCE_X);
WINED3D_TO_STR(CHANNEL_SOURCE_Y);
WINED3D_TO_STR(CHANNEL_SOURCE_Z);
WINED3D_TO_STR(CHANNEL_SOURCE_W);
WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
#undef WINED3D_TO_STR
default:
FIXME("Unrecognized fixup_channel_source %#x\n", source);
return "unrecognized";
}
}
const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
{
switch(yuv_fixup)
{
#define WINED3D_TO_STR(x) case x: return #x
WINED3D_TO_STR(YUV_FIXUP_YUY2);
WINED3D_TO_STR(YUV_FIXUP_UYVY);
WINED3D_TO_STR(YUV_FIXUP_YV12);
#undef WINED3D_TO_STR
default:
FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
return "unrecognized";
}
}
void dump_color_fixup_desc(struct color_fixup_desc fixup)
{
if (is_yuv_fixup(fixup))
{
TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
return;
}
TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
}
/*****************************************************************************
* Useful functions mapping GL <-> D3D values
*/
......@@ -1829,7 +1897,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
settings->op[i].aop = WINED3DTOP_DISABLE;
settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
settings->op[i].color_correction = WINED3DFMT_UNKNOWN;
settings->op[i].color_correction = COLOR_FIXUP_IDENTITY;
settings->op[i].dst = resultreg;
settings->op[i].tex_type = tex_1d;
settings->op[i].projected = proj_none;
......@@ -1839,7 +1907,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
if(texture) {
settings->op[i].color_correction = texture->baseTexture.shader_conversion_group;
settings->op[i].color_correction = texture->baseTexture.shader_color_fixup;
if(ignore_textype) {
settings->op[i].tex_type = tex_1d;
} else {
......@@ -1862,7 +1930,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
}
}
} else {
settings->op[i].color_correction = WINED3DFMT_UNKNOWN;
settings->op[i].color_correction = COLOR_FIXUP_IDENTITY;
settings->op[i].tex_type = tex_1d;
}
......
......@@ -43,6 +43,90 @@
#include "wined3d_gl.h"
#include "wine/list.h"
/* Texture format fixups */
enum fixup_channel_source
{
CHANNEL_SOURCE_ZERO = 0,
CHANNEL_SOURCE_ONE = 1,
CHANNEL_SOURCE_X = 2,
CHANNEL_SOURCE_Y = 3,
CHANNEL_SOURCE_Z = 4,
CHANNEL_SOURCE_W = 5,
CHANNEL_SOURCE_YUV0 = 6,
CHANNEL_SOURCE_YUV1 = 7,
};
enum yuv_fixup
{
YUV_FIXUP_YUY2 = 0,
YUV_FIXUP_UYVY = 1,
YUV_FIXUP_YV12 = 2,
};
#include <pshpack2.h>
struct color_fixup_desc
{
unsigned x_sign_fixup : 1;
unsigned x_source : 3;
unsigned y_sign_fixup : 1;
unsigned y_source : 3;
unsigned z_sign_fixup : 1;
unsigned z_source : 3;
unsigned w_sign_fixup : 1;
unsigned w_source : 3;
};
#include <poppack.h>
static const struct color_fixup_desc COLOR_FIXUP_IDENTITY =
{0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W};
static inline struct color_fixup_desc create_color_fixup_desc(
int sign0, enum fixup_channel_source src0, int sign1, enum fixup_channel_source src1,
int sign2, enum fixup_channel_source src2, int sign3, enum fixup_channel_source src3)
{
struct color_fixup_desc fixup =
{
sign0, src0,
sign1, src1,
sign2, src2,
sign3, src3,
};
return fixup;
}
static inline struct color_fixup_desc create_yuv_fixup_desc(enum yuv_fixup yuv_fixup)
{
struct color_fixup_desc fixup =
{
0, yuv_fixup & (1 << 0) ? CHANNEL_SOURCE_YUV1 : CHANNEL_SOURCE_YUV0,
0, yuv_fixup & (1 << 1) ? CHANNEL_SOURCE_YUV1 : CHANNEL_SOURCE_YUV0,
0, yuv_fixup & (1 << 2) ? CHANNEL_SOURCE_YUV1 : CHANNEL_SOURCE_YUV0,
0, yuv_fixup & (1 << 3) ? CHANNEL_SOURCE_YUV1 : CHANNEL_SOURCE_YUV0,
};
return fixup;
}
static inline BOOL is_identity_fixup(struct color_fixup_desc fixup)
{
return !memcmp(&fixup, &COLOR_FIXUP_IDENTITY, sizeof(fixup));
}
static inline BOOL is_yuv_fixup(struct color_fixup_desc fixup)
{
return fixup.x_source == CHANNEL_SOURCE_YUV0 || fixup.x_source == CHANNEL_SOURCE_YUV1;
}
static inline enum yuv_fixup get_yuv_fixup(struct color_fixup_desc fixup)
{
enum yuv_fixup yuv_fixup = 0;
if (fixup.x_source == CHANNEL_SOURCE_YUV1) yuv_fixup |= (1 << 0);
if (fixup.y_source == CHANNEL_SOURCE_YUV1) yuv_fixup |= (1 << 1);
if (fixup.z_source == CHANNEL_SOURCE_YUV1) yuv_fixup |= (1 << 2);
if (fixup.w_source == CHANNEL_SOURCE_YUV1) yuv_fixup |= (1 << 3);
return yuv_fixup;
}
/* Hash table functions */
typedef unsigned int (hash_function_t)(const void *key);
typedef BOOL (compare_function_t)(const void *keya, const void *keyb);
......@@ -350,7 +434,7 @@ typedef struct {
void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);
void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
void (*shader_cleanup)(IWineD3DDevice *iface);
void (*shader_color_correction)(const struct SHADER_OPCODE_ARG *arg);
void (*shader_color_correction)(const struct SHADER_OPCODE_ARG *arg, struct color_fixup_desc fixup);
void (*shader_destroy)(IWineD3DBaseShader *iface);
HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
void (*shader_free_private)(IWineD3DDevice *iface);
......@@ -358,7 +442,7 @@ typedef struct {
GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer);
void (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer);
void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps);
BOOL (*shader_conv_supported)(WINED3DFORMAT conv);
BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
} shader_backend_t;
extern const shader_backend_t glsl_shader_backend;
......@@ -655,7 +739,7 @@ struct fragment_pipeline {
void (*get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps);
HRESULT (*alloc_private)(IWineD3DDevice *iface);
void (*free_private)(IWineD3DDevice *iface);
BOOL (*conv_supported)(WINED3DFORMAT conv);
BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
const struct StateEntryTemplate *states;
BOOL ffp_proj_control;
};
......@@ -679,7 +763,7 @@ struct blit_shader {
void (*free_private)(IWineD3DDevice *iface);
HRESULT (*set_shader)(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum textype, UINT width, UINT height);
void (*unset_shader)(IWineD3DDevice *iface);
BOOL (*conv_supported)(WINED3DFORMAT conv);
BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
};
extern const struct blit_shader ffp_blit;
......@@ -852,17 +936,24 @@ enum dst_arg
/*****************************************************************************
* Fixed function pipeline replacements
*/
#define ARG_UNUSED 0x3f
struct texture_stage_op
{
unsigned cop : 5, aop : 5;
#define ARG_UNUSED 0x3f
unsigned carg1 : 6, carg2 : 6, carg0 : 6;
unsigned cop : 8;
unsigned carg1 : 8;
unsigned carg2 : 8;
unsigned carg0 : 8;
unsigned aop : 8;
unsigned aarg1 : 8;
unsigned aarg2 : 8;
unsigned aarg0 : 8;
struct color_fixup_desc color_correction;
unsigned tex_type : 3;
unsigned dst : 1; /* Total of 32 bits */
unsigned aarg1 : 6, aarg2 : 6, aarg0 : 6;
unsigned dst : 1;
unsigned projected : 2;
unsigned padding : 12; /* Total of 64 bits */
WINED3DFORMAT color_correction;
unsigned padding : 10;
};
struct ffp_frag_settings {
......@@ -1235,20 +1326,20 @@ typedef enum winetexturestates {
*/
typedef struct IWineD3DBaseTextureClass
{
DWORD states[MAX_WINETEXTURESTATES];
UINT levels;
BOOL dirty;
UINT textureName;
float pow2Matrix[16];
UINT LOD;
WINED3DTEXTUREFILTERTYPE filterType;
DWORD states[MAX_WINETEXTURESTATES];
LONG bindCount;
DWORD sampler;
BOOL is_srgb;
UINT srgb_mode_change_count;
WINED3DFORMAT shader_conversion_group;
float pow2Matrix[16];
const struct min_lookup *minMipLookup;
const GLenum *magLookup;
struct color_fixup_desc shader_color_fixup;
} IWineD3DBaseTextureClass;
typedef struct IWineD3DBaseTextureImpl
......@@ -1929,6 +2020,9 @@ const char *debug_glerror(GLenum error);
const char *debug_d3dbasis(WINED3DBASISTYPE basis);
const char *debug_d3ddegree(WINED3DDEGREETYPE order);
const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop);
const char *debug_fixup_channel_source(enum fixup_channel_source source);
const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup);
void dump_color_fixup_desc(struct color_fixup_desc fixup);
/* Routines for GL <-> D3D values */
GLenum StencilOp(DWORD op);
......@@ -2291,8 +2385,8 @@ struct stb_const_desc {
* into the shader code
*/
struct ps_compile_args {
struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS];
BOOL srgb_correction;
WINED3DFORMAT format_conversion[MAX_FRAGMENT_SAMPLERS];
enum vertexprocessing_mode vp_mode;
/* Projected textures(ps 1.0-1.3) */
/* Texture types(2D, Cube, 3D) in ps 1.x */
......@@ -2380,9 +2474,9 @@ struct GlPixelFormatDesc
GLint rtInternal;
GLint glFormat;
GLint glType;
WINED3DFORMAT conversion_group;
unsigned int Flags;
float heightscale;
struct color_fixup_desc color_fixup;
};
typedef struct {
......
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