[WINED3D] Addline cleanup

Ivan Gyurdiev ivg2 at cornell.edu
Mon May 8 14:44:25 CDT 2006


Ivan Gyurdiev wrote:
>
>> +
>> +#include <string.h>
>> +#include <stdio.h>
>> +#include "config.h"
>> +#include "wined3d_private.h"
>>   
> Make depend will fail as pointed out by Mike McCormack Sorry, I forgot 
> to run that. If you flip the above lines to include "config.h"  before 
> anything else directly in the patch it should not cause any problems.
Attached is a corrected patch from my git tree.


-------------- next part --------------
---

 dlls/wined3d/Makefile.in       |    1 
 dlls/wined3d/baseshader.c      |   57 +++++++++
 dlls/wined3d/pixelshader.c     |  251 ++++++++++++++--------------------------
 dlls/wined3d/vertexshader.c    |  120 ++++++-------------
 dlls/wined3d/wined3d_private.h |   13 ++
 5 files changed, 196 insertions(+), 246 deletions(-)
 create mode 100644 dlls/wined3d/baseshader.c

1ffb77dba1b1393d795c3e4f65958845b9feb521
diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in
index 24e1e26..291fb3d 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 = \
+	baseshader.c \
 	basetexture.c \
 	cubetexture.c \
 	device.c \
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
new file mode 100644
index 0000000..5b39e9a
--- /dev/null
+++ b/dlls/wined3d/baseshader.c
@@ -0,0 +1,57 @@
+/*
+ * shaders implementation
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+int shader_addline(
+    SHADER_BUFFER* buffer,  
+    const char *format, ...) {
+
+    char* base = buffer->buffer + buffer->bsize;
+    int rc;
+
+    va_list args;
+    va_start(args, format);
+    rc = vsnprintf(base, SHADER_PGMSIZE - 1 - buffer->bsize, format, args);
+    va_end(args);
+
+    if (rc < 0 ||                                   /* C89 */ 
+        rc > SHADER_PGMSIZE - 1 - buffer->bsize) {  /* C99 */
+
+        ERR("The buffer allocated for the shader program string "
+            "is too small at %d bytes.\n", SHADER_PGMSIZE);
+        buffer->bsize = SHADER_PGMSIZE - 1;
+        return -1;
+    }
+
+    buffer->bsize += rc;
+    buffer->lineNo++;
+    TRACE("GL HW (%u, %u) : %s", buffer->lineNo, buffer->bsize, base); 
+    return 0;
+}
+
+/* TODO: Move other shared code here */
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 0a0f920..76e1404 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -1,7 +1,9 @@
 /*
  * shaders implementation
  *
- * Copyright 2005      Oliver Stieber
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -37,9 +39,6 @@ # define PSTRACE(A)
 # define TRACE_VSVECTOR(name)
 #endif
 
-/* The maximum size of the program */
-#define PGMSIZE 65535
-
 #define GLNAME_REQUIRE_GLSL  ((const char *)1)
 /* *******************************************
    IWineD3DPixelShader IUnknown parts follow
@@ -851,20 +850,6 @@ inline static void get_input_register_sw
     }
 }
 
-inline static void addline(unsigned int *lineNum, char *pgm, unsigned int *pgmLength, char *line) {
-    int lineLen = strlen(line);
-    if(lineLen + *pgmLength > PGMSIZE - 1 /* - 1 to allow a NULL at the end */) {
-        ERR("The buffer allocated for the vertex program string pgmStr is too small at %d bytes, at least %d bytes in total are required.\n", PGMSIZE, lineLen + *pgmLength);
-        return;
-    } else {
-        memcpy(pgm + *pgmLength, line, lineLen);
-    }
-
-    *pgmLength += lineLen;
-    ++(*lineNum);
-    TRACE("GL HW (%u, %u) : %s", *lineNum, *pgmLength, line);
-}
-
 static const char* shift_tab[] = {
     "dummy",     /*  0 (none) */ 
     "coefmul.x", /*  1 (x2)   */ 
@@ -1021,36 +1006,34 @@ inline static VOID IWineD3DPixelShaderIm
     const SHADER_OPCODE *curOpcode = NULL;
     const DWORD *pInstr;
     DWORD i;
-    unsigned lineNum = 0; /* The line number of the generated program (for loging)*/
-    char *pgmStr = NULL; /* A pointer to the program data generated by this function */
     char  tmpLine[255];
 #if 0 /* TODO: loop register (just another address register ) */
     BOOL hasLoops = FALSE;
 #endif
+    SHADER_BUFFER buffer;
 
     BOOL saturate; /* clamp to 0.0 -> 1.0*/
     int row = 0; /* not sure, something to do with macros? */
     DWORD tcw[2];
     int version = 0; /* The version of the shader */
 
-    /* Keep a running length for pgmStr so that we don't have to caculate strlen every time we concatanate */
-    unsigned int pgmLength = 0;
-
     /* Keep bitmaps of used temporary and texture registers */
     DWORD tempsUsed, texUsed;
 
 #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 < PGMSIZE) {
+    if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
         HeapFree(GetProcessHeap(), 0, This->fixupVertexBuffer);
-        This->fixupVertexBuffer = HeapAlloc(GetProcessHeap() , 0, PGMSIZE);
-        This->fixupVertexBufferSize = PGMSIZE;
+        This->fixupVertexBuffer = HeapAlloc(GetProcessHeap() , 0, SHADER_PGMSIZE);
+        This->fixupVertexBufferSize = SHADER_PGMSIZE;
         This->fixupVertexBuffer[0] = 0;
     }
