wined3d: Implement texbeml.
This commit is contained in:
parent
0ed81b20af
commit
5ab9d85c39
|
@ -198,6 +198,7 @@ HRESULT shader_get_registers_used(
|
|||
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
|
||||
|
||||
reg_maps->bumpmat = -1;
|
||||
reg_maps->luminanceparams = -1;
|
||||
|
||||
if (pToken == NULL)
|
||||
return WINED3D_OK;
|
||||
|
@ -354,11 +355,15 @@ HRESULT shader_get_registers_used(
|
|||
}
|
||||
|
||||
/* texbem is only valid with < 1.4 pixel shaders */
|
||||
if(WINED3DSIO_TEXBEM == curOpcode->opcode) {
|
||||
if(WINED3DSIO_TEXBEM == curOpcode->opcode ||
|
||||
WINED3DSIO_TEXBEML == curOpcode->opcode) {
|
||||
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;
|
||||
if(WINED3DSIO_TEXBEML == curOpcode->opcode) {
|
||||
reg_maps->luminanceparams = sampler_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -389,7 +389,25 @@ void shader_glsl_load_constants(
|
|||
pos = GL_EXTCALL(glGetUniformLocationARB(programId, "bumpenvmat"));
|
||||
checkGLcall("glGetUniformLocationARB");
|
||||
GL_EXTCALL(glUniformMatrix2fvARB(pos, 1, 0, data));
|
||||
checkGLcall("glUniform4fvARB");
|
||||
checkGLcall("glUniformMatrix2fvARB");
|
||||
|
||||
/* 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
|
||||
*/
|
||||
if(((IWineD3DPixelShaderImpl *) pshader)->baseShader.reg_maps.luminanceparams != -1) {
|
||||
int stage = ((IWineD3DPixelShaderImpl *) pshader)->baseShader.reg_maps.luminanceparams;
|
||||
GLfloat *scale = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
|
||||
GLfloat *offset = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
|
||||
|
||||
pos = GL_EXTCALL(glGetUniformLocationARB(programId, "luminancescale"));
|
||||
checkGLcall("glGetUniformLocationARB");
|
||||
GL_EXTCALL(glUniform1fvARB(pos, 1, scale));
|
||||
checkGLcall("glUniform1fvARB");
|
||||
pos = GL_EXTCALL(glGetUniformLocationARB(programId, "luminanceoffset"));
|
||||
checkGLcall("glGetUniformLocationARB");
|
||||
GL_EXTCALL(glUniform1fvARB(pos, 1, offset));
|
||||
checkGLcall("glUniform1fvARB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -429,8 +447,13 @@ void shader_generate_glsl_declarations(
|
|||
|
||||
if(!pshader)
|
||||
shader_addline(buffer, "uniform vec4 posFixup;\n");
|
||||
else if(reg_maps->bumpmat != -1)
|
||||
else if(reg_maps->bumpmat != -1) {
|
||||
shader_addline(buffer, "uniform mat2 bumpenvmat;\n");
|
||||
if(reg_maps->luminanceparams) {
|
||||
shader_addline(buffer, "uniform float luminancescale;\n");
|
||||
shader_addline(buffer, "uniform float luminanceoffset;\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Declare texture samplers */
|
||||
for (i = 0; i < This->baseShader.limits.sampler; i++) {
|
||||
|
@ -1974,8 +1997,16 @@ void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) {
|
|||
|
||||
shader_glsl_append_dst(arg->buffer, arg);
|
||||
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0|WINED3DSP_WRITEMASK_1, &coord_param);
|
||||
shader_addline(arg->buffer, "%s(Psampler%u, T%u%s + vec4(bumpenvmat * %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);
|
||||
if(arg->opcode->opcode == WINED3DSIO_TEXBEML) {
|
||||
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_addline(arg->buffer, "(%s(Psampler%u, T%u%s + vec4(bumpenvmat * %s, 0.0, 0.0)%s )*(%s * luminancescale + luminanceoffset))%s);\n",
|
||||
sample_function.name, sampler_idx, sampler_idx, coord_mask, coord_param.param_str, coord_mask,
|
||||
luminance_param.param_str, dst_swizzle);
|
||||
} else {
|
||||
shader_addline(arg->buffer, "%s(Psampler%u, T%u%s + vec4(bumpenvmat * %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);
|
||||
}
|
||||
}
|
||||
|
||||
void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) {
|
||||
|
|
|
@ -223,7 +223,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
|
|||
{WINED3DSIO_TEX, "texld", "undefined", 1, 2, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
|
||||
{WINED3DSIO_TEX, "texld", "undefined", 1, 3, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_TEXBEM, "texbem", "undefined", 1, 2, pshader_hw_texbem, pshader_glsl_texbem, 0, WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXBEML, "texbeml", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXBEML, "texbeml", GLNAME_REQUIRE_GLSL, 1, 2, pshader_hw_texbem, pshader_glsl_texbem, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXREG2AR,"texreg2ar","undefined", 1, 2, pshader_hw_texreg2ar, pshader_glsl_texreg2ar, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXREG2GB,"texreg2gb","undefined", 1, 2, pshader_hw_texreg2gb, pshader_glsl_texreg2gb, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXREG2RGB, "texreg2rgb", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texreg2rgb, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
|
||||
|
|
|
@ -2139,6 +2139,20 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
|
|||
}
|
||||
}
|
||||
|
||||
static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||
|
||||
/* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
|
||||
* has an update pending
|
||||
*/
|
||||
if(isStateDirty(context, STATE_VDECL) ||
|
||||
isStateDirty(context, STATE_PIXELSHADER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
|
||||
}
|
||||
|
||||
static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
|
||||
union {
|
||||
|
@ -2146,6 +2160,17 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||
float f;
|
||||
} tmpvalue;
|
||||
|
||||
if(stateblock->pixelShader && stage != 0 &&
|
||||
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams == stage) {
|
||||
/* The pixel shader has to know the luminance scale. Do a constants update if it
|
||||
* isn't scheduled anyway
|
||||
*/
|
||||
if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
|
||||
!isStateDirty(context, STATE_PIXELSHADER)) {
|
||||
shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
|
||||
}
|
||||
}
|
||||
|
||||
tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
|
||||
if(tmpvalue.f != 0.0) {
|
||||
FIXME("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
|
||||
|
@ -2159,6 +2184,17 @@ static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock,
|
|||
float f;
|
||||
} tmpvalue;
|
||||
|
||||
if(stateblock->pixelShader && stage != 0 &&
|
||||
((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams == stage) {
|
||||
/* The pixel shader has to know the luminance offset. Do a constants update if it
|
||||
* isn't scheduled anyway
|
||||
*/
|
||||
if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
|
||||
!isStateDirty(context, STATE_PIXELSHADER)) {
|
||||
shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
|
||||
}
|
||||
}
|
||||
|
||||
tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
|
||||
if(tmpvalue.f != 0.0) {
|
||||
FIXME("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
|
||||
|
@ -2278,20 +2314,6 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
|
|||
}
|
||||
}
|
||||
|
||||
static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||
|
||||
/* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
|
||||
* has an update pending
|
||||
*/
|
||||
if(isStateDirty(context, STATE_VDECL) ||
|
||||
isStateDirty(context, STATE_PIXELSHADER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
|
||||
}
|
||||
|
||||
static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||
BOOL use_pshader = use_ps(device);
|
||||
|
|
|
@ -1657,7 +1657,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(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
|
||||
char bumpmat;
|
||||
char bumpmat, luminanceparams;
|
||||
|
||||
/* Whether or not a loop is used in this shader */
|
||||
char loop;
|
||||
|
|
|
@ -3346,9 +3346,9 @@ typedef enum _GL_SupportedExt {
|
|||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FARBPROC, glUniform2fARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM3FARBPROC, glUniform3fARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM4FARBPROC, glUniform4fARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IVARBPROC, glUniform1fvARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2IVARBPROC, glUniform2fvARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM3IVARBPROC, glUniform3fvARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM1FVARBPROC, glUniform1fvARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FVARBPROC, glUniform2fvARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM3FVARBPROC, glUniform3fvARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM4FVARBPROC, glUniform4fvARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IVARBPROC, glUniform1ivARB); \
|
||||
USE_GL_FUNC(WINED3D_PFNGLUNIFORM2IVARBPROC, glUniform2ivARB); \
|
||||
|
|
Loading…
Reference in New Issue