[WINED3D 2/7] Move constant loading into target-specific files

Jason Green jave27 at gmail.com
Fri Jun 16 15:07:00 CDT 2006


The ultimate goal for shaders is for the bulk of the GLSL and
ARB_program specific code to be placed in their own files for easier
management.  This patch helps further separate that, and should be a
no-op.

- Moves GLSL constant loading code into glsl_shader.c and out of the
over-populated drawprim.c
- Creates a new file named arb_program_shader.c which will hold code
specific to ARB_vertex_program & ARB_fragment_program.  (TODO: Take
all ARB specific code out of vertexshader.c and pixelshader.c)
- Remove the constant loading calls from drawprim.c
-------------- next part --------------
diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in
index 0df6792..e5982dc 100644
--- a/dlls/wined3d/Makefile.in
+++ b/dlls/wined3d/Makefile.in
@@ -9,6 +9,7 @@ EXTRAINCL = @X_CFLAGS@
 EXTRALIBS = -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
 
 C_SRCS = \
+	arb_program_shader.c \
 	baseshader.c \
 	basetexture.c \
 	cubetexture.c \
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
new file mode 100644
index 0000000..1562a07
--- /dev/null
+++ b/dlls/wined3d/arb_program_shader.c
@@ -0,0 +1,112 @@
+/*
+ * Pixel and vertex shaders implementation using ARB_vertex_program
+ * and ARB_fragment_program GL extensions.
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * Copyright 2006 Jason Green
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdio.h>
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+#define GLINFO_LOCATION      (*gl_info)
+
+/********************************************************
+ * ARB_[vertex/fragment]_program helper functions follow
+ ********************************************************/
+
+/** 
+ * Loads floating point constants into the currently set ARB_vertex/fragment_program.
+ * When @constants_set == NULL, it will load all the constants.
+ *  
+ * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
+ *  or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
+ */
+void shader_arb_load_constantsF(
+    WineD3D_GL_Info *gl_info,
+    GLuint target_type,
+    unsigned max_constants,
+    float* constants,
+    BOOL* constants_set) {
+
+    int i;
+    
+    for (i=0; i<max_constants; ++i) {
+        if (NULL == constants_set || constants_set[i]) {
+            TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
+                  constants[i * sizeof(float) + 0], constants[i * sizeof(float) + 1],
+                  constants[i * sizeof(float) + 2], constants[i * sizeof(float) + 3]);
+
+            GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, &constants[i * sizeof(float)]));
+            checkGLcall("glProgramEnvParameter4fvARB");
+        }
+    }
+}
+
+/**
+ * Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
+ * 
+ * We only support float constants in ARB at the moment, so don't 
+ * worry about the Integers or Booleans
+ */
+void shader_arb_load_constants(
+    IWineD3DStateBlock* iface,
+    char usePixelShader,
+    char useVertexShader) {
+    
+    IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
+    WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
+
+    if (useVertexShader) {
+        IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
+        IWineD3DVertexDeclarationImpl* vertexDeclaration = 
+            (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
+
+        if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
+            /* Load DirectX 8 float constants for vertex shader */
+            shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
+                                       WINED3D_VSHADER_MAX_CONSTANTS,
+                                       vertexDeclaration->constants, NULL);
+        }
+
+        /* Load DirectX 9 float constants for vertex shader */
+        shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
+                                   WINED3D_VSHADER_MAX_CONSTANTS,
+                                   stateBlock->vertexShaderConstantF,
+                                   stateBlock->set.vertexShaderConstantsF);
+    }
+
+    if (usePixelShader) {
+
+        /* Load DirectX 9 float constants for pixel shader */
+        shader_arb_load_constantsF(gl_info, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
+                                   stateBlock->pixelShaderConstantF,
+                                   stateBlock->set.pixelShaderConstantsF);
+    }
+}
+
+/* TODO: Add more ARB_[vertex/fragment]_program specific code here */
+
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index a042199..65a3df1 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1742,174 +1742,6 @@ void drawStridedSoftwareVS(IWineD3DDevic
 
 #endif
 
-/**
- * Loads (pixel shader) samplers
- */
-void drawPrimLoadPSamplersGLSL(
-    IWineD3DDevice* iface) {
-
-    IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
-    GLhandleARB programId = This->stateBlock->shaderPrgId;
-    GLhandleARB name_loc;
-    int i;
-    char sampler_name[20];
-
-    if (programId == 0) {
-        /* No GLSL program set - nothing to do. */
-        return;
-    }
-
-    for (i=0; i< GL_LIMITS(textures); ++i) {
-        if (This->stateBlock->textures[i] != NULL) {
-           snprintf(sampler_name, sizeof(sampler_name), "psampler%d", i);
-           name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
-           if (name_loc != -1) {
-               TRACE_(d3d_shader)("Loading %s for texture %d\n", sampler_name, i);
-               GL_EXTCALL(glUniform1iARB(name_loc, i));
-               checkGLcall("glUniform1iARB");
-           }
-        }
-    }
-}
-
-/** 
- * Loads floating point constants (aka uniforms) into the currently set GLSL program.
- * When @constants_set == NULL, it will load all the constants.
- */
-void drawPrimLoadConstantsGLSL_F(IWineD3DDevice* iface,
-                                 unsigned max_constants,
-                                 float* constants,
-                                 BOOL* constants_set,
-                                 char is_pshader) {
-    
-    IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
-    GLhandleARB programId = This->stateBlock->shaderPrgId;
-    GLhandleARB tmp_loc;
-    int i;
-    char tmp_name[7];
-    
-    if (programId == 0) {
-        /* No GLSL program set - nothing to do. */
-        return;
-    }
-    
-    for (i=0; i<max_constants; ++i) {
-        if (NULL == constants_set || constants_set[i]) {
-
-            const char* prefix = is_pshader? "PC":"VC";
-
-            TRACE_(d3d_shader)("Loading constants %i: %f, %f, %f, %f\n",
-                   i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
-
-            /* TODO: Benchmark and see if it would be beneficial to store the 
-             * locations of the constants to avoid looking up each time */
-            snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
-            tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
-            if (tmp_loc != -1) {
-                /* We found this uniform name in the program - go ahead and send the data */
-                GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, &constants[i*4]));
-                checkGLcall("glUniform4fvARB");
-            }
-        }
-    }
-}
-
-/** 
- * Loads floating point constants into the currently set ARB_vertex/fragment_program.
- * When @constants_set == NULL, it will load all the constants.
- *  
- * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
- *  or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
- */
-void drawPrimLoadConstantsARB_F(IWineD3DDevice* iface,
-                                GLuint target_type,
-                                unsigned max_constants,
-                                float* constants,
-                                BOOL* constants_set) {
-    
-    IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
-    int i;
-    
-    for (i=0; i<max_constants; ++i) {
-        if (NULL == constants_set || constants_set[i]) {
-            TRACE_(d3d_shader)("Loading constants %i: %f, %f, %f, %f\n",
-                    i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
-
-            GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, &constants[i*4]));
-            checkGLcall("glProgramEnvParameter4fvARB");
-        }
-    }
-}
- 
-/* Load the constants/uniforms which were passed by the application into either GLSL or ARB shader programs. */
-void drawPrimLoadConstants(IWineD3DDevice *iface,
-                           BOOL useVertexShader,
-                           BOOL usePixelShader) {
-
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DVertexShaderImpl *vshader = (IWineD3DVertexShaderImpl*) This->stateBlock->vertexShader;
-
-    if (wined3d_settings.shader_mode == SHADER_GLSL) {
-        
-        if (useVertexShader) {
-            IWineD3DVertexDeclarationImpl* vertexDeclaration =
-                (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
-
-            if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
-                /* Load DirectX 8 float constants/uniforms for vertex shader */
-                drawPrimLoadConstantsGLSL_F(iface, WINED3D_VSHADER_MAX_CONSTANTS,
-                                            vertexDeclaration->constants, NULL, 0);
-            }
-
-            /* Load DirectX 9 float constants/uniforms for vertex shader */
-            drawPrimLoadConstantsGLSL_F(iface, WINED3D_VSHADER_MAX_CONSTANTS,
-                                        This->stateBlock->vertexShaderConstantF, 
-                                        This->stateBlock->set.vertexShaderConstantsF, 0);
-
-            /* TODO: Load boolean & integer constants for vertex shader */
-        }
-        if (usePixelShader) {
-
-            /* Load pixel shader samplers */
-            drawPrimLoadPSamplersGLSL(iface);
-
-            /* Load DirectX 9 float constants/uniforms for pixel shader */
-            drawPrimLoadConstantsGLSL_F(iface, WINED3D_PSHADER_MAX_CONSTANTS,
-                                        This->stateBlock->pixelShaderConstantF,
-                                        This->stateBlock->set.pixelShaderConstantsF, 1);
-
-            /* TODO: Load boolean & integer constants for pixel shader */
-        }
-    } else if (wined3d_settings.shader_mode == SHADER_ARB) {
-        
-        /* We only support float constants in ARB at the moment, so don't 
-         * worry about the Integers or Booleans */
-        
-        if (useVertexShader) {
-            IWineD3DVertexDeclarationImpl* vertexDeclaration = 
-                (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
-
-            if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
-                /* Load DirectX 8 float constants for vertex shader */
-                drawPrimLoadConstantsARB_F(iface, GL_VERTEX_PROGRAM_ARB, WINED3D_VSHADER_MAX_CONSTANTS,
-                                           vertexDeclaration->constants, NULL);
-            }
-
-            /* Load DirectX 9 float constants for vertex shader */
-            drawPrimLoadConstantsARB_F(iface, GL_VERTEX_PROGRAM_ARB, WINED3D_VSHADER_MAX_CONSTANTS,
-                                       This->stateBlock->vertexShaderConstantF,
-                                       This->stateBlock->set.vertexShaderConstantsF);
-        }
-        if (usePixelShader) {
-
-            /* Load DirectX 9 float constants for pixel shader */
-            drawPrimLoadConstantsARB_F(iface, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
-                                       This->stateBlock->pixelShaderConstantF,
-                                       This->stateBlock->set.pixelShaderConstantsF);
-        }
-    }
-}
-   
 void inline  drawPrimitiveDrawStrided(IWineD3DDevice *iface, BOOL useVertexShaderFunction, BOOL usePixelShaderFunction, int useHW, WineDirect3DVertexStridedData *dataLocations,
 UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idxData, short idxSize, int minIndex, long StartIdx) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
