[2/4] wined3d: Move set_glsl_shader_program() to glsl_shader.c

H. Verbeet hverbeet at gmail.com
Wed Dec 27 20:13:24 CST 2006


This is quite specific to the GLSL shader backend.

Changelog:
  - Move set_glsl_shader_program() to glsl_shader.c
-------------- next part --------------
---

 dlls/wined3d/device.c          |  117 ----------------------------------------
 dlls/wined3d/glsl_shader.c     |  117 ++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |    1 
 3 files changed, 117 insertions(+), 118 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 14d6d9e..4ebca23 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -251,123 +251,6 @@ static void setup_light(IWineD3DDevice *
  * GLSL helper functions follow
  **********************************************************/
 
-/** Attach a GLSL pixel or vertex shader object to the shader program */
-static void attach_glsl_shader(IWineD3DDevice *iface, IWineD3DBaseShader* shader) {
-
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    GLhandleARB shaderObj = ((IWineD3DBaseShaderImpl*)shader)->baseShader.prgId;
-    if (This->stateBlock->glsl_program && shaderObj != 0) {
-        TRACE_(d3d_shader)("Attaching GLSL shader object %u to program %u\n", shaderObj, This->stateBlock->glsl_program->programId);
-        GL_EXTCALL(glAttachObjectARB(This->stateBlock->glsl_program->programId, shaderObj));
-        checkGLcall("glAttachObjectARB");
-    }
-}
-
-/** Sets the GLSL program ID for the given pixel and vertex shader combination.
- * It sets the programId on the current StateBlock (because it should be called
- * inside of the DrawPrimitive() part of the render loop).
- *
- * If a program for the given combination does not exist, create one, and store
- * the program in the list.  If it creates a program, it will link the given 
- * objects, too.
- * 
- * We keep the shader programs around on a list because linking
- * shader objects together is an expensive operation.  It's much
- * faster to loop through a list of pre-compiled & linked programs
- * each time that the application sets a new pixel or vertex shader
- * than it is to re-link them together at that time.
- *
- * The list will be deleted in IWineD3DDevice::Release().
- */
-void set_glsl_shader_program(IWineD3DDevice *iface) {
-
-    IWineD3DDeviceImpl *This               = (IWineD3DDeviceImpl *)iface;
-    IWineD3DPixelShader  *pshader          = This->stateBlock->pixelShader;
-    IWineD3DVertexShader *vshader          = This->stateBlock->vertexShader;
-    struct glsl_shader_prog_link *curLink  = NULL;
-    struct glsl_shader_prog_link *newLink  = NULL;
-    struct list *ptr                       = NULL;
-    GLhandleARB programId                  = 0;
-    int i;
-    char glsl_name[8];
-    
-    ptr = list_head( &This->glsl_shader_progs );
-    while (ptr) {
-        /* At least one program exists - see if it matches our ps/vs combination */
-        curLink = LIST_ENTRY( ptr, struct glsl_shader_prog_link, entry );
-        if (vshader == curLink->vertexShader && pshader == curLink->pixelShader) {
-            /* Existing Program found, use it */
-            TRACE_(d3d_shader)("Found existing program (%u) for this vertex/pixel shader combination\n", 
-                   curLink->programId);
-            This->stateBlock->glsl_program = curLink;
-            return;
-        }
-        /* This isn't the entry we need - try the next one */
-        ptr = list_next( &This->glsl_shader_progs, ptr );
-    }
-
-    /* If we get to this point, then no matching program exists, so we create one */
-    programId = GL_EXTCALL(glCreateProgramObjectARB());
-    TRACE_(d3d_shader)("Created new GLSL shader program %u\n", programId);
-
-    /* Allocate a new link for the list of programs */
-    newLink = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
-    newLink->programId    = programId;
-    This->stateBlock->glsl_program = newLink;
-   
-    /* Attach GLSL vshader */ 
-    if (NULL != vshader && This->vs_selected_mode == SHADER_GLSL) {
-        int i;
-        int max_attribs = 16;   /* TODO: Will this always be the case? It is at the moment... */
-        char tmp_name[10];
-    
-        TRACE("Attaching vertex shader to GLSL program\n");    
-        attach_glsl_shader(iface, (IWineD3DBaseShader*)vshader);
-        
-        /* Bind vertex attributes to a corresponding index number to match
-         * the same index numbers as ARB_vertex_programs (makes loading
-         * vertex attributes simpler).  With this method, we can use the
-         * exact same code to load the attributes later for both ARB and 
-         * GLSL shaders.
-         * 
-         * We have to do this here because we need to know the Program ID
-         * in order to make the bindings work, and it has to be done prior
-         * to linking the GLSL program. */
-        for (i = 0; i < max_attribs; ++i) {
-             snprintf(tmp_name, sizeof(tmp_name), "attrib%i", i);
-             GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
-        }
-        checkGLcall("glBindAttribLocationARB");
-        newLink->vertexShader = vshader;
-    }
-    
-    /* Attach GLSL pshader */
-    if (NULL != pshader && This->ps_selected_mode == SHADER_GLSL) {
-        TRACE("Attaching pixel shader to GLSL program\n");
-        attach_glsl_shader(iface, (IWineD3DBaseShader*)pshader);
-        newLink->pixelShader = pshader;
-    }    
-
-    /* Link the program */
-    TRACE_(d3d_shader)("Linking GLSL shader program %u\n", programId);
-    GL_EXTCALL(glLinkProgramARB(programId));
-    print_glsl_info_log(&GLINFO_LOCATION, programId);
-    list_add_head( &This->glsl_shader_progs, &newLink->entry);
-
-    newLink->vuniformF_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * GL_LIMITS(vshader_constantsF));
-    for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i) {
-        snprintf(glsl_name, sizeof(glsl_name), "VC[%i]", i);
-        newLink->vuniformF_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
-    }
-    newLink->puniformF_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * GL_LIMITS(pshader_constantsF));
-    for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i) {
-        snprintf(glsl_name, sizeof(glsl_name), "PC[%i]", i);
-        newLink->puniformF_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
-    }
-
-    return;
-}
-
 /** Detach the GLSL pixel or vertex shader object from the shader program */
 static void detach_glsl_shader(IWineD3DDevice *iface, GLhandleARB shaderObj, GLhandleARB programId) {
 
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 17b6a47..fe0bb65 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1879,6 +1879,123 @@ void vshader_glsl_output_unpack(
     }
 }
 
