wined3d: Move the shader version to reg_maps.

This commit is contained in:
Henri Verbeet 2008-12-15 12:10:14 +01:00 committed by Alexandre Julliard
parent dd094fe69d
commit 8553665cb1
7 changed files with 132 additions and 129 deletions

View File

@ -70,6 +70,7 @@ struct shader_arb_priv {
static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info,
GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
{
DWORD shader_version = This->baseShader.reg_maps.shader_version;
local_constant* lconst;
DWORD i, j;
unsigned int ret;
@ -83,8 +84,8 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, con
}
}
/* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */
if(target_type == GL_FRAGMENT_PROGRAM_ARB &&
WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1) {
if (target_type == GL_FRAGMENT_PROGRAM_ARB && WINED3DSHADER_VERSION_MAJOR(shader_version) == 1)
{
float lcl_const[4];
for(i = 0; i < max_constants; i++) {
if(!dirty_consts[i]) continue;
@ -232,7 +233,7 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
DWORD i, cur;
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
char pshader = shader_is_pshader_version(reg_maps->shader_version);
unsigned max_constantsF = min(This->baseShader.limits.constant_float,
(pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
UINT extra_constants_needed = 0;
@ -360,9 +361,8 @@ static const char * const shift_tab[] = {
static void shader_arb_get_write_mask(const SHADER_OPCODE_ARG *arg, const DWORD param, char *write_mask)
{
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) arg->shader;
char *ptr = write_mask;
char vshader = shader_is_vshader_version(This->baseShader.hex_version);
char vshader = shader_is_vshader_version(arg->reg_maps->shader_version);
if(vshader && shader_get_regtype(param) == WINED3DSPR_ADDR) {
*ptr++ = '.';
@ -787,7 +787,6 @@ static void pshader_hw_bem(const SHADER_OPCODE_ARG *arg)
static void pshader_hw_cnd(const SHADER_OPCODE_ARG *arg)
{
IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
SHADER_BUFFER* buffer = arg->buffer;
char dst_wmask[20];
char dst_name[50];
@ -807,8 +806,8 @@ static void pshader_hw_cnd(const SHADER_OPCODE_ARG *arg)
pshader_gen_input_modifier_line(arg->shader, buffer, arg->src[2], 2, src_name[2]);
/* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
if (shader->baseShader.hex_version <= WINED3DPS_VERSION(1, 3) &&
arg->opcode_token & WINED3DSI_COISSUE) {
if (arg->reg_maps->shader_version <= WINED3DPS_VERSION(1, 3) && arg->opcode_token & WINED3DSI_COISSUE)
{
shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]);
} else {
shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]);
@ -877,7 +876,6 @@ static void pshader_hw_dp2add(const SHADER_OPCODE_ARG *arg)
/* Map the opcode 1-to-1 to the GL code */
static void shader_hw_map2gl(const SHADER_OPCODE_ARG *arg)
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader;
CONST SHADER_OPCODE* curOpcode = arg->opcode;
SHADER_BUFFER* buffer = arg->buffer;
DWORD dst = arg->dst;
@ -885,7 +883,7 @@ static void shader_hw_map2gl(const SHADER_OPCODE_ARG *arg)
char arguments[256];
unsigned int i;
if (shader_is_pshader_version(shader->baseShader.hex_version))
if (shader_is_pshader_version(arg->reg_maps->shader_version))
{
/* Output token related */
char output_rname[256];
@ -963,8 +961,8 @@ static void shader_hw_mov(const SHADER_OPCODE_ARG *arg)
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader;
if ((WINED3DSHADER_VERSION_MAJOR(shader->baseShader.hex_version) == 1
&& !shader_is_pshader_version(shader->baseShader.hex_version)
if ((WINED3DSHADER_VERSION_MAJOR(arg->reg_maps->shader_version) == 1
&& !shader_is_pshader_version(arg->reg_maps->shader_version)
&& shader_get_regtype(arg->dst) == WINED3DSPR_ADDR)
|| arg->opcode->opcode == WINED3DSIO_MOVA)
{
@ -1008,8 +1006,7 @@ static void shader_hw_mov(const SHADER_OPCODE_ARG *arg)
static void pshader_hw_texkill(const SHADER_OPCODE_ARG *arg)
{
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
DWORD hex_version = This->baseShader.hex_version;
DWORD shader_version = arg->reg_maps->shader_version;
SHADER_BUFFER* buffer = arg->buffer;
char reg_dest[40];
@ -1018,7 +1015,8 @@ static void pshader_hw_texkill(const SHADER_OPCODE_ARG *arg)
*/
pshader_get_register_name(arg->shader, arg->dst, reg_dest);
if(hex_version >= WINED3DPS_VERSION(2,0)) {
if (shader_version >= WINED3DPS_VERSION(2,0))
{
/* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */
shader_addline(buffer, "KIL %s;\n", reg_dest);
} else {
@ -1039,7 +1037,7 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
DWORD dst = arg->dst;
const DWORD *src = arg->src;
SHADER_BUFFER* buffer = arg->buffer;
DWORD hex_version = This->baseShader.hex_version;
DWORD shader_version = arg->reg_maps->shader_version;
BOOL projected = FALSE, bias = FALSE;
char reg_dest[40];
@ -1053,14 +1051,14 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
/* 1.0-1.3: Use destination register as coordinate source.
1.4+: Use provided coordinate source register. */
if (hex_version < WINED3DPS_VERSION(1,4))
if (shader_version < WINED3DPS_VERSION(1,4))
strcpy(reg_coord, reg_dest);
else
pshader_gen_input_modifier_line(arg->shader, buffer, src[0], 0, reg_coord);
/* 1.0-1.4: Use destination register number as texture code.
2.0+: Use provided sampler number as texure code. */
if (hex_version < WINED3DPS_VERSION(2,0))
if (shader_version < WINED3DPS_VERSION(2,0))
reg_sampler_code = reg_dest_code;
else
reg_sampler_code = src[1] & WINED3DSP_REGNUM_MASK;
@ -1070,7 +1068,8 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
* 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0]
* 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode
*/
if(hex_version < WINED3DPS_VERSION(1,4)) {
if (shader_version < WINED3DPS_VERSION(1,4))
{
DWORD flags = 0;
if(reg_sampler_code < MAX_TEXTURES) {
flags = deviceImpl->stateBlock->textureState[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS];
@ -1078,7 +1077,9 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
if (flags & WINED3DTTFF_PROJECTED) {
projected = TRUE;
}
} else if(hex_version < WINED3DPS_VERSION(2,0)) {
}
else if (shader_version < WINED3DPS_VERSION(2,0))
{
DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK;
if (src_mod == WINED3DSPSM_DZ) {
projected = TRUE;
@ -1098,14 +1099,13 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
static void pshader_hw_texcoord(const SHADER_OPCODE_ARG *arg)
{
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
DWORD dst = arg->dst;
SHADER_BUFFER* buffer = arg->buffer;
DWORD hex_version = This->baseShader.hex_version;
char tmp[20];
shader_arb_get_write_mask(arg, dst, tmp);
if (hex_version != WINED3DPS_VERSION(1,4)) {
if (arg->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
{
DWORD reg = dst & WINED3DSP_REGNUM_MASK;
shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg);
} else {
@ -1487,7 +1487,7 @@ static void shader_hw_mnxn(const SHADER_OPCODE_ARG *arg)
SHADER_OPCODE_ARG tmpArg;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins;
DWORD shader_version = shader->baseShader.hex_version;
DWORD shader_version = arg->reg_maps->shader_version;
memset(&tmpArg, 0, sizeof(SHADER_OPCODE_ARG));
@ -1787,9 +1787,9 @@ static void shader_arb_cleanup(IWineD3DDevice *iface) {
static void shader_arb_destroy(IWineD3DBaseShader *iface) {
IWineD3DBaseShaderImpl *baseShader = (IWineD3DBaseShaderImpl *) iface;
const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.device)->adapter->gl_info;
char pshader = shader_is_pshader_version(baseShader->baseShader.hex_version);
if(pshader) {
if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version))
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
UINT i;
@ -1868,6 +1868,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
DWORD shader_version = reg_maps->shader_version;
const char *fragcolor;
const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
const local_constant *lconst;
@ -1890,9 +1891,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
/* We need two variables for fog blending */
shader_addline(buffer, "TEMP TMP_FOG;\n");
if (This->baseShader.hex_version >= WINED3DPS_VERSION(2,0)) {
shader_addline(buffer, "TEMP TMP_COLOR;\n");
}
if (shader_version >= WINED3DPS_VERSION(2,0)) shader_addline(buffer, "TEMP TMP_COLOR;\n");
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
@ -1903,15 +1902,13 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
*/
shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n");
if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
fragcolor = "R0";
} else {
fragcolor = "TMP_COLOR";
}
fragcolor = (shader_version < WINED3DPS_VERSION(2,0)) ? "R0" : "TMP_COLOR";
if(((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
}
if (This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) {
if (shader_version < WINED3DPS_VERSION(3,0))
{
shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, state.fog.color;\n", fragcolor);
shader_addline(buffer, "MOV result.color.a, %s.a;\n", fragcolor);
}

View File

@ -206,7 +206,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
{
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
DWORD shader_version = This->baseShader.hex_version;
DWORD shader_version;
unsigned int cur_loop_depth = 0, max_loop_depth = 0;
const DWORD* pToken = byte_code;
char pshader;
@ -236,8 +236,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
FIXME("First token is not a version token, invalid shader.\n");
return WINED3DERR_INVALIDCALL;
}
shader_version = *pToken++;
This->baseShader.hex_version = shader_version;
reg_maps->shader_version = shader_version = *pToken++;
pshader = shader_is_pshader_version(shader_version);
while (WINED3DVS_END() != *pToken) {
@ -302,7 +301,8 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
memcpy(lconst->value, pToken + 1, 4 * sizeof(DWORD));
/* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
if(WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 && pshader) {
if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1 && pshader)
{
float *value = (float *) lconst->value;
if(value[0] < -1.0) value[0] = -1.0;
else if(value[0] > 1.0) value[0] = 1.0;
@ -361,20 +361,20 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
int i, limit;
/* Declare 1.X samplers implicitly, based on the destination reg. number */
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 &&
pshader /* Filter different instructions with the same enum values in VS */ &&
(WINED3DSIO_TEX == curOpcode->opcode ||
WINED3DSIO_TEXBEM == curOpcode->opcode ||
WINED3DSIO_TEXBEML == curOpcode->opcode ||
WINED3DSIO_TEXDP3TEX == curOpcode->opcode ||
WINED3DSIO_TEXM3x2TEX == curOpcode->opcode ||
WINED3DSIO_TEXM3x3SPEC == curOpcode->opcode ||
WINED3DSIO_TEXM3x3TEX == curOpcode->opcode ||
WINED3DSIO_TEXM3x3VSPEC == curOpcode->opcode ||
WINED3DSIO_TEXREG2AR == curOpcode->opcode ||
WINED3DSIO_TEXREG2GB == curOpcode->opcode ||
WINED3DSIO_TEXREG2RGB == curOpcode->opcode)) {
if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1
&& pshader /* Filter different instructions with the same enum values in VS */
&& (WINED3DSIO_TEX == curOpcode->opcode
|| WINED3DSIO_TEXBEM == curOpcode->opcode
|| WINED3DSIO_TEXBEML == curOpcode->opcode
|| WINED3DSIO_TEXDP3TEX == curOpcode->opcode
|| WINED3DSIO_TEXM3x2TEX == curOpcode->opcode
|| WINED3DSIO_TEXM3x3SPEC == curOpcode->opcode
|| WINED3DSIO_TEXM3x3TEX == curOpcode->opcode
|| WINED3DSIO_TEXM3x3VSPEC == curOpcode->opcode
|| WINED3DSIO_TEXREG2AR == curOpcode->opcode
|| WINED3DSIO_TEXREG2GB == curOpcode->opcode
|| WINED3DSIO_TEXREG2RGB == curOpcode->opcode))
{
/* Fake sampler usage, only set reserved bit and ttype */
DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK;
@ -476,8 +476,9 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
* in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel shaders because TECRDOUT
* isn't used in them, but future register types might cause issues
*/
else if(WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */ &&
!pshader && WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) < 3) {
else if (WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */
&& !pshader && WINED3DSHADER_VERSION_MAJOR(shader_version) < 3)
{
reg_maps->texcoord_mask[reg] |= shader_get_writemask(param);
}
}
@ -832,7 +833,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */
const SHADER_OPCODE *opcode_table = This->baseShader.shader_ins;
const SHADER_HANDLER *handler_table = device->shader_backend->shader_instruction_handler_table;
DWORD shader_version = This->baseShader.hex_version;
DWORD shader_version = reg_maps->shader_version;
const DWORD *pToken = pFunction;
const SHADER_OPCODE *curOpcode = NULL;
SHADER_HANDLER hw_fct = NULL;

View File

@ -220,8 +220,9 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const Wine
}
/* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
if(WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 &&
shader_is_pshader_version(This->baseShader.hex_version)) {
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.reg_maps.shader_version) == 1
&& shader_is_pshader_version(This->baseShader.reg_maps.shader_version))
{
float lcl_const[4];
LIST_FOR_EACH_ENTRY(constant, constant_list, constants_entry, entry) {
@ -336,7 +337,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine
GLhandleARB tmp_loc;
unsigned int i;
char tmp_name[8];
char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version);
const char* prefix = is_pshader? "PB":"VB";
struct list* ptr;
@ -503,11 +504,12 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
{
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
DWORD shader_version = reg_maps->shader_version;
unsigned int i, extra_constants_needed = 0;
const local_constant *lconst;
/* There are some minor differences between pixel and vertex shaders */
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
char pshader = shader_is_pshader_version(shader_version);
char prefix = pshader ? 'P' : 'V';
/* Prototype the subroutines */
@ -541,7 +543,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
* out. The nvidia driver only does that if the parameter is inout instead of out, hence the
* inout.
*/
if(This->baseShader.hex_version >= WINED3DVS_VERSION(3, 0)) {
if (shader_version >= WINED3DVS_VERSION(3, 0))
{
shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", MAX_REG_OUTPUT);
} else {
shader_addline(buffer, "void order_ps_input();\n");
@ -642,7 +645,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
/* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the
* helper function shader that is linked in at link time
*/
if(pshader && This->baseShader.hex_version >= WINED3DPS_VERSION(3, 0)) {
if (pshader && shader_version >= WINED3DPS_VERSION(3, 0))
{
if(use_vs(device)) {
shader_addline(buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
} else {
@ -812,8 +816,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
DWORD shader_version = This->baseShader.reg_maps.shader_version;
char pshader = shader_is_pshader_version(shader_version);
char tmpStr[150];
*is_color = FALSE;
@ -825,7 +829,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
case WINED3DSPR_INPUT:
if (pshader) {
/* Pixel shaders >= 3.0 */
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3) {
if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3)
{
DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
if (param & WINED3DSHADER_ADDRMODE_RELATIVE) {
@ -885,7 +890,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
/* Relative addressing on shaders 2.0+ have a relative address token,
* prior to that, it was hard-coded as "A0.x" because there's only 1 register */
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2) {
if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2)
{
glsl_src_param_t rel_param;
shader_glsl_add_src_param(arg, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
if(reg) {
@ -964,10 +970,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
break;
case WINED3DSPR_TEXCRDOUT:
/* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3)
sprintf(tmpStr, "OUT[%u]", reg);
else
sprintf(tmpStr, "gl_TexCoord[%u]", reg);
if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(tmpStr, "OUT[%u]", reg);
else sprintf(tmpStr, "gl_TexCoord[%u]", reg);
break;
case WINED3DSPR_MISCTYPE:
if (reg == 0) {
@ -1316,7 +1320,6 @@ static void shader_glsl_arith(const SHADER_OPCODE_ARG *arg)
/* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
static void shader_glsl_mov(const SHADER_OPCODE_ARG *arg)
{
IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
SHADER_BUFFER* buffer = arg->buffer;
glsl_src_param_t src0_param;
DWORD write_mask;
@ -1326,9 +1329,10 @@ static void shader_glsl_mov(const SHADER_OPCODE_ARG *arg)
/* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later
* shader versions WINED3DSIO_MOVA is used for this. */
if ((WINED3DSHADER_VERSION_MAJOR(shader->baseShader.hex_version) == 1 &&
!shader_is_pshader_version(shader->baseShader.hex_version) &&
shader_get_regtype(arg->dst) == WINED3DSPR_ADDR)) {
if ((WINED3DSHADER_VERSION_MAJOR(arg->reg_maps->shader_version) == 1
&& !shader_is_pshader_version(arg->reg_maps->shader_version)
&& shader_get_regtype(arg->dst) == WINED3DSPR_ADDR))
{
/* This is a simple floor() */
unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
if (mask_size > 1) {
@ -1496,12 +1500,12 @@ static void shader_glsl_map2gl(const SHADER_OPCODE_ARG *arg)
*/
static void shader_glsl_expp(const SHADER_OPCODE_ARG *arg)
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
glsl_src_param_t src_param;
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src_param);
if (shader->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
if (arg->reg_maps->shader_version < WINED3DPS_VERSION(2,0))
{
char dst_mask[6];
shader_addline(arg->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
@ -1692,14 +1696,14 @@ static void shader_glsl_cmp(const SHADER_OPCODE_ARG *arg)
* the compare is done per component of src0. */
static void shader_glsl_cnd(const SHADER_OPCODE_ARG *arg)
{
IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
glsl_src_param_t src2_param;
DWORD write_mask, cmp_channel = 0;
unsigned int i, j;
if (shader->baseShader.hex_version < WINED3DPS_VERSION(1, 4)) {
if (arg->reg_maps->shader_version < WINED3DPS_VERSION(1, 4))
{
write_mask = shader_glsl_append_dst(arg->buffer, arg);
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], write_mask, &src1_param);
@ -1758,7 +1762,7 @@ static void shader_glsl_mnxn(const SHADER_OPCODE_ARG *arg)
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins;
DWORD shader_version = shader->baseShader.hex_version;
DWORD shader_version = arg->reg_maps->shader_version;
int i;
int nComponents = 0;
SHADER_OPCODE_ARG tmpArg;
@ -2094,7 +2098,7 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
{
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
DWORD hex_version = This->baseShader.hex_version;
DWORD shader_version = arg->reg_maps->shader_version;
char dst_swizzle[6];
glsl_sample_function_t sample_function;
DWORD sampler_type;
@ -2107,14 +2111,12 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
/* 1.0-1.4: Use destination register as sampler source.
* 2.0+: Use provided sampler source. */
if (hex_version < WINED3DPS_VERSION(2,0)) {
sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
} else {
sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
}
if (shader_version < WINED3DPS_VERSION(2,0)) sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
else sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
if (hex_version < WINED3DPS_VERSION(1,4)) {
if (shader_version < WINED3DPS_VERSION(1,4))
{
DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
/* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
@ -2130,7 +2132,9 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
} else {
projected = FALSE;
}
} else if (hex_version < WINED3DPS_VERSION(2,0)) {
}
else if (shader_version < WINED3DPS_VERSION(2,0))
{
DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK;
if (src_mod == WINED3DSPSM_DZ) {
@ -2160,15 +2164,13 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
shader_glsl_get_sample_function(sampler_type, projected, texrect, &sample_function);
mask |= sample_function.coord_mask;
if (hex_version < WINED3DPS_VERSION(2,0)) {
shader_glsl_get_write_mask(arg->dst, dst_swizzle);
} else {
shader_glsl_get_swizzle(arg->src[1], FALSE, arg->dst, dst_swizzle);
}
if (shader_version < WINED3DPS_VERSION(2,0)) shader_glsl_get_write_mask(arg->dst, dst_swizzle);
else shader_glsl_get_swizzle(arg->src[1], FALSE, arg->dst, dst_swizzle);
/* 1.0-1.3: Use destination register as coordinate source.
1.4+: Use provided coordinate source register. */
if (hex_version < WINED3DPS_VERSION(1,4)) {
if (shader_version < WINED3DPS_VERSION(1,4))
{
char coord_mask[6];
shader_glsl_get_write_mask(mask, coord_mask);
shader_addline(arg->buffer, "%s(Psampler%u, T%u%s)%s);\n",
@ -2214,7 +2216,8 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg)
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param);
if (shader_is_pshader_version(This->baseShader.hex_version)) {
if (shader_is_pshader_version(arg->reg_maps->shader_version))
{
/* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
* However, they seem to work just fine in fragment shaders as well. */
WARN("Using %sLod in fragment shader.\n", sample_function.name);
@ -2229,17 +2232,15 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg)
static void pshader_glsl_texcoord(const SHADER_OPCODE_ARG *arg)
{
/* FIXME: Make this work for more than just 2D textures */
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
SHADER_BUFFER* buffer = arg->buffer;
DWORD hex_version = This->baseShader.hex_version;
DWORD write_mask;
char dst_mask[6];
write_mask = shader_glsl_append_dst(arg->buffer, arg);
shader_glsl_get_write_mask(write_mask, dst_mask);
if (hex_version != WINED3DPS_VERSION(1,4)) {
if (arg->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
{
DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n", reg, dst_mask);
} else {
@ -2663,13 +2664,12 @@ static void pshader_glsl_texreg2rgb(const SHADER_OPCODE_ARG *arg)
* If any of the first 3 components are < 0, discard this pixel */
static void pshader_glsl_texkill(const SHADER_OPCODE_ARG *arg)
{
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
DWORD hex_version = This->baseShader.hex_version;
glsl_dst_param_t dst_param;
/* The argument is a destination parameter, and no writemasks are allowed */
shader_glsl_add_dst_param(arg, arg->dst, 0, &dst_param);
if((hex_version >= WINED3DPS_VERSION(2,0))) {
if ((arg->reg_maps->shader_version >= WINED3DPS_VERSION(2,0)))
{
/* 2.0 shaders compare all 4 components in texkill */
shader_addline(arg->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
} else {
@ -2957,8 +2957,8 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pixelshader;
IWineD3DDeviceImpl *device;
DWORD vs_major = WINED3DSHADER_VERSION_MAJOR(vs->baseShader.hex_version);
DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.hex_version) : 0;
DWORD vs_major = WINED3DSHADER_VERSION_MAJOR(vs->baseShader.reg_maps.shader_version);
DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.reg_maps.shader_version) : 0;
unsigned int i;
SHADER_BUFFER buffer;
DWORD usage_token;
@ -3270,8 +3270,10 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
checkGLcall("Find glsl program uniform locations");
if (pshader && WINED3DSHADER_VERSION_MAJOR(((IWineD3DPixelShaderImpl *)pshader)->baseShader.hex_version) >= 3
&& ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4) {
if (pshader
&& WINED3DSHADER_VERSION_MAJOR(((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version) >= 3
&& ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4)
{
TRACE("Shader %d needs vertex color clamping disabled\n", programId);
entry->vertex_color_clamp = GL_FALSE;
} else {
@ -3462,7 +3464,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
/* Note: Do not use QueryInterface here to find out which shader type this is because this code
* can be called from IWineD3DBaseShader::Release
*/
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version);
if(pshader) {
ps = (IWineD3DPixelShaderImpl *) This;
@ -3596,8 +3598,8 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
/* Pack 3.0 inputs */
if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
if (reg_maps->shader_version >= WINED3DPS_VERSION(3,0))
{
if(((IWineD3DDeviceImpl *) This->baseShader.device)->strided_streams.u.s.position_transformed) {
pshader_glsl_input_pack(buffer, This->semantics_in, iface, pretransformed);
} else if(!use_vs((IWineD3DDeviceImpl *) This->baseShader.device)) {
@ -3609,7 +3611,8 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
if (reg_maps->shader_version < WINED3DPS_VERSION(2,0))
{
/* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
if(GL_SUPPORT(ARB_DRAW_BUFFERS))
shader_addline(buffer, "gl_FragData[0] = R0;\n");
@ -3638,7 +3641,8 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
* NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
* -1/(e-s) and e/(e-s) respectively.
*/
if(This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) {
if (reg_maps->shader_version < WINED3DPS_VERSION(3,0))
{
shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");
shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
}
@ -3672,11 +3676,8 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
/* Unpack 3.0 outputs */
if (This->baseShader.hex_version >= WINED3DVS_VERSION(3,0)) {
shader_addline(buffer, "order_ps_input(OUT);\n");
} else {
shader_addline(buffer, "order_ps_input();\n");
}
if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n");
else shader_addline(buffer, "order_ps_input();\n");
/* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */
if (!reg_maps->fog)

View File

@ -226,7 +226,8 @@ static void pshader_set_limits(
This->baseShader.limits.address = 0;
This->baseShader.limits.packed_output = 0;
switch (This->baseShader.hex_version) {
switch (This->baseShader.reg_maps.shader_version)
{
case WINED3DPS_VERSION(1,0):
case WINED3DPS_VERSION(1,1):
case WINED3DPS_VERSION(1,2):
@ -293,8 +294,8 @@ static void pshader_set_limits(
This->baseShader.limits.sampler = 16;
This->baseShader.limits.packed_input = 0;
This->baseShader.limits.label = 0;
FIXME("Unrecognized pixel shader version %#x\n",
This->baseShader.hex_version);
FIXME("Unrecognized pixel shader version %#x\n",
This->baseShader.reg_maps.shader_version);
}
}
@ -395,9 +396,9 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
return WINED3D_OK;
}
static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures,
DWORD shader_version)
static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures)
{
DWORD shader_version = reg_maps->shader_version;
DWORD *samplers = reg_maps->samplers;
unsigned int i;
@ -448,7 +449,7 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
TRACE("(%p) : function %p\n", This, function);
pixelshader_update_samplers(&This->baseShader.reg_maps,
((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures, This->baseShader.hex_version);
((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures);
/* Reset fields tracking stateblock values being hardcoded in the shader */
This->baseShader.num_sampled_samplers = 0;
@ -493,7 +494,8 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
}
args->color_fixup[sampler] = tex->baseTexture.shader_color_fixup;
}
if(shader->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
if (shader->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0))
{
if(((IWineD3DDeviceImpl *) shader->baseShader.device)->strided_streams.u.s.position_transformed) {
args->vp_mode = pretransformed;
} else if(use_vs((IWineD3DDeviceImpl *) shader->baseShader.device)) {

View File

@ -901,8 +901,9 @@ static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock,
static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *)stateblock->pixelShader;
BOOL is_ps3 = use_ps(stateblock->wineD3DDevice)
&& ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version >= WINED3DPS_VERSION(3,0);
&& ps_impl->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0);
float fogstart, fogend;
union {
@ -914,8 +915,9 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
/* No fog? Disable it, and we're done :-) */
glDisable(GL_FOG);
checkGLcall("glDisable GL_FOG");
if( use_ps(stateblock->wineD3DDevice)
&& ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version < WINED3DPS_VERSION(3,0) ) {
if (use_ps(stateblock->wineD3DDevice)
&& ps_impl->baseShader.reg_maps.shader_version < WINED3DPS_VERSION(3,0))
{
/* disable fog in the pixel shader
* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
* -1/(e-s) and e/(e-s) respectively.

View File

@ -120,7 +120,8 @@ static void vshader_set_limits(
/* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF);
switch (This->baseShader.hex_version) {
switch (This->baseShader.reg_maps.shader_version)
{
case WINED3DVS_VERSION(1,0):
case WINED3DVS_VERSION(1,1):
This->baseShader.limits.temporary = 12;
@ -161,7 +162,7 @@ static void vshader_set_limits(
This->baseShader.limits.sampler = 0;
This->baseShader.limits.label = 16;
FIXME("Unrecognized vertex shader version %#x\n",
This->baseShader.hex_version);
This->baseShader.reg_maps.shader_version);
}
}

View File

@ -2067,7 +2067,7 @@ typedef struct local_constant {
} local_constant;
typedef struct shader_reg_maps {
DWORD shader_version;
char texcoord[MAX_REG_TEXCRD]; /* pixel < 3.0 */
char temporary[MAX_REG_TEMP]; /* pixel, vertex */
char address[MAX_REG_ADDR]; /* vertex */
@ -2185,7 +2185,6 @@ extern void shader_glsl_add_instruction_modifiers(const SHADER_OPCODE_ARG *arg);
typedef struct IWineD3DBaseShaderClass
{
LONG ref;
DWORD hex_version;
SHADER_LIMITS limits;
SHADER_PARSE_STATE parse_state;
CONST SHADER_OPCODE *shader_ins;