@@ -2055,7 +1887,11 @@ #endif
         }
         
         /* Load any global constants/uniforms that may have been set by the application */
-        drawPrimLoadConstants(iface, useVertexShaderFunction, usePixelShaderFunction);
+        if (wined3d_settings.shader_mode == SHADER_GLSL)
+            shader_glsl_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction); 
+        else if (wined3d_settings.shader_mode == SHADER_ARB)
+            shader_arb_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
+        
 
         /* DirectX colours are in a different format to opengl colours
          * so if diffuse or specular are used then we need to use drawStridedSlow
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 54e311d..20780ca 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -47,6 +47,119 @@ void print_glsl_info_log(WineD3D_GL_Info
     }
 }
 
+/**
+ * Loads (pixel shader) samplers
+ */
+void shader_glsl_load_psamplers(
+    WineD3D_GL_Info *gl_info,
+    IWineD3DStateBlock* iface) {
+
+    IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
+    GLhandleARB programId = stateBlock->shaderPrgId;
+    GLhandleARB name_loc;
+    int i;
+    char sampler_name[20];
+
+    for (i=0; i< GL_LIMITS(textures); ++i) {
+        if (stateBlock->textures[i] != NULL) {
+           snprintf(sampler_name, sizeof(sampler_name), "psampler%d", i);
+           name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
+           if (name_loc != -1) {
+               TRACE_(d3d_shader)("Loading %s for texture %d\n", sampler_name, i);
+               GL_EXTCALL(glUniform1iARB(name_loc, i));
+               checkGLcall("glUniform1iARB");
+           }
+        }
+    }
+}
+
+/** 
+ * Loads floating point constants (aka uniforms) into the currently set GLSL program.
+ * When @constants_set == NULL, it will load all the constants.
+ */
+void shader_glsl_load_constantsF(
+    WineD3D_GL_Info *gl_info,
+    GLhandleARB programId,
+    unsigned max_constants,
+    float* constants,
+    BOOL* constants_set,
+    char is_pshader) {
+        
+    GLhandleARB tmp_loc;
+    int i;
+    char tmp_name[7];
+    const char* prefix = is_pshader? "PC":"VC";
+
+    for (i=0; i<max_constants; ++i) {
+        if (NULL == constants_set || constants_set[i]) {
+
+            TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
+                  constants[i * sizeof(float) + 0], constants[i * sizeof(float) + 1],
+                  constants[i * sizeof(float) + 2], constants[i * sizeof(float) + 3]);
+
+            /* TODO: Benchmark and see if it would be beneficial to store the 
+             * locations of the constants to avoid looking up each time */
+            snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
+            tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
+            if (tmp_loc != -1) {
+                /* We found this uniform name in the program - go ahead and send the data */
+                GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, &constants[i * sizeof(float)]));
+                checkGLcall("glUniform4fvARB");
+            }
+        }
+    }
+}
+
+/**
+ * Loads the app-supplied constants into the currently set GLSL program.
+ */
+void shader_glsl_load_constants(
+    IWineD3DStateBlock* iface,
+    char usePixelShader,
+    char useVertexShader) {
+    
+    IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
+    WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
+    GLhandleARB programId = stateBlock->shaderPrgId;
+    
+    if (programId == 0) {
+        /* No GLSL program set - nothing to do. */
+        return;
+    }
+
+    if (useVertexShader) {
+        IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
+        IWineD3DVertexDeclarationImpl* vertexDeclaration =
+            (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
+
+        if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
+            /* Load DirectX 8 float constants/uniforms for vertex shader */
+            shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
+                                        vertexDeclaration->constants, NULL, 0);
+        }
+
+        /* Load DirectX 9 float constants/uniforms for vertex shader */
+        shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
+                                    stateBlock->vertexShaderConstantF, 
+                                    stateBlock->set.vertexShaderConstantsF, 0);
+
+        /* TODO: Load boolean & integer constants for vertex shader */
+    }
+
+    if (usePixelShader) {
+
+        /* Load pixel shader samplers */
+        shader_glsl_load_psamplers(gl_info, iface);
+
+        /* Load DirectX 9 float constants/uniforms for pixel shader */
+        shader_glsl_load_constantsF(gl_info, programId, WINED3D_PSHADER_MAX_CONSTANTS,
+                                    stateBlock->pixelShaderConstantF,
+                                    stateBlock->set.pixelShaderConstantsF, 1);
+
+        /* TODO: Load boolean & integer constants for pixel shader */
+    }
+}
+
 /*****************************************************************************
  * Functions to generate GLSL strings from DirectX Shader bytecode begin here.
  *
@@ -1043,3 +1156,4 @@ void vshader_glsl_output_unpack(
       }
    }
 }
+
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index cd7cfa0..10accc6 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1344,12 +1344,22 @@ extern const SHADER_OPCODE* shader_get_o
     IWineD3DBaseShader *iface, 
     const DWORD code);
 
+/* ARB_[vertex/fragment]_program helper functions */
+extern void shader_arb_load_constants(
+    IWineD3DStateBlock* iface,
+    char usePixelShader,
+    char useVertexShader);
+
 /* ARB shader program Prototypes */
 extern void shader_hw_def(SHADER_OPCODE_ARG *arg);
 
 /* GLSL helper functions */
 extern void set_glsl_shader_program(IWineD3DDevice *iface);
 extern void shader_glsl_add_instruction_modifiers(SHADER_OPCODE_ARG *arg);
+extern void shader_glsl_load_constants(
+    IWineD3DStateBlock* iface,
+    char usePixelShader,
+    char useVertexShader);
 
 /** The following translate DirectX pixel/vertex shader opcodes to GLSL lines */
 extern void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg);


More information about the wine-patches mailing list