wined3d: Allow vertex shaders to generate GLSL shaders [Take Two]

Jason Green jave27 at gmail.com
Thu May 18 01:48:58 CDT 2006


This is a resend of the earlier patch, with one addition:
 - previously, the line to alias the program.env[] to C[] was done in
the vertex shaders since that was the only function that needed them
(and it needs to be done to support relative addressing).  However,
with PS 2.0+, pixel shaders now need to be able to use relative
addressing as well.  This can't be done with ARB_fragment_program, but
it can be done with GLSL, so for consistency, we are now aliasing the
program.env[] array to C[] for both ps & vs.

I will sent the 1-line modification for pixelshaders as a separate
patch.  They will still work without that modification.

On 5/18/06, Jason Green <jave27 at gmail.com> wrote:
> This patch allows vertex shaders to generate GLSL shaders instead of /
> in addition to ARB_vertex_program's.
>
> Please let me know if any of these patches conflict with Ivan's recent
> patches, and I can re-submit if necessary.
>
>
>
-------------- next part --------------
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 10def6a..84330e7 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -499,14 +499,25 @@ void generate_arb_declarations(IWineD3DB
     if (This->baseShader.textures_used & (1 << i))
         shader_addline(buffer, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
     }
+
+    /* Need to PARAM the environment parameters (constants) so we can use relative addressing */
+    shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
+                    This->baseShader.limits.constant_float, 
+                    This->baseShader.limits.constant_float - 1);
 }
 
 /** Generate the variable & register declarations for the GLSL
     output target */
 void generate_glsl_declarations(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer) {
 
+    IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
+
     FIXME("GLSL not fully implemented yet.\n");
 
+    /* Create the uniforms (aka constants) */
+    shader_addline(buffer, "uniform vec4 C[%u];\n", This->baseShader.limits.constant_float);
+    /* TODO - Add varyings, attributes, etc. */
+
 }
 
 /** Shared code in order to generate the bulk of the shader string.
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 4321693..1c5263e 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -5,6 +5,7 @@
  * 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
@@ -1063,8 +1064,27 @@ inline static VOID IWineD3DVertexShaderI
     buffer.bsize = 0;
     buffer.lineNo = 0;
 
-    /* TODO: Optionally, generate the GLSL shader instead */
-    if (GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
+    if (USING_GLSL) {
+        /* Create the hw GLSL shader program */
+        GLhandleARB shader, program;
+
+        /* Generate the bulk of the shader code */
+        generate_base_shader( (IWineD3DBaseShader*) This, &buffer, pFunction);
+
+        shader_addline(&buffer, "}\n\0");
+
+        /* Create the GLSL shader object */
+        shader = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+        GL_EXTCALL(glShaderSourceARB(shader, 1, (const char**)&buffer.buffer, NULL));
+        GL_EXTCALL(glCompileShaderARB(shader));
+        /* Create the shader program and bind the object to it */
+        program = GL_EXTCALL(glCreateProgramObjectARB());
+        GL_EXTCALL(glAttachObjectARB(program, shader));
+        GL_EXTCALL(glLinkProgramARB(program));
+        This->baseShader.prgId = program;
+        /* We will check for errors later when we try to use the program */
+
+    } else if (GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
         /*  Create the hw ARB shader */
         shader_addline(&buffer, "!!ARBvp1.0\n");
 
@@ -1073,10 +1093,6 @@ inline static VOID IWineD3DVertexShaderI
             This->baseShader.limits.constant_float = 
                 min(95, This->baseShader.limits.constant_float);
 
-        shader_addline(&buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
-            This->baseShader.limits.constant_float, 
-            This->baseShader.limits.constant_float - 1);
-
         /** Call the base shader generation routine to generate most 
             of the vertex shader string for us */
         generate_base_shader( (IWineD3DBaseShader*) This, &buffer, pFunction);





More information about the wine-patches mailing list