-    pgmStr = This->device->fixupVertexBuffer;
+    buffer.buffer = This->device->fixupVertexBuffer;
 #else
-    pgmStr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PGMSIZE); /* 64kb should be enough */
+    buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE);
 #endif
+    buffer.bsize = 0;
+    buffer.lineNo = 0;
 
     /* TODO: Think about using a first pass to work out what's required for the second pass. */
     for(i = 0; i < WINED3D_PSHADER_MAX_CONSTANTS; i++)
@@ -1111,46 +1094,31 @@ #endif
                 }
 
                 /* FIXME: if jumps are used, use GLSL, else use ARB_fragment_program */
-                strcpy(tmpLine, "!!ARBfp1.0\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                shader_addline(&buffer, "!!ARBfp1.0\n");
 
                 for(i = 0; i < numTex; i++) {
-                    if (texUsed & (1 << i)) {
-                        sprintf(tmpLine, "TEMP T%lu;\n", i);
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
+                    if (texUsed & (1 << i)) 
+                        shader_addline(&buffer,"TEMP T%lu;\n", i);
                 }
 
                 for(i = 0; i < numTemps; i++) {
-                    if (tempsUsed & (1 << i)) {
-                        sprintf(tmpLine, "TEMP R%lu;\n", i);
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
+                    if (tempsUsed & (1 << i)) 
+                        shader_addline(&buffer, "TEMP R%lu;\n", i);
                 }
 
-                sprintf(tmpLine, "TEMP TMP;\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                sprintf(tmpLine, "TEMP TMP2;\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                sprintf(tmpLine, "TEMP TA;\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                sprintf(tmpLine, "TEMP TB;\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                sprintf(tmpLine, "TEMP TC;\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-
-                strcpy(tmpLine, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                strcpy(tmpLine, "PARAM coefmul = { 2, 4, 8, 16 };\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                strcpy(tmpLine, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
-                addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                shader_addline(&buffer, "TEMP TMP;\n");
+                shader_addline(&buffer, "TEMP TMP2;\n");
+                shader_addline(&buffer, "TEMP TA;\n");
+                shader_addline(&buffer, "TEMP TB;\n");
+                shader_addline(&buffer, "TEMP TC;\n");
+
+                shader_addline(&buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n");
+                shader_addline(&buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
+                shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
 
                 for(i = 0; i < numTex; i++) {
-                    if (texUsed & (1 << i)) {
-                        sprintf(tmpLine, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
+                    if (texUsed & (1 << i)) 
+                        shader_addline(&buffer, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
                 }
 
                 ++pToken;
@@ -1192,14 +1160,13 @@ #endif
                     TRACE("Found opcode D3D:%s GL:%s, PARAMS:%d, \n",
                     curOpcode->name, curOpcode->glname, curOpcode->num_params);
 
-                    sprintf(tmpLine, "PARAM C%lu = { %f, %f, %f, %f };\n", reg,
+                    shader_addline(&buffer, 
+                              "PARAM C%lu = { %f, %f, %f, %f };\n", reg,
                               *((const float *)(pToken + 1)),
                               *((const float *)(pToken + 2)),
                               *((const float *)(pToken + 3)),
                               *((const float *)(pToken + 4)) );
 
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-
                     This->constants[reg] = 1;
                     pToken += 5;
                     continue;
@@ -1269,7 +1236,7 @@ #endif
               
                     else if (version == 14) { 
                         if (gen_input_modifier_line(*pToken, 0, reg_coord, tmpLine, This->constants))
-                            addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                            shader_addline(&buffer, tmpLine);
                         get_input_register_swizzle(*pToken, reg_coord_swz);
                         pToken++;
                     }
@@ -1293,9 +1260,8 @@ #endif
                         pToken++;
                     }
 
-                    sprintf(tmpLine, "TEX %s, %s%s, texture[%lu], 2D;\n",
+                    shader_addline(&buffer, "TEX %s, %s%s, texture[%lu], 2D;\n",
                         reg_dest, reg_coord, reg_coord_swz, reg_sampler_code);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
                     continue;
                 }
                 break;
@@ -1305,14 +1271,12 @@ #endif
                     get_write_mask(*pToken, tmp);
                     if (version != 14) {
                         DWORD reg = *pToken & D3DSP_REGNUM_MASK;
-                        sprintf(tmpLine, "MOV T%lu%s, fragment.texcoord[%lu];\n", reg, tmp, reg);
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                        shader_addline(&buffer, "MOV T%lu%s, fragment.texcoord[%lu];\n", reg, tmp, reg);
                         ++pToken;
                     } else {
                         DWORD reg1 = *pToken & D3DSP_REGNUM_MASK;
                         DWORD reg2 = *++pToken & D3DSP_REGNUM_MASK;
-                        sprintf(tmpLine, "MOV R%lu%s, fragment.texcoord[%lu];\n", reg1, tmp, reg2);
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                        shader_addline(&buffer, "MOV R%lu%s, fragment.texcoord[%lu];\n", reg1, tmp, reg2);
                         ++pToken;
                     }
                     continue;
@@ -1322,11 +1286,9 @@ #endif
                 {
                     DWORD reg = *pToken & D3DSP_REGNUM_MASK;
                     char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) {
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
-                    sprintf(tmpLine, "DP3 TMP.x, T%lu, %s;\n", reg, buf);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
+                        shader_addline(&buffer, tmpLine);
+                    shader_addline(&buffer, "DP3 TMP.x, T%lu, %s;\n", reg, buf);
                     ++pToken;
                     continue;
                 }
@@ -1335,13 +1297,10 @@ #endif
                 {
                     DWORD reg = *pToken & D3DSP_REGNUM_MASK;
                     char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) {
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
-                    sprintf(tmpLine, "DP3 TMP.y, T%lu, %s;\n", reg, buf);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg, reg);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
+                        shader_addline(&buffer, tmpLine);
+                    shader_addline(&buffer, "DP3 TMP.y, T%lu, %s;\n", reg, buf);
+                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg, reg);
                     ++pToken;
                     continue;
                 }
@@ -1350,12 +1309,9 @@ #endif
                 {
                     DWORD reg1 = *pToken & D3DSP_REGNUM_MASK;
                     DWORD reg2 = *++pToken & D3DSP_REGNUM_MASK;
-                    sprintf(tmpLine, "MOV TMP.r, T%lu.a;\n", reg2);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "MOV TMP.g, T%lu.r;\n", reg2);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg1, reg1);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "MOV TMP.r, T%lu.a;\n", reg2);
+                    shader_addline(&buffer, "MOV TMP.g, T%lu.r;\n", reg2);
+                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg1, reg1);
                     ++pToken;
                     continue;
                 }
@@ -1364,12 +1320,9 @@ #endif
                 {
                     DWORD reg1 = *pToken & D3DSP_REGNUM_MASK;
                     DWORD reg2 = *++pToken & D3DSP_REGNUM_MASK;
-                    sprintf(tmpLine, "MOV TMP.r, T%lu.g;\n", reg2);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "MOV TMP.g, T%lu.b;\n", reg2);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg1, reg1);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "MOV TMP.r, T%lu.g;\n", reg2);
+                    shader_addline(&buffer, "MOV TMP.g, T%lu.b;\n", reg2);
+                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg1, reg1);
                     ++pToken;
                     continue;
                 }
@@ -1380,10 +1333,8 @@ #endif
                     DWORD reg2 = *++pToken & D3DSP_REGNUM_MASK;
 
                     /* FIXME: Should apply the BUMPMAPENV matrix */
-                    sprintf(tmpLine, "ADD TMP.rg, fragment.texcoord[%lu], T%lu;\n", reg1, reg2);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg1, reg1);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "ADD TMP.rg, fragment.texcoord[%lu], T%lu;\n", reg1, reg2);
+                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg1, reg1);
                     ++pToken;
                     continue;
                 }
