wined3d: Implement texbem in arb, improve it in glsl.
This commit is contained in:
parent
49a49fcfec
commit
99576ea24e
|
@ -119,6 +119,15 @@ void shader_arb_load_constants(
|
|||
GL_LIMITS(pshader_constantsF),
|
||||
stateBlock->pixelShaderConstantF,
|
||||
&stateBlock->set_pconstantsF);
|
||||
if(((IWineD3DPixelShaderImpl *) pshader)->bumpenvmatconst) {
|
||||
/* 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
|
||||
*/
|
||||
IWineD3DPixelShaderImpl *psi = (IWineD3DPixelShaderImpl *) pshader;
|
||||
float *data = (float *) &stateBlock->textureState[(int) psi->needsbumpmat][WINED3DTSS_BUMPENVMAT00];
|
||||
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->bumpenvmatconst, data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,6 +168,19 @@ void shader_generate_arb_declarations(
|
|||
shader_addline(buffer, "MOV T%u, fragment.texcoord[%u];\n", i, i);
|
||||
}
|
||||
|
||||
if(reg_maps->bumpmat /* Only a pshader can use texbem */) {
|
||||
/* 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 = program.env[%d];\n", ((IWineD3DPixelShaderImpl *)This)->bumpenvmatconst);
|
||||
} else {
|
||||
FIXME("No free constant found to load environemnt bump mapping matrix into the shader. texbem instruction will not apply bump mapping\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Need to PARAM the environment parameters (constants) so we can use relative addressing */
|
||||
shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
|
||||
max_constantsF, max_constantsF - 1);
|
||||
|
@ -662,7 +684,7 @@ void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg) {
|
|||
}
|
||||
|
||||
void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
#if 0
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
DWORD reg1 = arg->dst & WINED3DSP_REGNUM_MASK;
|
||||
DWORD reg2 = arg->src[0] & WINED3DSP_REGNUM_MASK;
|
||||
|
@ -672,6 +694,35 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
|
|||
sprintf(dst_str, "T%u", reg1);
|
||||
shader_addline(buffer, "ADD TMP.rg, fragment.texcoord[%u], T%u;\n", reg1, reg2);
|
||||
shader_hw_sample(arg, reg1, dst_str, "TMP");
|
||||
#endif
|
||||
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||
|
||||
DWORD dst = arg->dst;
|
||||
DWORD src = arg->src[0] & WINED3DSP_REGNUM_MASK;
|
||||
SHADER_BUFFER* buffer = arg->buffer;
|
||||
|
||||
char reg_coord[40];
|
||||
DWORD reg_dest_code;
|
||||
|
||||
/* All versions have a destination register */
|
||||
reg_dest_code = dst & WINED3DSP_REGNUM_MASK;
|
||||
/* Can directly use the name because texbem is only valid for <= 1.3 shaders */
|
||||
pshader_get_register_name(dst, reg_coord);
|
||||
|
||||
if(This->bumpenvmatconst) {
|
||||
/*shader_addline(buffer, "MOV T%u, fragment.texcoord[%u];\n", 1, 1); Not needed - done already */
|
||||
shader_addline(buffer, "SWZ TMP2, bumpenvmat, x, z, 0, 0;\n");
|
||||
shader_addline(buffer, "DP3 TMP.r, TMP2, T%u;\n", src);
|
||||
shader_addline(buffer, "SWZ TMP2, bumpenvmat, y, w, 0, 0;\n");
|
||||
shader_addline(buffer, "DP3 TMP.g, TMP2, T%u;\n", src);
|
||||
shader_addline(buffer, "ADD TMP.rg, TMP, %s;\n", reg_coord);
|
||||
/* Not sure about this, but hl2 needs it. It uses a projected texture with texbem and depends on the 4th coordinate */
|
||||
shader_addline(buffer, "MOV TMP.a, %s;\n", reg_coord);
|
||||
shader_hw_sample(arg, reg_dest_code, reg_coord, "TMP");
|
||||
} else {
|
||||
/* Without a bump matrix loaded, just sample with the unmodified coordinates */
|
||||
shader_hw_sample(arg, reg_dest_code, reg_coord, reg_coord);
|
||||
}
|
||||
}
|
||||
|
||||
void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) {
|
||||
|
|
|
@ -1767,15 +1767,50 @@ void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
|
|||
|
||||
/** Process the WINED3DSIO_TEXBEM instruction in GLSL.
|
||||
* Apply a fake bump map transform.
|
||||
* FIXME: Should apply the BUMPMAPENV matrix. For now, just sample the texture */
|
||||
* texbem is pshader <= 1.3 only, this saves a few version checks
|
||||
*/
|
||||
void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) {
|
||||
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
|
||||
char dst_swizzle[6];
|
||||
glsl_sample_function_t sample_function;
|
||||
DWORD sampler_type;
|
||||
DWORD sampler_idx;
|
||||
BOOL projected;
|
||||
DWORD mask = 0;
|
||||
DWORD flags;
|
||||
char coord_mask[6];
|
||||
|
||||
DWORD reg1 = arg->dst & WINED3DSP_REGNUM_MASK;
|
||||
DWORD reg2 = arg->src[0] & WINED3DSP_REGNUM_MASK;
|
||||
/* All versions have a destination register */
|
||||
shader_glsl_append_dst(arg->buffer, arg);
|
||||
|
||||
FIXME("Not applying the BUMPMAPENV matrix for pixel shader instruction texbem.\n");
|
||||
shader_addline(arg->buffer, "T%u = texture2D(Psampler%u, gl_TexCoord[%u].xy + T%u.xy);\n",
|
||||
reg1, reg1, reg1, reg2);
|
||||
sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
|
||||
flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
|
||||
|
||||
/* TODO: Does texbem even support projected textures? half-life 2 uses it */
|
||||
if (flags & WINED3DTTFF_PROJECTED) {
|
||||
projected = TRUE;
|
||||
switch (flags & ~WINED3DTTFF_PROJECTED) {
|
||||
case WINED3DTTFF_COUNT1: FIXME("WINED3DTTFF_PROJECTED with WINED3DTTFF_COUNT1?\n"); break;
|
||||
case WINED3DTTFF_COUNT2: mask = WINED3DSP_WRITEMASK_1; break;
|
||||
case WINED3DTTFF_COUNT3: mask = WINED3DSP_WRITEMASK_2; break;
|
||||
case WINED3DTTFF_COUNT4:
|
||||
case WINED3DTTFF_DISABLE: mask = WINED3DSP_WRITEMASK_3; break;
|
||||
}
|
||||
} else {
|
||||
projected = FALSE;
|
||||
}
|
||||
|
||||
sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
|
||||
shader_glsl_get_sample_function(sampler_type, projected, &sample_function);
|
||||
mask |= sample_function.coord_mask;
|
||||
|
||||
shader_glsl_get_write_mask(arg->dst, dst_swizzle);
|
||||
|
||||
shader_glsl_get_write_mask(mask, coord_mask);
|
||||
FIXME("Bump map transform not handled yet\n");
|
||||
shader_addline(arg->buffer, "%s(Psampler%u, T%u%s)%s);\n",
|
||||
sample_function.name, sampler_idx, sampler_idx, coord_mask, dst_swizzle);
|
||||
}
|
||||
|
||||
/** Process the WINED3DSIO_TEXREG2AR instruction in GLSL
|
||||
|
|
Loading…
Reference in New Issue