From f912f18b133a5b1e0801b9639de8c3762baddb5a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Sun, 24 Feb 2008 11:23:53 +0100 Subject: [PATCH] wined3d: Move shader model private data into its own structure. --- dlls/wined3d/arb_program_shader.c | 38 +++++++++++++++++++++++++++----------- dlls/wined3d/baseshader.c | 6 +++++- dlls/wined3d/device.c | 2 ++ dlls/wined3d/directx.c | 6 ++++++ dlls/wined3d/glsl_shader.c | 36 ++++++++++++++++++++++++++++-------- dlls/wined3d/wined3d_private.h | 17 ++++++++++++++--- 6 files changed, 82 insertions(+), 23 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 84516c30d0f..ae849b21109 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1712,28 +1712,30 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { static void shader_arb_select_depth_blt(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv; WineD3D_GL_Info *gl_info = &This->adapter->gl_info; - if (!This->depth_blt_vprogram_id) This->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info); - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->depth_blt_vprogram_id)); + if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info); + GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id)); glEnable(GL_VERTEX_PROGRAM_ARB); - if (!This->depth_blt_fprogram_id) This->depth_blt_fprogram_id = create_arb_blt_fragment_program(gl_info); - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, This->depth_blt_fprogram_id)); + if (!priv->depth_blt_fprogram_id) priv->depth_blt_fprogram_id = create_arb_blt_fragment_program(gl_info); + GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->depth_blt_fprogram_id)); glEnable(GL_FRAGMENT_PROGRAM_ARB); } static void shader_arb_destroy_depth_blt(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv; WineD3D_GL_Info *gl_info = &This->adapter->gl_info; - if(This->depth_blt_vprogram_id) { - GL_EXTCALL(glDeleteProgramsARB(1, &This->depth_blt_vprogram_id)); - This->depth_blt_vprogram_id = 0; + if(priv->depth_blt_vprogram_id) { + GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id)); + priv->depth_blt_vprogram_id = 0; } - if(This->depth_blt_fprogram_id) { - GL_EXTCALL(glDeleteProgramsARB(1, &This->depth_blt_fprogram_id)); - This->depth_blt_fprogram_id = 0; + if(priv->depth_blt_fprogram_id) { + GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id)); + priv->depth_blt_fprogram_id = 0; } } @@ -1756,6 +1758,17 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) { This->baseShader.is_compiled = FALSE; } +static HRESULT shader_arb_alloc(IWineD3DDevice *iface) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + This->shader_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_arb_priv)); + return WINED3D_OK; +} + +static void shader_arb_free(IWineD3DDevice *iface) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + HeapFree(GetProcessHeap(), 0, This->shader_priv); +} + const shader_backend_t arb_program_shader_backend = { &shader_arb_select, &shader_arb_select_depth_blt, @@ -1763,5 +1776,8 @@ const shader_backend_t arb_program_shader_backend = { &shader_arb_load_constants, &shader_arb_cleanup, &shader_arb_color_correction, - &shader_arb_destroy + &shader_arb_destroy, + &shader_arb_alloc, + &shader_arb_free + }; diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index e06d7f7039b..fdb5236b787 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -1103,6 +1103,8 @@ static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char u static void shader_none_cleanup(IWineD3DDevice *iface) {} static void shader_none_color_correction(SHADER_OPCODE_ARG* arg) {} static void shader_none_destroy(IWineD3DBaseShader *iface) {} +static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;} +static void shader_none_free(IWineD3DDevice *iface) {} const shader_backend_t none_shader_backend = { &shader_none_select, @@ -1111,7 +1113,9 @@ const shader_backend_t none_shader_backend = { &shader_none_load_constants, &shader_none_cleanup, &shader_none_color_correction, - &shader_none_destroy + &shader_none_destroy, + &shader_none_alloc, + &shader_none_free }; /* ******************************************* diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 952e796e20d..efe8d9e3453 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -173,6 +173,8 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) { GL_EXTCALL(glDeleteFramebuffersEXT(1, &This->dst_fbo)); } + This->shader_backend->shader_free_private(iface); + if (This->glsl_program_lookup) hash_table_destroy(This->glsl_program_lookup); /* TODO: Clean up all the surfaces and textures! */ diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 2e31f3381b4..9b17db0947e 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2826,6 +2826,12 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, } else { object->shader_backend = &none_shader_backend; } + if(FAILED(object->shader_backend->shader_alloc_private((IWineD3DDevice *) object))) { + IWineD3D_Release(object->wineD3D); + HeapFree(GetProcessHeap(), 0, object); + *ppReturnedDeviceInterface = NULL; + return E_OUTOFMEMORY; + } /* set the state of the device to valid */ object->state = WINED3D_OK; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index b15d9b26c61..ae2c9a2db44 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3226,6 +3226,11 @@ static GLhandleARB create_glsl_blt_shader(WineD3D_GL_Info *gl_info) { print_glsl_info_log(&GLINFO_LOCATION, program_id); + /* Once linked we can mark the shaders for deletion. They will be deleted once the program + * is destroyed + */ + GL_EXTCALL(glDeleteObjectARB(vshader_id)); + GL_EXTCALL(glDeleteObjectARB(pshader_id)); return program_id; } @@ -3246,24 +3251,26 @@ static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { static void shader_glsl_select_depth_blt(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; WineD3D_GL_Info *gl_info = &This->adapter->gl_info; + struct shader_glsl_priv *priv = (struct shader_glsl_priv *) This->shader_priv; static GLhandleARB loc = -1; - if (!This->depth_blt_glsl_program_id) { - This->depth_blt_glsl_program_id = create_glsl_blt_shader(gl_info); - loc = GL_EXTCALL(glGetUniformLocationARB(This->depth_blt_glsl_program_id, "sampler")); + if (!priv->depth_blt_glsl_program_id) { + priv->depth_blt_glsl_program_id = create_glsl_blt_shader(gl_info); + loc = GL_EXTCALL(glGetUniformLocationARB(priv->depth_blt_glsl_program_id, "sampler")); } - GL_EXTCALL(glUseProgramObjectARB(This->depth_blt_glsl_program_id)); + GL_EXTCALL(glUseProgramObjectARB(priv->depth_blt_glsl_program_id)); GL_EXTCALL(glUniform1iARB(loc, 0)); } static void shader_glsl_destroy_depth_blt(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + struct shader_glsl_priv *priv = (struct shader_glsl_priv *) This->shader_priv; WineD3D_GL_Info *gl_info = &This->adapter->gl_info; - if(This->depth_blt_glsl_program_id) { - GL_EXTCALL(glDeleteObjectARB(This->depth_blt_glsl_program_id)); - This->depth_blt_glsl_program_id = 0; + if(priv->depth_blt_glsl_program_id) { + GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_glsl_program_id)); + priv->depth_blt_glsl_program_id = 0; } } @@ -3308,6 +3315,17 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { This->baseShader.is_compiled = FALSE; } +static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + This->shader_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv)); + return WINED3D_OK; +} + +static void shader_glsl_free(IWineD3DDevice *iface) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + HeapFree(GetProcessHeap(), 0, This->shader_priv); +} + const shader_backend_t glsl_shader_backend = { &shader_glsl_select, &shader_glsl_select_depth_blt, @@ -3315,5 +3333,7 @@ const shader_backend_t glsl_shader_backend = { &shader_glsl_load_constants, &shader_glsl_cleanup, &shader_glsl_color_correction, - &shader_glsl_destroy + &shader_glsl_destroy, + &shader_glsl_alloc, + &shader_glsl_free }; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9ece795f845..96a80fa68c1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -257,12 +257,25 @@ typedef struct { void (*shader_cleanup)(IWineD3DDevice *iface); void (*shader_color_correction)(struct SHADER_OPCODE_ARG *arg); void (*shader_destroy)(IWineD3DBaseShader *iface); + HRESULT (*shader_alloc_private)(IWineD3DDevice *iface); + void (*shader_free_private)(IWineD3DDevice *iface); } shader_backend_t; extern const shader_backend_t glsl_shader_backend; extern const shader_backend_t arb_program_shader_backend; extern const shader_backend_t none_shader_backend; +/* GLSL shader private data */ +struct shader_glsl_priv { + GLhandleARB depth_blt_glsl_program_id; +}; + +/* ARB_program_shader private data */ +struct shader_arb_priv { + GLuint depth_blt_vprogram_id; + GLuint depth_blt_fprogram_id; +}; + /* X11 locking */ extern void (*wine_tsx11_lock_ptr)(void); @@ -712,6 +725,7 @@ struct IWineD3DDeviceImpl int ps_selected_mode; const shader_backend_t *shader_backend; hash_table_t *glsl_program_lookup; + void *shader_priv; /* To store */ BOOL view_ident; /* true iff view matrix is identity */ @@ -761,9 +775,6 @@ struct IWineD3DDeviceImpl GLuint dst_fbo; GLenum *draw_buffers; GLuint depth_blt_texture; - GLuint depth_blt_vprogram_id; - GLuint depth_blt_fprogram_id; - GLhandleARB depth_blt_glsl_program_id; /* Cursor management */ BOOL bCursorVisible; -- 2.11.4.GIT