@@ -1392,11 +1343,9 @@ #endif
                 {
                     DWORD reg = *pToken & D3DSP_REGNUM_MASK;
                     char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) {
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
-                    sprintf(tmpLine, "DP3 TMP.%c, T%lu, %s;\n", 'x'+row, reg, buf);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
+                        shader_addline(&buffer, tmpLine);
+                    shader_addline(&buffer, "DP3 TMP.%c, T%lu, %s;\n", 'x'+row, reg, buf);
                     tcw[row++] = reg;
                     ++pToken;
                     continue;
@@ -1406,16 +1355,12 @@ #endif
                 {
                     DWORD reg = *pToken & D3DSP_REGNUM_MASK;
                     char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) {
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
-
-                    sprintf(tmpLine, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
+                        shader_addline(&buffer, tmpLine);
+                    shader_addline(&buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
 
                     /* Cubemap textures will be more used than 3D ones. */
-                    sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
                     row = 0;
                     ++pToken;
                     continue;
@@ -1424,31 +1369,22 @@ #endif
                 {
                     DWORD reg = *pToken & D3DSP_REGNUM_MASK;
                     char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) {
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
-                    sprintf(tmpLine, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
+                        shader_addline(&buffer, tmpLine);
+                    shader_addline(&buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
 
                     /* Construct the eye-ray vector from w coordinates */
-                    sprintf(tmpLine, "MOV TMP2.x, fragment.texcoord[%lu].w;\n", tcw[0]);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "MOV TMP2.y, fragment.texcoord[%lu].w;\n", tcw[1]);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "MOV TMP2.z, fragment.texcoord[%lu].w;\n", reg);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "MOV TMP2.x, fragment.texcoord[%lu].w;\n", tcw[0]);
+                    shader_addline(&buffer, "MOV TMP2.y, fragment.texcoord[%lu].w;\n", tcw[1]);
+                    shader_addline(&buffer, "MOV TMP2.z, fragment.texcoord[%lu].w;\n", reg);
 
                     /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
-                    sprintf(tmpLine, "DP3 TMP.w, TMP, TMP2;\n");
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "MUL TMP, TMP.w, TMP;\n");
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "MAD TMP, coefmul.x, TMP, -TMP2;\n");
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "DP3 TMP.w, TMP, TMP2;\n");
+                    shader_addline(&buffer, "MUL TMP, TMP.w, TMP;\n");
+                    shader_addline(&buffer, "MAD TMP, coefmul.x, TMP, -TMP2;\n");
 
                     /* Cubemap textures will be more used than 3D ones. */
-                    sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
                     row = 0;
                     ++pToken;
                     continue;
@@ -1459,24 +1395,17 @@ #endif
                     DWORD reg = *pToken & D3DSP_REGNUM_MASK;
                     DWORD reg3 = *(pToken + 2) & D3DSP_REGNUM_MASK;
                     char buf[50];
-                    if (gen_input_modifier_line(*(pToken + 1), 0, buf, tmpLine, This->constants)) {
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    }
-                    sprintf(tmpLine, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    if (gen_input_modifier_line(*(pToken + 1), 0, buf, tmpLine, This->constants)) 
+                        shader_addline(&buffer, tmpLine);
+                    shader_addline(&buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
 
                     /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
-                    sprintf(tmpLine, "DP3 TMP.w, TMP, C[%lu];\n", reg3);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-
-                    sprintf(tmpLine, "MUL TMP, TMP.w, TMP;\n");
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                    sprintf(tmpLine, "MAD TMP, coefmul.x, TMP, -C[%lu];\n", reg3);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "DP3 TMP.w, TMP, C[%lu];\n", reg3);
+                    shader_addline(&buffer, "MUL TMP, TMP.w, TMP;\n");
+                    shader_addline(&buffer, "MAD TMP, coefmul.x, TMP, -C[%lu];\n", reg3);
 
                     /* Cubemap textures will be more used than 3D ones. */
-                    sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
                     row = 0;
                     pToken += 3;
                     continue;
@@ -1519,7 +1448,7 @@ #endif
                     for (i = 1; i < curOpcode->num_params; ++i) {
                         TRACE("(%p) : Param %ld token %lx\n", This, i, *(pToken + i));
                         if (gen_input_modifier_line(*(pToken + i), i - 1, regs[i - 1], tmpOp, This->constants)) {
-                            addline(&lineNum, pgmStr, &pgmLength, tmpOp);
+                            shader_addline(&buffer, tmpOp);
                         }
                     }
 
@@ -1540,12 +1469,13 @@ #endif
 
                     switch(curOpcode->opcode) {
                     case D3DSIO_CMP:
-                        sprintf(tmpLine, "CMP%s %s, %s, %s, %s;\n", (saturate ? "_SAT" : ""), operands[0], operands[1], operands[3], operands[2]);
+                        sprintf(tmpLine, "CMP%s %s, %s, %s, %s;\n", (saturate ? "_SAT" : ""), 
+                           operands[0], operands[1], operands[3], operands[2]);
                     break;
                     case D3DSIO_CND:
-                        sprintf(tmpLine, "ADD TMP, -%s, coefdiv.x;", operands[1]);
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-                        sprintf(tmpLine, "CMP%s %s, TMP, %s, %s;\n", (saturate ? "_SAT" : ""), operands[0], operands[2], operands[3]);
+                        shader_addline(&buffer, "ADD TMP, -%s, coefdiv.x;\n", operands[1]);
+                        sprintf(tmpLine, "CMP%s %s, TMP, %s, %s;\n", (saturate ? "_SAT" : ""), 
+                           operands[0], operands[2], operands[3]);
                     break;
                     default:
                         if (saturate && (shift == 0))
@@ -1558,34 +1488,31 @@ #endif
                         }
                         strcat(tmpLine,";\n");
                     }
-                    addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                    shader_addline(&buffer, tmpLine);
 
                     /* A shift requires another line. */
                     if (shift != 0) {
                         gen_output_modifier_line(saturate, output_wmask, shift, output_rname, tmpLine);
-                        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+                        shader_addline(&buffer, tmpLine);
                     }
                     pToken += curOpcode->num_params;
                 }
             }
         }
         /* TODO: What about result.depth? */
