[7/9] WineD3D: Use the context manager to prepare for blitting
Stefan Dösinger
stefan at codeweavers.com
Thu Feb 8 15:36:26 CST 2007
-------------- next part --------------
From 21587ae79f8defe31c4130edf13e4acd469b9b6d Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Sun, 4 Feb 2007 19:44:37 +0100
Subject: [PATCH] WineD3D: Use the context manager to prepare for blitting
---
dlls/wined3d/context.c | 159 +++++++++++++++++++++++++++++++++++++-
dlls/wined3d/surface.c | 168 +---------------------------------------
dlls/wined3d/wined3d_private.h | 1 +
3 files changed, 161 insertions(+), 167 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 3090538..1f6d693 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -27,6 +27,160 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
+
+/*****************************************************************************
+ * SetupForBlit
+ *
+ * Sets up a context for DirectDraw blitting.
+ * All texture units are disabled, except unit 0
+ * Texture unit 0 is activted where GL_TEXTURE_2D is activated
+ * fog, lighting, blending, alpha test, z test, scissor test, culling diabled
+ * color writing enabled for all channels
+ * register combiners disabled, shaders disabled
+ * world matris is set to identity, texture matrix 0 too
+ * projection matrix is setup for drawing screen coordinates
+ *
+ * Params:
+ * This: Device to activate the context for
+ * context: Context to setup
+ * width: render target width
+ * height: render target height
+ *
+ *****************************************************************************/
+static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *context, UINT width, UINT height) {
+ int i;
+
+ TRACE("Setting up context %p for blitting\n", context);
+ if(context->last_was_blit) {
+ TRACE("Context is already set up for blitting, nothing to do\n");
+ return;
+ }
+ context->last_was_blit = TRUE;
+
+ /* Disable shaders */
+ This->shader_backend->shader_cleanup((IWineD3DDevice *) This);
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VSHADER);
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADER);
+
+ /* Disable all textures. The caller can then bind a texture it wants to blit
+ * from
+ */
+ if(GL_SUPPORT(NV_REGISTER_COMBINERS)) {
+ glDisable(GL_REGISTER_COMBINERS_NV);
+ checkGLcall("glDisable(GL_REGISTER_COMBINERS_NV)");
+ }
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+ for(i = GL_LIMITS(samplers) - 1; i > 0 ; i--) {
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+ GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
+ checkGLcall("glActiveTextureARB");
+ }
+ glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
+ glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable GL_TEXTURE_3D");
+ glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable GL_TEXTURE_2D");
+ glDisable(GL_TEXTURE_1D);
+ checkGLcall("glDisable GL_TEXTURE_1D");
+
+ if(i < MAX_TEXTURES) {
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP));
+ }
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
+ }
+ GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
+ checkGLcall("glActiveTextureARB");
+ }
+ glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
+ glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable GL_TEXTURE_3D");
+ glDisable(GL_TEXTURE_1D);
+ checkGLcall("glDisable GL_TEXTURE_1D");
+ glEnable(GL_TEXTURE_2D);
+ checkGLcall("glEnable GL_TEXTURE_2D");
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ glMatrixMode(GL_TEXTURE);
+ checkGLcall("glMatrixMode(GL_TEXTURE)");
+ glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TRANSFORM(WINED3DTS_TEXTURE0));
+
+ if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
+ glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
+ GL_TEXTURE_LOD_BIAS_EXT,
+ 0.0);
+ checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
+ }
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(0));
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP));
+
+ /* Other misc states */
+ glDisable(GL_ALPHA_TEST);
+ checkGLcall("glDisable(GL_ALPHA_TEST)");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ALPHATESTENABLE));
+ glDisable(GL_LIGHTING);
+ checkGLcall("glDisable GL_LIGHTING");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_LIGHTING));
+ glDisable(GL_DEPTH_TEST);
+ checkGLcall("glDisable GL_DEPTH_TEST");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZENABLE));
+ glDisable(GL_FOG);
+ checkGLcall("glDisable GL_FOG");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_FOGENABLE));
+ glDisable(GL_BLEND);
+ checkGLcall("glDisable GL_BLEND");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE));
+ glDisable(GL_CULL_FACE);
+ checkGLcall("glDisable GL_CULL_FACE");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_CULLMODE));
+ glDisable(GL_STENCIL_TEST);
+ checkGLcall("glDisable GL_STENCIL_TEST");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILENABLE));
+ if(GL_SUPPORT(ARB_POINT_SPRITE)) {
+ glDisable(GL_POINT_SPRITE_ARB);
+ checkGLcall("glDisable GL_POINT_SPRITE_ARB");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_POINTSPRITEENABLE));
+ }
+ glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
+ checkGLcall("glColorMask");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_CLIPPING));
+
+ /* Setup transforms */
+ glMatrixMode(GL_MODELVIEW);
+ checkGLcall("glMatrixMode(GL_MODELVIEW)");
+ glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)));
+
+ glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode(GL_PROJECTION)");
+ glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+ glOrtho(0, width, height, 0, 0.0, -1.0);
+ checkGLcall("glOrtho");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TRANSFORM(WINED3DTS_PROJECTION));
+
+ context->last_was_rhw = TRUE;
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL); /* because of last_was_rhw = TRUE */
+
+ glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)");
+ glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)");
+ glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)");
+ glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)");
+ glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)");
+ glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_CLIPPING));
+
+ glViewport(0, 0, width, height);
+ checkGLcall("glViewport");
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VIEWPORT);
+}
+
/*****************************************************************************
* ActivateContext
*
@@ -70,10 +224,13 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
StateTable[dirtyState].apply(dirtyState, This->stateBlock, context);
}
context->numDirtyEntries = 0; /* This makes the whole list clean */
+ context->last_was_blit = FALSE;
break;
case CTXUSAGE_BLIT:
- FIXME("Setting up for blitting not supported yet\n");
+ SetupForBlit(This, context,
+ ((IWineD3DSurfaceImpl *)target)->currentDesc.Width,
+ ((IWineD3DSurfaceImpl *)target)->currentDesc.Height);
break;
default:
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 6b3d200..be08c34 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -853,8 +853,6 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) {
glDisable(GL_TEXTURE_2D);
vcheckGLcall("glDisable(GL_TEXTURE_2D)");
- glDisable(GL_TEXTURE_1D);
- vcheckGLcall("glDisable(GL_TEXTURE_1D)");
glFlush();
vcheckGLcall("glFlush");
@@ -1039,21 +1037,6 @@ static void flush_to_framebuffer_texture(IWineD3DSurface *iface) {
ENTER_GL();
- /* Disable some fancy graphics effects */
- glDisable(GL_LIGHTING);
- checkGLcall("glDisable GL_LIGHTING");
- glDisable(GL_DEPTH_TEST);
- checkGLcall("glDisable GL_DEPTH_TEST");
- glDisable(GL_FOG);
- checkGLcall("glDisable GL_FOG");
- glDisable(GL_CULL_FACE);
- checkGLcall("glDisable GL_CULL_FACE");
- glDisable(GL_BLEND);
- checkGLcall("glDisable GL_BLEND");
- glDisable(GL_STENCIL_TEST);
- checkGLcall("glDisable GL_STENCIL_TEST");
-
- glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, This->glDescription.textureName);
checkGLcall("glEnable glBindTexture");
@@ -1160,19 +1143,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
IWineD3DDevice_GetSwapChain((IWineD3DDevice *)myDevice, 0, (IWineD3DSwapChain **)&implSwapChain);
if ((backbuf || iface == implSwapChain->frontBuffer || iface == myDevice->render_targets[0]) && wined3d_settings.rendertargetlock_mode != RTL_DISABLE) {
- int tex;
ENTER_GL();
- /* glDrawPixels transforms the raster position as though it was a vertex -
- we want to draw at screen position 0,0 - Set up ortho (rhw) mode as
- per drawprim (and leave set - it will sort itself out due to last_was_rhw */
- myDevice->contexts[myDevice->activeContext].last_was_rhw = TRUE;
- /* Apply the projection and world matrices, it sets up orthogonal projection due to last_was_rhw */
- StateTable[STATE_TRANSFORM(WINED3DTS_PROJECTION)].apply(STATE_TRANSFORM(WINED3DTS_PROJECTION), myDevice->stateBlock, &myDevice->contexts[myDevice->activeContext]);
- StateTable[STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))].apply(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), myDevice->stateBlock, &myDevice->contexts[myDevice->activeContext]);
- /* Will reapply the projection matrix too */
- IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
+ ActivateContext(myDevice, iface, CTXUSAGE_BLIT);
if (iface == implSwapChain->frontBuffer) {
glDrawBuffer(GL_FRONT);
@@ -1182,31 +1156,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
checkGLcall("glDrawBuffer GL_BACK");
}
- /* Disable higher textures before calling glDrawPixels */
- for(tex = 1; tex < GL_LIMITS(samplers); tex++) {
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + tex));
- checkGLcall("glActiveTextureARB");
- }
- IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(tex));
- glDisable(GL_TEXTURE_2D);
- checkGLcall("glDisable GL_TEXTURE_2D");
- glDisable(GL_TEXTURE_1D);
- checkGLcall("glDisable GL_TEXTURE_1D");
- }
- /* Activate texture 0, but don't disable it necessarily */
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
- checkGLcall("glActiveTextureARB");
- }
- IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(0));
-
- /* And back buffers are not blended. Disable the depth test,
- that helps performance */
- glDisable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_FOG);
-
switch(wined3d_settings.rendertargetlock_mode) {
case RTL_AUTO:
case RTL_READDRAW:
@@ -1234,10 +1183,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
glDrawBuffer(GL_BACK);
vcheckGLcall("glDrawBuffer");
}
- if(myDevice->stateBlock->renderState[WINED3DRS_ZENABLE] == WINED3DZB_TRUE ||
- myDevice->stateBlock->renderState[WINED3DRS_ZENABLE] == WINED3DZB_USEW) glEnable(GL_DEPTH_TEST);
- if (myDevice->stateBlock->renderState[WINED3DRS_ALPHABLENDENABLE]) glEnable(GL_BLEND);
- if (myDevice->stateBlock->renderState[WINED3DRS_FOGENABLE]) glEnable(GL_FOG);
LEAVE_GL();
@@ -2343,10 +2288,6 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
float glTexCoord[4];
DWORD oldCKey;
DDCOLORKEY oldBltCKey = {0,0};
- GLint oldLight, oldFog, oldDepth, oldBlend, oldCull, oldAlpha;
- GLint oldStencil, oldNVRegisterCombiners = 0;
- GLint alphafunc;
- GLclampf alpharef;
RECT SourceRectangle;
GLint oldDraw;
@@ -2399,23 +2340,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
ENTER_GL();
- /* Save all the old stuff until we have a proper opengl state manager */
- oldLight = glIsEnabled(GL_LIGHTING);
- oldFog = glIsEnabled(GL_FOG);
- oldDepth = glIsEnabled(GL_DEPTH_TEST);
- oldBlend = glIsEnabled(GL_BLEND);
- oldCull = glIsEnabled(GL_CULL_FACE);
- oldAlpha = glIsEnabled(GL_ALPHA_TEST);
- oldStencil = glIsEnabled(GL_STENCIL_TEST);
-
- if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
- oldNVRegisterCombiners = glIsEnabled(GL_REGISTER_COMBINERS_NV);
- }
-
- glGetIntegerv(GL_ALPHA_TEST_FUNC, &alphafunc);
- checkGLcall("glGetFloatv GL_ALPHA_TEST_FUNC");
- glGetFloatv(GL_ALPHA_TEST_REF, &alpharef);
- checkGLcall("glGetFloatv GL_ALPHA_TEST_REF");
+ ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);
glGetIntegerv(GL_DRAW_BUFFER, &oldDraw);
if(This == (IWineD3DSurfaceImpl *) swapchain->frontBuffer) {
@@ -2424,52 +2349,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
checkGLcall("glDrawBuffer GL_FRONT");
}
- /* Unbind the old texture */
- glBindTexture(GL_TEXTURE_2D, 0);
- IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(0));
-
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- /* We use texture unit 0 for blts */
- GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
- checkGLcall("glActiveTextureARB");
- } else {
- WARN("Multi-texturing is unsupported in the local OpenGL implementation\n");
- }
-
- /* Disable some fancy graphics effects */
- glDisable(GL_LIGHTING);
- checkGLcall("glDisable GL_LIGHTING");
- glDisable(GL_DEPTH_TEST);
- checkGLcall("glDisable GL_DEPTH_TEST");
- glDisable(GL_FOG);
- checkGLcall("glDisable GL_FOG");
- glDisable(GL_BLEND);
- checkGLcall("glDisable GL_BLEND");
- glDisable(GL_CULL_FACE);
- checkGLcall("glDisable GL_CULL_FACE");
- glDisable(GL_STENCIL_TEST);
- checkGLcall("glDisable GL_STENCIL_TEST");
- if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
- glDisable(GL_REGISTER_COMBINERS_NV);
- checkGLcall("glDisable GL_REGISTER_COMBINERS_NV");
- }
-
- /* Ok, we need 2d textures, but not 1D or 3D */
- glDisable(GL_TEXTURE_1D);
- checkGLcall("glDisable GL_TEXTURE_1D");
- glEnable(GL_TEXTURE_2D);
- checkGLcall("glEnable GL_TEXTURE_2D");
- glDisable(GL_TEXTURE_3D);
- checkGLcall("glDisable GL_TEXTURE_3D");
-
/* Bind the texture */
glBindTexture(GL_TEXTURE_2D, Src->glDescription.textureName);
checkGLcall("glBindTexture");
- glEnable(GL_SCISSOR_TEST);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
/* No filtering for blts */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
@@ -2495,13 +2378,6 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
/* Draw a textured quad
*/
- myDevice->contexts[myDevice->activeContext].last_was_rhw = TRUE;
- /* Apply the projection matrix, it sets up orthogonal projection due to last_was_rhw */
- StateTable[STATE_TRANSFORM(WINED3DTS_PROJECTION)].apply(STATE_TRANSFORM(WINED3DTS_PROJECTION), myDevice->stateBlock, &myDevice->contexts[myDevice->activeContext]);
- StateTable[STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))].apply(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), myDevice->stateBlock, &myDevice->contexts[myDevice->activeContext]);
- /* That will reapply the projection matrix too */
- IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
-
glBegin(GL_QUADS);
glColor3d(1.0f, 1.0f, 1.0f);
@@ -2529,46 +2405,6 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
glBindTexture(GL_TEXTURE_2D, 0);
checkGLcall("glEnable glBindTexture");
- /* Restore the old settings */
- if(oldLight) {
- glEnable(GL_LIGHTING);
- checkGLcall("glEnable GL_LIGHTING");
- }
- if(oldFog) {
- glEnable(GL_FOG);
- checkGLcall("glEnable GL_FOG");
- }
- if(oldDepth) {
- glEnable(GL_DEPTH_TEST);
- checkGLcall("glEnable GL_DEPTH_TEST");
- }
- if(oldBlend) {
- glEnable(GL_BLEND);
- checkGLcall("glEnable GL_BLEND");
- }
- if(oldCull) {
- glEnable(GL_CULL_FACE);
- checkGLcall("glEnable GL_CULL_FACE");
- }
- if(oldStencil) {
- glEnable(GL_STENCIL_TEST);
- checkGLcall("glEnable GL_STENCIL_TEST");
- }
- if(!oldAlpha) {
- glDisable(GL_ALPHA_TEST);
- checkGLcall("glDisable GL_ALPHA_TEST");
- } else {
- glEnable(GL_ALPHA_TEST);
- checkGLcall("glEnable GL_ALPHA_TEST");
- }
- if (GL_SUPPORT(NV_REGISTER_COMBINERS) && oldNVRegisterCombiners) {
- glEnable(GL_REGISTER_COMBINERS_NV);
- checkGLcall("glEnable GL_REGISTER_COMBINERS_NV");
- }
-
- glAlphaFunc(alphafunc, alpharef);
- checkGLcall("glAlphaFunc\n");
-
if(This == (IWineD3DSurfaceImpl *) swapchain->frontBuffer && oldDraw == GL_BACK) {
glDrawBuffer(oldDraw);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ab3e947..03d5759 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -477,6 +477,7 @@ struct WineD3DContext {
BOOL namedArraysLoaded, numberedArraysLoaded;
BOOL lastWasPow2Texture[MAX_TEXTURES];
GLenum tracking_parm; /* Which source is tracking current colour */
+ BOOL last_was_blit;
};
typedef enum ContextUsage {
--
1.4.4.3
More information about the wine-patches
mailing list