+/** Attach a GLSL pixel or vertex shader object to the shader program */
+static void attach_glsl_shader(IWineD3DDevice *iface, IWineD3DBaseShader* shader) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    WineD3D_GL_Info *gl_info = &((IWineD3DImpl *)(This->wineD3D))->gl_info;
+    GLhandleARB shaderObj = ((IWineD3DBaseShaderImpl*)shader)->baseShader.prgId;
+    if (This->stateBlock->glsl_program && shaderObj != 0) {
+        TRACE("Attaching GLSL shader object %u to program %u\n", shaderObj, This->stateBlock->glsl_program->programId);
+        GL_EXTCALL(glAttachObjectARB(This->stateBlock->glsl_program->programId, shaderObj));
+        checkGLcall("glAttachObjectARB");
+    }
+}
+
+/** Sets the GLSL program ID for the given pixel and vertex shader combination.
+ * It sets the programId on the current StateBlock (because it should be called
+ * inside of the DrawPrimitive() part of the render loop).
+ *
+ * If a program for the given combination does not exist, create one, and store
+ * the program in the list.  If it creates a program, it will link the given
+ * objects, too.
+ *
+ * We keep the shader programs around on a list because linking
+ * shader objects together is an expensive operation.  It's much
+ * faster to loop through a list of pre-compiled & linked programs
+ * each time that the application sets a new pixel or vertex shader
+ * than it is to re-link them together at that time.
+ *
+ * The list will be deleted in IWineD3DDevice::Release().
+ */
+static void set_glsl_shader_program(IWineD3DDevice *iface) {
+    IWineD3DDeviceImpl *This               = (IWineD3DDeviceImpl *)iface;
+    WineD3D_GL_Info *gl_info               = &((IWineD3DImpl *)(This->wineD3D))->gl_info;
+    IWineD3DPixelShader  *pshader          = This->stateBlock->pixelShader;
+    IWineD3DVertexShader *vshader          = This->stateBlock->vertexShader;
+    struct glsl_shader_prog_link *curLink  = NULL;
+    struct glsl_shader_prog_link *newLink  = NULL;
+    struct list *ptr                       = NULL;
+    GLhandleARB programId                  = 0;
+    int i;
+    char glsl_name[8];
+
+    ptr = list_head( &This->glsl_shader_progs );
+    while (ptr) {
+        /* At least one program exists - see if it matches our ps/vs combination */
+        curLink = LIST_ENTRY( ptr, struct glsl_shader_prog_link, entry );
+        if (vshader == curLink->vertexShader && pshader == curLink->pixelShader) {
+            /* Existing Program found, use it */
+            TRACE("Found existing program (%u) for this vertex/pixel shader combination\n", 
+                   curLink->programId);
+            This->stateBlock->glsl_program = curLink;
+            return;
+        }
+        /* This isn't the entry we need - try the next one */
+        ptr = list_next( &This->glsl_shader_progs, ptr );
+    }
+
+    /* If we get to this point, then no matching program exists, so we create one */
+    programId = GL_EXTCALL(glCreateProgramObjectARB());
+    TRACE("Created new GLSL shader program %u\n", programId);
+
+    /* Allocate a new link for the list of programs */
+    newLink = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
+    newLink->programId    = programId;
+    This->stateBlock->glsl_program = newLink;
+
+    /* Attach GLSL vshader */
+    if (NULL != vshader && This->vs_selected_mode == SHADER_GLSL) {
+        int i;
+        int max_attribs = 16;   /* TODO: Will this always be the case? It is at the moment... */
+        char tmp_name[10];
+
+        TRACE("Attaching vertex shader to GLSL program\n");
+        attach_glsl_shader(iface, (IWineD3DBaseShader*)vshader);
+
+        /* Bind vertex attributes to a corresponding index number to match
+         * the same index numbers as ARB_vertex_programs (makes loading
+         * vertex attributes simpler).  With this method, we can use the
+         * exact same code to load the attributes later for both ARB and
+         * GLSL shaders.
+         *
+         * We have to do this here because we need to know the Program ID
+         * in order to make the bindings work, and it has to be done prior
+         * to linking the GLSL program. */
+        for (i = 0; i < max_attribs; ++i) {
+             snprintf(tmp_name, sizeof(tmp_name), "attrib%i", i);
+             GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
+        }
+        checkGLcall("glBindAttribLocationARB");
+        newLink->vertexShader = vshader;
+    }
+
+    /* Attach GLSL pshader */
+    if (NULL != pshader && This->ps_selected_mode == SHADER_GLSL) {
+        TRACE("Attaching pixel shader to GLSL program\n");
+        attach_glsl_shader(iface, (IWineD3DBaseShader*)pshader);
+        newLink->pixelShader = pshader;
+    }
+
+    /* Link the program */
+    TRACE("Linking GLSL shader program %u\n", programId);
+    GL_EXTCALL(glLinkProgramARB(programId));
+    print_glsl_info_log(&GLINFO_LOCATION, programId);
+    list_add_head( &This->glsl_shader_progs, &newLink->entry);
+
+    newLink->vuniformF_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * GL_LIMITS(vshader_constantsF));
+    for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i) {
+        snprintf(glsl_name, sizeof(glsl_name), "VC[%i]", i);
+        newLink->vuniformF_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
+    }
+    newLink->puniformF_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * GL_LIMITS(pshader_constantsF));
+    for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i) {
+        snprintf(glsl_name, sizeof(glsl_name), "PC[%i]", i);
+        newLink->puniformF_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
+    }
+
+    return;
+}
+
 static GLhandleARB create_glsl_blt_shader(WineD3D_GL_Info *gl_info) {
     GLhandleARB program_id;
     GLhandleARB vshader_id, pshader_id;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e3af89b..14d1b0e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1587,7 +1587,6 @@ extern void vshader_hw_map2gl(SHADER_OPC
 extern void vshader_hw_mnxn(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(
     IWineD3DDevice* device,


More information about the wine-patches mailing list