-        strcpy(tmpLine, "MOV result.color, R0;\n");
-        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
-
-        strcpy(tmpLine, "END\n");
-        addline(&lineNum, pgmStr, &pgmLength, tmpLine);
+        shader_addline(&buffer, "MOV result.color, R0;\n");
+        shader_addline(&buffer, "END\n");
     }
 
-    /* finally null terminate the pgmStr*/
-    pgmStr[pgmLength] = 0;
+    /* finally null terminate the buffer */
+    buffer.buffer[buffer.bsize] = 0;
     if (GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
         /*  Create the hw shader */
 
-        /* pgmStr sometimes gets too long for a normal TRACE */
+        /* The program string sometimes gets too long for a normal TRACE */
         TRACE("Generated program:\n");
         if (TRACE_ON(d3d_shader)) {
-            fprintf(stderr, "%s\n", pgmStr);
+            fprintf(stderr, "%s\n", buffer.buffer);
         }
 
         /* TODO: change to resource.glObjectHandel or something like that */
@@ -1596,7 +1523,9 @@ #endif
 
         TRACE("Created hw pixel shader, prg=%d\n", This->baseShader.prgId);
         /* Create the program and check for errors */
-        GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(pgmStr), pgmStr));
+        GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_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);
@@ -1606,7 +1535,7 @@ #endif
         }
     }
 #if 1 /* if were using the data buffer of device then we don't need to free it */
