wined3d: Implement texldd.
GL_ARB_shader_texture is supported on dx9 ATI cards(and probably dx10 ones too). For Nvidia cards I included a fallback to normal texld. GL_EXT_gpu_shader4 supports similar texture*Grad GLSL functions, just with an EXT prefix instead of ARB. For dx9 NV cards we'd have to use GL_NV_fragment_program2, which supports a texldd equivalent on those cards.
This commit is contained in:
parent
e7537418d9
commit
f5e24f7a85
|
@ -570,6 +570,10 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
|
|||
{
|
||||
reg_maps->usesdsy = 1;
|
||||
}
|
||||
else if(ins.handler_idx == WINED3DSIH_TEXLDD)
|
||||
{
|
||||
reg_maps->usestexldd = 1;
|
||||
}
|
||||
|
||||
limit = ins.src_count + (ins.predicate ? 1 : 0);
|
||||
for (i = 0; i < limit; ++i)
|
||||
|
|
|
@ -91,6 +91,7 @@ static const struct {
|
|||
{"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 },
|
||||
{"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 },
|
||||
{"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 },
|
||||
{"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD, 0 },
|
||||
|
||||
/* EXT */
|
||||
{"GL_EXT_blend_color", EXT_BLEND_COLOR, 0 },
|
||||
|
|
|
@ -44,6 +44,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
|
|||
#define WINED3D_GLSL_SAMPLE_PROJECTED 0x1
|
||||
#define WINED3D_GLSL_SAMPLE_RECT 0x2
|
||||
#define WINED3D_GLSL_SAMPLE_LOD 0x4
|
||||
#define WINED3D_GLSL_SAMPLE_GRAD 0x8
|
||||
|
||||
typedef struct {
|
||||
char reg_name[150];
|
||||
|
@ -1394,12 +1395,15 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
|
|||
BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
|
||||
BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT;
|
||||
BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
|
||||
BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD;
|
||||
|
||||
/* Note that there's no such thing as a projected cube texture. */
|
||||
switch(sampler_type) {
|
||||
case WINED3DSTT_1D:
|
||||
if(lod) {
|
||||
sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
|
||||
} else if(grad) {
|
||||
sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
|
||||
} else {
|
||||
sample_function->name = projected ? "texture1DProj" : "texture1D";
|
||||
}
|
||||
|
@ -1409,12 +1413,19 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
|
|||
if(texrect) {
|
||||
if(lod) {
|
||||
sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
|
||||
} else if(grad) {
|
||||
/* What good are texrect grad functions? I don't know, but GL_EXT_gpu_shader4 defines them.
|
||||
* There is no GL_ARB_shader_texture_lod spec yet, so I don't know if they're defined there
|
||||
*/
|
||||
sample_function->name = projected ? "shadow2DRectProjGradARB" : "shadow2DRectGradARB";
|
||||
} else {
|
||||
sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
|
||||
}
|
||||
} else {
|
||||
if(lod) {
|
||||
sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
|
||||
} else if(grad) {
|
||||
sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
|
||||
} else {
|
||||
sample_function->name = projected ? "texture2DProj" : "texture2D";
|
||||
}
|
||||
|
@ -1424,6 +1435,8 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
|
|||
case WINED3DSTT_CUBE:
|
||||
if(lod) {
|
||||
sample_function->name = "textureCubeLod";
|
||||
} else if(grad) {
|
||||
sample_function->name = "textureCubeGradARB";
|
||||
} else {
|
||||
sample_function->name = "textureCube";
|
||||
}
|
||||
|
@ -1432,6 +1445,8 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
|
|||
case WINED3DSTT_VOLUME:
|
||||
if(lod) {
|
||||
sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
|
||||
} else if(grad) {
|
||||
sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
|
||||
} else {
|
||||
sample_function->name = projected ? "texture3DProj" : "texture3D";
|
||||
}
|
||||
|
@ -1551,8 +1566,9 @@ static void shader_glsl_color_correction(const struct wined3d_shader_instruction
|
|||
}
|
||||
}
|
||||
|
||||
static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
|
||||
static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
|
||||
DWORD sampler, const glsl_sample_function_t *sample_function, DWORD swizzle,
|
||||
const char *dx, const char *dy,
|
||||
const char *bias, const char *coord_reg_fmt, ...)
|
||||
{
|
||||
const char *sampler_base;
|
||||
|
@ -1594,6 +1610,8 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s
|
|||
} else {
|
||||
if (np2_fixup) {
|
||||
shader_addline(ins->ctx->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, dst_swizzle);
|
||||
} else if(dx && dy) {
|
||||
shader_addline(ins->ctx->buffer, ", %s, %s)%s);\n", dx, dy, dst_swizzle);
|
||||
} else {
|
||||
shader_addline(ins->ctx->buffer, ")%s);\n", dst_swizzle);
|
||||
}
|
||||
|
@ -2520,7 +2538,7 @@ static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
|
|||
{
|
||||
char coord_mask[6];
|
||||
shader_glsl_write_mask_to_str(mask, coord_mask);
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
|
||||
"T%u%s", sampler_idx, coord_mask);
|
||||
} else {
|
||||
glsl_src_param_t coord_param;
|
||||
|
@ -2529,15 +2547,48 @@ static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
|
|||
{
|
||||
glsl_src_param_t bias;
|
||||
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias);
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, bias.param_str,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
|
||||
"%s", coord_param.param_str);
|
||||
} else {
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
|
||||
"%s", coord_param.param_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
|
||||
{
|
||||
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
|
||||
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
|
||||
const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
|
||||
glsl_sample_function_t sample_function;
|
||||
glsl_src_param_t coord_param, dx_param, dy_param;
|
||||
DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD;
|
||||
DWORD sampler_type;
|
||||
DWORD sampler_idx;
|
||||
DWORD swizzle = ins->src[1].swizzle;
|
||||
|
||||
if(!GL_SUPPORT(ARB_SHADER_TEXTURE_LOD)) {
|
||||
FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n");
|
||||
return pshader_glsl_tex(ins);
|
||||
}
|
||||
|
||||
sampler_idx = ins->src[1].register_idx;
|
||||
sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
|
||||
if(deviceImpl->stateBlock->textures[sampler_idx] &&
|
||||
IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
|
||||
sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
|
||||
}
|
||||
|
||||
shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
|
||||
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
|
||||
shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param);
|
||||
shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param);
|
||||
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, NULL,
|
||||
"%s", coord_param.param_str);
|
||||
}
|
||||
|
||||
static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
|
||||
{
|
||||
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
|
||||
|
@ -2566,7 +2617,7 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
|
|||
* However, they seem to work just fine in fragment shaders as well. */
|
||||
WARN("Using %s in fragment shader.\n", sample_function.name);
|
||||
}
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, lod_param.param_str,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str,
|
||||
"%s", coord_param.param_str);
|
||||
}
|
||||
|
||||
|
@ -2641,17 +2692,17 @@ static void pshader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
|
|||
switch(mask_size)
|
||||
{
|
||||
case 1:
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
|
||||
"dot(gl_TexCoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
|
||||
"vec2(dot(gl_TexCoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
|
||||
"vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
|
||||
break;
|
||||
|
||||
|
@ -2761,7 +2812,7 @@ static void pshader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins
|
|||
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
|
||||
|
||||
/* Sample the texture using the calculated coordinates */
|
||||
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, "tmp0.xy");
|
||||
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy");
|
||||
}
|
||||
|
||||
/** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
|
||||
|
@ -2783,7 +2834,7 @@ static void pshader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins
|
|||
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
|
||||
|
||||
/* Sample the texture using the calculated coordinates */
|
||||
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, "tmp0.xyz");
|
||||
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
|
||||
|
||||
current_state->current_row = 0;
|
||||
}
|
||||
|
@ -2834,7 +2885,7 @@ static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *in
|
|||
shader_glsl_get_sample_function(stype, 0, &sample_function);
|
||||
|
||||
/* Sample the texture */
|
||||
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, "tmp0.xyz");
|
||||
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
|
||||
|
||||
current_state->current_row = 0;
|
||||
}
|
||||
|
@ -2866,7 +2917,7 @@ static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *i
|
|||
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
|
||||
|
||||
/* Sample the texture using the calculated coordinates */
|
||||
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, "tmp0.xyz");
|
||||
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
|
||||
|
||||
current_state->current_row = 0;
|
||||
}
|
||||
|
@ -2916,7 +2967,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
|
|||
|
||||
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param);
|
||||
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
|
||||
"T%u%s + vec4(bumpenvmat%d * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx,
|
||||
coord_param.param_str, coord_mask);
|
||||
|
||||
|
@ -2959,7 +3010,7 @@ static void pshader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
|
|||
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
|
||||
|
||||
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
|
||||
"%s.wx", src0_param.reg_name);
|
||||
}
|
||||
|
||||
|
@ -2975,7 +3026,7 @@ static void pshader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
|
|||
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
|
||||
|
||||
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
|
||||
"%s.yz", src0_param.reg_name);
|
||||
}
|
||||
|
||||
|
@ -2992,7 +3043,7 @@ static void pshader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins
|
|||
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
|
||||
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
|
||||
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL,
|
||||
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
|
||||
"%s", src0_param.param_str);
|
||||
}
|
||||
|
||||
|
@ -4001,6 +4052,9 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface,
|
|||
if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
|
||||
shader_addline(buffer, "#extension GL_ARB_draw_buffers : enable\n");
|
||||
}
|
||||
if(GL_SUPPORT(ARB_SHADER_TEXTURE_LOD) && reg_maps->usestexldd) {
|
||||
shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
|
||||
}
|
||||
if (GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
|
||||
/* The spec says that it doesn't have to be explicitly enabled, but the nvidia
|
||||
* drivers write a warning if we don't do so
|
||||
|
@ -4288,7 +4342,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
|
|||
/* WINED3DSIH_TEXDP3 */ pshader_glsl_texdp3,
|
||||
/* WINED3DSIH_TEXDP3TEX */ pshader_glsl_texdp3tex,
|
||||
/* WINED3DSIH_TEXKILL */ pshader_glsl_texkill,
|
||||
/* WINED3DSIH_TEXLDD */ NULL,
|
||||
/* WINED3DSIH_TEXLDD */ shader_glsl_texldd,
|
||||
/* WINED3DSIH_TEXLDL */ shader_glsl_texldl,
|
||||
/* WINED3DSIH_TEXM3x2DEPTH */ pshader_glsl_texm3x2depth,
|
||||
/* WINED3DSIH_TEXM3x2PAD */ pshader_glsl_texm3x2pad,
|
||||
|
|
|
@ -3397,6 +3397,7 @@ typedef enum _GL_SupportedExt {
|
|||
ARB_VERTEX_BUFFER_OBJECT,
|
||||
ARB_VERTEX_SHADER,
|
||||
ARB_SHADER_OBJECTS,
|
||||
ARB_SHADER_TEXTURE_LOD,
|
||||
/* EXT */
|
||||
EXT_BLEND_COLOR,
|
||||
EXT_BLEND_MINMAX,
|
||||
|
|
|
@ -610,7 +610,7 @@ typedef struct shader_reg_maps
|
|||
|
||||
WINED3DSAMPLER_TEXTURE_TYPE sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
|
||||
BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
|
||||
char usesnrm, vpos, usesdsy;
|
||||
char usesnrm, vpos, usesdsy, usestexldd;
|
||||
char usesrelconstF;
|
||||
|
||||
/* Whether or not loops are used in this shader, and nesting depth */
|
||||
|
|
Loading…
Reference in New Issue