wined3d: Support more than one texbem instruction per shader.

This commit is contained in:
Stefan Dösinger 2008-03-05 03:18:55 +01:00 committed by Alexandre Julliard
parent 739278baf1
commit 167a271434
6 changed files with 140 additions and 83 deletions

View File

@ -153,6 +153,7 @@ void shader_arb_load_constants(
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
unsigned char i;
if (useVertexShader) {
IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
@ -180,25 +181,25 @@ void shader_arb_load_constants(
stateBlock->pixelShaderConstantF,
deviceImpl->activeContext->pshader_const_dirty);
if(((IWineD3DPixelShaderImpl *) pshader)->bumpenvmatconst != -1) {
/* needsbumpmat stores the stage number from where to load the matrix. bumpenvmatconst stores the
* number of the constant to load the matrix into.
* The state manager takes care that this function is always called if the bump env matrix changes
for(i = 0; i < psi->numbumpenvmatconsts; i++) {
/* The state manager takes care that this function is always called if the bump env matrix changes
*/
float *data = (float *) &stateBlock->textureState[(int) psi->needsbumpmat][WINED3DTSS_BUMPENVMAT00];
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->bumpenvmatconst, data));
float *data = (float *) &stateBlock->textureState[(int) psi->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->bumpenvmatconst[i].const_num, data));
deviceImpl->activeContext->pshader_const_dirty[psi->bumpenvmatconst[i].const_num] = 1;
if(((IWineD3DPixelShaderImpl *) pshader)->luminanceconst != -1) {
if(psi->luminanceconst[i].const_num != -1) {
/* WINED3DTSS_BUMPENVLSCALE and WINED3DTSS_BUMPENVLOFFSET are next to each other.
* point gl to the scale, and load 4 floats. x = scale, y = offset, z and w are junk, we
* don't care about them. The pointers are valid for sure because the stateblock is bigger.
* (they're WINED3DTSS_TEXTURETRANSFORMFLAGS and WINED3DTSS_ADDRESSW, so most likely 0 or NaN
*/
float *scale = (float *) &stateBlock->textureState[(int) psi->needsbumpmat][WINED3DTSS_BUMPENVLSCALE];
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->luminanceconst, scale));
deviceImpl->activeContext->pshader_const_dirty[psi->luminanceconst] = 1;
float *scale = (float *) &stateBlock->textureState[(int) psi->luminanceconst[i].texunit][WINED3DTSS_BUMPENVLSCALE];
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->luminanceconst[i].const_num, scale));
deviceImpl->activeContext->pshader_const_dirty[psi->luminanceconst[i].const_num] = 1;
}
}
if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
!((IWineD3DPixelShaderImpl *) pshader)->srgb_mode_hardcoded) {
float comparison[4];
@ -236,7 +237,7 @@ void shader_generate_arb_declarations(
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
DWORD i;
DWORD i, cur;
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
unsigned max_constantsF = min(This->baseShader.limits.constant_float,
(pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
@ -267,29 +268,41 @@ void shader_generate_arb_declarations(
shader_addline(buffer, "MOV T%u, fragment.texcoord[%u];\n", i, i);
}
((IWineD3DPixelShaderImpl *)This)->bumpenvmatconst = -1;
((IWineD3DPixelShaderImpl *)This)->luminanceconst = -1;
if(reg_maps->bumpmat != -1 /* Only a pshader can use texbem */) {
for(i = 0; i < (sizeof(reg_maps->bumpmat) / sizeof(reg_maps->bumpmat[0])); i++) {
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) This;
if(!reg_maps->bumpmat[i]) continue;
cur = ps->numbumpenvmatconsts;
ps->bumpenvmatconst[cur].const_num = -1;
ps->bumpenvmatconst[cur].texunit = i;
ps->luminanceconst[cur].const_num = -1;
ps->luminanceconst[cur].texunit = i;
/* If the shader does not use all available constants, use the next free constant to load the bump mapping environment matrix from
* the stateblock into the shader. If no constant is available don't load, texbem will then just sample the texture without applying
* bump mapping.
*/
if(max_constantsF < GL_LIMITS(pshader_constantsF)) {
((IWineD3DPixelShaderImpl *)This)->bumpenvmatconst = max_constantsF;
shader_addline(buffer, "PARAM bumpenvmat%d = program.env[%d];\n", reg_maps->bumpmat, ((IWineD3DPixelShaderImpl *)This)->bumpenvmatconst);
if(max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF)) {
ps->bumpenvmatconst[cur].const_num = max_constantsF + extra_constants_needed;
shader_addline(buffer, "PARAM bumpenvmat%d = program.env[%d];\n",
i, ps->bumpenvmatconst[cur].const_num);
extra_constants_needed++;
if(reg_maps->luminanceparams != -1 && max_constantsF +1 < GL_LIMITS(pshader_constantsF)) {
extra_constants_needed += 1;
((IWineD3DPixelShaderImpl *)This)->luminanceconst = max_constantsF + 1;
shader_addline(buffer, "PARAM luminance%d = program.env[%d];\n", reg_maps->luminanceparams, ((IWineD3DPixelShaderImpl *)This)->luminanceconst);
} else if(reg_maps->luminanceparams != -1) {
if(reg_maps->luminanceparams && max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF)) {
((IWineD3DPixelShaderImpl *)This)->luminanceconst[cur].const_num = max_constantsF + extra_constants_needed;
shader_addline(buffer, "PARAM luminance%d = program.env[%d];\n",
i, ps->luminanceconst[cur].const_num);
extra_constants_needed++;
} else if(reg_maps->luminanceparams) {
FIXME("No free constant to load the luminance parameters\n");
}
} else {
FIXME("No free constant found to load environemnt bump mapping matrix into the shader. texbem instruction will not apply bump mapping\n");
}
extra_constants_needed += 1;
ps->numbumpenvmatconsts = cur + 1;
}
if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] && pshader) {
IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
/* If there are 2 constants left to use, use them to pass the sRGB correction values in. This way
@ -891,7 +904,15 @@ void pshader_hw_bem(SHADER_OPCODE_ARG* arg) {
char src_name[2][50];
char dst_wmask[20];
DWORD sampler_code = arg->dst & WINED3DSP_REGNUM_MASK;
BOOL has_bumpmat = (This->bumpenvmatconst != -1);
BOOL has_bumpmat = FALSE;
int i;
for(i = 0; i < This->numbumpenvmatconsts; i++) {
if(This->bumpenvmatconst[i].const_num != -1 && This->bumpenvmatconst[i].texunit == sampler_code) {
has_bumpmat = TRUE;
break;
}
}
pshader_get_register_name(arg->shader, arg->dst, dst_name);
shader_arb_get_write_mask(arg, arg->dst, dst_wmask);
@ -1234,9 +1255,9 @@ void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg) {
void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
DWORD sampler_code = arg->dst & WINED3DSP_REGNUM_MASK;
BOOL has_bumpmat = (This->bumpenvmatconst != -1);
BOOL has_luminance = (This->luminanceconst != -1);
BOOL has_bumpmat = FALSE;
BOOL has_luminance = FALSE;
int i;
DWORD dst = arg->dst;
DWORD src = arg->src[0] & WINED3DSP_REGNUM_MASK;
@ -1250,12 +1271,25 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
/* Can directly use the name because texbem is only valid for <= 1.3 shaders */
pshader_get_register_name(arg->shader, dst, reg_coord);
for(i = 0; i < This->numbumpenvmatconsts; i++) {
if(This->bumpenvmatconst[i].const_num != -1 && reg_dest_code == This->bumpenvmatconst[i].texunit) {
has_bumpmat = TRUE;
break;
}
}
for(i = 0; i < This->numbumpenvmatconsts; i++) {
if(This->luminanceconst[i].const_num != -1 && reg_dest_code == This->luminanceconst[i].texunit) {
has_luminance = TRUE;
break;
}
}
if(has_bumpmat) {
/* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", sampler_code);
shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
shader_addline(buffer, "DP3 TMP.r, TMP2, T%u;\n", src);
shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, y, w, 0, 0;\n", sampler_code);
shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, y, w, 0, 0;\n", reg_dest_code);
shader_addline(buffer, "DP3 TMP.g, TMP2, T%u;\n", src);
/* with projective textures, texbem only divides the static texture coord, not the displacement,
@ -1274,7 +1308,7 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
if(arg->opcode->opcode == WINED3DSIO_TEXBEML && has_luminance) {
shader_addline(buffer, "MAD TMP, T%u.z, luminance%d.x, luminance%d.y;\n",
src, sampler_code, sampler_code);
src, reg_dest_code, reg_dest_code);
shader_addline(buffer, "MUL %s, %s, TMP;\n", reg_coord, reg_coord);
}

View File

@ -212,8 +212,8 @@ HRESULT shader_get_registers_used(
/* There are some minor differences between pixel and vertex shaders */
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
reg_maps->bumpmat = -1;
reg_maps->luminanceparams = -1;
memset(reg_maps->bumpmat, 0, sizeof(reg_maps->bumpmat));
memset(reg_maps->luminanceparams, 0, sizeof(reg_maps->luminanceparams));
if (pToken == NULL)
return WINED3D_OK;
@ -348,7 +348,8 @@ HRESULT shader_get_registers_used(
int i, limit;
/* Declare 1.X samplers implicitly, based on the destination reg. number */
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 &&
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 ||
@ -395,25 +396,17 @@ HRESULT shader_get_registers_used(
/* texbem is only valid with < 1.4 pixel shaders */
if(WINED3DSIO_TEXBEM == curOpcode->opcode ||
WINED3DSIO_TEXBEML == curOpcode->opcode) {
if(reg_maps->bumpmat != -1 && reg_maps->bumpmat != sampler_code) {
FIXME("Pixel shader uses texbem instruction on more than 1 sampler\n");
} else {
reg_maps->bumpmat = sampler_code;
if(WINED3DSIO_TEXBEML == curOpcode->opcode) {
reg_maps->luminanceparams = sampler_code;
}
reg_maps->bumpmat[sampler_code] = TRUE;
if(WINED3DSIO_TEXBEML == curOpcode->opcode) {
reg_maps->luminanceparams[sampler_code] = TRUE;
}
}
}
if(WINED3DSIO_NRM == curOpcode->opcode) {
reg_maps->usesnrm = 1;
} else if(WINED3DSIO_BEM == curOpcode->opcode) {
} else if(WINED3DSIO_BEM == curOpcode->opcode && pshader) {
DWORD regnum = *pToken & WINED3DSP_REGNUM_MASK;
if(reg_maps->bumpmat != -1 && reg_maps->bumpmat != regnum) {
FIXME("Pixel shader uses bem or texbem instruction on more than 1 sampler\n");
} else {
reg_maps->bumpmat = regnum;
}
reg_maps->bumpmat[regnum] = TRUE;
} else if(WINED3DSIO_DSY == curOpcode->opcode) {
reg_maps->usesdsy = 1;
}

View File

@ -371,6 +371,7 @@ void shader_glsl_load_constants(
struct list *constant_list;
GLhandleARB programId;
struct glsl_shader_prog_link *prog = stateBlock->glsl_program;
unsigned int i;
if (!prog) {
/* No GLSL program set - nothing to do. */
@ -429,25 +430,29 @@ void shader_glsl_load_constants(
/* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
* It can't be 0 for a valid texbem instruction.
*/
if(((IWineD3DPixelShaderImpl *) pshader)->needsbumpmat != -1) {
float *data = (float *) &stateBlock->textureState[(int) ((IWineD3DPixelShaderImpl *) pshader)->needsbumpmat][WINED3DTSS_BUMPENVMAT00];
GL_EXTCALL(glUniformMatrix2fvARB(prog->bumpenvmat_location, 1, 0, data));
for(i = 0; i < ((IWineD3DPixelShaderImpl *) pshader)->numbumpenvmatconsts; i++) {
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pshader;
int stage = ps->luminanceconst[i].texunit;
float *data = (float *) &stateBlock->textureState[(int) ps->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
GL_EXTCALL(glUniformMatrix2fvARB(prog->bumpenvmat_location[i], 1, 0, data));
checkGLcall("glUniformMatrix2fvARB");
/* texbeml needs the luminance scale and offset too. If texbeml is used, needsbumpmat
* is set too, so we can check that in the needsbumpmat check
*/
if(((IWineD3DPixelShaderImpl *) pshader)->baseShader.reg_maps.luminanceparams != -1) {
int stage = ((IWineD3DPixelShaderImpl *) pshader)->baseShader.reg_maps.luminanceparams;
if(ps->baseShader.reg_maps.luminanceparams[stage]) {
GLfloat *scale = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
GLfloat *offset = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
GL_EXTCALL(glUniform1fvARB(prog->luminancescale_location, 1, scale));
GL_EXTCALL(glUniform1fvARB(prog->luminancescale_location[i], 1, scale));
checkGLcall("glUniform1fvARB");
GL_EXTCALL(glUniform1fvARB(prog->luminanceoffset_location, 1, offset));
GL_EXTCALL(glUniform1fvARB(prog->luminanceoffset_location[i], 1, offset));
checkGLcall("glUniform1fvARB");
}
} else if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
}
if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
!((IWineD3DPixelShaderImpl *) pshader)->srgb_mode_hardcoded) {
float comparison[4];
float mul_low[4];
@ -540,14 +545,26 @@ void shader_generate_glsl_declarations(
} else {
IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
if(reg_maps->bumpmat != -1) {
shader_addline(buffer, "uniform mat2 bumpenvmat;\n");
if(reg_maps->luminanceparams) {
shader_addline(buffer, "uniform float luminancescale;\n");
shader_addline(buffer, "uniform float luminanceoffset;\n");
extra_constants_needed++;
ps_impl->numbumpenvmatconsts = 0;
for(i = 0; i < (sizeof(reg_maps->bumpmat) / sizeof(reg_maps->bumpmat[0])); i++) {
if(!reg_maps->bumpmat[i]) {
continue;
}
ps_impl->bumpenvmatconst[(int) ps_impl->numbumpenvmatconsts].texunit = i;
shader_addline(buffer, "uniform mat2 bumpenvmat%d;\n", i);
if(reg_maps->luminanceparams) {
ps_impl->luminanceconst[(int) ps_impl->numbumpenvmatconsts].texunit = i;
shader_addline(buffer, "uniform float luminancescale%d;\n", i);
shader_addline(buffer, "uniform float luminanceoffset%d;\n", i);
extra_constants_needed++;
} else {
ps_impl->luminanceconst[(int) ps_impl->numbumpenvmatconsts].texunit = -1;
}
extra_constants_needed++;
ps_impl->numbumpenvmatconsts++;
}
if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
@ -2555,24 +2572,25 @@ void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) {
if(arg->opcode->opcode == WINED3DSIO_TEXBEML) {
glsl_src_param_t luminance_param;
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_2, &luminance_param);
shader_addline(arg->buffer, "(%s(Psampler%u, T%u%s + vec4(bumpenvmat * %s, 0.0, 0.0)%s )*(%s * luminancescale + luminanceoffset))%s);\n",
sample_function.name, sampler_idx, sampler_idx, coord_mask, coord_param.param_str, coord_mask,
luminance_param.param_str, dst_swizzle);
shader_addline(arg->buffer, "(%s(Psampler%u, T%u%s + vec4(bumpenvmat%d * %s, 0.0, 0.0)%s )*(%s * luminancescale%d + luminanceoffset%d))%s);\n",
sample_function.name, sampler_idx, sampler_idx, coord_mask, sampler_idx, coord_param.param_str, coord_mask,
luminance_param.param_str, sampler_idx, sampler_idx, dst_swizzle);
} else {
shader_addline(arg->buffer, "%s(Psampler%u, T%u%s + vec4(bumpenvmat * %s, 0.0, 0.0)%s )%s);\n",
sample_function.name, sampler_idx, sampler_idx, coord_mask, coord_param.param_str, coord_mask, dst_swizzle);
shader_addline(arg->buffer, "%s(Psampler%u, T%u%s + vec4(bumpenvmat%d * %s, 0.0, 0.0)%s )%s);\n",
sample_function.name, sampler_idx, sampler_idx, coord_mask, sampler_idx, coord_param.param_str, coord_mask, dst_swizzle);
}
}
void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) {
glsl_src_param_t src0_param, src1_param;
DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0|WINED3DSP_WRITEMASK_1, &src0_param);
shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], WINED3DSP_WRITEMASK_0|WINED3DSP_WRITEMASK_1, &src1_param);
shader_glsl_append_dst(arg->buffer, arg);
shader_addline(arg->buffer, "%s + bumpenvmat * %s);\n",
src0_param.param_str, src1_param.param_str);
shader_addline(arg->buffer, "%s + bumpenvmat%d * %s);\n",
src0_param.param_str, sampler_idx, src1_param.param_str);
}
/** Process the WINED3DSIO_TEXREG2AR instruction in GLSL
@ -3148,10 +3166,20 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
entry->puniformI_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
}
if(pshader) {
for(i = 0; i < ((IWineD3DPixelShaderImpl*)pshader)->numbumpenvmatconsts; i++) {
char name[32];
sprintf(name, "bumpenvmat%d", ((IWineD3DPixelShaderImpl*)pshader)->bumpenvmatconst[i].texunit);
entry->bumpenvmat_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
sprintf(name, "luminancescale%d", ((IWineD3DPixelShaderImpl*)pshader)->luminanceconst[i].texunit);
entry->luminancescale_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
sprintf(name, "luminanceoffset%d", ((IWineD3DPixelShaderImpl*)pshader)->luminanceconst[i].texunit);
entry->luminanceoffset_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
}
}
entry->posFixup_location = GL_EXTCALL(glGetUniformLocationARB(programId, "posFixup"));
entry->bumpenvmat_location = GL_EXTCALL(glGetUniformLocationARB(programId, "bumpenvmat"));
entry->luminancescale_location = GL_EXTCALL(glGetUniformLocationARB(programId, "luminancescale"));
entry->luminanceoffset_location = GL_EXTCALL(glGetUniformLocationARB(programId, "luminanceoffset"));
entry->srgb_comparison_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_comparison"));
entry->srgb_mul_low_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_mul_low"));
entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));

View File

@ -467,8 +467,6 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
}
}
This->needsbumpmat = reg_maps->bumpmat;
#if 1 /* if were using the data buffer of device then we don't need to free it */
HeapFree(GetProcessHeap(), 0, buffer.buffer);
#endif

View File

@ -2403,7 +2403,7 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, W
} tmpvalue;
if(stateblock->pixelShader && stage != 0 &&
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams == stage) {
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
/* The pixel shader has to know the luminance scale. Do a constants update if it
* isn't scheduled anyway
*/
@ -2427,7 +2427,7 @@ static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock,
} tmpvalue;
if(stateblock->pixelShader && stage != 0 &&
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams == stage) {
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
/* The pixel shader has to know the luminance offset. Do a constants update if it
* isn't scheduled anyway
*/
@ -2621,9 +2621,8 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
float mat[2][2];
if(stateblock->pixelShader && stage != 0 &&
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->needsbumpmat == stage) {
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
/* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
* anyway
*/

View File

@ -1735,9 +1735,9 @@ struct glsl_shader_prog_link {
GLhandleARB vuniformI_locations[MAX_CONST_I];
GLhandleARB puniformI_locations[MAX_CONST_I];
GLhandleARB posFixup_location;
GLhandleARB bumpenvmat_location;
GLhandleARB luminancescale_location;
GLhandleARB luminanceoffset_location;
GLhandleARB bumpenvmat_location[MAX_TEXTURES];
GLhandleARB luminancescale_location[MAX_TEXTURES];
GLhandleARB luminanceoffset_location[MAX_TEXTURES];
GLhandleARB srgb_comparison_location;
GLhandleARB srgb_mul_low_location;
GLhandleARB ycorrection_location;
@ -1788,7 +1788,7 @@ typedef struct shader_reg_maps {
/* Sampler usage tokens
* Use 0 as default (bit 31 is always 1 on a valid token) */
DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
char bumpmat, luminanceparams;
BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
char usesnrm, vpos, usesdsy;
char usesrelconstF;
@ -2243,6 +2243,11 @@ enum vertexprocessing_mode {
pretransformed
};
struct stb_const_desc {
char texunit;
UINT const_num;
};
typedef struct IWineD3DPixelShaderImpl {
/* IUnknown parts */
const IWineD3DPixelShaderVtbl *lpVtbl;
@ -2262,9 +2267,9 @@ typedef struct IWineD3DPixelShaderImpl {
PSHADERDATA *data;
/* Some information about the shader behavior */
char needsbumpmat;
UINT bumpenvmatconst;
UINT luminanceconst;
struct stb_const_desc bumpenvmatconst[MAX_TEXTURES];
char numbumpenvmatconsts;
struct stb_const_desc luminanceconst[MAX_TEXTURES];
char srgb_enabled;
char srgb_mode_hardcoded;
UINT srgb_low_const;