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:
Jason Green 2006-06-09 03:33:33 -04:00 committed by Alexandre Julliard
parent 0c59ca6448
commit ca70d13af4
4 changed files with 50 additions and 79 deletions

View File

@ -614,9 +614,11 @@ void generate_base_shader(
DWORD opcode_token;
DWORD i;
shader_reg_maps reg_maps;
SHADER_OPCODE_ARG hw_arg;
memset(&reg_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 = &reg_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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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;