wined3d: Place immediate constants in the same array as global constants.
- move DEF, DEFI, DEFB handling into the register counting pass - keep track of defined constants as a linked list (because there's a few of them) - apply immediate constants after global constants in the constant loading function - both types of constants now get loaded with array notation in the shader (into the same array)
This commit is contained in:
parent
915174d8d9
commit
e9de563e41
|
@ -46,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
|||
* or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
|
||||
*/
|
||||
void shader_arb_load_constantsF(
|
||||
IWineD3DBaseShaderImpl* This,
|
||||
WineD3D_GL_Info *gl_info,
|
||||
GLuint target_type,
|
||||
unsigned max_constants,
|
||||
|
@ -53,6 +54,7 @@ void shader_arb_load_constantsF(
|
|||
BOOL* constants_set) {
|
||||
|
||||
int i;
|
||||
struct list* ptr;
|
||||
|
||||
for (i=0; i<max_constants; ++i) {
|
||||
if (NULL == constants_set || constants_set[i]) {
|
||||
|
@ -64,6 +66,22 @@ void shader_arb_load_constantsF(
|
|||
checkGLcall("glProgramEnvParameter4fvARB");
|
||||
}
|
||||
}
|
||||
|
||||
/* Load immediate constants */
|
||||
ptr = list_head(&This->baseShader.constantsF);
|
||||
while (ptr) {
|
||||
|
||||
local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
|
||||
unsigned int idx = lconst->idx;
|
||||
GLfloat* values = (GLfloat*) lconst->value;
|
||||
|
||||
TRACE("Loading local constants %i: %f, %f, %f, %f\n", idx,
|
||||
values[0], values[1], values[2], values[3]);
|
||||
|
||||
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, idx, values));
|
||||
checkGLcall("glProgramEnvParameter4fvARB");
|
||||
ptr = list_next(&This->baseShader.constantsF, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,19 +99,20 @@ void shader_arb_load_constants(
|
|||
WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
|
||||
|
||||
if (useVertexShader) {
|
||||
IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
|
||||
IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
|
||||
IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
|
||||
IWineD3DVertexDeclarationImpl* vertexDeclaration =
|
||||
(IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
|
||||
(IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
|
||||
|
||||
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
|
||||
/* Load DirectX 8 float constants for vertex shader */
|
||||
shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
|
||||
shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
|
||||
WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
vertexDeclaration->constants, NULL);
|
||||
}
|
||||
|
||||
/* Load DirectX 9 float constants for vertex shader */
|
||||
shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
|
||||
shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
|
||||
WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
stateBlock->vertexShaderConstantF,
|
||||
stateBlock->set.vertexShaderConstantsF);
|
||||
|
@ -101,8 +120,10 @@ void shader_arb_load_constants(
|
|||
|
||||
if (usePixelShader) {
|
||||
|
||||
IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
|
||||
|
||||
/* Load DirectX 9 float constants for pixel shader */
|
||||
shader_arb_load_constantsF(gl_info, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
|
||||
shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
|
||||
stateBlock->pixelShaderConstantF,
|
||||
stateBlock->set.pixelShaderConstantsF);
|
||||
}
|
||||
|
@ -264,7 +285,8 @@ static void vshader_program_add_input_param_swizzle(const DWORD param, int is_co
|
|||
}
|
||||
}
|
||||
|
||||
static void pshader_get_register_name(const DWORD param, char* regstr, CHAR *constants) {
|
||||
static void pshader_get_register_name(
|
||||
const DWORD param, char* regstr) {
|
||||
|
||||
DWORD reg = param & D3DSP_REGNUM_MASK;
|
||||
DWORD regtype = shader_get_regtype(param);
|
||||
|
@ -281,10 +303,7 @@ static void pshader_get_register_name(const DWORD param, char* regstr, CHAR *con
|
|||
}
|
||||
break;
|
||||
case D3DSPR_CONST:
|
||||
if (constants[reg])
|
||||
sprintf(regstr, "C%lu", reg);
|
||||
else
|
||||
sprintf(regstr, "C[%lu]", reg);
|
||||
sprintf(regstr, "C[%lu]", reg);
|
||||
break;
|
||||
case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */
|
||||
sprintf(regstr,"T%lu", reg);
|
||||
|
@ -347,15 +366,7 @@ static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param,
|
|||
strcat(hwLine, tmpReg);
|
||||
break;
|
||||
case D3DSPR_CONST:
|
||||
/* FIXME: some constants are named so we need a constants map*/
|
||||
if (arg->reg_maps->constantsF[reg]) {
|
||||
if (param & D3DVS_ADDRMODE_RELATIVE) {
|
||||
FIXME("Relative addressing not expected for a named constant %lu\n", reg);
|
||||
}
|
||||
sprintf(tmpReg, "C%lu", reg);
|
||||
} else {
|
||||
sprintf(tmpReg, "C[%s%lu]", (param & D3DVS_ADDRMODE_RELATIVE) ? "A0.x + " : "", reg);
|
||||
}
|
||||
sprintf(tmpReg, "C[%s%lu]", (param & D3DVS_ADDRMODE_RELATIVE) ? "A0.x + " : "", reg);
|
||||
strcat(hwLine, tmpReg);
|
||||
break;
|
||||
case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/
|
||||
|
@ -394,8 +405,7 @@ static void pshader_gen_input_modifier_line (
|
|||
SHADER_BUFFER* buffer,
|
||||
const DWORD instr,
|
||||
int tmpreg,
|
||||
char *outregstr,
|
||||
CHAR *constants) {
|
||||
char *outregstr) {
|
||||
|
||||
/* Generate a line that does the input modifier computation and return the input register to use */
|
||||
char regstr[256];
|
||||
|
@ -406,7 +416,7 @@ static void pshader_gen_input_modifier_line (
|
|||
insert_line = 1;
|
||||
|
||||
/* Get register name */
|
||||
pshader_get_register_name(instr, regstr, constants);
|
||||
pshader_get_register_name(instr, regstr);
|
||||
pshader_get_input_register_swizzle(instr, swzstr);
|
||||
|
||||
switch (instr & D3DSP_SRCMOD_MASK) {
|
||||
|
@ -469,22 +479,6 @@ inline static void pshader_gen_output_modifier_line(
|
|||
regstr, write_mask, regstr, shift_tab[shift]);
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_DEF 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 & D3DSP_REGNUM_MASK;
|
||||
|
||||
shader_addline(arg->buffer,
|
||||
"PARAM C%lu = { %f, %f, %f, %f };\n", reg,
|
||||
*((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;
|
||||
}
|
||||
|
||||
void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
|
@ -495,14 +489,14 @@ void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) {
|
|||
/* FIXME: support output modifiers */
|
||||
|
||||
/* Handle output register */
|
||||
pshader_get_register_name(arg->dst, dst_name, arg->reg_maps->constantsF);
|
||||
pshader_get_register_name(arg->dst, dst_name);
|
||||
pshader_get_write_mask(arg->dst, dst_wmask);
|
||||
strcat(dst_name, dst_wmask);
|
||||
|
||||
/* Generate input register names (with modifiers) */
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0], arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1], arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2], arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0]);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1]);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2]);
|
||||
|
||||
shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]);
|
||||
shader_addline(buffer, "CMP %s, TMP, %s, %s;\n", dst_name, src_name[1], src_name[2]);
|
||||
|
@ -518,14 +512,14 @@ void pshader_hw_cmp(SHADER_OPCODE_ARG* arg) {
|
|||
/* FIXME: support output modifiers */
|
||||
|
||||
/* Handle output register */
|
||||
pshader_get_register_name(arg->dst, dst_name, arg->reg_maps->constantsF);
|
||||
pshader_get_register_name(arg->dst, dst_name);
|
||||
pshader_get_write_mask(arg->dst, dst_wmask);
|
||||
strcat(dst_name, dst_wmask);
|
||||
|
||||
/* Generate input register names (with modifiers) */
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0], arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1], arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2], arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0]);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1]);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2]);
|
||||
|
||||
shader_addline(buffer, "CMP %s, %s, %s, %s;\n", dst_name,
|
||||
src_name[0], src_name[2], src_name[1]);
|
||||
|
@ -574,10 +568,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], arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, src[i-1], i-1, operands[i]);
|
||||
|
||||
/* Handle output register */
|
||||
pshader_get_register_name(dst, output_rname, arg->reg_maps->constantsF);
|
||||
pshader_get_register_name(dst, output_rname);
|
||||
strcpy(operands[0], output_rname);
|
||||
pshader_get_write_mask(dst, output_wmask);
|
||||
strcat(operands[0], output_wmask);
|
||||
|
@ -614,14 +608,14 @@ void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
|
|||
|
||||
/* All versions have a destination register */
|
||||
reg_dest_code = dst & D3DSP_REGNUM_MASK;
|
||||
pshader_get_register_name(dst, reg_dest, arg->reg_maps->constantsF);
|
||||
pshader_get_register_name(dst, reg_dest);
|
||||
|
||||
/* 1.0-1.3: Use destination register as coordinate source.
|
||||
1.4+: Use provided coordinate source register. */
|
||||
if (hex_version < D3DPS_VERSION(1,4))
|
||||
strcpy(reg_coord, reg_dest);
|
||||
else
|
||||
pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord, arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(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. */
|
||||
|
@ -693,7 +687,7 @@ void pshader_hw_texm3x2pad(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, arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
|
||||
shader_addline(buffer, "DP3 TMP.x, T%lu, %s;\n", reg, src0_name);
|
||||
}
|
||||
|
||||
|
@ -703,7 +697,7 @@ void pshader_hw_texm3x2tex(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, arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
|
||||
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);
|
||||
}
|
||||
|
@ -716,7 +710,7 @@ void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) {
|
|||
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
|
||||
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;
|
||||
}
|
||||
|
@ -729,7 +723,7 @@ void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) {
|
|||
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
|
||||
shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name);
|
||||
|
||||
/* Cubemap textures will be more used than 3D ones. */
|
||||
|
@ -745,7 +739,7 @@ void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
|
|||
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
|
||||
char src0_name[50];
|
||||
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
|
||||
shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name);
|
||||
|
||||
/* Construct the eye-ray vector from w coordinates */
|
||||
|
@ -772,7 +766,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, arg->reg_maps->constantsF);
|
||||
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
|
||||
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 */
|
||||
|
|
|
@ -174,7 +174,7 @@ unsigned int shader_get_float_offset(const DWORD reg) {
|
|||
/* Note that this does not count the loop register
|
||||
* as an address register. */
|
||||
|
||||
void shader_get_registers_used(
|
||||
HRESULT shader_get_registers_used(
|
||||
IWineD3DBaseShader *iface,
|
||||
shader_reg_maps* reg_maps,
|
||||
semantic* semantics_in,
|
||||
|
@ -187,7 +187,7 @@ void shader_get_registers_used(
|
|||
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
||||
|
||||
if (pToken == NULL)
|
||||
return;
|
||||
return WINED3D_OK;
|
||||
|
||||
while (D3DVS_END() != *pToken) {
|
||||
CONST SHADER_OPCODE* curOpcode;
|
||||
|
@ -245,8 +245,31 @@ void shader_get_registers_used(
|
|||
} else if (D3DSPR_SAMPLER == regtype)
|
||||
reg_maps->samplers[regnum] = usage;
|
||||
|
||||
/* Skip definitions (for now) */
|
||||
} else if (D3DSIO_DEF == curOpcode->opcode) {
|
||||
|
||||
local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
|
||||
if (!lconst) return E_OUTOFMEMORY;
|
||||
lconst->idx = *pToken & D3DSP_REGNUM_MASK;
|
||||
memcpy(&lconst->value, pToken + 1, 4 * sizeof(DWORD));
|
||||
list_add_head(&This->baseShader.constantsF, &lconst->entry);
|
||||
pToken += curOpcode->num_params;
|
||||
|
||||
} else if (D3DSIO_DEFI == curOpcode->opcode) {
|
||||
|
||||
local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
|
||||
if (!lconst) return E_OUTOFMEMORY;
|
||||
lconst->idx = *pToken & D3DSP_REGNUM_MASK;
|
||||
memcpy(&lconst->value, pToken + 1, 4 * sizeof(DWORD));
|
||||
list_add_head(&This->baseShader.constantsI, &lconst->entry);
|
||||
pToken += curOpcode->num_params;
|
||||
|
||||
} else if (D3DSIO_DEFB == curOpcode->opcode) {
|
||||
|
||||
local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
|
||||
if (!lconst) return E_OUTOFMEMORY;
|
||||
lconst->idx = *pToken & D3DSP_REGNUM_MASK;
|
||||
memcpy(&lconst->value, pToken + 1, 1 * sizeof(DWORD));
|
||||
list_add_head(&This->baseShader.constantsB, &lconst->entry);
|
||||
pToken += curOpcode->num_params;
|
||||
|
||||
/* If there's a loop in the shader */
|
||||
|
@ -315,6 +338,8 @@ void shader_get_registers_used(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static void shader_dump_decl_usage(
|
||||
|
@ -655,7 +680,10 @@ void shader_generate_main(
|
|||
|
||||
/* Nothing to do */
|
||||
} else if (D3DSIO_DCL == curOpcode->opcode ||
|
||||
D3DSIO_NOP == curOpcode->opcode) {
|
||||
D3DSIO_NOP == curOpcode->opcode ||
|
||||
D3DSIO_DEF == curOpcode->opcode ||
|
||||
D3DSIO_DEFI == curOpcode->opcode ||
|
||||
D3DSIO_DEFB == curOpcode->opcode) {
|
||||
|
||||
pToken += shader_skip_opcode(This, curOpcode, opcode_token);
|
||||
|
||||
|
@ -682,15 +710,7 @@ void shader_generate_main(
|
|||
|
||||
DWORD param, addr_token = 0;
|
||||
|
||||
/* DEF* instructions have constant src parameters, not registers */
|
||||
if (curOpcode->opcode == D3DSIO_DEF ||
|
||||
curOpcode->opcode == D3DSIO_DEFI ||
|
||||
curOpcode->opcode == D3DSIO_DEFB) {
|
||||
param = *pToken++;
|
||||
|
||||
} else
|
||||
pToken += shader_get_param(iface, pToken, ¶m, &addr_token);
|
||||
|
||||
pToken += shader_get_param(iface, pToken, ¶m, &addr_token);
|
||||
hw_arg.src[i-1] = param;
|
||||
hw_arg.src_addr[i-1] = addr_token;
|
||||
}
|
||||
|
@ -882,4 +902,16 @@ void shader_trace_init(
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: Move other shared code here */
|
||||
void shader_delete_constant_list(
|
||||
struct list* clist) {
|
||||
|
||||
struct list *ptr;
|
||||
struct local_constant* constant;
|
||||
|
||||
ptr = list_head(clist);
|
||||
while (ptr) {
|
||||
constant = LIST_ENTRY(ptr, struct local_constant, entry);
|
||||
ptr = list_next(clist, ptr);
|
||||
HeapFree(GetProcessHeap(), 0, constant);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,17 +78,19 @@ void shader_glsl_load_psamplers(
|
|||
* When @constants_set == NULL, it will load all the constants.
|
||||
*/
|
||||
void shader_glsl_load_constantsF(
|
||||
IWineD3DBaseShaderImpl* This,
|
||||
WineD3D_GL_Info *gl_info,
|
||||
GLhandleARB programId,
|
||||
unsigned max_constants,
|
||||
float* constants,
|
||||
BOOL* constants_set,
|
||||
char is_pshader) {
|
||||
BOOL* constants_set) {
|
||||
|
||||
GLhandleARB tmp_loc;
|
||||
int i;
|
||||
char tmp_name[7];
|
||||
char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
||||
const char* prefix = is_pshader? "PC":"VC";
|
||||
struct list* ptr;
|
||||
|
||||
for (i=0; i<max_constants; ++i) {
|
||||
if (NULL == constants_set || constants_set[i]) {
|
||||
|
@ -108,6 +110,26 @@ void shader_glsl_load_constantsF(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load immediate constants */
|
||||
ptr = list_head(&This->baseShader.constantsF);
|
||||
while (ptr) {
|
||||
local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
|
||||
unsigned int idx = lconst->idx;
|
||||
GLfloat* values = (GLfloat*) lconst->value;
|
||||
|
||||
TRACE("Loading local constants %i: %f, %f, %f, %f\n", idx,
|
||||
values[0], values[1], values[2], values[3]);
|
||||
|
||||
snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, idx);
|
||||
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
|
||||
if (tmp_loc != -1) {
|
||||
/* We found this uniform name in the program - go ahead and send the data */
|
||||
GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, values));
|
||||
checkGLcall("glUniform4fvARB");
|
||||
}
|
||||
ptr = list_next(&This->baseShader.constantsF, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,17 +137,19 @@ void shader_glsl_load_constantsF(
|
|||
* When @constants_set == NULL, it will load all the constants.
|
||||
*/
|
||||
void shader_glsl_load_constantsI(
|
||||
IWineD3DBaseShaderImpl* This,
|
||||
WineD3D_GL_Info *gl_info,
|
||||
GLhandleARB programId,
|
||||
unsigned max_constants,
|
||||
int* constants,
|
||||
BOOL* constants_set,
|
||||
char is_pshader) {
|
||||
BOOL* constants_set) {
|
||||
|
||||
GLhandleARB tmp_loc;
|
||||
int i;
|
||||
char tmp_name[7];
|
||||
char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
||||
const char* prefix = is_pshader? "PI":"VI";
|
||||
struct list* ptr;
|
||||
|
||||
for (i=0; i<max_constants; ++i) {
|
||||
if (NULL == constants_set || constants_set[i]) {
|
||||
|
@ -144,6 +168,26 @@ void shader_glsl_load_constantsI(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load immediate constants */
|
||||
ptr = list_head(&This->baseShader.constantsI);
|
||||
while (ptr) {
|
||||
local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
|
||||
unsigned int idx = lconst->idx;
|
||||
GLint* values = (GLint*) lconst->value;
|
||||
|
||||
TRACE("Loading local constants %i: %i, %i, %i, %i\n", idx,
|
||||
values[0], values[1], values[2], values[3]);
|
||||
|
||||
snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, idx);
|
||||
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
|
||||
if (tmp_loc != -1) {
|
||||
/* We found this uniform name in the program - go ahead and send the data */
|
||||
GL_EXTCALL(glUniform4ivARB(tmp_loc, 1, values));
|
||||
checkGLcall("glUniform4ivARB");
|
||||
}
|
||||
ptr = list_next(&This->baseShader.constantsI, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,17 +195,19 @@ void shader_glsl_load_constantsI(
|
|||
* When @constants_set == NULL, it will load all the constants.
|
||||
*/
|
||||
void shader_glsl_load_constantsB(
|
||||
IWineD3DBaseShaderImpl* This,
|
||||
WineD3D_GL_Info *gl_info,
|
||||
GLhandleARB programId,
|
||||
unsigned max_constants,
|
||||
BOOL* constants,
|
||||
BOOL* constants_set,
|
||||
char is_pshader) {
|
||||
BOOL* constants_set) {
|
||||
|
||||
GLhandleARB tmp_loc;
|
||||
int i;
|
||||
char tmp_name[7];
|
||||
char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
||||
const char* prefix = is_pshader? "PB":"VB";
|
||||
struct list* ptr;
|
||||
|
||||
for (i=0; i<max_constants; ++i) {
|
||||
if (NULL == constants_set || constants_set[i]) {
|
||||
|
@ -179,6 +225,25 @@ void shader_glsl_load_constantsB(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load immediate constants */
|
||||
ptr = list_head(&This->baseShader.constantsB);
|
||||
while (ptr) {
|
||||
local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
|
||||
unsigned int idx = lconst->idx;
|
||||
GLint* values = (GLint*) lconst->value;
|
||||
|
||||
TRACE("Loading local constants %i: %i\n", idx, values[0]);
|
||||
|
||||
snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, idx);
|
||||
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
|
||||
if (tmp_loc != -1) {
|
||||
/* We found this uniform name in the program - go ahead and send the data */
|
||||
GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, values));
|
||||
checkGLcall("glUniform1ivARB");
|
||||
}
|
||||
ptr = list_next(&This->baseShader.constantsB, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,51 +266,55 @@ void shader_glsl_load_constants(
|
|||
}
|
||||
|
||||
if (useVertexShader) {
|
||||
IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
|
||||
IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
|
||||
IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) vshader;
|
||||
|
||||
IWineD3DVertexDeclarationImpl* vertexDeclaration =
|
||||
(IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
|
||||
(IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
|
||||
|
||||
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
|
||||
/* Load DirectX 8 float constants/uniforms for vertex shader */
|
||||
shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
vertexDeclaration->constants, NULL, 0);
|
||||
shader_glsl_load_constantsF(vshader, gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
vertexDeclaration->constants, NULL);
|
||||
}
|
||||
|
||||
/* Load DirectX 9 float constants/uniforms for vertex shader */
|
||||
shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
shader_glsl_load_constantsF(vshader, gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
stateBlock->vertexShaderConstantF,
|
||||
stateBlock->set.vertexShaderConstantsF, 0);
|
||||
stateBlock->set.vertexShaderConstantsF);
|
||||
|
||||
/* Load DirectX 9 integer constants/uniforms for vertex shader */
|
||||
shader_glsl_load_constantsI(gl_info, programId, MAX_CONST_I,
|
||||
shader_glsl_load_constantsI(vshader, gl_info, programId, MAX_CONST_I,
|
||||
stateBlock->vertexShaderConstantI,
|
||||
stateBlock->set.vertexShaderConstantsI, 0);
|
||||
stateBlock->set.vertexShaderConstantsI);
|
||||
|
||||
/* Load DirectX 9 boolean constants/uniforms for vertex shader */
|
||||
shader_glsl_load_constantsB(gl_info, programId, MAX_CONST_B,
|
||||
shader_glsl_load_constantsB(vshader, gl_info, programId, MAX_CONST_B,
|
||||
stateBlock->vertexShaderConstantB,
|
||||
stateBlock->set.vertexShaderConstantsB, 0);
|
||||
stateBlock->set.vertexShaderConstantsB);
|
||||
}
|
||||
|
||||
if (usePixelShader) {
|
||||
|
||||
IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
|
||||
|
||||
/* Load pixel shader samplers */
|
||||
shader_glsl_load_psamplers(gl_info, iface);
|
||||
|
||||
/* Load DirectX 9 float constants/uniforms for pixel shader */
|
||||
shader_glsl_load_constantsF(gl_info, programId, WINED3D_PSHADER_MAX_CONSTANTS,
|
||||
shader_glsl_load_constantsF(pshader, gl_info, programId, WINED3D_PSHADER_MAX_CONSTANTS,
|
||||
stateBlock->pixelShaderConstantF,
|
||||
stateBlock->set.pixelShaderConstantsF, 1);
|
||||
stateBlock->set.pixelShaderConstantsF);
|
||||
|
||||
/* Load DirectX 9 integer constants/uniforms for pixel shader */
|
||||
shader_glsl_load_constantsI(gl_info, programId, MAX_CONST_I,
|
||||
shader_glsl_load_constantsI(pshader, gl_info, programId, MAX_CONST_I,
|
||||
stateBlock->pixelShaderConstantI,
|
||||
stateBlock->set.pixelShaderConstantsI, 1);
|
||||
stateBlock->set.pixelShaderConstantsI);
|
||||
|
||||
/* Load DirectX 9 boolean constants/uniforms for pixel shader */
|
||||
shader_glsl_load_constantsB(gl_info, programId, MAX_CONST_B,
|
||||
shader_glsl_load_constantsB(pshader, gl_info, programId, MAX_CONST_B,
|
||||
stateBlock->pixelShaderConstantB,
|
||||
stateBlock->set.pixelShaderConstantsB, 1);
|
||||
stateBlock->set.pixelShaderConstantsB);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,61 +579,34 @@ static void shader_glsl_get_register_name(
|
|||
{
|
||||
const char* prefix = pshader? "PC":"VC";
|
||||
|
||||
if (arg->reg_maps->constantsF[reg]) {
|
||||
/* Use a local constant declared by "def" */
|
||||
|
||||
if (param & D3DVS_ADDRMODE_RELATIVE) {
|
||||
/* FIXME: Copy all constants (local & global) into a single array
|
||||
* to handle this case where we want a relative address from a
|
||||
* local constant. */
|
||||
FIXME("Relative addressing not yet supported on named constants\n");
|
||||
} else {
|
||||
sprintf(tmpStr, "%s%lu", prefix, reg);
|
||||
}
|
||||
} else {
|
||||
/* Use a global constant declared in Set____ShaderConstantF() */
|
||||
if (param & D3DVS_ADDRMODE_RELATIVE) {
|
||||
/* 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 (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2) {
|
||||
char relStr[100], relReg[50], relMask[6];
|
||||
shader_glsl_add_param(arg, addr_token, 0, TRUE, relReg, relMask, relStr);
|
||||
sprintf(tmpStr, "%s[%s + %lu]", prefix, relStr, reg);
|
||||
} else {
|
||||
sprintf(tmpStr, "%s[A0.x + %lu]", prefix, reg);
|
||||
}
|
||||
} else {
|
||||
/* Just a normal global constant - no relative addressing */
|
||||
sprintf(tmpStr, "%s[%lu]", prefix, reg);
|
||||
}
|
||||
}
|
||||
/* Relative addressing */
|
||||
if (param & D3DVS_ADDRMODE_RELATIVE) {
|
||||
|
||||
/* 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 (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2) {
|
||||
char relStr[100], relReg[50], relMask[6];
|
||||
shader_glsl_add_param(arg, addr_token, 0, TRUE, relReg, relMask, relStr);
|
||||
sprintf(tmpStr, "%s[%s + %lu]", prefix, relStr, reg);
|
||||
} else
|
||||
sprintf(tmpStr, "%s[A0.x + %lu]", prefix, reg);
|
||||
|
||||
} else
|
||||
sprintf(tmpStr, "%s[%lu]", prefix, reg);
|
||||
|
||||
break;
|
||||
}
|
||||
case D3DSPR_CONSTINT:
|
||||
if (arg->reg_maps->constantsI[reg]) {
|
||||
/* Integer vector was defined locally using "defi" */
|
||||
sprintf(tmpStr, "I%lu", reg);
|
||||
} else {
|
||||
/* Uniform integer value - pixel or vertex specific */
|
||||
if (pshader) {
|
||||
sprintf(tmpStr, "PI[%lu]", reg);
|
||||
} else {
|
||||
sprintf(tmpStr, "VI[%lu]", reg);
|
||||
}
|
||||
}
|
||||
if (pshader)
|
||||
sprintf(tmpStr, "PI[%lu]", reg);
|
||||
else
|
||||
sprintf(tmpStr, "VI[%lu]", reg);
|
||||
break;
|
||||
case D3DSPR_CONSTBOOL:
|
||||
if (arg->reg_maps->constantsB[reg]) {
|
||||
/* Boolean was defined locally using "defb" */
|
||||
sprintf(tmpStr, "B%lu", reg);
|
||||
} else {
|
||||
/* Uniform boolean value - pixel or vertex specific */
|
||||
if (pshader) {
|
||||
sprintf(tmpStr, "PB[%lu]", reg);
|
||||
} else {
|
||||
sprintf(tmpStr, "VB[%lu]", reg);
|
||||
}
|
||||
}
|
||||
if (pshader)
|
||||
sprintf(tmpStr, "PB[%lu]", reg);
|
||||
else
|
||||
sprintf(tmpStr, "VB[%lu]", reg);
|
||||
break;
|
||||
case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */
|
||||
if (pshader) {
|
||||
|
@ -1041,51 +1083,6 @@ void shader_glsl_lrp(SHADER_OPCODE_ARG* arg) {
|
|||
tmpLine, src2_str, src0_str, src1_str, src2_str, dst_mask);
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_DEF opcode into a GLSL string - creates a local vec4
|
||||
* float constant, and stores it's usage on the regmaps. */
|
||||
void shader_glsl_def(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
|
||||
|
||||
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
|
||||
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
||||
const char* prefix = pshader? "PC":"VC";
|
||||
|
||||
shader_addline(arg->buffer,
|
||||
"const vec4 %s%lu = vec4(%f, %f, %f, %f);\n", prefix, reg,
|
||||
*((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;
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_DEFI opcode into a GLSL string - creates a local ivec4
|
||||
* integer constant, and stores it's usage on the regmaps. */
|
||||
void shader_glsl_defi(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
|
||||
|
||||
shader_addline(arg->buffer,
|
||||
"const ivec4 I%lu = ivec4(%ld, %ld, %ld, %ld);\n", reg,
|
||||
(long)arg->src[0], (long)arg->src[1],
|
||||
(long)arg->src[2], (long)arg->src[3]);
|
||||
|
||||
arg->reg_maps->constantsI[reg] = 1;
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_DEFB opcode into a GLSL string - creates a local boolean
|
||||
* constant, and stores it's usage on the regmaps. */
|
||||
void shader_glsl_defb(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
|
||||
|
||||
shader_addline(arg->buffer, "const bool B%lu = %s;\n", reg, (arg->src[0]) ? "true" : "false");
|
||||
|
||||
arg->reg_maps->constantsB[reg] = 1;
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_LIT instruction in GLSL:
|
||||
* dst.x = dst.w = 1.0
|
||||
* dst.y = (src0.x > 0) ? src0.x
|
||||
|
|
|
@ -72,13 +72,16 @@ static ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface)
|
|||
TRACE("(%p) : Releasing from %ld\n", This, This->ref);
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (ref == 0) {
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
||||
/* If this shader is still attached to a program, GL will perform a lazy delete */
|
||||
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
|
||||
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
|
||||
checkGLcall("glDeleteObjectARB");
|
||||
}
|
||||
shader_delete_constant_list(&This->baseShader.constantsF);
|
||||
shader_delete_constant_list(&This->baseShader.constantsB);
|
||||
shader_delete_constant_list(&This->baseShader.constantsI);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
@ -690,9 +693,9 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
|
|||
{D3DSIO_LABEL, "label", GLNAME_REQUIRE_GLSL, 0, 1, pshader_label, NULL, NULL, 0, 0},
|
||||
|
||||
/* Constant definitions */
|
||||
{D3DSIO_DEF, "def", "undefined", 1, 5, pshader_def, shader_hw_def, shader_glsl_def, 0, 0},
|
||||
{D3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, pshader_defb, NULL, shader_glsl_defb, 0, 0},
|
||||
{D3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, pshader_defi, NULL, shader_glsl_defi, 0, 0},
|
||||
{D3DSIO_DEF, "def", "undefined", 1, 5, pshader_def, NULL, NULL, 0, 0},
|
||||
{D3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, pshader_defb, NULL, NULL, 0, 0},
|
||||
{D3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, pshader_defi, NULL, NULL, 0, 0},
|
||||
|
||||
/* Texture */
|
||||
{D3DSIO_TEXCOORD, "texcoord", "undefined", 1, 1, pshader_texcoord, pshader_hw_texcoord, pshader_glsl_texcoord, 0, D3DPS_VERSION(1,3)},
|
||||
|
@ -898,16 +901,23 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
|
|||
static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
|
||||
|
||||
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
|
||||
HRESULT hr;
|
||||
shader_reg_maps reg_maps;
|
||||
|
||||
/* First pass: trace shader */
|
||||
shader_trace_init((IWineD3DBaseShader*) This, pFunction);
|
||||
pshader_set_limits(This);
|
||||
|
||||
/* Initialize immediate constant lists */
|
||||
list_init(&This->baseShader.constantsF);
|
||||
list_init(&This->baseShader.constantsB);
|
||||
list_init(&This->baseShader.constantsI);
|
||||
|
||||
/* Second pass: figure out which registers are used, what the semantics are, etc.. */
|
||||
memset(®_maps, 0, sizeof(shader_reg_maps));
|
||||
shader_get_registers_used((IWineD3DBaseShader*) This, ®_maps,
|
||||
memset(®_maps, 0, sizeof(shader_reg_maps));
|
||||
hr = shader_get_registers_used((IWineD3DBaseShader*) This, ®_maps,
|
||||
This->semantics_in, NULL, pFunction);
|
||||
if (hr != WINED3D_OK) return hr;
|
||||
/* FIXME: validate reg_maps against OpenGL */
|
||||
|
||||
/* Generate HW shader in needed */
|
||||
|
@ -920,13 +930,12 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
|
|||
TRACE("(%p) : Copying the function\n", This);
|
||||
if (NULL != pFunction) {
|
||||
This->baseShader.function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
|
||||
if (!This->baseShader.function) return E_OUTOFMEMORY;
|
||||
memcpy((void *)This->baseShader.function, pFunction, This->baseShader.functionLength);
|
||||
} else {
|
||||
This->baseShader.function = NULL;
|
||||
}
|
||||
|
||||
/* TODO: Some proper return values for failures */
|
||||
TRACE("(%p) : Returning WINED3D_OK\n", This);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -531,9 +531,9 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
|
|||
{D3DSIO_DCL, "dcl", NULL, 0, 2, vshader_dcl, NULL, NULL, 0, 0},
|
||||
|
||||
/* Constant definitions */
|
||||
{D3DSIO_DEF, "def", NULL, 1, 5, vshader_def, shader_hw_def, shader_glsl_def, 0, 0},
|
||||
{D3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, vshader_defb, NULL, shader_glsl_defb, 0, 0},
|
||||
{D3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, vshader_defi, NULL, shader_glsl_defi, 0, 0},
|
||||
{D3DSIO_DEF, "def", NULL, 1, 5, vshader_def, NULL, NULL, 0, 0},
|
||||
{D3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, vshader_defb, NULL, NULL, 0, 0},
|
||||
{D3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, vshader_defi, NULL, NULL, 0, 0},
|
||||
|
||||
/* Flow control - requires GLSL or software shaders */
|
||||
{D3DSIO_REP , "rep", GLNAME_REQUIRE_GLSL, 0, 1, vshader_rep, NULL, NULL, 0, 0},
|
||||
|
@ -1045,7 +1045,11 @@ static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface
|
|||
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
|
||||
checkGLcall("glDeleteObjectARB");
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
shader_delete_constant_list(&This->baseShader.constantsF);
|
||||
shader_delete_constant_list(&This->baseShader.constantsB);
|
||||
shader_delete_constant_list(&This->baseShader.constantsI);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
@ -1099,12 +1103,18 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader*
|
|||
static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
|
||||
|
||||
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
|
||||
HRESULT hr;
|
||||
shader_reg_maps reg_maps;
|
||||
|
||||
/* First pass: trace shader */
|
||||
shader_trace_init((IWineD3DBaseShader*) This, pFunction);
|
||||
vshader_set_limits(This);
|
||||
|
||||
/* Initialize immediate constant lists */
|
||||
list_init(&This->baseShader.constantsF);
|
||||
list_init(&This->baseShader.constantsB);
|
||||
list_init(&This->baseShader.constantsI);
|
||||
|
||||
/* Preload semantics for d3d8 shaders */
|
||||
if (This->vertexDeclaration) {
|
||||
IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*) This->vertexDeclaration;
|
||||
|
@ -1117,8 +1127,9 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
|
|||
|
||||
/* Second pass: figure out registers used, semantics, etc.. */
|
||||
memset(®_maps, 0, sizeof(shader_reg_maps));
|
||||
shader_get_registers_used((IWineD3DBaseShader*) This, ®_maps,
|
||||
hr = shader_get_registers_used((IWineD3DBaseShader*) This, ®_maps,
|
||||
This->semantics_in, This->semantics_out, pFunction);
|
||||
if (hr != WINED3D_OK) return hr;
|
||||
|
||||
/* Generate HW shader in needed */
|
||||
This->baseShader.shader_mode = wined3d_settings.vs_selected_mode;
|
||||
|
@ -1128,6 +1139,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
|
|||
/* copy the function ... because it will certainly be released by application */
|
||||
if (NULL != pFunction) {
|
||||
This->baseShader.function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
|
||||
if (!This->baseShader.function) return E_OUTOFMEMORY;
|
||||
memcpy((void *)This->baseShader.function, pFunction, This->baseShader.functionLength);
|
||||
} else {
|
||||
This->baseShader.function = NULL;
|
||||
|
|
|
@ -1279,7 +1279,6 @@ struct glsl_shader_prog_link {
|
|||
#define MAX_REG_INPUT 12
|
||||
#define MAX_REG_OUTPUT 12
|
||||
#define MAX_ATTRIBS 16
|
||||
#define MAX_CONST_F 256
|
||||
#define MAX_CONST_I 16
|
||||
#define MAX_CONST_B 16
|
||||
|
||||
|
@ -1288,6 +1287,12 @@ typedef struct semantic {
|
|||
DWORD reg;
|
||||
} semantic;
|
||||
|
||||
typedef struct local_constant {
|
||||
struct list entry;
|
||||
unsigned int idx;
|
||||
DWORD value[4];
|
||||
} local_constant;
|
||||
|
||||
typedef struct shader_reg_maps {
|
||||
|
||||
char texcoord[MAX_REG_TEXCRD]; /* pixel < 3.0 */
|
||||
|
@ -1297,10 +1302,6 @@ typedef struct shader_reg_maps {
|
|||
char packed_output[MAX_REG_OUTPUT]; /* vertex >= 3.0 */
|
||||
char attributes[MAX_ATTRIBS]; /* vertex */
|
||||
|
||||
char constantsF[MAX_CONST_F]; /* pixel, vertex */
|
||||
char constantsI[MAX_CONST_I]; /* pixel & vertex >= 2.0 */
|
||||
char constantsB[MAX_CONST_B]; /* pixel & vertex >= 2.0 */
|
||||
|
||||
/* Sampler usage tokens
|
||||
* Use 0 as default (bit 31 is always 1 on a valid token) */
|
||||
DWORD samplers[MAX_SAMPLERS];
|
||||
|
@ -1372,6 +1373,9 @@ extern const SHADER_OPCODE* shader_get_opcode(
|
|||
IWineD3DBaseShader *iface,
|
||||
const DWORD code);
|
||||
|
||||
extern void shader_delete_constant_list(
|
||||
struct list* clist);
|
||||
|
||||
/* Vertex shader utility functions */
|
||||
extern BOOL vshader_get_input(
|
||||
IWineD3DVertexShader* iface,
|
||||
|
@ -1475,6 +1479,11 @@ typedef struct IWineD3DBaseShaderClass
|
|||
/* Type of shader backend */
|
||||
int shader_mode;
|
||||
|
||||
/* Immediate constants (override global ones) */
|
||||
struct list constantsB;
|
||||
struct list constantsF;
|
||||
struct list constantsI;
|
||||
|
||||
} IWineD3DBaseShaderClass;
|
||||
|
||||
typedef struct IWineD3DBaseShaderImpl {
|
||||
|
@ -1486,7 +1495,7 @@ typedef struct IWineD3DBaseShaderImpl {
|
|||
IWineD3DBaseShaderClass baseShader;
|
||||
} IWineD3DBaseShaderImpl;
|
||||
|
||||
extern void shader_get_registers_used(
|
||||
extern HRESULT shader_get_registers_used(
|
||||
IWineD3DBaseShader *iface,
|
||||
shader_reg_maps* reg_maps,
|
||||
semantic* semantics_in,
|
||||
|
|
Loading…
Reference in New Issue