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