Stefan Dösinger : wined3d: Move glsl shader destruction to the glsl shader backend.

Alexandre Julliard julliard at winehq.org
Wed Nov 21 07:47:41 CST 2007


Module: wine
Branch: master
Commit: cfc5725760e3070d53b522709208237e63b2ba03
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cfc5725760e3070d53b522709208237e63b2ba03

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Nov 20 17:40:54 2007 +0100

wined3d: Move glsl shader destruction to the glsl shader backend.

---

 dlls/wined3d/arb_program_shader.c |    6 +++++-
 dlls/wined3d/baseshader.c         |    9 ++++++++-
 dlls/wined3d/glsl_shader.c        |   36 +++++++++++++++++++++++++++++++++++-
 dlls/wined3d/pixelshader.c        |   33 ++-------------------------------
 dlls/wined3d/vertexshader.c       |   27 +--------------------------
 dlls/wined3d/wined3d_private.h    |    1 +
 6 files changed, 52 insertions(+), 60 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index d6ca4a8..4a08f70 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1723,10 +1723,14 @@ static void shader_arb_cleanup(IWineD3DDevice *iface) {
     if (GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) glDisable(GL_FRAGMENT_PROGRAM_ARB);
 }
 
+static void shader_arb_destroy(IWineD3DBaseShader *iface) {
+}
+
 const shader_backend_t arb_program_shader_backend = {
     &shader_arb_select,
     &shader_arb_select_depth_blt,
     &shader_arb_load_constants,
     &shader_arb_cleanup,
-    &shader_arb_color_correction
+    &shader_arb_color_correction,
+    &shader_arb_destroy
 };
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 35d8d32..638db90 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -1080,12 +1080,16 @@ static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {}
 static void shader_none_select_depth_blt(IWineD3DDevice *iface) {}
 static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
 static void shader_none_cleanup(IWineD3DDevice *iface) {}
+static void shader_none_color_correction(SHADER_OPCODE_ARG* arg) {}
+static void shader_none_destroy(IWineD3DBaseShader *iface) {}
 
 const shader_backend_t none_shader_backend = {
     &shader_none_select,
     &shader_none_select_depth_blt,
     &shader_none_load_constants,
-    &shader_none_cleanup
+    &shader_none_cleanup,
+    &shader_none_color_correction,
+    &shader_none_destroy
 };
 
 /* *******************************************
@@ -1115,14 +1119,17 @@ ULONG  WINAPI IWineD3DBaseShaderImpl_AddRef(IWineD3DBaseShader *iface) {
 
 ULONG  WINAPI IWineD3DBaseShaderImpl_Release(IWineD3DBaseShader *iface) {
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
+    IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
     ULONG ref;
     TRACE("(%p) : Releasing from %d\n", This, This->baseShader.ref);
     ref = InterlockedDecrement(&This->baseShader.ref);
     if (ref == 0) {
+        deviceImpl->shader_backend->shader_destroy(iface);
         HeapFree(GetProcessHeap(), 0, This->baseShader.function);
         shader_delete_constant_list(&This->baseShader.constantsF);
         shader_delete_constant_list(&This->baseShader.constantsB);
         shader_delete_constant_list(&This->baseShader.constantsI);
+        HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
 }
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 5d988e4..1cc3ec8 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3176,10 +3176,44 @@ static void shader_glsl_cleanup(IWineD3DDevice *iface) {
     GL_EXTCALL(glUseProgramObjectARB(0));
 }
 
+static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
+    struct list *linked_programs;
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
+    WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *) This->baseShader.device)->adapter->gl_info;
+
+    /* Note: Do not use QueryInterface here to find out which shader type this is because this code
+     * can be called from IWineD3DBaseShader::Release
+     */
+    char pshader = shader_is_pshader_version(This->baseShader.hex_version);
+
+    if(This->baseShader.prgId == 0) return;
+    linked_programs = &This->baseShader.linked_programs;
+
+    TRACE("Deleting linked programs\n");
+    if (linked_programs->next) {
+        struct glsl_shader_prog_link *entry, *entry2;
+
+        if(pshader) {
+            LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) {
+                delete_glsl_program_entry(This->baseShader.device, entry);
+            }
+        } else {
+            LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, vshader_entry) {
+                delete_glsl_program_entry(This->baseShader.device, entry);
+            }
+        }
+    }
+
+    TRACE("Deleting shader object %u\n", This->baseShader.prgId);
+    GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
+    checkGLcall("glDeleteObjectARB");
+}
+
 const shader_backend_t glsl_shader_backend = {
     &shader_glsl_select,
     &shader_glsl_select_depth_blt,
     &shader_glsl_load_constants,
     &shader_glsl_cleanup,
-    &shader_glsl_color_correction
+    &shader_glsl_color_correction,
+    &shader_glsl_destroy
 };
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 5654c46..b9fbd75 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -51,35 +51,8 @@ static ULONG  WINAPI IWineD3DPixelShaderImpl_AddRef(IWineD3DPixelShader *iface)
     return IWineD3DBaseShaderImpl_AddRef((IWineD3DBaseShader *) iface);
 }
 
