wined3d: Load one bump mapping environment matrix into pixel shaders if needed.
This commit is contained in:
parent
efbd6d6332
commit
49a49fcfec
|
@ -344,6 +344,15 @@ HRESULT shader_get_registers_used(
|
|||
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
|
||||
|
|
|
@ -284,10 +284,17 @@ void select_shader_max_constants(
|
|||
|
||||
switch (ps_selected_mode) {
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
case SHADER_SW:
|
||||
|
|
|
@ -283,6 +283,7 @@ void shader_glsl_load_constants(
|
|||
GLhandleARB *constant_locations;
|
||||
struct list *constant_list;
|
||||
GLhandleARB programId;
|
||||
GLint pos;
|
||||
|
||||
if (!stateBlock->glsl_program) {
|
||||
/* No GLSL program set - nothing to do. */
|
||||
|
@ -341,6 +342,17 @@ void shader_glsl_load_constants(
|
|||
shader_glsl_load_constantsB(pshader, gl_info, programId, MAX_CONST_B,
|
||||
stateBlock->pixelShaderConstantB,
|
||||
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(
|
|||
|
||||
if(!pshader)
|
||||
shader_addline(buffer, "uniform vec4 posFixup;\n");
|
||||
else if(reg_maps->bumpmat)
|
||||
shader_addline(buffer, "uniform vec4 bumpenvmat;\n");
|
||||
|
||||
/* Declare texture samplers */
|
||||
for (i = 0; i < This->baseShader.limits.sampler; i++) {
|
||||
|
|
|
@ -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 */
|
||||
HeapFree(GetProcessHeap(), 0, buffer.buffer);
|
||||
#endif
|
||||
|
|
|
@ -1951,6 +1951,18 @@ 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;
|
||||
|
||||
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) {
|
||||
|
|
|
@ -1468,6 +1468,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_SAMPLERS];
|
||||
char bumpmat;
|
||||
|
||||
/* Whether or not a loop is used in this shader */
|
||||
char loop;
|
||||
|
@ -1834,6 +1835,10 @@ typedef struct IWineD3DPixelShaderImpl {
|
|||
/* run time data */
|
||||
PSHADERDATA *data;
|
||||
|
||||
/* Some information about the shader behavior */
|
||||
char needsbumpmat;
|
||||
UINT bumpenvmatconst;
|
||||
|
||||
#if 0 /* needs reworking */
|
||||
PSHADERINPUTDATA input;
|
||||
PSHADEROUTPUTDATA output;
|
||||
|
|
Loading…
Reference in New Issue