[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