[1/5] wined3d: Implement texldl
H. Verbeet
hverbeet at gmail.com
Wed Jun 27 16:46:53 CDT 2007
This is needed for shaders to be able to do VTF.
Changelog:
- Implement texldl
-------------- next part --------------
---
dlls/wined3d/glsl_shader.c | 56 ++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/pixelshader.c | 2 +
dlls/wined3d/vertexshader.c | 2 +
dlls/wined3d/wined3d_private.h | 1 +
4 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 11ede05..1e77b96 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -99,6 +99,29 @@ static void shader_glsl_load_psamplers(
}
}
+static void shader_glsl_load_vsamplers(WineD3D_GL_Info *gl_info, IWineD3DStateBlock* iface) {
+ IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
+ GLhandleARB programId = stateBlock->glsl_program->programId;
+ GLhandleARB name_loc;
+ char sampler_name[20];
+ int i;
+
+ for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
+ snprintf(sampler_name, sizeof(sampler_name), "Vsampler%d", i);
+ name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
+ if (name_loc != -1) {
+ int mapped_unit = stateBlock->wineD3DDevice->texUnitMap[MAX_FRAGMENT_SAMPLERS + i];
+ if (mapped_unit != -1 && mapped_unit < GL_LIMITS(combined_samplers)) {
+ TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit);
+ GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit));
+ checkGLcall("glUniform1iARB");
+ } else {
+ ERR("Trying to load sampler %s on unsupported unit %d\n", sampler_name, mapped_unit);
+ }
+ }
+ }
+}
+
/**
* Loads floating point constants (aka uniforms) into the currently set GLSL program.
* When constant_list == NULL, it will load all the constants.
@@ -308,6 +331,9 @@ void shader_glsl_load_constants(
constant_locations = stateBlock->glsl_program->vuniformF_locations;
constant_list = &stateBlock->set_vconstantsF;
+ /* Load vertex shader samplers */
+ shader_glsl_load_vsamplers(gl_info, (IWineD3DStateBlock*)stateBlock);
+
/* Load DirectX 9 float constants/uniforms for vertex shader */
shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF),
stateBlock->vertexShaderConstantF, constant_locations, constant_list);
@@ -1563,6 +1589,36 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) {
}
}
+void shader_glsl_texldl(SHADER_OPCODE_ARG* arg) {
+ IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*)arg->shader;
+ glsl_sample_function_t sample_function;
+ glsl_src_param_t coord_param, lod_param;
+ char dst_swizzle[6];
+ DWORD sampler_type;
+ DWORD sampler_idx;
+
+ shader_glsl_append_dst(arg->buffer, arg);
+ shader_glsl_get_swizzle(arg->src[1], FALSE, arg->dst, dst_swizzle);
+
+ sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
+ sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ shader_glsl_get_sample_function(sampler_type, FALSE, &sample_function);
+ shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], sample_function.coord_mask, &coord_param);
+
+ shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param);
+
+ if (shader_is_pshader_version(This->baseShader.hex_version)) {
+ /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
+ * However, they seem to work just fine in fragment shaders as well. */
+ WARN("Using %sLod in fragment shader.\n", sample_function.name);
+ shader_addline(arg->buffer, "%sLod(Psampler%u, %s, %s)%s);\n",
+ sample_function.name, sampler_idx, coord_param.param_str, lod_param.param_str, dst_swizzle);
+ } else {
+ shader_addline(arg->buffer, "%sLod(Vsampler%u, %s, %s)%s);\n",
+ sample_function.name, sampler_idx, coord_param.param_str, lod_param.param_str, dst_swizzle);
+ }
+}
+
void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) {
/* FIXME: Make this work for more than just 2D textures */
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 1f81fbd..eb41d1f 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -256,7 +256,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
{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},
{WINED3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, 0, 0},
- {WINED3DSIO_TEXLDL, "texldl", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, 0, 0},
+ {WINED3DSIO_TEXLDL, "texldl", NULL, 1, 3, NULL, shader_glsl_texldl, WINED3DPS_VERSION(3,0), -1},
{WINED3DSIO_PHASE, "phase", GLNAME_REQUIRE_GLSL, 0, 0, NULL, NULL, 0, 0},
{0, NULL, NULL, 0, 0, NULL, NULL, 0, 0}
};
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index af6bc36..cb3b873 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -156,7 +156,7 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
{WINED3DSIO_LABEL, "label", NULL, 0, 1, NULL, shader_glsl_label, WINED3DVS_VERSION(2,0), -1},
{WINED3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, 0, 0},
- {WINED3DSIO_TEXLDL, "texdl", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, 0, 0},
+ {WINED3DSIO_TEXLDL, "texldl", NULL, 1, 3, NULL, shader_glsl_texldl, WINED3DVS_VERSION(3,0), -1},
{0, NULL, NULL, 0, 0, NULL, NULL, 0, 0}
};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index dd9a67d..135114f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1737,6 +1737,7 @@ extern void shader_glsl_call(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_callnz(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_label(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_pow(SHADER_OPCODE_ARG* arg);
+extern void shader_glsl_texldl(SHADER_OPCODE_ARG* arg);
/** GLSL Pixel Shader Prototypes */
extern void pshader_glsl_tex(SHADER_OPCODE_ARG* arg);
More information about the wine-patches
mailing list