[WINED3D 8/13] Resend: Added new GenerateShader function for Vertex Shaders & declare generate_base_shader()

Jason Green jave27 at gmail.com
Tue May 9 21:33:24 CDT 2006


-------------- next part --------------
Subject: [PATCH 08/13] Added new GenerateShader() function for Vertex Shaders, and declared generate_base_shader() so that vs & ps know of its existence

---

 dlls/wined3d/vertexshader.c    |   69 ++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |    5 +++
 2 files changed, 74 insertions(+), 0 deletions(-)

af7c44c16aa304b41ed506f8f1330e54c4567ae2
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 1b92652..2e3d4a8 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -1126,6 +1126,75 @@ void vshader_hw_mnxn(SHADER_OPCODE_ARG* 
     }
 }
 
+/** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
+    or GLSL and send it to the card */
+inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
+    IWineD3DVertexShader *iface,
+    CONST DWORD *pFunction) {
+
+    IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
+    SHADER_BUFFER buffer;
+
+#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
+        it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
+    if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
+        HeapFree(GetProcessHeap(), 0, This->fixupVertexBuffer);
+        This->fixupVertexBuffer = HeapAlloc(GetProcessHeap() , 0, SHADER_PGMSIZE);
+        This->fixupVertexBufferSize = PGMSIZE;
+        This->fixupVertexBuffer[0] = 0;
+    }
+    buffer.buffer = This->device->fixupVertexBuffer;
+#else
+    buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE); 
+#endif
+    buffer.bsize = 0;
+    buffer.lineNo = 0;
+
+    /* TODO: Optionally, generate the GLSL shader instead */
+    if (GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
+        /*  Create the hw ARB shader */
+        shader_addline(&buffer, "!!ARBvp1.0\n");
+
+        /* Mesa supports only 95 constants */
+        if (GL_VEND(MESA) || GL_VEND(WINE))
+            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);
+
+        shader_addline(&buffer, "END\n\0"); 
+
+        /* TODO: change to resource.glObjectHandle or something like that */
+        GL_EXTCALL(glGenProgramsARB(1, &This->baseShader.prgId));
+
+        TRACE("Creating a hw vertex shader, prg=%d\n", This->baseShader.prgId);
+        GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->baseShader.prgId));
+
+        TRACE("Created hw vertex shader, prg=%d\n", This->baseShader.prgId);
+        /* Create the program and check for errors */
+        GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+            buffer.bsize, buffer.buffer));
+
+        if (glGetError() == GL_INVALID_OPERATION) {
+            GLint errPos;
+            glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
+            FIXME("HW VertexShader Error at position %d: %s\n",
+                  errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+            This->baseShader.prgId = -1;
+        }
+    }
+
+#if 1 /* if were using the data buffer of device then we don't need to free it */
+  HeapFree(GetProcessHeap(), 0, buffer.buffer);
+#endif
+}
+
 /**
  * Function parser ...
  */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ab36d82..073c6bd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1287,6 +1287,11 @@ extern void shader_program_dump_decl_usa
     DWORD dcl,
     DWORD param);
 
+extern void generate_base_shader(
+    IWineD3DBaseShader *iface,
+    SHADER_BUFFER* buffer,
+    CONST DWORD* pFunction);
+
 inline static int shader_get_regtype(const DWORD param) {
     return (((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT) |
             ((param & D3DSP_REGTYPE_MASK2) >> D3DSP_REGTYPE_SHIFT2));
-- 
1.1.3



More information about the wine-patches mailing list