wined3d: Get rid of a few stack buffers.

This commit is contained in:
Henri Verbeet 2009-03-10 09:19:04 +01:00 committed by Alexandre Julliard
parent 1fa83c95de
commit 67da604eca
3 changed files with 61 additions and 71 deletions

View File

@ -52,17 +52,12 @@ void shader_buffer_free(struct SHADER_BUFFER *buffer)
HeapFree(GetProcessHeap(), 0, buffer->buffer);
}
int shader_addline(
SHADER_BUFFER* buffer,
const char *format, ...) {
int shader_vaddline(SHADER_BUFFER* buffer, const char *format, va_list args)
{
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 */
@ -88,6 +83,18 @@ int shader_addline(
return 0;
}
int shader_addline(SHADER_BUFFER* buffer, const char *format, ...)
{
int ret;
va_list args;
va_start(args, format);
ret = shader_vaddline(buffer, format, args);
va_end(args);
return ret;
}
void shader_init(struct IWineD3DBaseShaderClass *shader,
IWineD3DDevice *device, const SHADER_OPCODE *instruction_table)
{

View File

@ -1470,12 +1470,14 @@ static void shader_glsl_color_correction(const struct SHADER_OPCODE_ARG *arg, st
}
}
static void shader_glsl_gen_sample_code(const SHADER_OPCODE_ARG *arg, DWORD sampler, const char *coord_reg,
const glsl_sample_function_t *sample_function, DWORD swizzle,
const char *bias) {
static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const SHADER_OPCODE_ARG *arg,
DWORD sampler, const glsl_sample_function_t *sample_function, DWORD swizzle,
const char *bias, const char *coord_reg_fmt, ...)
{
const char *sampler_base;
char dst_swizzle[6];
struct color_fixup_desc fixup;
va_list args;
shader_glsl_get_swizzle(swizzle, FALSE, arg->dst, dst_swizzle);
@ -1490,12 +1492,16 @@ static void shader_glsl_gen_sample_code(const SHADER_OPCODE_ARG *arg, DWORD samp
shader_glsl_append_dst(arg->buffer, arg);
shader_addline(arg->buffer, "%s(%s%u, ", sample_function->name, sampler_base, sampler);
va_start(args, coord_reg_fmt);
shader_vaddline(arg->buffer, coord_reg_fmt, args);
va_end(args);
if(bias) {
shader_addline(arg->buffer, "%s(%s%u, %s, %s)%s);\n",
sample_function->name, sampler_base, sampler, coord_reg, bias, dst_swizzle);
shader_addline(arg->buffer, ", %s)%s);\n", bias, dst_swizzle);
} else {
shader_addline(arg->buffer, "%s(%s%u, %s)%s);\n",
sample_function->name, sampler_base, sampler, coord_reg, dst_swizzle);
shader_addline(arg->buffer, ")%s);\n", dst_swizzle);
}
if(!is_identity_fixup(fixup)) {
@ -1671,7 +1677,6 @@ static void shader_glsl_map2gl(const SHADER_OPCODE_ARG *arg)
SHADER_BUFFER* buffer = arg->buffer;
glsl_src_param_t src_param;
const char *instruction;
char arguments[256];
DWORD write_mask;
unsigned i;
@ -1694,18 +1699,18 @@ static void shader_glsl_map2gl(const SHADER_OPCODE_ARG *arg)
write_mask = shader_glsl_append_dst(buffer, arg);
arguments[0] = '\0';
shader_addline(buffer, "%s(", instruction);
if (curOpcode->num_params > 0) {
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], write_mask, &src_param);
strcat(arguments, src_param.param_str);
shader_addline(buffer, "%s", src_param.param_str);
for (i = 2; i < curOpcode->num_params; ++i) {
strcat(arguments, ", ");
shader_glsl_add_src_param(arg, arg->src[i-1], arg->src_addr[i-1], write_mask, &src_param);
strcat(arguments, src_param.param_str);
shader_addline(buffer, ", %s", src_param.param_str);
}
}
shader_addline(buffer, "%s(%s));\n", instruction, arguments);
shader_addline(buffer, "));\n");
}
/** Process the WINED3DSIO_EXPP instruction in GLSL:
@ -2380,21 +2385,21 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
1.4+: Use provided coordinate source register. */
if (shader_version < WINED3DPS_VERSION(1,4))
{
char coord_mask[6], srcreg[12];
char coord_mask[6];
shader_glsl_get_write_mask(mask, coord_mask);
sprintf(srcreg, "T%u%s", sampler_idx, coord_mask);
shader_glsl_gen_sample_code(arg, sampler_idx, srcreg, &sample_function, swizzle, NULL);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, swizzle, NULL,
"T%u%s", sampler_idx, coord_mask);
} else {
glsl_src_param_t coord_param;
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], mask, &coord_param);
if(arg->opcode_token & WINED3DSI_TEXLD_BIAS) {
glsl_src_param_t bias;
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &bias);
shader_glsl_gen_sample_code(arg, sampler_idx, coord_param.param_str, &sample_function,
swizzle, bias.param_str);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, swizzle, bias.param_str,
"%s", coord_param.param_str);
} else {
shader_glsl_gen_sample_code(arg, sampler_idx, coord_param.param_str, &sample_function,
swizzle, NULL);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, swizzle, NULL,
"%s", coord_param.param_str);
}
}
}
@ -2427,9 +2432,8 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg)
* However, they seem to work just fine in fragment shaders as well. */
WARN("Using %s in fragment shader.\n", sample_function.name);
}
shader_glsl_gen_sample_code(arg, sampler_idx, coord_param.param_str,
&sample_function, swizzle,
lod_param.param_str);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, swizzle, lod_param.param_str,
"%s", coord_param.param_str);
}
static void pshader_glsl_texcoord(const SHADER_OPCODE_ARG *arg)
@ -2485,7 +2489,6 @@ static void pshader_glsl_texcoord(const SHADER_OPCODE_ARG *arg)
static void pshader_glsl_texdp3tex(const SHADER_OPCODE_ARG *arg)
{
glsl_src_param_t src0_param;
char coord_param[64];
glsl_sample_function_t sample_function;
DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
@ -2505,27 +2508,24 @@ static void pshader_glsl_texdp3tex(const SHADER_OPCODE_ARG *arg)
switch(mask_size)
{
case 1:
sprintf(coord_param, "dot(gl_TexCoord[%u].xyz, %s)",
sampler_idx, src0_param.param_str);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
"dot(gl_TexCoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
break;
case 2:
sprintf(coord_param, "vec2(dot(gl_TexCoord[%u].xyz, %s), 0.0)",
sampler_idx, src0_param.param_str);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
"vec2(dot(gl_TexCoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
break;
case 3:
sprintf(coord_param, "vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)",
sampler_idx, src0_param.param_str);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
"vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
break;
default:
FIXME("Unexpected mask size %u\n", mask_size);
break;
}
shader_glsl_gen_sample_code(arg, sampler_idx, coord_param,
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
}
/** Process the WINED3DSIO_TEXDP3 instruction in GLSL:
@ -2627,9 +2627,7 @@ static void pshader_glsl_texm3x2tex(const SHADER_OPCODE_ARG *arg)
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(arg, reg, "tmp0.xy",
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
shader_glsl_gen_sample_code(arg, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xy");
}
/** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
@ -2651,9 +2649,7 @@ static void pshader_glsl_texm3x3tex(const SHADER_OPCODE_ARG *arg)
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(arg, reg, "tmp0.xyz",
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
shader_glsl_gen_sample_code(arg, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
current_state->current_row = 0;
}
@ -2704,9 +2700,7 @@ static void pshader_glsl_texm3x3spec(const SHADER_OPCODE_ARG *arg)
shader_glsl_get_sample_function(stype, 0, &sample_function);
/* Sample the texture */
shader_glsl_gen_sample_code(arg, reg, "tmp0.xyz",
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
shader_glsl_gen_sample_code(arg, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
current_state->current_row = 0;
}
@ -2738,9 +2732,7 @@ static void pshader_glsl_texm3x3vspec(const SHADER_OPCODE_ARG *arg)
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(arg, reg, "tmp0.xyz",
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
shader_glsl_gen_sample_code(arg, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
current_state->current_row = 0;
}
@ -2753,7 +2745,6 @@ static void pshader_glsl_texbem(const SHADER_OPCODE_ARG *arg)
{
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
char coord[128];
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param;
DWORD sampler_type;
@ -2791,11 +2782,9 @@ static void pshader_glsl_texbem(const SHADER_OPCODE_ARG *arg)
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0|WINED3DSP_WRITEMASK_1, &coord_param);
sprintf(coord, "T%u%s + vec4(bumpenvmat%d * %s, 0.0, 0.0)%s",
sampler_idx, coord_mask, sampler_idx, coord_param.param_str, coord_mask);
shader_glsl_gen_sample_code(arg, sampler_idx, coord,
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
"T%u%s + vec4(bumpenvmat%d * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx,
coord_param.param_str, coord_mask);
if(arg->opcode->opcode == WINED3DSIO_TEXBEML) {
glsl_src_param_t luminance_param;
@ -2829,17 +2818,14 @@ static void pshader_glsl_texreg2ar(const SHADER_OPCODE_ARG *arg)
{
glsl_src_param_t src0_param;
DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
char src[16];
DWORD sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
glsl_sample_function_t sample_function;
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
sprintf(src, "%s.wx", src0_param.reg_name);
shader_glsl_gen_sample_code(arg, sampler_idx, src,
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
"%s.wx", src0_param.reg_name);
}
/** Process the WINED3DSIO_TEXREG2GB instruction in GLSL
@ -2848,17 +2834,14 @@ static void pshader_glsl_texreg2gb(const SHADER_OPCODE_ARG *arg)
{
glsl_src_param_t src0_param;
DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
char src[16];
DWORD sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
glsl_sample_function_t sample_function;
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
sprintf(src, "%s.yz", src0_param.reg_name);
shader_glsl_gen_sample_code(arg, sampler_idx, src,
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
"%s.yz", src0_param.reg_name);
}
/** Process the WINED3DSIO_TEXREG2RGB instruction in GLSL
@ -2874,9 +2857,8 @@ static void pshader_glsl_texreg2rgb(const SHADER_OPCODE_ARG *arg)
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], sample_function.coord_mask, &src0_param);
shader_glsl_gen_sample_code(arg, sampler_idx, src0_param.param_str,
&sample_function, WINED3DVS_NOSWIZZLE,
NULL);
shader_glsl_gen_sample_code(arg, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
"%s", src0_param.param_str);
}
/** Process the WINED3DSIO_TEXKILL instruction in GLSL.

View File

@ -2219,6 +2219,7 @@ typedef struct SHADER_PARSE_STATE {
extern int shader_addline(
SHADER_BUFFER* buffer,
const char* fmt, ...) PRINTF_ATTR(2,3);
int shader_vaddline(SHADER_BUFFER *buffer, const char *fmt, va_list args);
const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *shader_ins, DWORD shader_version, DWORD code);