-static void destroy_glsl_pshader(IWineD3DPixelShaderImpl *This) {
-    struct list *linked_programs = &This->baseShader.linked_programs;
-
-    TRACE("Deleting linked programs\n");
-    if (linked_programs->next) {
-        struct glsl_shader_prog_link *entry, *entry2;
-        LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) {
-            delete_glsl_program_entry(This->baseShader.device, entry);
-        }
-    }
-
-    TRACE("Deleting shader object %u\n", This->baseShader.prgId);
-    GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
-    checkGLcall("glDeleteObjectARB");
-}
-
 static ULONG  WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
-    ULONG ref;
-    ref = IWineD3DBaseShaderImpl_Release((IWineD3DBaseShader *) iface);
-
-    if(ref == 0) {
-        if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
-            destroy_glsl_pshader(This);
-        }
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-
-    return ref;
+    return IWineD3DBaseShaderImpl_Release((IWineD3DBaseShader *) iface);
 }
 
 /* *******************************************
@@ -658,9 +631,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader
             This->baseShader.recompile_count++;
         }
 
-        if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
-            destroy_glsl_pshader(This);
-        }
+        deviceImpl->shader_backend->shader_destroy((IWineD3DBaseShader *) iface);
     }
 
     /* We don't need to compile */
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 934fed0..2b16f04 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -445,33 +445,8 @@ static ULONG  WINAPI IWineD3DVertexShaderImpl_AddRef(IWineD3DVertexShader *iface
     return IWineD3DBaseShaderImpl_AddRef((IWineD3DBaseShader *) iface);
 }
 
-static void destroy_glsl_vshader(IWineD3DVertexShaderImpl *This) {
-    struct list *linked_programs = &This->baseShader.linked_programs;
-
-    TRACE("Deleting linked programs\n");
-    if (linked_programs->next) {
-        struct glsl_shader_prog_link *entry, *entry2;
-        LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, vshader_entry) {
-            delete_glsl_program_entry(This->baseShader.device, entry);
-        }
-    }
-
-    TRACE("Deleting shader object %u\n", This->baseShader.prgId);
-    GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
-    checkGLcall("glDeleteObjectARB");
-}
 static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface) {
-    IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-    ULONG ref;
-    ref = IWineD3DBaseShaderImpl_Release((IWineD3DBaseShader *) iface);
-
-    if (ref == 0) {
-        if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
-            destroy_glsl_vshader(This);
-        }
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-    return ref;
+    return IWineD3DBaseShaderImpl_Release((IWineD3DBaseShader *) iface);
 }
 
 /* *******************************************
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index c77d2af..5c6d7e9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -211,6 +211,7 @@ typedef struct {
     void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
     void (*shader_cleanup)(IWineD3DDevice *iface);
     void (*shader_color_correction)(struct SHADER_OPCODE_ARG *arg);
+    void (*shader_destroy)(IWineD3DBaseShader *iface);
 } shader_backend_t;
 
 extern const shader_backend_t glsl_shader_backend;




More information about the wine-cvs mailing list