wined3d: Support more than one texbem instruction per shader.
This commit is contained in:
parent
739278baf1
commit
167a271434
@ -153,6 +153,7 @@ void shader_arb_load_constants(
|
|||||||
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
|
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
|
||||||
IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
|
IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
|
||||||
WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
|
WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
|
||||||
|
unsigned char i;
|
||||||
|
|
||||||
if (useVertexShader) {
|
if (useVertexShader) {
|
||||||
IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
|
IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
|
||||||
@ -180,25 +181,25 @@ void shader_arb_load_constants(
|
|||||||
stateBlock->pixelShaderConstantF,
|
stateBlock->pixelShaderConstantF,
|
||||||
deviceImpl->activeContext->pshader_const_dirty);
|
deviceImpl->activeContext->pshader_const_dirty);
|
||||||
|
|
||||||
if(((IWineD3DPixelShaderImpl *) pshader)->bumpenvmatconst != -1) {
|
for(i = 0; i < psi->numbumpenvmatconsts; i++) {
|
||||||
/* needsbumpmat stores the stage number from where to load the matrix. bumpenvmatconst stores the
|
/* The state manager takes care that this function is always called if the bump env matrix changes
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
float *data = (float *) &stateBlock->textureState[(int) psi->needsbumpmat][WINED3DTSS_BUMPENVMAT00];
|
float *data = (float *) &stateBlock->textureState[(int) psi->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
|
||||||
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->bumpenvmatconst, data));
|
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.
|
/* 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
|
* 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.
|
* 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
|
* (they're WINED3DTSS_TEXTURETRANSFORMFLAGS and WINED3DTSS_ADDRESSW, so most likely 0 or NaN
|
||||||
*/
|
*/
|
||||||
float *scale = (float *) &stateBlock->textureState[(int) psi->needsbumpmat][WINED3DTSS_BUMPENVLSCALE];
|
float *scale = (float *) &stateBlock->textureState[(int) psi->luminanceconst[i].texunit][WINED3DTSS_BUMPENVLSCALE];
|
||||||
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->luminanceconst, scale));
|
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->luminanceconst[i].const_num, scale));
|
||||||
deviceImpl->activeContext->pshader_const_dirty[psi->luminanceconst] = 1;
|
deviceImpl->activeContext->pshader_const_dirty[psi->luminanceconst[i].const_num] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
|
if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
|
||||||
!((IWineD3DPixelShaderImpl *) pshader)->srgb_mode_hardcoded) {
|
!((IWineD3DPixelShaderImpl *) pshader)->srgb_mode_hardcoded) {
|
||||||
float comparison[4];
|
float comparison[4];
|
||||||
@ -236,7 +237,7 @@ void shader_generate_arb_declarations(
|
|||||||
|
|
||||||
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
||||||
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
|
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
|
||||||
DWORD i;
|
DWORD i, cur;
|
||||||
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
||||||
unsigned max_constantsF = min(This->baseShader.limits.constant_float,
|
unsigned max_constantsF = min(This->baseShader.limits.constant_float,
|
||||||
(pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
|
(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);
|
shader_addline(buffer, "MOV T%u, fragment.texcoord[%u];\n", i, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
((IWineD3DPixelShaderImpl *)This)->bumpenvmatconst = -1;
|
for(i = 0; i < (sizeof(reg_maps->bumpmat) / sizeof(reg_maps->bumpmat[0])); i++) {
|
||||||
((IWineD3DPixelShaderImpl *)This)->luminanceconst = -1;
|
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) This;
|
||||||
if(reg_maps->bumpmat != -1 /* Only a pshader can use texbem */) {
|
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
|
/* 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
|
* the stateblock into the shader. If no constant is available don't load, texbem will then just sample the texture without applying
|
||||||
* bump mapping.
|
* bump mapping.
|
||||||
*/
|
*/
|
||||||
if(max_constantsF < GL_LIMITS(pshader_constantsF)) {
|
if(max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF)) {
|
||||||
((IWineD3DPixelShaderImpl *)This)->bumpenvmatconst = max_constantsF;
|
ps->bumpenvmatconst[cur].const_num = max_constantsF + extra_constants_needed;
|
||||||
shader_addline(buffer, "PARAM bumpenvmat%d = program.env[%d];\n", reg_maps->bumpmat, ((IWineD3DPixelShaderImpl *)This)->bumpenvmatconst);
|
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)) {
|
if(reg_maps->luminanceparams && max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF)) {
|
||||||
extra_constants_needed += 1;
|
((IWineD3DPixelShaderImpl *)This)->luminanceconst[cur].const_num = max_constantsF + extra_constants_needed;
|
||||||
((IWineD3DPixelShaderImpl *)This)->luminanceconst = max_constantsF + 1;
|
shader_addline(buffer, "PARAM luminance%d = program.env[%d];\n",
|
||||||
shader_addline(buffer, "PARAM luminance%d = program.env[%d];\n", reg_maps->luminanceparams, ((IWineD3DPixelShaderImpl *)This)->luminanceconst);
|
i, ps->luminanceconst[cur].const_num);
|
||||||
} else if(reg_maps->luminanceparams != -1) {
|
extra_constants_needed++;
|
||||||
|
} else if(reg_maps->luminanceparams) {
|
||||||
FIXME("No free constant to load the luminance parameters\n");
|
FIXME("No free constant to load the luminance parameters\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FIXME("No free constant found to load environemnt bump mapping matrix into the shader. texbem instruction will not apply bump mapping\n");
|
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) {
|
if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] && pshader) {
|
||||||
IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
|
IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
|
||||||
/* If there are 2 constants left to use, use them to pass the sRGB correction values in. This way
|
/* 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 src_name[2][50];
|
||||||
char dst_wmask[20];
|
char dst_wmask[20];
|
||||||
DWORD sampler_code = arg->dst & WINED3DSP_REGNUM_MASK;
|
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);
|
pshader_get_register_name(arg->shader, arg->dst, dst_name);
|
||||||
shader_arb_get_write_mask(arg, arg->dst, dst_wmask);
|
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) {
|
void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
|
||||||
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||||
DWORD sampler_code = arg->dst & WINED3DSP_REGNUM_MASK;
|
BOOL has_bumpmat = FALSE;
|
||||||
BOOL has_bumpmat = (This->bumpenvmatconst != -1);
|
BOOL has_luminance = FALSE;
|
||||||
BOOL has_luminance = (This->luminanceconst != -1);
|
int i;
|
||||||
|
|
||||||
DWORD dst = arg->dst;
|
DWORD dst = arg->dst;
|
||||||
DWORD src = arg->src[0] & WINED3DSP_REGNUM_MASK;
|
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 */
|
/* Can directly use the name because texbem is only valid for <= 1.3 shaders */
|
||||||
pshader_get_register_name(arg->shader, dst, reg_coord);
|
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) {
|
if(has_bumpmat) {
|
||||||
/* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
|
/* 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, "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);
|
shader_addline(buffer, "DP3 TMP.g, TMP2, T%u;\n", src);
|
||||||
|
|
||||||
/* with projective textures, texbem only divides the static texture coord, not the displacement,
|
/* 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) {
|
if(arg->opcode->opcode == WINED3DSIO_TEXBEML && has_luminance) {
|
||||||
shader_addline(buffer, "MAD TMP, T%u.z, luminance%d.x, luminance%d.y;\n",
|
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);
|
shader_addline(buffer, "MUL %s, %s, TMP;\n", reg_coord, reg_coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,8 +212,8 @@ HRESULT shader_get_registers_used(
|
|||||||
/* There are some minor differences between pixel and vertex shaders */
|
/* There are some minor differences between pixel and vertex shaders */
|
||||||
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
||||||
|
|
||||||
reg_maps->bumpmat = -1;
|
memset(reg_maps->bumpmat, 0, sizeof(reg_maps->bumpmat));
|
||||||
reg_maps->luminanceparams = -1;
|
memset(reg_maps->luminanceparams, 0, sizeof(reg_maps->luminanceparams));
|
||||||
|
|
||||||
if (pToken == NULL)
|
if (pToken == NULL)
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
@ -349,6 +349,7 @@ HRESULT shader_get_registers_used(
|
|||||||
|
|
||||||
/* Declare 1.X samplers implicitly, based on the destination reg. number */
|
/* 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_TEX == curOpcode->opcode ||
|
||||||
WINED3DSIO_TEXBEM == curOpcode->opcode ||
|
WINED3DSIO_TEXBEM == curOpcode->opcode ||
|
||||||
WINED3DSIO_TEXBEML == curOpcode->opcode ||
|
WINED3DSIO_TEXBEML == curOpcode->opcode ||
|
||||||
@ -395,25 +396,17 @@ HRESULT shader_get_registers_used(
|
|||||||
/* texbem is only valid with < 1.4 pixel shaders */
|
/* texbem is only valid with < 1.4 pixel shaders */
|
||||||
if(WINED3DSIO_TEXBEM == curOpcode->opcode ||
|
if(WINED3DSIO_TEXBEM == curOpcode->opcode ||
|
||||||
WINED3DSIO_TEXBEML == curOpcode->opcode) {
|
WINED3DSIO_TEXBEML == curOpcode->opcode) {
|
||||||
if(reg_maps->bumpmat != -1 && reg_maps->bumpmat != sampler_code) {
|
reg_maps->bumpmat[sampler_code] = TRUE;
|
||||||
FIXME("Pixel shader uses texbem instruction on more than 1 sampler\n");
|
|
||||||
} else {
|
|
||||||
reg_maps->bumpmat = sampler_code;
|
|
||||||
if(WINED3DSIO_TEXBEML == curOpcode->opcode) {
|
if(WINED3DSIO_TEXBEML == curOpcode->opcode) {
|
||||||
reg_maps->luminanceparams = sampler_code;
|
reg_maps->luminanceparams[sampler_code] = TRUE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(WINED3DSIO_NRM == curOpcode->opcode) {
|
if(WINED3DSIO_NRM == curOpcode->opcode) {
|
||||||
reg_maps->usesnrm = 1;
|
reg_maps->usesnrm = 1;
|
||||||
} else if(WINED3DSIO_BEM == curOpcode->opcode) {
|
} else if(WINED3DSIO_BEM == curOpcode->opcode && pshader) {
|
||||||
DWORD regnum = *pToken & WINED3DSP_REGNUM_MASK;
|
DWORD regnum = *pToken & WINED3DSP_REGNUM_MASK;
|
||||||
if(reg_maps->bumpmat != -1 && reg_maps->bumpmat != regnum) {
|
reg_maps->bumpmat[regnum] = TRUE;
|
||||||
FIXME("Pixel shader uses bem or texbem instruction on more than 1 sampler\n");
|
|
||||||
} else {
|
|
||||||
reg_maps->bumpmat = regnum;
|
|
||||||
}
|
|
||||||
} else if(WINED3DSIO_DSY == curOpcode->opcode) {
|
} else if(WINED3DSIO_DSY == curOpcode->opcode) {
|
||||||
reg_maps->usesdsy = 1;
|
reg_maps->usesdsy = 1;
|
||||||
}
|
}
|
||||||
|
@ -371,6 +371,7 @@ void shader_glsl_load_constants(
|
|||||||
struct list *constant_list;
|
struct list *constant_list;
|
||||||
GLhandleARB programId;
|
GLhandleARB programId;
|
||||||
struct glsl_shader_prog_link *prog = stateBlock->glsl_program;
|
struct glsl_shader_prog_link *prog = stateBlock->glsl_program;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if (!prog) {
|
if (!prog) {
|
||||||
/* No GLSL program set - nothing to do. */
|
/* 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.
|
/* 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.
|
* It can't be 0 for a valid texbem instruction.
|
||||||
*/
|
*/
|
||||||
if(((IWineD3DPixelShaderImpl *) pshader)->needsbumpmat != -1) {
|
for(i = 0; i < ((IWineD3DPixelShaderImpl *) pshader)->numbumpenvmatconsts; i++) {
|
||||||
float *data = (float *) &stateBlock->textureState[(int) ((IWineD3DPixelShaderImpl *) pshader)->needsbumpmat][WINED3DTSS_BUMPENVMAT00];
|
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pshader;
|
||||||
GL_EXTCALL(glUniformMatrix2fvARB(prog->bumpenvmat_location, 1, 0, data));
|
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");
|
checkGLcall("glUniformMatrix2fvARB");
|
||||||
|
|
||||||
/* texbeml needs the luminance scale and offset too. If texbeml is used, needsbumpmat
|
/* 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
|
* is set too, so we can check that in the needsbumpmat check
|
||||||
*/
|
*/
|
||||||
if(((IWineD3DPixelShaderImpl *) pshader)->baseShader.reg_maps.luminanceparams != -1) {
|
if(ps->baseShader.reg_maps.luminanceparams[stage]) {
|
||||||
int stage = ((IWineD3DPixelShaderImpl *) pshader)->baseShader.reg_maps.luminanceparams;
|
|
||||||
GLfloat *scale = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
|
GLfloat *scale = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
|
||||||
GLfloat *offset = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
|
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");
|
checkGLcall("glUniform1fvARB");
|
||||||
GL_EXTCALL(glUniform1fvARB(prog->luminanceoffset_location, 1, offset));
|
GL_EXTCALL(glUniform1fvARB(prog->luminanceoffset_location[i], 1, offset));
|
||||||
checkGLcall("glUniform1fvARB");
|
checkGLcall("glUniform1fvARB");
|
||||||
}
|
}
|
||||||
} else if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
|
}
|
||||||
|
|
||||||
|
if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
|
||||||
!((IWineD3DPixelShaderImpl *) pshader)->srgb_mode_hardcoded) {
|
!((IWineD3DPixelShaderImpl *) pshader)->srgb_mode_hardcoded) {
|
||||||
float comparison[4];
|
float comparison[4];
|
||||||
float mul_low[4];
|
float mul_low[4];
|
||||||
@ -540,14 +545,26 @@ void shader_generate_glsl_declarations(
|
|||||||
} else {
|
} else {
|
||||||
IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
|
IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
|
||||||
|
|
||||||
if(reg_maps->bumpmat != -1) {
|
ps_impl->numbumpenvmatconsts = 0;
|
||||||
shader_addline(buffer, "uniform mat2 bumpenvmat;\n");
|
for(i = 0; i < (sizeof(reg_maps->bumpmat) / sizeof(reg_maps->bumpmat[0])); i++) {
|
||||||
if(reg_maps->luminanceparams) {
|
if(!reg_maps->bumpmat[i]) {
|
||||||
shader_addline(buffer, "uniform float luminancescale;\n");
|
continue;
|
||||||
shader_addline(buffer, "uniform float luminanceoffset;\n");
|
|
||||||
extra_constants_needed++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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++;
|
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]) {
|
if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
|
||||||
@ -2555,24 +2572,25 @@ void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) {
|
|||||||
if(arg->opcode->opcode == WINED3DSIO_TEXBEML) {
|
if(arg->opcode->opcode == WINED3DSIO_TEXBEML) {
|
||||||
glsl_src_param_t luminance_param;
|
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_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",
|
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, coord_param.param_str, coord_mask,
|
sample_function.name, sampler_idx, sampler_idx, coord_mask, sampler_idx, coord_param.param_str, coord_mask,
|
||||||
luminance_param.param_str, dst_swizzle);
|
luminance_param.param_str, sampler_idx, sampler_idx, dst_swizzle);
|
||||||
} else {
|
} else {
|
||||||
shader_addline(arg->buffer, "%s(Psampler%u, T%u%s + vec4(bumpenvmat * %s, 0.0, 0.0)%s )%s);\n",
|
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, coord_param.param_str, coord_mask, dst_swizzle);
|
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) {
|
void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) {
|
||||||
glsl_src_param_t src0_param, src1_param;
|
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[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_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_glsl_append_dst(arg->buffer, arg);
|
||||||
shader_addline(arg->buffer, "%s + bumpenvmat * %s);\n",
|
shader_addline(arg->buffer, "%s + bumpenvmat%d * %s);\n",
|
||||||
src0_param.param_str, src1_param.param_str);
|
src0_param.param_str, sampler_idx, src1_param.param_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Process the WINED3DSIO_TEXREG2AR instruction in GLSL
|
/** 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));
|
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->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_comparison_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_comparison"));
|
||||||
entry->srgb_mul_low_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_mul_low"));
|
entry->srgb_mul_low_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_mul_low"));
|
||||||
entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
|
entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
|
||||||
|
@ -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 */
|
#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
|
||||||
|
@ -2403,7 +2403,7 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||||||
} tmpvalue;
|
} tmpvalue;
|
||||||
|
|
||||||
if(stateblock->pixelShader && stage != 0 &&
|
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
|
/* The pixel shader has to know the luminance scale. Do a constants update if it
|
||||||
* isn't scheduled anyway
|
* isn't scheduled anyway
|
||||||
*/
|
*/
|
||||||
@ -2427,7 +2427,7 @@ static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock,
|
|||||||
} tmpvalue;
|
} tmpvalue;
|
||||||
|
|
||||||
if(stateblock->pixelShader && stage != 0 &&
|
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
|
/* The pixel shader has to know the luminance offset. Do a constants update if it
|
||||||
* isn't scheduled anyway
|
* 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) {
|
static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||||
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
|
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
|
||||||
float mat[2][2];
|
float mat[2][2];
|
||||||
|
|
||||||
if(stateblock->pixelShader && stage != 0 &&
|
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
|
/* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
|
||||||
* anyway
|
* anyway
|
||||||
*/
|
*/
|
||||||
|
@ -1735,9 +1735,9 @@ struct glsl_shader_prog_link {
|
|||||||
GLhandleARB vuniformI_locations[MAX_CONST_I];
|
GLhandleARB vuniformI_locations[MAX_CONST_I];
|
||||||
GLhandleARB puniformI_locations[MAX_CONST_I];
|
GLhandleARB puniformI_locations[MAX_CONST_I];
|
||||||
GLhandleARB posFixup_location;
|
GLhandleARB posFixup_location;
|
||||||
GLhandleARB bumpenvmat_location;
|
GLhandleARB bumpenvmat_location[MAX_TEXTURES];
|
||||||
GLhandleARB luminancescale_location;
|
GLhandleARB luminancescale_location[MAX_TEXTURES];
|
||||||
GLhandleARB luminanceoffset_location;
|
GLhandleARB luminanceoffset_location[MAX_TEXTURES];
|
||||||
GLhandleARB srgb_comparison_location;
|
GLhandleARB srgb_comparison_location;
|
||||||
GLhandleARB srgb_mul_low_location;
|
GLhandleARB srgb_mul_low_location;
|
||||||
GLhandleARB ycorrection_location;
|
GLhandleARB ycorrection_location;
|
||||||
@ -1788,7 +1788,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(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
|
DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
|
||||||
char bumpmat, luminanceparams;
|
BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
|
||||||
char usesnrm, vpos, usesdsy;
|
char usesnrm, vpos, usesdsy;
|
||||||
char usesrelconstF;
|
char usesrelconstF;
|
||||||
|
|
||||||
@ -2243,6 +2243,11 @@ enum vertexprocessing_mode {
|
|||||||
pretransformed
|
pretransformed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct stb_const_desc {
|
||||||
|
char texunit;
|
||||||
|
UINT const_num;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct IWineD3DPixelShaderImpl {
|
typedef struct IWineD3DPixelShaderImpl {
|
||||||
/* IUnknown parts */
|
/* IUnknown parts */
|
||||||
const IWineD3DPixelShaderVtbl *lpVtbl;
|
const IWineD3DPixelShaderVtbl *lpVtbl;
|
||||||
@ -2262,9 +2267,9 @@ typedef struct IWineD3DPixelShaderImpl {
|
|||||||
PSHADERDATA *data;
|
PSHADERDATA *data;
|
||||||
|
|
||||||
/* Some information about the shader behavior */
|
/* Some information about the shader behavior */
|
||||||
char needsbumpmat;
|
struct stb_const_desc bumpenvmatconst[MAX_TEXTURES];
|
||||||
UINT bumpenvmatconst;
|
char numbumpenvmatconsts;
|
||||||
UINT luminanceconst;
|
struct stb_const_desc luminanceconst[MAX_TEXTURES];
|
||||||
char srgb_enabled;
|
char srgb_enabled;
|
||||||
char srgb_mode_hardcoded;
|
char srgb_mode_hardcoded;
|
||||||
UINT srgb_low_const;
|
UINT srgb_low_const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user