[PATCH 2/5] wined3d: Track render_offscreen in the context.
Henri Verbeet
hverbeet at codeweavers.com
Thu Aug 6 01:12:19 CDT 2009
This makes sure the relevant states in FindContext() are actually marked dirty
when needed.
---
dlls/wined3d/arb_program_shader.c | 8 +++++---
dlls/wined3d/context.c | 22 ++++++++++++----------
dlls/wined3d/device.c | 10 ++++++----
dlls/wined3d/drawprim.c | 2 +-
dlls/wined3d/glsl_shader.c | 19 ++++++++++---------
dlls/wined3d/state.c | 27 ++++++++++++++++-----------
dlls/wined3d/surface.c | 9 ++++++---
dlls/wined3d/wined3d_private.h | 5 ++---
8 files changed, 58 insertions(+), 44 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 9b891a2..180d929 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -428,8 +428,9 @@ static void shader_arb_load_np2fixup_constants(
/* GL locking is done by the caller. */
static inline void shader_arb_ps_local_constants(IWineD3DDeviceImpl* deviceImpl)
{
+ const struct wined3d_context *context = context_get_current();
IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
- const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned char i;
struct shader_arb_priv *priv = deviceImpl->shader_priv;
const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog;
@@ -463,8 +464,9 @@ static inline void shader_arb_ps_local_constants(IWineD3DDeviceImpl* deviceImpl)
* ycorrection.w: 0.0
*/
float val[4];
- val[0] = deviceImpl->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height;
- val[1] = deviceImpl->render_offscreen ? 1.0f : -1.0f;
+ val[0] = context->render_offscreen ? 0.0f
+ : ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height;
+ val[1] = context->render_offscreen ? 1.0f : -1.0f;
val[2] = 1.0f;
val[3] = 0.0f;
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->ycorrection, val));
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index d0b23b7..6cd67f2 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -438,9 +438,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_
/* GL locking is done by the caller */
static void context_apply_fbo_state(struct wined3d_context *context)
{
- IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
-
- if (device->render_offscreen)
+ if (context->render_offscreen)
{
context->current_fbo = context_find_fbo_entry(context);
context_apply_fbo_entry(context, context->current_fbo);
@@ -1723,11 +1721,10 @@ static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain *
static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid)
{
IWineD3DSwapChain *swapchain = NULL;
- BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen;
struct wined3d_context *current_context = context_get_current();
- BOOL oldRenderOffscreen = This->render_offscreen;
const struct StateEntry *StateTable = This->StateTable;
struct wined3d_context *context;
+ BOOL old_render_offscreen;
if (current_context && current_context->destroyed) current_context = NULL;
@@ -1757,7 +1754,8 @@ static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWin
context = findThreadContextForSwapChain(swapchain, tid);
- This->render_offscreen = FALSE;
+ old_render_offscreen = context->render_offscreen;
+ context->render_offscreen = FALSE;
/* The context != This->activeContext will catch a NOP context change. This can occur
* if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
* rendering. No context change is needed in that case
@@ -1773,7 +1771,6 @@ static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWin
else
{
TRACE("Rendering offscreen\n");
- This->render_offscreen = TRUE;
retry:
if (wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER)
@@ -1831,9 +1828,12 @@ retry:
context = findThreadContextForSwapChain(This->swapchains[0], tid);
}
}
+
+ old_render_offscreen = context->render_offscreen;
+ context->render_offscreen = TRUE;
}
- if (This->render_offscreen != oldRenderOffscreen)
+ if (context->render_offscreen != old_render_offscreen)
{
Context_MarkStateDirty(context, WINED3DTS_PROJECTION, StateTable);
Context_MarkStateDirty(context, STATE_VDECL, StateTable);
@@ -1890,7 +1890,8 @@ retry:
* After that, the outer ActivateContext(which calls PreLoad) can activate the new
* target for the new thread
*/
- if (readTexture && context->current_rt && context->current_rt != target)
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO && old_render_offscreen
+ && context->current_rt && context->current_rt != target)
{
BOOL oldInDraw = This->isInDraw;
@@ -2035,7 +2036,8 @@ struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurfac
case CTXUSAGE_BLIT:
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
- if (This->render_offscreen) {
+ if (context->render_offscreen)
+ {
FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
ENTER_GL();
context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 40ea34d..c9e50d1 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4939,7 +4939,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa
}
if (Flags & WINED3DCLEAR_ZBUFFER) {
- DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+ DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
glDepthMask(GL_TRUE);
glClearDepth(Z);
checkGLcall("glClearDepth");
@@ -4985,7 +4985,8 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa
if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
IntersectRect(&vp_rect, &vp_rect, &This->stateBlock->scissorRect);
}
- if(This->render_offscreen) {
+ if (context->render_offscreen)
+ {
glScissor(vp_rect.left, vp_rect.top,
vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top);
} else {
@@ -5017,7 +5018,8 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa
continue;
}
- if(This->render_offscreen) {
+ if (context->render_offscreen)
+ {
glScissor(curRect.x1, curRect.y1,
curRect.x2 - curRect.x1, curRect.y2 - curRect.y1);
} else {
@@ -5049,7 +5051,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa
}
if (Flags & WINED3DCLEAR_ZBUFFER) {
/* Note that WINED3DCLEAR_ZBUFFER implies a depth stencil exists on the device */
- DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+ DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
surface_modify_ds_location(This->stencilBufferTarget, location);
}
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index d6d1469..09cb960 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -589,7 +589,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice
* Z-compare function into account, but we could skip loading the
* depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note
* that we never copy the stencil data.*/
- DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+ DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]
|| This->stateBlock->renderState[WINED3DRS_ZENABLE])
surface_load_ds_location(This->stencilBufferTarget, context, location);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 95649ec..a6b98ff 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -627,15 +627,13 @@ static void shader_glsl_load_np2fixup_constants(
* Loads the app-supplied constants into the currently set GLSL program.
*/
/* GL locking is done by the caller (state handler) */
-static void shader_glsl_load_constants(
- IWineD3DDevice* device,
- char usePixelShader,
- char useVertexShader) {
-
+static void shader_glsl_load_constants(IWineD3DDevice *device, char usePixelShader, char useVertexShader)
+{
+ const struct wined3d_context *context = context_get_current();
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
struct shader_glsl_priv *priv = deviceImpl->shader_priv;
IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
- const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
GLhandleARB programId;
struct glsl_shader_prog_link *prog = priv->glsl_program;
@@ -713,7 +711,9 @@ static void shader_glsl_load_constants(
if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) {
float correction_params[4];
- if(deviceImpl->render_offscreen) {
+
+ if (context->render_offscreen)
+ {
correction_params[0] = 0.0f;
correction_params[1] = 1.0f;
} else {
@@ -808,6 +808,7 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
struct wined3d_shader_buffer *buffer, const struct wined3d_gl_info *gl_info,
struct shader_glsl_ctx_priv *ctx_priv)
{
+ const struct wined3d_context *context = context_get_current();
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
@@ -931,8 +932,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
*/
FIXME("Cannot find a free uniform for vpos correction params\n");
shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n",
- device->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *)device->render_targets[0])->currentDesc.Height,
- device->render_offscreen ? 1.0f : -1.0f);
+ context->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *)device->render_targets[0])->currentDesc.Height,
+ context->render_offscreen ? 1.0f : -1.0f);
}
shader_addline(buffer, "vec4 vpos;\n");
}
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index c8f3d4d..c61f897 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3591,9 +3591,7 @@ static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
- if(stateblock->wineD3DDevice->render_offscreen) {
- glScalef(1.0f, -1.0f, 1.0f);
- }
+ if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f);
}
TRACE("Clipplane [%f,%f,%f,%f]\n",
@@ -3808,7 +3806,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
* problem either.
*/
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
- if(stateblock->wineD3DDevice->render_offscreen) {
+ if (context->render_offscreen)
+ {
glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
} else {
glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
@@ -3822,7 +3821,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
* replacement shader.
*/
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
- if(stateblock->wineD3DDevice->render_offscreen) {
+ if (context->render_offscreen)
+ {
glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0);
} else {
glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
@@ -3835,7 +3835,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
checkGLcall("glTranslatef(0.5f, 0.5f, 0.0f)");
/* D3D texture coordinates are flipped compared to OpenGL ones, so
* render everything upside down when rendering offscreen. */
- if (stateblock->wineD3DDevice->render_offscreen) {
+ if (context->render_offscreen)
+ {
glScalef(1.0f, -1.0f, 1.0f);
checkGLcall("glScalef");
}
@@ -3877,7 +3878,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
* glScalef(1.0, flip, 2.0);
*/
- if (stateblock->wineD3DDevice->render_offscreen) {
+ if (context->render_offscreen)
+ {
/* D3D texture coordinates are flipped compared to OpenGL ones, so
* render everything upside down when rendering offscreen. */
glTranslatef(1.0f / stateblock->viewport.Width, 1.0f / stateblock->viewport.Height, -1.0f);
@@ -4489,7 +4491,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s
* TODO: Move to the viewport state
*/
if (useVertexShaderFunction) {
- device->posFixup[1] = device->render_offscreen ? -1.0f : 1.0f;
+ device->posFixup[1] = context->render_offscreen ? -1.0f : 1.0f;
device->posFixup[3] = -device->posFixup[1] / stateblock->viewport.Height;
}
}
@@ -4616,7 +4618,8 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, s
checkGLcall("glDepthRange");
/* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
*/
- if(stateblock->wineD3DDevice->render_offscreen) {
+ if (context->render_offscreen)
+ {
glViewport(stateblock->viewport.X,
stateblock->viewport.Y,
stateblock->viewport.Width, stateblock->viewport.Height);
@@ -4774,7 +4777,8 @@ static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - height,
pRect->right - pRect->left, pRect->bottom - pRect->top);
- if (stateblock->wineD3DDevice->render_offscreen) {
+ if (context->render_offscreen)
+ {
glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
} else {
glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
@@ -4794,7 +4798,8 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
- if(stateblock->wineD3DDevice->render_offscreen) {
+ if (context->render_offscreen)
+ {
glFrontFace(GL_CCW);
checkGLcall("glFrontFace(GL_CCW)");
} else {
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 1cf4c71..66bdbed 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -4529,7 +4529,9 @@ static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float
f->b = ((r->bottom * 2.0f) / h) - 1.0f;
}
-static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in) {
+static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in)
+{
+ const struct wined3d_context *context;
struct coords coords[4];
RECT rect;
IWineD3DSwapChain *swapchain;
@@ -4636,7 +4638,8 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
return;
}
- ActivateContext(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT);
+ context = ActivateContext(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT);
+
ENTER_GL();
glEnable(bind_target);
@@ -4648,7 +4651,7 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
checkGLcall("glTexParameteri");
- if (device->render_offscreen)
+ if (context->render_offscreen)
{
LONG tmp = rect.top;
rect.top = rect.bottom;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index c83ee20..414b519 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1169,6 +1169,7 @@ struct wined3d_context
DWORD tid; /* Thread ID which owns this context at the moment */
/* Stores some information about the context state for optimization */
+ WORD render_offscreen : 1;
WORD draw_buffer_dirty : 1;
WORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */
WORD last_was_pshader : 1;
@@ -1183,7 +1184,6 @@ struct wined3d_context
WORD num_untracked_materials : 2; /* Max value 2 */
WORD current : 1;
WORD destroyed : 1;
- WORD padding : 1;
BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
DWORD numbered_array_mask;
@@ -1535,7 +1535,6 @@ struct IWineD3DDeviceImpl
WORD vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */
WORD isRecordingState : 1;
WORD isInDraw : 1;
- WORD render_offscreen : 1;
WORD bCursorVisible : 1;
WORD haveHardwareCursor : 1;
WORD d3d_initialized : 1;
@@ -1543,7 +1542,7 @@ struct IWineD3DDeviceImpl
WORD softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */
WORD useDrawStridedSlow : 1;
WORD instancedDraw : 1;
- WORD padding : 3;
+ WORD padding : 4;
BYTE fixed_function_usage_map; /* MAX_TEXTURES, 8 */
--
1.6.0.6
More information about the wine-patches
mailing list