[PATCH] WineD3D: Start a framework for color conversion shaders =

Stefan Doesinger stefan at codeweavers.com
Fri Aug 1 13:21:10 CDT 2008


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

------=_NextPart_000_0021_01C901F1.A7B2AA60--




More information about the wine-patches mailing list