[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