wined3d: Reuse the shader buffer between shaders.

This commit is contained in:
Henri Verbeet 2009-07-09 09:56:07 +02:00 committed by Alexandre Julliard
parent def8d4f401
commit bddc4d3f0d
3 changed files with 65 additions and 62 deletions

View File

@ -138,15 +138,20 @@ const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token
} }
} }
void shader_buffer_init(struct SHADER_BUFFER *buffer) void shader_buffer_clear(struct SHADER_BUFFER *buffer)
{ {
buffer->buffer = HeapAlloc(GetProcessHeap(), 0, SHADER_PGMSIZE);
buffer->buffer[0] = '\0'; buffer->buffer[0] = '\0';
buffer->bsize = 0; buffer->bsize = 0;
buffer->lineNo = 0; buffer->lineNo = 0;
buffer->newline = TRUE; buffer->newline = TRUE;
} }
void shader_buffer_init(struct SHADER_BUFFER *buffer)
{
buffer->buffer = HeapAlloc(GetProcessHeap(), 0, SHADER_PGMSIZE);
shader_buffer_clear(buffer);
}
void shader_buffer_free(struct SHADER_BUFFER *buffer) void shader_buffer_free(struct SHADER_BUFFER *buffer)
{ {
HeapFree(GetProcessHeap(), 0, buffer->buffer); HeapFree(GetProcessHeap(), 0, buffer->buffer);

View File

@ -83,6 +83,7 @@ struct constant_heap
/* GLSL shader private data */ /* GLSL shader private data */
struct shader_glsl_priv { struct shader_glsl_priv {
struct SHADER_BUFFER shader_buffer;
struct wine_rb_tree program_lookup; struct wine_rb_tree program_lookup;
struct glsl_shader_prog_link *glsl_program; struct glsl_shader_prog_link *glsl_program;
struct constant_heap vconst_heap; struct constant_heap vconst_heap;
@ -3504,8 +3505,8 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_in
} }
/* GL locking is done by the caller */ /* GL locking is done by the caller */
static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexshader, static GLhandleARB generate_param_reorder_function(struct SHADER_BUFFER *buffer,
IWineD3DPixelShader *pixelshader, const WineD3D_GL_Info *gl_info) IWineD3DVertexShader *vertexshader, IWineD3DPixelShader *pixelshader, const WineD3D_GL_Info *gl_info)
{ {
GLhandleARB ret = 0; GLhandleARB ret = 0;
IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader; IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
@ -3514,15 +3515,14 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
DWORD vs_major = vs->baseShader.reg_maps.shader_version.major; DWORD vs_major = vs->baseShader.reg_maps.shader_version.major;
DWORD ps_major = ps ? ps->baseShader.reg_maps.shader_version.major : 0; DWORD ps_major = ps ? ps->baseShader.reg_maps.shader_version.major : 0;
unsigned int i; unsigned int i;
SHADER_BUFFER buffer;
const char *semantic_name; const char *semantic_name;
UINT semantic_idx; UINT semantic_idx;
char reg_mask[6]; char reg_mask[6];
const struct wined3d_shader_signature_element *output_signature; const struct wined3d_shader_signature_element *output_signature;
shader_buffer_init(&buffer); shader_buffer_clear(buffer);
shader_addline(&buffer, "#version 120\n"); shader_addline(buffer, "#version 120\n");
if(vs_major < 3 && ps_major < 3) { if(vs_major < 3 && ps_major < 3) {
/* That one is easy: The vertex shader writes to the builtin varyings, the pixel shader reads from them. /* That one is easy: The vertex shader writes to the builtin varyings, the pixel shader reads from them.
@ -3532,16 +3532,16 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
if (((GLINFO_LOCATION).quirks & WINED3D_QUIRK_SET_TEXCOORD_W) if (((GLINFO_LOCATION).quirks & WINED3D_QUIRK_SET_TEXCOORD_W)
&& ps_major == 0 && vs_major > 0 && !device->frag_pipe->ffp_proj_control) && ps_major == 0 && vs_major > 0 && !device->frag_pipe->ffp_proj_control)
{ {
shader_addline(&buffer, "void order_ps_input() {\n"); shader_addline(buffer, "void order_ps_input() {\n");
for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) { for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) {
if(vs->baseShader.reg_maps.texcoord_mask[i] != 0 && if(vs->baseShader.reg_maps.texcoord_mask[i] != 0 &&
vs->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) { vs->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) {
shader_addline(&buffer, "gl_TexCoord[%u].w = 1.0;\n", i); shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", i);
} }
} }
shader_addline(&buffer, "}\n"); shader_addline(buffer, "}\n");
} else { } else {
shader_addline(&buffer, "void order_ps_input() { /* do nothing */ }\n"); shader_addline(buffer, "void order_ps_input() { /* do nothing */ }\n");
} }
} else if(ps_major < 3 && vs_major >= 3) { } else if(ps_major < 3 && vs_major >= 3) {
WORD map = vs->baseShader.reg_maps.output_registers; WORD map = vs->baseShader.reg_maps.output_registers;
@ -3549,7 +3549,7 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
/* The vertex shader writes to its own varyings, the pixel shader needs them in the builtin ones */ /* The vertex shader writes to its own varyings, the pixel shader needs them in the builtin ones */
output_signature = vs->output_signature; output_signature = vs->output_signature;
shader_addline(&buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT); shader_addline(buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT);
for (i = 0; map; map >>= 1, ++i) for (i = 0; map; map >>= 1, ++i)
{ {
DWORD write_mask; DWORD write_mask;
@ -3564,13 +3564,13 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR)) if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
{ {
if (semantic_idx == 0) if (semantic_idx == 0)
shader_addline(&buffer, "gl_FrontColor%s = OUT[%u]%s;\n", reg_mask, i, reg_mask); shader_addline(buffer, "gl_FrontColor%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
else if (semantic_idx == 1) else if (semantic_idx == 1)
shader_addline(&buffer, "gl_FrontSecondaryColor%s = OUT[%u]%s;\n", reg_mask, i, reg_mask); shader_addline(buffer, "gl_FrontSecondaryColor%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
} }
else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION)) else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION))
{ {
shader_addline(&buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask); shader_addline(buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
} }
else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD)) else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
{ {
@ -3579,22 +3579,22 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
if (!((GLINFO_LOCATION).quirks & WINED3D_QUIRK_SET_TEXCOORD_W) || ps_major > 0) if (!((GLINFO_LOCATION).quirks & WINED3D_QUIRK_SET_TEXCOORD_W) || ps_major > 0)
write_mask |= WINED3DSP_WRITEMASK_3; write_mask |= WINED3DSP_WRITEMASK_3;
shader_addline(&buffer, "gl_TexCoord[%u]%s = OUT[%u]%s;\n", shader_addline(buffer, "gl_TexCoord[%u]%s = OUT[%u]%s;\n",
semantic_idx, reg_mask, i, reg_mask); semantic_idx, reg_mask, i, reg_mask);
if (!(write_mask & WINED3DSP_WRITEMASK_3)) if (!(write_mask & WINED3DSP_WRITEMASK_3))
shader_addline(&buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx); shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx);
} }
} }
else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE)) else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE))
{ {
shader_addline(&buffer, "gl_PointSize = OUT[%u].x;\n", i); shader_addline(buffer, "gl_PointSize = OUT[%u].x;\n", i);
} }
else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_FOG)) else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_FOG))
{ {
shader_addline(&buffer, "gl_FogFragCoord = OUT[%u].%c;\n", i, reg_mask[1]); shader_addline(buffer, "gl_FogFragCoord = OUT[%u].%c;\n", i, reg_mask[1]);
} }
} }
shader_addline(&buffer, "}\n"); shader_addline(buffer, "}\n");
} else if(ps_major >= 3 && vs_major >= 3) { } else if(ps_major >= 3 && vs_major >= 3) {
WORD map = vs->baseShader.reg_maps.output_registers; WORD map = vs->baseShader.reg_maps.output_registers;
@ -3602,8 +3602,8 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
output_signature = vs->output_signature; output_signature = vs->output_signature;
/* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */ /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */
shader_addline(&buffer, "varying vec4 IN[%u];\n", vec4_varyings(3, gl_info)); shader_addline(buffer, "varying vec4 IN[%u];\n", vec4_varyings(3, gl_info));
shader_addline(&buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT); shader_addline(buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT);
/* First, sort out position and point size. Those are not passed to the pixel shader */ /* First, sort out position and point size. Those are not passed to the pixel shader */
for (i = 0; map; map >>= 1, ++i) for (i = 0; map; map >>= 1, ++i)
@ -3615,41 +3615,40 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION)) if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION))
{ {
shader_addline(&buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask); shader_addline(buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
} }
else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE)) else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE))
{ {
shader_addline(&buffer, "gl_PointSize = OUT[%u].x;\n", i); shader_addline(buffer, "gl_PointSize = OUT[%u].x;\n", i);
} }
} }
/* Then, fix the pixel shader input */ /* Then, fix the pixel shader input */
handle_ps3_input(&buffer, gl_info, ps->input_reg_map, ps->input_signature, handle_ps3_input(buffer, gl_info, ps->input_reg_map, ps->input_signature,
&ps->baseShader.reg_maps, output_signature, &vs->baseShader.reg_maps); &ps->baseShader.reg_maps, output_signature, &vs->baseShader.reg_maps);
shader_addline(&buffer, "}\n"); shader_addline(buffer, "}\n");
} else if(ps_major >= 3 && vs_major < 3) { } else if(ps_major >= 3 && vs_major < 3) {
shader_addline(&buffer, "varying vec4 IN[%u];\n", vec4_varyings(3, gl_info)); shader_addline(buffer, "varying vec4 IN[%u];\n", vec4_varyings(3, gl_info));
shader_addline(&buffer, "void order_ps_input() {\n"); shader_addline(buffer, "void order_ps_input() {\n");
/* The vertex shader wrote to the builtin varyings. There is no need to figure out position and /* The vertex shader wrote to the builtin varyings. There is no need to figure out position and
* point size, but we depend on the optimizers kindness to find out that the pixel shader doesn't * point size, but we depend on the optimizers kindness to find out that the pixel shader doesn't
* read gl_TexCoord and gl_ColorX, otherwise we'll run out of varyings * read gl_TexCoord and gl_ColorX, otherwise we'll run out of varyings
*/ */
handle_ps3_input(&buffer, gl_info, ps->input_reg_map, ps->input_signature, handle_ps3_input(buffer, gl_info, ps->input_reg_map, ps->input_signature,
&ps->baseShader.reg_maps, NULL, NULL); &ps->baseShader.reg_maps, NULL, NULL);
shader_addline(&buffer, "}\n"); shader_addline(buffer, "}\n");
} else { } else {
ERR("Unexpected vertex and pixel shader version condition: vs: %d, ps: %d\n", vs_major, ps_major); ERR("Unexpected vertex and pixel shader version condition: vs: %d, ps: %d\n", vs_major, ps_major);
} }
ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)"); checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)");
GL_EXTCALL(glShaderSourceARB(ret, 1, (const char**)&buffer.buffer, NULL)); GL_EXTCALL(glShaderSourceARB(ret, 1, (const char**)&buffer->buffer, NULL));
checkGLcall("glShaderSourceARB(ret, 1, &buffer.buffer, NULL)"); checkGLcall("glShaderSourceARB(ret, 1, &buffer->buffer, NULL)");
GL_EXTCALL(glCompileShaderARB(ret)); GL_EXTCALL(glCompileShaderARB(ret));
checkGLcall("glCompileShaderARB(ret)"); checkGLcall("glCompileShaderARB(ret)");
shader_buffer_free(&buffer);
return ret; return ret;
} }
@ -3839,15 +3838,14 @@ static GLuint shader_glsl_generate_vshader(IWineD3DVertexShaderImpl *This,
return shader_obj; return shader_obj;
} }
static GLhandleARB find_glsl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args, static GLhandleARB find_glsl_pshader(struct SHADER_BUFFER *buffer, IWineD3DPixelShaderImpl *shader,
const struct ps_np2fixup_info **np2fixup_info) const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
{ {
UINT i; UINT i;
DWORD new_size; DWORD new_size;
struct glsl_ps_compiled_shader *new_array; struct glsl_ps_compiled_shader *new_array;
struct glsl_pshader_private *shader_data; struct glsl_pshader_private *shader_data;
struct ps_np2fixup_info *np2fixup = NULL; struct ps_np2fixup_info *np2fixup = NULL;
SHADER_BUFFER buffer;
GLhandleARB ret; GLhandleARB ret;
if(!shader->backend_priv) { if(!shader->backend_priv) {
@ -3894,9 +3892,8 @@ static GLhandleARB find_glsl_pshader(IWineD3DPixelShaderImpl *shader, const stru
pixelshader_update_samplers(&shader->baseShader.reg_maps, pixelshader_update_samplers(&shader->baseShader.reg_maps,
((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures); ((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures);
shader_buffer_init(&buffer); shader_buffer_clear(buffer);
ret = shader_glsl_generate_pshader(shader, &buffer, args, np2fixup); ret = shader_glsl_generate_pshader(shader, buffer, args, np2fixup);
shader_buffer_free(&buffer);
shader_data->gl_shaders[shader_data->num_gl_shaders++].prgId = ret; shader_data->gl_shaders[shader_data->num_gl_shaders++].prgId = ret;
*np2fixup_info = np2fixup; *np2fixup_info = np2fixup;
@ -3909,13 +3906,13 @@ static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const str
return stored->fog_src == new->fog_src; return stored->fog_src == new->fog_src;
} }
static GLhandleARB find_glsl_vshader(IWineD3DVertexShaderImpl *shader, const struct vs_compile_args *args) static GLhandleARB find_glsl_vshader(struct SHADER_BUFFER *buffer, IWineD3DVertexShaderImpl *shader,
const struct vs_compile_args *args)
{ {
UINT i; UINT i;
DWORD new_size; DWORD new_size;
struct glsl_vs_compiled_shader *new_array; struct glsl_vs_compiled_shader *new_array;
DWORD use_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.use_map; DWORD use_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.use_map;
SHADER_BUFFER buffer;
struct glsl_vshader_private *shader_data; struct glsl_vshader_private *shader_data;
GLhandleARB ret; GLhandleARB ret;
@ -3957,9 +3954,8 @@ static GLhandleARB find_glsl_vshader(IWineD3DVertexShaderImpl *shader, const str
shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args; shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
shader_buffer_init(&buffer); shader_buffer_clear(buffer);
ret = shader_glsl_generate_vshader(shader, &buffer, args); ret = shader_glsl_generate_vshader(shader, buffer, args);
shader_buffer_free(&buffer);
shader_data->gl_shaders[shader_data->num_gl_shaders++].prgId = ret; shader_data->gl_shaders[shader_data->num_gl_shaders++].prgId = ret;
return ret; return ret;
@ -4020,11 +4016,12 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
/* Attach GLSL vshader */ /* Attach GLSL vshader */
if (vshader) if (vshader)
{ {
GLhandleARB vshader_id = find_glsl_vshader((IWineD3DVertexShaderImpl *)vshader, &vs_compile_args); GLhandleARB vshader_id = find_glsl_vshader(&priv->shader_buffer, (IWineD3DVertexShaderImpl *)vshader,
&vs_compile_args);
WORD map = ((IWineD3DBaseShaderImpl *)vshader)->baseShader.reg_maps.input_registers; WORD map = ((IWineD3DBaseShaderImpl *)vshader)->baseShader.reg_maps.input_registers;
char tmp_name[10]; char tmp_name[10];
reorder_shader_id = generate_param_reorder_function(vshader, pshader, gl_info); reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info);
TRACE("Attaching GLSL shader object %u to program %u\n", reorder_shader_id, programId); TRACE("Attaching GLSL shader object %u to program %u\n", reorder_shader_id, programId);
GL_EXTCALL(glAttachObjectARB(programId, reorder_shader_id)); GL_EXTCALL(glAttachObjectARB(programId, reorder_shader_id));
checkGLcall("glAttachObjectARB"); checkGLcall("glAttachObjectARB");
@ -4061,8 +4058,8 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
/* Attach GLSL pshader */ /* Attach GLSL pshader */
if (pshader) if (pshader)
{ {
GLhandleARB pshader_id = find_glsl_pshader((IWineD3DPixelShaderImpl *)pshader, &ps_compile_args, GLhandleARB pshader_id = find_glsl_pshader(&priv->shader_buffer, (IWineD3DPixelShaderImpl *)pshader,
&entry->np2Fixup_info); &ps_compile_args, &entry->np2Fixup_info);
TRACE("Attaching GLSL shader object %u to program %u\n", pshader_id, programId); TRACE("Attaching GLSL shader object %u to program %u\n", pshader_id, programId);
GL_EXTCALL(glAttachObjectARB(programId, pshader_id)); GL_EXTCALL(glAttachObjectARB(programId, pshader_id));
checkGLcall("glAttachObjectARB"); checkGLcall("glAttachObjectARB");
@ -4459,45 +4456,45 @@ static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) {
struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv)); struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
SIZE_T stack_size = wined3d_log2i(max(GL_LIMITS(vshader_constantsF), GL_LIMITS(pshader_constantsF))) + 1; SIZE_T stack_size = wined3d_log2i(max(GL_LIMITS(vshader_constantsF), GL_LIMITS(pshader_constantsF))) + 1;
shader_buffer_init(&priv->shader_buffer);
priv->stack = HeapAlloc(GetProcessHeap(), 0, stack_size * sizeof(*priv->stack)); priv->stack = HeapAlloc(GetProcessHeap(), 0, stack_size * sizeof(*priv->stack));
if (!priv->stack) if (!priv->stack)
{ {
ERR("Failed to allocate memory.\n"); ERR("Failed to allocate memory.\n");
HeapFree(GetProcessHeap(), 0, priv); goto fail;
return E_OUTOFMEMORY;
} }
if (!constant_heap_init(&priv->vconst_heap, GL_LIMITS(vshader_constantsF))) if (!constant_heap_init(&priv->vconst_heap, GL_LIMITS(vshader_constantsF)))
{ {
ERR("Failed to initialize vertex shader constant heap\n"); ERR("Failed to initialize vertex shader constant heap\n");
HeapFree(GetProcessHeap(), 0, priv->stack); goto fail;
HeapFree(GetProcessHeap(), 0, priv);
return E_OUTOFMEMORY;
} }
if (!constant_heap_init(&priv->pconst_heap, GL_LIMITS(pshader_constantsF))) if (!constant_heap_init(&priv->pconst_heap, GL_LIMITS(pshader_constantsF)))
{ {
ERR("Failed to initialize pixel shader constant heap\n"); ERR("Failed to initialize pixel shader constant heap\n");
constant_heap_free(&priv->vconst_heap); goto fail;
HeapFree(GetProcessHeap(), 0, priv->stack);
HeapFree(GetProcessHeap(), 0, priv);
return E_OUTOFMEMORY;
} }
if (wine_rb_init(&priv->program_lookup, &wined3d_glsl_program_rb_functions) == -1) if (wine_rb_init(&priv->program_lookup, &wined3d_glsl_program_rb_functions) == -1)
{ {
ERR("Failed to initialize rbtree.\n"); ERR("Failed to initialize rbtree.\n");
constant_heap_free(&priv->pconst_heap); goto fail;
constant_heap_free(&priv->vconst_heap);
HeapFree(GetProcessHeap(), 0, priv->stack);
HeapFree(GetProcessHeap(), 0, priv);
return E_OUTOFMEMORY;
} }
priv->next_constant_version = 1; priv->next_constant_version = 1;
This->shader_priv = priv; This->shader_priv = priv;
return WINED3D_OK; return WINED3D_OK;
fail:
constant_heap_free(&priv->pconst_heap);
constant_heap_free(&priv->vconst_heap);
HeapFree(GetProcessHeap(), 0, priv->stack);
shader_buffer_free(&priv->shader_buffer);
HeapFree(GetProcessHeap(), 0, priv);
return E_OUTOFMEMORY;
} }
/* Context activation is done by the caller. */ /* Context activation is done by the caller. */

View File

@ -2601,6 +2601,7 @@ typedef struct IWineD3DBaseShaderImpl {
IWineD3DBaseShaderClass baseShader; IWineD3DBaseShaderClass baseShader;
} IWineD3DBaseShaderImpl; } IWineD3DBaseShaderImpl;
void shader_buffer_clear(struct SHADER_BUFFER *buffer);
void shader_buffer_init(struct SHADER_BUFFER *buffer); void shader_buffer_init(struct SHADER_BUFFER *buffer);
void shader_buffer_free(struct SHADER_BUFFER *buffer); void shader_buffer_free(struct SHADER_BUFFER *buffer);
void shader_cleanup(IWineD3DBaseShader *iface); void shader_cleanup(IWineD3DBaseShader *iface);