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:
parent
b04e992a65
commit
a7251f0f4e
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue