wined3d: Unified float constant register mapping between ARB pixel and vertex shaders.
- Got rid of the separate constant maps. - Side effect of this is that the map is a bit larger for pixel shaders than it needs to be
This commit is contained in:
parent
0c59ca6448
commit
ca70d13af4
|
@ -614,9 +614,11 @@ void generate_base_shader(
|
|||
DWORD opcode_token;
|
||||
DWORD i;
|
||||
shader_reg_maps reg_maps;
|
||||
SHADER_OPCODE_ARG hw_arg;
|
||||
|
||||
memset(®_maps, 0, sizeof(shader_reg_maps));
|
||||
|
||||
/* Initialize current parsing state */
|
||||
SHADER_OPCODE_ARG hw_arg;
|
||||
hw_arg.shader = iface;
|
||||
hw_arg.buffer = buffer;
|
||||
hw_arg.reg_maps = ®_maps;
|
||||
|
@ -746,4 +748,20 @@ void shader_dump_ins_modifiers(const DWORD output) {
|
|||
FIXME("_unrecognized_modifier(%#lx)", mmask >> D3DSP_DSTMOD_SHIFT);
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_DCL opcode into an ARB string - creates a local vec4
|
||||
* float constant, and stores it's usage on the regmaps. */
|
||||
void shader_hw_def(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
DWORD reg = arg->dst;
|
||||
|
||||
shader_addline(arg->buffer,
|
||||
"PARAM C%lu = { %f, %f, %f, %f };\n", reg & 0xFF,
|
||||
*((const float *)(arg->src + 0)),
|
||||
*((const float *)(arg->src + 1)),
|
||||
*((const float *)(arg->src + 2)),
|
||||
*((const float *)(arg->src + 3)) );
|
||||
|
||||
arg->reg_maps->constantsF[reg] = 1;
|
||||
}
|
||||
|
||||
/* TODO: Move other shared code here */
|
||||
|
|
|
@ -621,7 +621,6 @@ void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg);
|
|||
void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg);
|
||||
void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg);
|
||||
void pshader_hw_texbem(SHADER_OPCODE_ARG* arg);
|
||||
void pshader_hw_def(SHADER_OPCODE_ARG* arg);
|
||||
void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg);
|
||||
void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg);
|
||||
void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg);
|
||||
|
@ -705,7 +704,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
|
|||
{D3DSIO_LABEL, "label", GLNAME_REQUIRE_GLSL, 1, pshader_label, NULL, NULL, 0, 0},
|
||||
|
||||
/* Constant definitions */
|
||||
{D3DSIO_DEF, "def", "undefined", 5, pshader_def, pshader_hw_def, NULL, 0, 0},
|
||||
{D3DSIO_DEF, "def", "undefined", 5, pshader_def, shader_hw_def, NULL, 0, 0},
|
||||
{D3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 2, pshader_defb, NULL, NULL, 0, 0},
|
||||
{D3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 5, pshader_defi, NULL, NULL, 0, 0},
|
||||
|
||||
|
@ -744,7 +743,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
|
|||
{0, NULL, NULL, 0, NULL, NULL, 0, 0}
|
||||
};
|
||||
|
||||
inline static void get_register_name(const DWORD param, char* regstr, char constants[WINED3D_PSHADER_MAX_CONSTANTS]) {
|
||||
inline static void get_register_name(const DWORD param, char* regstr, CHAR *constants) {
|
||||
|
||||
DWORD reg = param & D3DSP_REGNUM_MASK;
|
||||
DWORD regtype = shader_get_regtype(param);
|
||||
|
@ -868,7 +867,7 @@ static void pshader_gen_input_modifier_line (
|
|||
const DWORD instr,
|
||||
int tmpreg,
|
||||
char *outregstr,
|
||||
char constants[WINED3D_PSHADER_MAX_CONSTANTS]) {
|
||||
CHAR *constants) {
|
||||
|
||||
/* Generate a line that does the input modifier computation and return the input register to use */
|
||||
char regstr[256];
|
||||
|
@ -991,7 +990,6 @@ void pshader_set_version(
|
|||
/* FIXME: fix CMP/CND, get rid of this switch */
|
||||
void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||
CONST SHADER_OPCODE* curOpcode = arg->opcode;
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
DWORD dst = arg->dst;
|
||||
|
@ -1033,10 +1031,10 @@ void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg) {
|
|||
|
||||
/* Generate input register names (with modifiers) */
|
||||
for (i = 1; i < curOpcode->num_params; ++i)
|
||||
pshader_gen_input_modifier_line(buffer, src[i-1], i-1, operands[i], This->constants);
|
||||
pshader_gen_input_modifier_line(buffer, src[i-1], i-1, operands[i], arg->reg_maps->constantsF);
|
||||
|
||||
/* Handle output register */
|
||||
get_register_name(dst, output_rname, This->constants);
|
||||
get_register_name(dst, output_rname, arg->reg_maps->constantsF);
|
||||
strcpy(operands[0], output_rname);
|
||||
get_write_mask(dst, output_wmask);
|
||||
strcat(operands[0], output_wmask);
|
||||
|
@ -1086,14 +1084,14 @@ void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
|
|||
|
||||
/* All versions have a destination register */
|
||||
reg_dest_code = dst & D3DSP_REGNUM_MASK;
|
||||
get_register_name(dst, reg_dest, This->constants);
|
||||
get_register_name(dst, reg_dest, arg->reg_maps->constantsF);
|
||||
|
||||
/* 1.0-1.3: Use destination register as coordinate source.
|
||||
2.0+: Use provided coordinate source register. */
|
||||
if (version < 14)
|
||||
strcpy(reg_coord, reg_dest);
|
||||
else
|
||||
pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord, This->constants);
|
||||
pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord, arg->reg_maps->constantsF);
|
||||
|
||||
/* 1.0-1.4: Use destination register number as texture code.
|
||||
2.0+: Use provided sampler number as texure code. */
|
||||
|
@ -1160,41 +1158,23 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
|
|||
shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg1, reg1);
|
||||
}
|
||||
|
||||
void pshader_hw_def(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||
DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
|
||||
shader_addline(buffer,
|
||||
"PARAM C%lu = { %f, %f, %f, %f };\n", reg,
|
||||
*((float*) (arg->src + 0)),
|
||||
*((float*) (arg->src + 1)),
|
||||
*((float*) (arg->src + 2)),
|
||||
*((float*) (arg->src + 3)) );
|
||||
|
||||
shader->constants[reg] = 1;
|
||||
}
|
||||
|
||||
void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||
DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
shader_addline(buffer, "DP3 TMP.x, T%lu, %s;\n", reg, src0_name);
|
||||
}
|
||||
|
||||
void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||
DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
shader_addline(buffer, "DP3 TMP.y, T%lu, %s;\n", reg, src0_name);
|
||||
shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg, reg);
|
||||
}
|
||||
|
@ -1207,7 +1187,7 @@ void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) {
|
|||
SHADER_PARSE_STATE current_state = shader->baseShader.parse_state;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
shader_addline(buffer, "DP3 TMP.%c, T%lu, %s;\n", 'x' + current_state.current_row, reg, src0_name);
|
||||
current_state.texcoord_w[current_state.current_row++] = reg;
|
||||
}
|
||||
|
@ -1220,7 +1200,7 @@ void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) {
|
|||
SHADER_PARSE_STATE current_state = shader->baseShader.parse_state;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name);
|
||||
|
||||
/* Cubemap textures will be more used than 3D ones. */
|
||||
|
@ -1236,7 +1216,7 @@ void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
|
|||
SHADER_PARSE_STATE current_state = shader->baseShader.parse_state;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name);
|
||||
|
||||
/* Construct the eye-ray vector from w coordinates */
|
||||
|
@ -1263,7 +1243,7 @@ void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) {
|
|||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name);
|
||||
|
||||
/* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
|
||||
|
|
|
@ -480,7 +480,6 @@ void vshader_texldl(WINED3DSHADERVECTOR* d) {
|
|||
/* Prototype */
|
||||
void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg);
|
||||
void vshader_hw_dcl(SHADER_OPCODE_ARG* arg);
|
||||
void vshader_hw_def(SHADER_OPCODE_ARG* arg);
|
||||
void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg);
|
||||
|
||||
/**
|
||||
|
@ -543,7 +542,7 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
|
|||
{D3DSIO_DCL, "dcl", NULL, 2, vshader_dcl, vshader_hw_dcl, NULL, 0, 0},
|
||||
|
||||
/* Constant definitions */
|
||||
{D3DSIO_DEF, "def", NULL, 5, vshader_def, vshader_hw_def, NULL, 0, 0},
|
||||
{D3DSIO_DEF, "def", NULL, 5, vshader_def, shader_hw_def, NULL, 0, 0},
|
||||
{D3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 2, vshader_defb, NULL, NULL, 0, 0},
|
||||
{D3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 5, vshader_defi, NULL, NULL, 0, 0},
|
||||
|
||||
|
@ -631,7 +630,10 @@ inline static void vshader_program_add_input_param_swizzle(const DWORD param, in
|
|||
}
|
||||
}
|
||||
|
||||
inline static void vshader_program_add_param(IWineD3DVertexShaderImpl *This, const DWORD param, BOOL is_input, char *hwLine) {
|
||||
inline static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, BOOL is_input, char *hwLine) {
|
||||
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)arg->shader;
|
||||
|
||||
/* oPos, oFog and oPts in D3D */
|
||||
static const char* hwrastout_reg_names[] = { "result.position", "result.fogcoord", "result.pointsize" };
|
||||
|
||||
|
@ -667,7 +669,7 @@ inline static void vshader_program_add_param(IWineD3DVertexShaderImpl *This, con
|
|||
break;
|
||||
case D3DSPR_CONST:
|
||||
/* FIXME: some constants are named so we need a constants map*/
|
||||
if (This->constantsUsedBitmap[reg] == VS_CONSTANT_CONSTANT) {
|
||||
if (arg->reg_maps->constantsF[reg]) {
|
||||
if (param & D3DVS_ADDRMODE_RELATIVE) {
|
||||
FIXME("Relative addressing not expected for a named constant %lu\n", reg);
|
||||
}
|
||||
|
@ -879,7 +881,6 @@ void vshader_set_version(
|
|||
/* Map the opcode 1-to-1 to the GL code */
|
||||
void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) arg->shader;
|
||||
CONST SHADER_OPCODE* curOpcode = arg->opcode;
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
DWORD dst = arg->dst;
|
||||
|
@ -895,10 +896,10 @@ void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg) {
|
|||
strcpy(tmpLine, curOpcode->glname);
|
||||
|
||||
if (curOpcode->num_params > 0) {
|
||||
vshader_program_add_param(This, dst, FALSE, tmpLine);
|
||||
vshader_program_add_param(arg, dst, FALSE, tmpLine);
|
||||
for (i = 1; i < curOpcode->num_params; ++i) {
|
||||
strcat(tmpLine, ",");
|
||||
vshader_program_add_param(This, src[i-1], TRUE, tmpLine);
|
||||
vshader_program_add_param(arg, src[i-1], TRUE, tmpLine);
|
||||
}
|
||||
}
|
||||
shader_addline(buffer, "%s;\n", tmpLine);
|
||||
|
@ -972,29 +973,13 @@ void vshader_hw_dcl(SHADER_OPCODE_ARG* arg) {
|
|||
}
|
||||
{
|
||||
sprintf(tmpLine, "ATTRIB ");
|
||||
vshader_program_add_param(This, dst, FALSE, tmpLine);
|
||||
vshader_program_add_param(arg, dst, FALSE, tmpLine);
|
||||
if (This->namedArrays)
|
||||
shader_addline(buffer, "%s = %s;\n", tmpLine, attribName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vshader_hw_def(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
IWineD3DVertexShaderImpl* shader = (IWineD3DVertexShaderImpl*) arg->shader;
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
DWORD reg = arg->dst;
|
||||
|
||||
shader_addline(buffer,
|
||||
"PARAM C%lu = { %f, %f, %f, %f };\n", reg & 0xFF,
|
||||
*((const float *)(arg->src + 0)),
|
||||
*((const float *)(arg->src + 1)),
|
||||
*((const float *)(arg->src + 2)),
|
||||
*((const float *)(arg->src + 3)) );
|
||||
|
||||
shader->constantsUsedBitmap[reg & 0xFF] = VS_CONSTANT_CONSTANT;
|
||||
}
|
||||
|
||||
/** Handles transforming all D3DSIO_M?x? opcodes for
|
||||
Vertex shaders to ARB_vertex_program codes */
|
||||
void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg) {
|
||||
|
@ -1004,10 +989,11 @@ void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg) {
|
|||
SHADER_OPCODE_ARG tmpArg;
|
||||
|
||||
/* Set constants for the temporary argument */
|
||||
tmpArg.shader = arg->shader;
|
||||
tmpArg.buffer = arg->buffer;
|
||||
tmpArg.src[0] = arg->src[0];
|
||||
|
||||
tmpArg.shader = arg->shader;
|
||||
tmpArg.buffer = arg->buffer;
|
||||
tmpArg.src[0] = arg->src[0];
|
||||
tmpArg.reg_maps = arg->reg_maps;
|
||||
|
||||
switch(arg->opcode->opcode) {
|
||||
case D3DSIO_M4x4:
|
||||
nComponents = 4;
|
||||
|
|
|
@ -1233,18 +1233,6 @@ void multiply_matrix(D3DMATRIX *dest, D3DMATRIX *src1, D3DMATRIX *src2);
|
|||
/*** class static members ***/
|
||||
void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface);
|
||||
|
||||
/* An enum for the type of constants that are used... addressing causes
|
||||
* problems with being able to work out what's used and what's not.. so
|
||||
* maybe we'll have to rely on the server vertex shader const functions?
|
||||
*/
|
||||
enum vsConstantsEnum {
|
||||
VS_CONSTANT_NOT_USED = 0,
|
||||
VS_CONSTANT_CONSTANT,
|
||||
VS_CONSTANT_INTEGER,
|
||||
VS_CONSTANT_BOOLEAN,
|
||||
VS_CONSTANT_FLOAT
|
||||
};
|
||||
|
||||
struct SHADER_OPCODE_ARG;
|
||||
typedef void (*shader_fct_t)();
|
||||
typedef void (*SHADER_HANDLER) (struct SHADER_OPCODE_ARG*);
|
||||
|
@ -1326,6 +1314,9 @@ extern const SHADER_OPCODE* shader_get_opcode(
|
|||
IWineD3DBaseShader *iface,
|
||||
const DWORD code);
|
||||
|
||||
/* ARB shader program Prototypes */
|
||||
extern void shader_hw_def(SHADER_OPCODE_ARG *arg);
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DBaseShader implementation structure
|
||||
*/
|
||||
|
@ -1422,9 +1413,7 @@ typedef struct IWineD3DVertexShaderImpl {
|
|||
BOOL namedArrays; /* don't map use named functions */
|
||||
BOOL declaredArrays; /* mapping requires */
|
||||
INT arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE]; /* lookup table for the maps */
|
||||
INT highestConstant;
|
||||
CHAR constantsUsedBitmap[256];
|
||||
/* FIXME: This needs to be populated with some flags of VS_CONSTANT_NOT_USED, VS_CONSTANT_CONSTANT, VS_CONSTANT_INTEGER, VS_CONSTANT_BOOLEAN, VS_CONSTANT_FLOAT, a half byte bitmap will be the best option, but I'll keep it as chards for siplicity */
|
||||
|
||||
/* run time datas... */
|
||||
VSHADERDATA *data;
|
||||
IWineD3DVertexDeclaration *vertexDeclaration;
|
||||
|
@ -1452,8 +1441,6 @@ typedef struct IWineD3DPixelShaderImpl {
|
|||
IUnknown *parent;
|
||||
IWineD3DDeviceImpl *wineD3DDevice;
|
||||
|
||||
CHAR constants[WINED3D_PSHADER_MAX_CONSTANTS];
|
||||
|
||||
/* run time data */
|
||||
PSHADERDATA *data;
|
||||
|
||||
|
|
Loading…
Reference in New Issue