From 1d4042cee10b0647d8de730632a13e7319de1140 Mon Sep 17 00:00:00 2001 From: "H. Verbeet" Date: Wed, 27 Jun 2007 23:46:53 +0200 Subject: [PATCH] wined3d: Implement texldl. --- 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 11ede057ffe..1e77b96dc72 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 1f81fbdcf64..eb41d1f9792 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 af6bc36bb97..cb3b8733aa5 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 dd9a67db2e7..135114fbbe4 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);