-    HeapFree(GetProcessHeap(), 0, pgmStr);
+    HeapFree(GetProcessHeap(), 0, buffer.buffer);
 #endif
 }
 
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 857b46d..5229760 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -1261,8 +1261,7 @@ inline static VOID IWineD3DVertexShaderI
     const SHADER_OPCODE* curOpcode = NULL;
     int nRemInstr = -1;
     DWORD i;
-    unsigned lineNum = 0;
-    char *pgmStr = NULL;
+    SHADER_BUFFER buffer;
     char  tmpLine[255];
     DWORD nUseAddressRegister = 0;
     DWORD nUseTempRegister = 0;
@@ -1273,31 +1272,20 @@ #if 0 /* TODO: loope register (just anot
     BOOL hasLoops = FALSE;
 #endif
 
-#define PGMSIZE 65535
-/* Keep a running length for pgmStr so that we don't have to caculate strlen every time we concatanate */
-    int pgmLength = 0;
-
 #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 < PGMSIZE) {
+    if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
         HeapFree(GetProcessHeap(), 0, This->fixupVertexBuffer);
-        This->fixupVertexBuffer = HeapAlloc(GetProcessHeap() , 0, PGMSIZE);
+        This->fixupVertexBuffer = HeapAlloc(GetProcessHeap() , 0, SHADER_PGMSIZE);
         This->fixupVertexBufferSize = PGMSIZE;
         This->fixupVertexBuffer[0] = 0;
     }
