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

wined3d: Implement bem shader instruction.

parent 929116f2
......@@ -177,7 +177,7 @@ 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(reg_maps->bumpmat != -1 /* 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.
......@@ -510,6 +510,34 @@ static inline void pshader_gen_output_modifier_line(
regstr, write_mask, regstr, shift_tab[shift]);
}
void pshader_hw_bem(SHADER_OPCODE_ARG* arg) {
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
SHADER_BUFFER* buffer = arg->buffer;
char dst_name[50];
char src_name[2][50];
char dst_wmask[20];
pshader_get_register_name(arg->dst, dst_name);
shader_arb_get_write_mask(arg->dst, dst_wmask);
strcat(dst_name, dst_wmask);
pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0]);
pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1]);
if(This->bumpenvmatconst != -1) {
/* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
shader_addline(buffer, "SWZ TMP2, bumpenvmat, x, z, 0, 0;\n");
shader_addline(buffer, "DP3 TMP.r, TMP2, %s;\n", src_name[1]);
shader_addline(buffer, "SWZ TMP2, bumpenvmat, y, w, 0, 0;\n");
shader_addline(buffer, "DP3 TMP.g, TMP2, %s;\n", src_name[1]);
shader_addline(buffer, "ADD %s, %s, TMP;\n", dst_name, src_name[0]);
} else {
shader_addline(buffer, "MOV %s, %s;\n", dst_name, src_name[0]);
}
}
void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) {
SHADER_BUFFER* buffer = arg->buffer;
......@@ -723,7 +751,7 @@ 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(dst, reg_coord);
if(This->bumpenvmatconst) {
if(This->bumpenvmatconst != -1) {
/* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
shader_addline(buffer, "SWZ TMP2, bumpenvmat, x, z, 0, 0;\n");
......
......@@ -197,6 +197,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;
if (pToken == NULL)
return WINED3D_OK;
......@@ -295,7 +297,15 @@ HRESULT shader_get_registers_used(
DWORD snum = *pToken & WINED3DSP_REGNUM_MASK;
reg_maps->labels[snum] = 1;
pToken += curOpcode->num_params;
} else if(WINED3DSIO_BEM == curOpcode->opcode) {
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;
}
/* Set texture, address, temporary registers */
} else {
int i, limit;
......@@ -347,7 +357,7 @@ HRESULT shader_get_registers_used(
/* texbem is only valid with < 1.4 pixel shaders */
if(WINED3DSIO_TEXBEM == curOpcode->opcode) {
if(reg_maps->bumpmat != 0 && reg_maps->bumpmat != sampler_code) {
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;
......
......@@ -355,7 +355,7 @@ 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 != 0) {
if(((IWineD3DPixelShaderImpl *) pshader)->needsbumpmat != -1) {
float *data = (float *) &stateBlock->textureState[(int) ((IWineD3DPixelShaderImpl *) pshader)->needsbumpmat][WINED3DTSS_BUMPENVMAT00];
pos = GL_EXTCALL(glGetUniformLocationARB(programId, "bumpenvmat"));
checkGLcall("glGetUniformLocationARB");
......@@ -400,7 +400,7 @@ void shader_generate_glsl_declarations(
if(!pshader)
shader_addline(buffer, "uniform vec4 posFixup;\n");
else if(reg_maps->bumpmat)
else if(reg_maps->bumpmat != -1)
shader_addline(buffer, "uniform mat2 bumpenvmat;\n");
/* Declare texture samplers */
......@@ -1824,6 +1824,17 @@ void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) {
sample_function.name, sampler_idx, sampler_idx, coord_mask, coord_param.param_str, coord_mask, dst_swizzle);
}
void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) {
glsl_src_param_t src0_param, src1_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_append_dst(arg->buffer, arg);
shader_addline(arg->buffer, "%s + bumpenvmat * %s);\n",
src0_param.param_str, src1_param.param_str);
}
/** Process the WINED3DSIO_TEXREG2AR instruction in GLSL
* Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg) {
......
......@@ -239,7 +239,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
{WINED3DSIO_TEXDP3, "texdp3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texdp3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x3, "texm3x3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texm3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXDEPTH, "texdepth", GLNAME_REQUIRE_GLSL, 1, 1, NULL, pshader_glsl_texdepth, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_BEM, "bem", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_BEM, "bem", "undefined", 1, 3, pshader_hw_bem, pshader_glsl_bem, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_DSX, "dsx", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, 0, 0},
{WINED3DSIO_DSY, "dsy", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, 0, 0},
{WINED3DSIO_TEXLDD, "texldd", GLNAME_REQUIRE_GLSL, 1, 5, NULL, NULL, WINED3DPS_VERSION(2,1), -1},
......
......@@ -1625,6 +1625,7 @@ extern void shader_arb_load_constants(
extern void shader_hw_def(SHADER_OPCODE_ARG *arg);
/* ARB pixel shader prototypes */
extern void pshader_hw_bem(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_cnd(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_cmp(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg);
......@@ -1700,6 +1701,7 @@ extern void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_bem(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg);
......
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