[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