-    pgmStr = This->device->fixupVertexBuffer;
+    buffer.buffer = This->device->fixupVertexBuffer;
 #endif
-#define PNSTRCAT(_pgmStr, _tmpLine) { \
-        int _tmpLineLen = strlen(_tmpLine); \
-        if(_tmpLineLen + pgmLength > PGMSIZE) { \
-            ERR("The buffer allocated for the vertex program string pgmStr is too small at %d bytes, at least %d bytes in total are required.\n", PGMSIZE, _tmpLineLen + pgmLength); \
-        } else { \
-           memcpy(_pgmStr + pgmLength, _tmpLine, _tmpLineLen); \
-        } \
-        pgmLength += _tmpLineLen; \
-        }
+    buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE); 
+    buffer.bsize = 0;
+    buffer.lineNo = 0;
 
-    pgmStr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 65535); /* 64kb should be enough */
     /* Initialise the shader */
     This->namedArrays = FALSE;
     This->declaredArrays = FALSE;
@@ -1454,43 +1442,31 @@ #endif
 
 
         /* FIXME: if jumps are used, use GLSL, else use ARB_vertex_program */
-        strcpy(tmpLine, "!!ARBvp1.0\n");
-        TRACE("GL HW (%u) : %s", pgmLength, tmpLine); /* Don't add \n to this line as already in tmpLine */
-        PNSTRCAT(pgmStr, tmpLine);
-        ++lineNum;
+        shader_addline(&buffer, "!!ARBvp1.0\n");
 
         /* This should be a bitmap so that only temp registers that are used are declared. */
         for (i = 0; i < nUseTempRegister /* we should check numTemps here */ ; i++) {
-            if (tmpsUsed[i]) { /* only write out the temps if they are actually in use */
-                sprintf(tmpLine, "TEMP T%ld;\n", i);
-                ++lineNum;
-                TRACE("GL HW (%u, %u) : %s", lineNum, pgmLength, tmpLine); /* Don't add \n to this line as already in tmpLine */
-                PNSTRCAT(pgmStr, tmpLine);
-
-            }
+            if (tmpsUsed[i])
+                shader_addline(&buffer, "TEMP T%ld;\n", i);
         }
         /* TODO: loop register counts as an address register */
         for (i = 0; i < nUseAddressRegister; i++) {
-            sprintf(tmpLine, "ADDRESS A%ld;\n", i);
-            ++lineNum;
-            TRACE("GL HW (%u, %u) : %s", lineNum, pgmLength, tmpLine); /* Don't add \n to this line as already in tmpLine */
-                PNSTRCAT(pgmStr, tmpLine);
-
+            shader_addline(&buffer, "ADDRESS A%ld;\n", i);
         }
