Stefan Dösinger : wined3d: Start a framework for color conversion shaders in blits.

Alexandre Julliard julliard at winehq.org
Wed Aug 20 08:13:53 CDT 2008


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Aug  1 13:21:10 2008 -0500

wined3d: Start a framework for color conversion shaders in blits.

---

 dlls/wined3d/device.c          |   23 +++++++++++++++++++++--
 dlls/wined3d/directx.c         |   10 ++++++++++
 dlls/wined3d/surface.c         |   39 +++++++++++++++++++++++++++++++++++----
 dlls/wined3d/wined3d_private.h |   12 ++++++++++++
 4 files changed, 78 insertions(+), 6 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 43837b2..e1e01e2 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2170,6 +2170,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
         TRACE("Fragment pipeline private data couldn't be allocated\n");
         goto err_out;
     }
+    hr = This->blitter->alloc_private(iface);
+    if(FAILED(hr)) {
+        TRACE("Blitter private data couldn't be allocated\n");
+        goto err_out;
+    }
 
     /* Set up some starting GL setup */
 
@@ -2254,6 +2259,7 @@ err_out:
         IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->stateBlock);
         This->stateBlock = NULL;
     }
+    This->blitter->free_private(iface);
     This->frag_pipe->free_private(iface);
     This->shader_backend->shader_free_private(iface);
     return hr;
@@ -2371,6 +2377,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D
     }
 
     /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */
+    This->blitter->free_private(iface);
     This->frag_pipe->free_private(iface);
     This->shader_backend->shader_free_private(iface);
 
@@ -7220,6 +7227,7 @@ void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_
         This->depth_blt_rb_w = 0;
         This->depth_blt_rb_h = 0;
     }
+    This->blitter->free_private(iface);
     This->frag_pipe->free_private(iface);
     This->shader_backend->shader_free_private(iface);
 
@@ -7263,15 +7271,26 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *
     hr = This->shader_backend->shader_alloc_private(iface);
     if(FAILED(hr)) {
         ERR("Failed to recreate shader private data\n");
-        return hr;
+        goto err_out;
     }
     hr = This->frag_pipe->alloc_private(iface);
     if(FAILED(hr)) {
         TRACE("Fragment pipeline private data couldn't be allocated\n");
-        return hr;
+        goto err_out;
+    }
+    hr = This->blitter->alloc_private(iface);
+    if(FAILED(hr)) {
+        TRACE("Blitter private data couldn't be allocated\n");
+        goto err_out;
     }
 
     return WINED3D_OK;
+
+err_out:
+    This->blitter->free_private(iface);
+    This->frag_pipe->free_private(iface);
+    This->shader_backend->shader_free_private(iface);
+    return hr;
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) {
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index b5bc44d..de4e1b9 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2933,6 +2933,15 @@ static const struct fragment_pipeline *select_fragment_implementation(UINT Adapt
     }
 }
 
+static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType) {
+    int vs_selected_mode;
+    int ps_selected_mode;
+
+    select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
+    return &ffp_blit;
+
+}
+
 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
       subset of a D3DCAPS9 structure. However, it has to come via a void *
       as the d3d8 interface cannot import the d3d9 header                  */
@@ -3568,6 +3577,7 @@ static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
     object->frag_pipe = frag_pipeline;
     compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
                         ffp_vertexstate_template, frag_pipeline, misc_state_template);
+    object->blitter = select_blit_implementation(Adapter, DeviceType);
 
     /* Prefer the vtable with functions optimized for single dirtifyable objects if the shader
      * model can deal with that. It is essentially the same, just with adjusted
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index a114921..197ff16 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3467,8 +3467,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
         glDrawBuffer(buffer);
         checkGLcall("glDrawBuffer");
 
-        glEnable(Src->glDescription.target);
-        checkGLcall("glEnable(Src->glDescription.target)");
+        myDevice->blitter->set_shader((IWineD3DDevice *) myDevice, Src->resource.format,
+                                       Src->glDescription.target, Src->pow2Width, Src->pow2Height);
 
         /* Bind the texture */
         glBindTexture(Src->glDescription.target, Src->glDescription.textureName);
@@ -3537,8 +3537,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
         glBindTexture(Src->glDescription.target, 0);
         checkGLcall("glBindTexture(Src->glDescription.target, 0)");
         /* Leave the opengl state valid for blitting */
-        glDisable(Src->glDescription.target);
-        checkGLcall("glDisable(Src->glDescription.target)");
+        myDevice->blitter->unset_shader((IWineD3DDevice *) myDevice);
 
         /* The draw buffer should only need to be restored if we were drawing to the front buffer, and there is a back buffer.
          * otherwise the context manager should choose between GL_BACK / offscreenDrawBuffer
@@ -4623,3 +4622,35 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
     IWineD3DSurfaceImpl_GetImplType,
     IWineD3DSurfaceImpl_DrawOverlay
 };
+#undef GLINFO_LOCATION
+
+#define GLINFO_LOCATION device->adapter->gl_info
+static HRESULT ffp_blit_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
+static void ffp_blit_free(IWineD3DDevice *iface) { }
+
+static HRESULT ffp_blit_set(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum textype, UINT width, UINT height) {
+    glEnable(textype);
+    checkGLcall("glEnable(textype)");
+    return WINED3D_OK;
+}
+
+static void ffp_blit_unset(IWineD3DDevice *iface) {
+    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
+    glDisable(GL_TEXTURE_2D);
+    checkGLcall("glDisable(GL_TEXTURE_2D)");
+    if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
+        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+    }
+    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
+        glDisable(GL_TEXTURE_RECTANGLE_ARB);
+        checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+    }
+}
+
+const struct blit_shader ffp_blit =  {
+    ffp_blit_alloc,
+    ffp_blit_free,
+    ffp_blit_set,
+    ffp_blit_unset
+};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 6f14790..70bac96 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -575,6 +575,16 @@ void compile_state_table(struct StateEntry *StateTable,
                          const struct fragment_pipeline *fragment,
                          const struct StateEntryTemplate *misc);
 
+/* Shaders for color conversions in blits */
+struct blit_shader {
+    HRESULT (*alloc_private)(IWineD3DDevice *iface);
+    void (*free_private)(IWineD3DDevice *iface);
+    HRESULT (*set_shader)(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum textype, UINT width, UINT height);
+    void (*unset_shader)(IWineD3DDevice *iface);
+};
+
+extern const struct blit_shader ffp_blit;
+
 /* The new context manager that should deal with onscreen and offscreen rendering */
 struct WineD3DContext {
     /* State dirtification
@@ -829,10 +839,12 @@ struct IWineD3DDeviceImpl
     const shader_backend_t *shader_backend;
     void *shader_priv;
     void *fragment_priv;
+    void *blit_priv;
     struct StateEntry StateTable[STATE_HIGHEST + 1];
     /* Array of functions for states which are handled by more than one pipeline part */
     APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1];
     const struct fragment_pipeline *frag_pipe;
+    const struct blit_shader *blitter;
 
     /* To store */
     BOOL                    view_ident;        /* true iff view matrix is identity                */




More information about the wine-cvs mailing list