Stefan Dösinger : wined3d: Load GLSL sampler uniforms at shader link time.

Alexandre Julliard julliard at winehq.org
Fri Nov 9 07:44:20 CST 2007


Module: wine
Branch: master
Commit: 9fb70b99db4f9a6eb0a585243666751ad1209137
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9fb70b99db4f9a6eb0a585243666751ad1209137

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Wed Nov  7 23:03:15 2007 +0100

wined3d: Load GLSL sampler uniforms at shader link time.

---

 dlls/wined3d/directx.c     |   23 +++++++++++++++++++++++
 dlls/wined3d/glsl_shader.c |   34 ++++++++++++++++++++++++----------
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index aff5bee..5401ff5 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -738,6 +738,29 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
                 gl_info->max_vertex_samplers = tmp;
                 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
                 gl_info->max_combined_samplers = tmp;
+
+                /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
+                 * is known at shader link time. In a vertex shader + pixel shader combination this isn't
+                 * an issue because then the sampler setup only depends on the two shaders. If a pixel
+                 * shader is used with fixed function vertex processing we're fine too because fixed function
+                 * vertex processing doesn't use any samplers. If fixed function fragment processing is
+                 * used we have to make sure that all vertex sampler setups are valid together with all
+                 * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
+                 * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
+                 * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
+                 * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
+                 * a fixed function pipeline anymore.
+                 *
+                 * So this is just a check to check that our assumption holds true. If not, write a warning
+                 * and reduce the number of vertex samplers or propably disable vertex texture fetch.
+                 */
+                if(gl_info->max_vertex_samplers &&
+                   MAX_TEXTURES + gl_info->max_vertex_samplers > gl_info->max_combined_samplers) {
+                    FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers\n",
+                          gl_info->max_vertex_samplers, gl_info->max_combined_samplers);
+                    FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers\n");
+                    gl_info->max_vertex_samplers = max(0, gl_info->max_combined_samplers - MAX_TEXTURES);
+                }
             } else {
                 gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
             }
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index ee94037..adfaa9f 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -77,10 +77,10 @@ void print_glsl_info_log(WineD3D_GL_Info *gl_info, GLhandleARB obj) {
  */
 static void shader_glsl_load_psamplers(
     WineD3D_GL_Info *gl_info,
-    IWineD3DStateBlock* iface) {
+    IWineD3DStateBlock* iface,
+    GLhandleARB programId) {
 
     IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
-    GLhandleARB programId = stateBlock->glsl_program->programId;
     GLhandleARB name_loc;
     int i;
     char sampler_name[20];
@@ -101,9 +101,8 @@ static void shader_glsl_load_psamplers(
     }
 }
 
-static void shader_glsl_load_vsamplers(WineD3D_GL_Info *gl_info, IWineD3DStateBlock* iface) {
+static void shader_glsl_load_vsamplers(WineD3D_GL_Info *gl_info, IWineD3DStateBlock* iface, GLhandleARB programId) {
     IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
-    GLhandleARB programId = stateBlock->glsl_program->programId;
     GLhandleARB name_loc;
     char sampler_name[20];
     int i;
@@ -354,9 +353,6 @@ void shader_glsl_load_constants(
         constant_locations = prog->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);
@@ -384,9 +380,6 @@ void shader_glsl_load_constants(
         constant_locations = prog->puniformF_locations;
         constant_list = &stateBlock->set_pconstantsF;
 
-        /* Load pixel shader samplers */
-        shader_glsl_load_psamplers(gl_info, (IWineD3DStateBlock*) stateBlock);
-
         /* Load DirectX 9 float constants/uniforms for pixel shader */
         shader_glsl_load_constantsF(pshader, gl_info, GL_LIMITS(pshader_constantsF),
                 stateBlock->pixelShaderConstantF, constant_locations, constant_list);
@@ -3047,6 +3040,27 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     entry->srgb_mul_low_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_mul_low"));
     entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
     checkGLcall("Find glsl program uniform locations");
+
+    /* Set the shader to allow uniform loading on it */
+    GL_EXTCALL(glUseProgramObjectARB(programId));
+    checkGLcall("glUseProgramObjectARB(programId)");
+
+    /* Load the vertex and pixel samplers now. The function that finds the mappings makes sure
+     * that it stays the same for each vertexshader-pixelshader pair(=linked glsl program). If
+     * a pshader with fixed function pipeline is used there are no vertex samplers, and if a
+     * vertex shader with fixed function pixel processing is used we make sure that the card
+     * supports enough samplers to allow the max number of vertex samplers with all possible
+     * fixed function fragment processing setups. So once the program is linked these samplers
+     * won't change.
+     */
+    if(vshader_id) {
+        /* Load vertex shader samplers */
+        shader_glsl_load_vsamplers(gl_info, (IWineD3DStateBlock*)This->stateBlock, programId);
+    }
+    if(pshader_id) {
+        /* Load pixel shader samplers */
+        shader_glsl_load_psamplers(gl_info, (IWineD3DStateBlock*)This->stateBlock, programId);
+    }
 }
 
 static GLhandleARB create_glsl_blt_shader(WineD3D_GL_Info *gl_info) {




More information about the wine-cvs mailing list