+
         /* Due to the dynamic constants binding mechanism, we need to declare
         * all the constants for relative addressing. */
         /* Mesa supports only 95 constants for VS1.X although we should have at least 96. */
         if (GL_VEND(MESA) || GL_VEND(WINE)) {
             numConstants = 95;
         }
-        /* FIXME: We should  be counting the number of constants in the first pass and then validating that many are supported
-                Looking at some of the shaders in use by applications we'd need to create a list of all used env variables
-        */
-        sprintf(tmpLine, "PARAM C[%d] = { program.env[0..%d] };\n", numConstants, numConstants - 1);
-        TRACE("GL HW (%u,%u) : %s", lineNum, pgmLength, tmpLine); /* Don't add \n to this line as already in tmpLine */
-        PNSTRCAT(pgmStr, tmpLine);
 
-        ++lineNum;
+        /* FIXME: We should be counting the number of constants in the first pass 
+         * and then validating that many are supported. Looking at some of the shaders in use 
+         * by applications we'd need to create a list of all used env variables
+         */
+        shader_addline(&buffer, "PARAM C[%d] = { program.env[0..%d] };\n", 
+           numConstants, numConstants - 1);
 
         ++pToken;
         continue;
@@ -1522,21 +1498,12 @@ #endif
             /* Handle definitions here, they don't fit well with the
              * other instructions below [for now ] */
 
-            char tmpChar[80];
-            sprintf(tmpLine, "PARAM const%lu = {", *pToken & 0xFF);
-            sprintf(tmpChar,"%f ,", *(float *) (pToken + 1));
-            strcat(tmpLine, tmpChar);
-            sprintf(tmpChar,"%f ,", *(float *) (pToken + 2));
-            strcat(tmpLine, tmpChar);
-            sprintf(tmpChar,"%f ,", *(float *) (pToken + 3));
-            strcat(tmpLine, tmpChar);
-            sprintf(tmpChar,"%f}", *(float *) (pToken + 4));
-            strcat(tmpLine, tmpChar);
-
-            strcat(tmpLine,";\n");
-            ++lineNum;
-            TRACE("GL HW (%u, %u) : %s", lineNum, pgmLength, tmpLine); /* Don't add \n to this line as already in tmpLine */
-            PNSTRCAT(pgmStr, tmpLine);
+            shader_addline(&buffer, 
+                "PARAM const%lu = { %f, %f, %f, %f };\n", *pToken & 0xFF, 
+                  *(float *) (pToken + 1), 
+                  *(float *) (pToken + 2), 
+                  *(float *) (pToken + 3), 
+                  *(float *) (pToken + 4));
 
             pToken += 5;
             continue;
