Commit 49a49fcf authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Load one bump mapping environment matrix into pixel shaders if needed.

parent efbd6d63
...@@ -344,6 +344,15 @@ HRESULT shader_get_registers_used( ...@@ -344,6 +344,15 @@ HRESULT shader_get_registers_used(
reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D; reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
} }
} }
/* texbem is only valid with < 1.4 pixel shaders */
if(WINED3DSIO_TEXBEM == curOpcode->opcode) {
if(reg_maps->bumpmat != 0 && reg_maps->bumpmat != sampler_code) {
FIXME("Pixel shader uses texbem instruction on more than 1 sampler\n");
} else {
reg_maps->bumpmat = sampler_code;
}
}
} }
/* This will loop over all the registers and try to /* This will loop over all the registers and try to
......
...@@ -284,10 +284,17 @@ void select_shader_max_constants( ...@@ -284,10 +284,17 @@ void select_shader_max_constants(
switch (ps_selected_mode) { switch (ps_selected_mode) {
case SHADER_GLSL: case SHADER_GLSL:
/* Subtract the other potential uniforms from the max available (bools & ints) */ /* Subtract the other potential uniforms from the max available (bools & ints).
* In theory the texbem instruction may need one more shader constant too. But lets assume
* that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
* and lets not take away a uniform needlessly from all other shaders.
*/
gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - MAX_CONST_B - MAX_CONST_I; gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - MAX_CONST_B - MAX_CONST_I;
break; break;
case SHADER_ARB: case SHADER_ARB:
/* The arb shader only loads the bump mapping environment matrix into the shader if it finds
* a free constant to do that, so no need to reduce the number of available constants.
*/
gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF; gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF;
break; break;
case SHADER_SW: case SHADER_SW:
......
...@@ -283,7 +283,8 @@ void shader_glsl_load_constants( ...@@ -283,7 +283,8 @@ void shader_glsl_load_constants(
GLhandleARB *constant_locations; GLhandleARB *constant_locations;
struct list *constant_list; struct list *constant_list;
GLhandleARB programId; GLhandleARB programId;
GLint pos;
if (!stateBlock->glsl_program) { if (!stateBlock->glsl_program) {
/* No GLSL program set - nothing to do. */ /* No GLSL program set - nothing to do. */
return; return;
...@@ -336,11 +337,22 @@ void shader_glsl_load_constants( ...@@ -336,11 +337,22 @@ void shader_glsl_load_constants(
shader_glsl_load_constantsI(pshader, gl_info, programId, MAX_CONST_I, shader_glsl_load_constantsI(pshader, gl_info, programId, MAX_CONST_I,
stateBlock->pixelShaderConstantI, stateBlock->pixelShaderConstantI,
stateBlock->set.pixelShaderConstantsI); stateBlock->set.pixelShaderConstantsI);
/* Load DirectX 9 boolean constants/uniforms for pixel shader */ /* Load DirectX 9 boolean constants/uniforms for pixel shader */
shader_glsl_load_constantsB(pshader, gl_info, programId, MAX_CONST_B, shader_glsl_load_constantsB(pshader, gl_info, programId, MAX_CONST_B,
stateBlock->pixelShaderConstantB, stateBlock->pixelShaderConstantB,
stateBlock->set.pixelShaderConstantsB); stateBlock->set.pixelShaderConstantsB);
/* 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 != 0) {
float *data = (float *) &stateBlock->textureState[(int) ((IWineD3DPixelShaderImpl *) pshader)->needsbumpmat][WINED3DTSS_BUMPENVMAT00];
pos = GL_EXTCALL(glGetUniformLocationARB(programId, "bumpenvmat"));
checkGLcall("glGetUniformLocationARB");
GL_EXTCALL(glUniform4fvARB(pos, 1, data));
checkGLcall("glUniform4fvARB");
}
} }
} }
...@@ -379,6 +391,8 @@ void shader_generate_glsl_declarations( ...@@ -379,6 +391,8 @@ void shader_generate_glsl_declarations(
if(!pshader) if(!pshader)
shader_addline(buffer, "uniform vec4 posFixup;\n"); shader_addline(buffer, "uniform vec4 posFixup;\n");
else if(reg_maps->bumpmat)
shader_addline(buffer, "uniform vec4 bumpenvmat;\n");
/* Declare texture samplers */ /* Declare texture samplers */
for (i = 0; i < This->baseShader.limits.sampler; i++) { for (i = 0; i < This->baseShader.limits.sampler; i++) {
......
...@@ -914,6 +914,8 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( ...@@ -914,6 +914,8 @@ inline static 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 */ #if 1 /* if were using the data buffer of device then we don't need to free it */
HeapFree(GetProcessHeap(), 0, buffer.buffer); HeapFree(GetProcessHeap(), 0, buffer.buffer);
#endif #endif
......
...@@ -1951,6 +1951,18 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D ...@@ -1951,6 +1951,18 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
} }
static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
if(stateblock->pixelShader && stage != 0 &&
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->needsbumpmat == stage) {
/* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
* anyway
*/
if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
!isStateDirty(context, STATE_PIXELSHADER)) {
shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
}
}
} }
static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
......
...@@ -1468,6 +1468,7 @@ typedef struct shader_reg_maps { ...@@ -1468,6 +1468,7 @@ typedef struct shader_reg_maps {
/* Sampler usage tokens /* Sampler usage tokens
* Use 0 as default (bit 31 is always 1 on a valid token) */ * Use 0 as default (bit 31 is always 1 on a valid token) */
DWORD samplers[MAX_SAMPLERS]; DWORD samplers[MAX_SAMPLERS];
char bumpmat;
/* Whether or not a loop is used in this shader */ /* Whether or not a loop is used in this shader */
char loop; char loop;
...@@ -1834,6 +1835,10 @@ typedef struct IWineD3DPixelShaderImpl { ...@@ -1834,6 +1835,10 @@ typedef struct IWineD3DPixelShaderImpl {
/* run time data */ /* run time data */
PSHADERDATA *data; PSHADERDATA *data;
/* Some information about the shader behavior */
char needsbumpmat;
UINT bumpenvmatconst;
#if 0 /* needs reworking */ #if 0 /* needs reworking */
PSHADERINPUTDATA input; PSHADERINPUTDATA input;
PSHADEROUTPUTDATA output; PSHADEROUTPUTDATA output;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment