wined3d: Make find_gl_pshader backend private.

This commit is contained in:
Stefan Dösinger 2009-05-26 13:43:43 +02:00 committed by Alexandre Julliard
parent 5865d9c01b
commit d0d681c81e
5 changed files with 111 additions and 80 deletions

View File

@ -1926,6 +1926,60 @@ static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, en
return program_id; return program_id;
} }
static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface,
SHADER_BUFFER *buffer, const struct ps_compile_args *args);
/* GL locking is done by the caller */
static GLuint find_arb_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args)
{
UINT i;
DWORD new_size;
struct ps_compiled_shader *new_array;
SHADER_BUFFER buffer;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
* (cache coherency etc)
*/
for(i = 0; i < shader->num_gl_shaders; i++) {
if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) {
return shader->gl_shaders[i].prgId;
}
}
TRACE("No matching GL shader found, compiling a new shader\n");
if(shader->shader_array_size == shader->num_gl_shaders) {
if (shader->num_gl_shaders)
{
new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2);
new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders,
new_size * sizeof(*shader->gl_shaders));
} else {
new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
new_size = 1;
}
if(!new_array) {
ERR("Out of memory\n");
return 0;
}
shader->gl_shaders = new_array;
shader->shader_array_size = new_size;
}
shader->gl_shaders[shader->num_gl_shaders].args = *args;
pixelshader_update_samplers(&shader->baseShader.reg_maps,
((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures);
shader_buffer_init(&buffer);
shader->gl_shaders[shader->num_gl_shaders].prgId =
shader_arb_generate_pshader((IWineD3DPixelShader *)shader, &buffer, args);
shader_buffer_free(&buffer);
return shader->gl_shaders[shader->num_gl_shaders++].prgId;
}
/* GL locking is done by the caller */ /* GL locking is done by the caller */
static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
@ -1957,8 +2011,8 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
struct ps_compile_args compile_args; struct ps_compile_args compile_args;
TRACE("Using pixel shader\n"); TRACE("Using pixel shader\n");
find_ps_compile_args((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, This->stateBlock, &compile_args); find_ps_compile_args((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, This->stateBlock, &compile_args);
priv->current_fprogram_id = find_gl_pshader((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, priv->current_fprogram_id = find_arb_pshader((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader,
&compile_args); &compile_args);
/* Bind the fragment program */ /* Bind the fragment program */
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id)); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
@ -2539,7 +2593,6 @@ const shader_backend_t arb_program_shader_backend = {
shader_arb_alloc, shader_arb_alloc,
shader_arb_free, shader_arb_free,
shader_arb_dirty_const, shader_arb_dirty_const,
shader_arb_generate_pshader,
shader_arb_generate_vshader, shader_arb_generate_vshader,
shader_arb_get_caps, shader_arb_get_caps,
shader_arb_color_fixup_supported, shader_arb_color_fixup_supported,

View File

@ -1283,12 +1283,6 @@ static void shader_none_destroy(IWineD3DBaseShader *iface) {}
static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;} static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;}
static void shader_none_free(IWineD3DDevice *iface) {} static void shader_none_free(IWineD3DDevice *iface) {}
static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;} static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;}
static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface,
SHADER_BUFFER *buffer, const struct ps_compile_args *args)
{
FIXME("NONE shader backend asked to generate a pixel shader\n");
return 0;
}
static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface, static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface,
SHADER_BUFFER *buffer, const struct vs_compile_args *args) SHADER_BUFFER *buffer, const struct vs_compile_args *args)
{ {
@ -1338,7 +1332,6 @@ const shader_backend_t none_shader_backend = {
shader_none_alloc, shader_none_alloc,
shader_none_free, shader_none_free,
shader_none_dirty_const, shader_none_dirty_const,
shader_none_generate_pshader,
shader_none_generate_vshader, shader_none_generate_vshader,
shader_none_get_caps, shader_none_get_caps,
shader_none_color_fixup_supported, shader_none_color_fixup_supported,

View File

@ -3608,6 +3608,58 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD
checkGLcall("Hardcoding local constants\n"); checkGLcall("Hardcoding local constants\n");
} }
static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface,
SHADER_BUFFER *buffer, const struct ps_compile_args *args);
static GLhandleARB find_glsl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args)
{
UINT i;
DWORD new_size;
struct ps_compiled_shader *new_array;
SHADER_BUFFER buffer;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
* (cache coherency etc)
*/
for(i = 0; i < shader->num_gl_shaders; i++) {
if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) {
return shader->gl_shaders[i].prgId;
}
}
TRACE("No matching GL shader found, compiling a new shader\n");
if(shader->shader_array_size == shader->num_gl_shaders) {
if (shader->num_gl_shaders)
{
new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2);
new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders,
new_size * sizeof(*shader->gl_shaders));
} else {
new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
new_size = 1;
}
if(!new_array) {
ERR("Out of memory\n");
return 0;
}
shader->gl_shaders = new_array;
shader->shader_array_size = new_size;
}
shader->gl_shaders[shader->num_gl_shaders].args = *args;
pixelshader_update_samplers(&shader->baseShader.reg_maps,
((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures);
shader_buffer_init(&buffer);
shader->gl_shaders[shader->num_gl_shaders].prgId =
shader_glsl_generate_pshader((IWineD3DPixelShader*) shader, &buffer, args);
shader_buffer_free(&buffer);
return shader->gl_shaders[shader->num_gl_shaders++].prgId;
}
/** Sets the GLSL program ID for the given pixel and vertex shader combination. /** Sets the GLSL program ID for the given pixel and vertex shader combination.
* It sets the programId on the current StateBlock (because it should be called * It sets the programId on the current StateBlock (because it should be called
* inside of the DrawPrimitive() part of the render loop). * inside of the DrawPrimitive() part of the render loop).
@ -3715,7 +3767,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
} }
if(use_ps) { if(use_ps) {
pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &ps_compile_args); pshader_id = find_glsl_pshader((IWineD3DPixelShaderImpl *) pshader, &ps_compile_args);
} else { } else {
pshader_id = 0; pshader_id = 0;
} }
@ -4512,7 +4564,6 @@ const shader_backend_t glsl_shader_backend = {
shader_glsl_alloc, shader_glsl_alloc,
shader_glsl_free, shader_glsl_free,
shader_glsl_dirty_const, shader_glsl_dirty_const,
shader_glsl_generate_pshader,
shader_glsl_generate_vshader, shader_glsl_generate_vshader,
shader_glsl_get_caps, shader_glsl_get_caps,
shader_glsl_color_fixup_supported, shader_glsl_color_fixup_supported,

View File

@ -299,7 +299,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
return WINED3D_OK; return WINED3D_OK;
} }
static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures) void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures)
{ {
WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type; WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type;
unsigned int i; unsigned int i;
@ -343,28 +343,6 @@ static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD
} }
} }
/* GL locking is done by the caller */
static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps_compile_args *args)
{
CONST DWORD *function = This->baseShader.function;
GLuint retval;
SHADER_BUFFER buffer;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
TRACE("(%p) : function %p\n", This, function);
pixelshader_update_samplers(&This->baseShader.reg_maps,
((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures);
/* Generate the HW shader */
TRACE("(%p) : Generating hardware program\n", This);
shader_buffer_init(&buffer);
retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, &buffer, args);
shader_buffer_free(&buffer);
return retval;
}
const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl = const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
{ {
/*** IUnknown methods ***/ /*** IUnknown methods ***/
@ -443,45 +421,3 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
} }
} }
} }
/* GL locking is done by the caller */
GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args)
{
UINT i;
DWORD new_size;
struct ps_compiled_shader *new_array;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
* (cache coherency etc)
*/
for(i = 0; i < shader->num_gl_shaders; i++) {
if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) {
return shader->gl_shaders[i].prgId;
}
}
TRACE("No matching GL shader found, compiling a new shader\n");
if(shader->shader_array_size == shader->num_gl_shaders) {
if (shader->num_gl_shaders)
{
new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2);
new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders,
new_size * sizeof(*shader->gl_shaders));
} else {
new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
new_size = 1;
}
if(!new_array) {
ERR("Out of memory\n");
return 0;
}
shader->gl_shaders = new_array;
shader->shader_array_size = new_size;
}
shader->gl_shaders[shader->num_gl_shaders].args = *args;
shader->gl_shaders[shader->num_gl_shaders].prgId = pixelshader_compile(shader, args);
return shader->gl_shaders[shader->num_gl_shaders++].prgId;
}

View File

@ -809,8 +809,6 @@ typedef struct {
HRESULT (*shader_alloc_private)(IWineD3DDevice *iface); HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
void (*shader_free_private)(IWineD3DDevice *iface); void (*shader_free_private)(IWineD3DDevice *iface);
BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface); BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface,
SHADER_BUFFER *buffer, const struct ps_compile_args *args);
GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface,
SHADER_BUFFER *buffer, const struct vs_compile_args *args); SHADER_BUFFER *buffer, const struct vs_compile_args *args);
void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps); void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps);
@ -2729,7 +2727,7 @@ typedef struct IWineD3DPixelShaderImpl {
} IWineD3DPixelShaderImpl; } IWineD3DPixelShaderImpl;
extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl; extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args); void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures);
void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args); void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args);
/* sRGB correction constants */ /* sRGB correction constants */