@@ -1606,22 +1573,11 @@ #endif
                     FIXME("Unrecognised dcl %08lx", *pToken & 0xFFFF);
                 }
                 {
-                    char tmpChar[80];
                     ++pToken;
                     sprintf(tmpLine, "ATTRIB ");
                     vshader_program_add_param(This, *pToken, FALSE, tmpLine);
-
-                    sprintf(tmpChar," = %s", attribName);
-                    strcat(tmpLine, tmpChar);
-                    strcat(tmpLine,";\n");
-                    ++lineNum;
-                    if (This->namedArrays) {
-                        TRACE("GL HW (%u, %u) : %s", lineNum, pgmLength, tmpLine);
-                        PNSTRCAT(pgmStr, tmpLine);
-
-                    } else {
-                        TRACE("GL HW (%u, %u) : %s", lineNum, pgmLength, tmpLine);
-                    }
+                    if (This->namedArrays) 
+                        shader_addline(&buffer, "%s = %s;\n", tmpLine, attribName);
                 }
             } else {
                 /* eat the token so it doesn't generate a warning */
@@ -1703,21 +1659,14 @@ #endif
                 ++pToken;
             }
         }
-        strcat(tmpLine,";\n");
-        ++lineNum;
-        TRACE("GL HW (%u, %u) : %s", lineNum, pgmLength, tmpLine); /* Don't add \n to this line as already in tmpLine */
-        PNSTRCAT(pgmStr, tmpLine);
-
+        shader_addline(&buffer, "%s;\n", tmpLine);
       }
     }
-    strcpy(tmpLine, "END\n"); 
-    ++lineNum;
-    TRACE("GL HW (%u, %u) : %s", lineNum, pgmLength, tmpLine); /* Don't add \n to this line as already in tmpLine */
-    PNSTRCAT(pgmStr, tmpLine);
-
+    shader_addline(&buffer, "END\n"); 
   }
-  /* finally null terminate the pgmStr*/
-  pgmStr[pgmLength] = 0;
+
+  /* finally null terminate the buffer */
+  buffer.buffer[buffer.bsize] = 0;
 
   /* Check that Vertex Shaders are supported */
   if (GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
@@ -1728,7 +1677,9 @@ #endif
       GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->baseShader.prgId));
 
       /* Create the program and check for errors */
-      GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(pgmStr)/*pgmLength*/, pgmStr));
+      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);
@@ -1738,9 +1689,8 @@ #endif
       }
   }
 #if 1 /* if were using the data buffer of device then we don't need to free it */
-  HeapFree(GetProcessHeap(), 0, pgmStr);
+  HeapFree(GetProcessHeap(), 0, buffer.buffer);
 #endif
-#undef PNSTRCAT
 }
 
 BOOL IWineD3DVertexShaderImpl_ExecuteHAL(IWineD3DVertexShader* iface, WINEVSHADERINPUTDATA* input, WINEVSHADEROUTPUTDATA* output) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9ac0e41..b795e2a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1190,6 +1190,19 @@ typedef struct SHADER_OPCODE {
     DWORD         max_version;
 } SHADER_OPCODE;
 
+#define SHADER_PGMSIZE 65535
+typedef struct SHADER_BUFFER {
+    char* buffer;
+    size_t bsize;
+    unsigned int lineNo;
+} SHADER_BUFFER;
+
+/* Base Shader utility functions. 
+ * (may move callers into the same file in the future) */
+extern int shader_addline(
+    SHADER_BUFFER* buffer,
+    const char* fmt, ...);
+
 /*****************************************************************************
  * IDirect3DBaseShader implementation structure
  */
-- 
1.3.1



More information about the wine-patches mailing list