wined3d: Track render_offscreen in the context.

This makes sure the relevant states in FindContext() are actually marked dirty
when needed.
This commit is contained in:
Henri Verbeet 2009-08-06 08:12:19 +02:00 committed by Alexandre Julliard
parent b04e992a65
commit a7251f0f4e
8 changed files with 58 additions and 44 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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");
}

View File

@ -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 {

View File

@ -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;

View File

@ -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 */