From e4fc45e0fe2bae4e6653b54267e0419d51c66d72 Mon Sep 17 00:00:00 2001 From: "H. Verbeet" Date: Tue, 19 Dec 2006 19:25:42 +0100 Subject: [PATCH] wined3d: Allow wined3d to handle multiple render targets. --- dlls/wined3d/device.c | 28 +++++++++++++++++----------- dlls/wined3d/directx.c | 13 +++++++------ dlls/wined3d/glsl_shader.c | 12 ++++-------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8609c5579dc..53ab337343f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5643,11 +5643,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderTarget(IWineD3DDevice* iface,DWORD RenderTargetIndex, IWineD3DSurface **ppRenderTarget) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - /* FIXME: Implelent RenderTargetIndex >0 */ - if(RenderTargetIndex > 0) - FIXME("(%p) : RenderTargetIndex %d >0 not currently supported\n", This, RenderTargetIndex); + if (RenderTargetIndex >= GL_LIMITS(buffers)) { + ERR("(%p) : Only %d render targets are supported.\n", This, GL_LIMITS(buffers)); + return WINED3DERR_INVALIDCALL; + } - *ppRenderTarget = This->render_targets[0]; + *ppRenderTarget = This->render_targets[RenderTargetIndex]; TRACE("(%p) : RenderTarget %d Index returning %p\n", This, RenderTargetIndex, *ppRenderTarget); /* Note inc ref on returned surface */ if(*ppRenderTarget != NULL) @@ -5849,10 +5850,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, HRESULT hr = WINED3D_OK; WINED3DVIEWPORT viewport; - TRACE("(%p) Swapping rendertarget\n",This); - if (RenderTargetIndex > 0) { - FIXME("(%p) Render targets other than the first are not supported\n",This); - RenderTargetIndex = 0; + TRACE("(%p) : Setting rendertarget %d to %p\n", This, RenderTargetIndex, pRenderTarget); + + if (RenderTargetIndex >= GL_LIMITS(buffers)) { + ERR("(%p) : Only %d render targets are supported.\n", This, GL_LIMITS(buffers)); + return WINED3DERR_INVALIDCALL; } /* MSDN says that null disables the render target @@ -5867,7 +5869,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, return WINED3DERR_INVALIDCALL; } /* TODO: replace Impl* usage with interface usage */ - if (!((IWineD3DSurfaceImpl *)pRenderTarget)->resource.usage & WINED3DUSAGE_RENDERTARGET) { + if (pRenderTarget && !((IWineD3DSurfaceImpl *)pRenderTarget)->resource.usage & WINED3DUSAGE_RENDERTARGET) { FIXME("(%p)Trying to set the render target to a surface(%p) that wasn't created with a usage of WINED3DUSAGE_RENDERTARGET\n",This ,pRenderTarget); return WINED3DERR_INVALIDCALL; } @@ -5875,7 +5877,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, * builds, but I think wine counts as a 'debug' build for now. ******************************/ /* If we are trying to set what we already have, don't bother */ - if (pRenderTarget == This->render_targets[0]) { + if (pRenderTarget == This->render_targets[RenderTargetIndex]) { TRACE("Trying to do a NOP SetRenderTarget operation\n"); } else { /* Otherwise, set the render target up */ @@ -5890,7 +5892,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, A shared context implementation will share all buffers between all rendertargets (including swapchains), implementations that use separate pbuffers for different swapchains or rendertargets will have to duplicate the stencil buffer and incure an extra memory overhead */ - hr = IWineD3DDeviceImpl_ActiveRender(iface, pRenderTarget); + if (RenderTargetIndex == 0) { + hr = IWineD3DDeviceImpl_ActiveRender(iface, pRenderTarget); + } else { + hr = WINED3D_OK; + } /* Replace the render target */ if (This->render_targets[RenderTargetIndex]) IWineD3DSurface_Release(This->render_targets[RenderTargetIndex]); diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index b3b891f884e..fb65bab9400 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -804,6 +804,11 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) { wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER; } + /* MRTs are currently only supported when FBOs are used. */ + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) { + gl_info->max_buffers = 1; + } + /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and * in case of the latest videocards in the number of pixel/vertex pipelines. @@ -2284,12 +2289,8 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, } else *pCaps->DeclTypes = 0; -#if 0 /* We don't properly support multiple render targets yet, so disable this for now */ - if (GL_SUPPORT(ARB_DRAWBUFFERS)) { - *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers); - } else -#endif - *pCaps->NumSimultaneousRTs = 1; + *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers); + *pCaps->StretchRectFilterCaps = 0; *pCaps->VertexTextureFilterCaps = 0; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index dffc1aae8d0..17b6a474c5e 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -680,17 +680,13 @@ static void shader_glsl_get_register_name( sprintf(tmpStr, "Vsampler%u", reg); break; case WINED3DSPR_COLOROUT: + if (reg >= GL_LIMITS(buffers)) { + WARN("Write to render target %u, only %d supported\n", reg, 4); + } if (GL_SUPPORT(ARB_DRAW_BUFFERS)) { sprintf(tmpStr, "gl_FragData[%u]", reg); - if (reg > 0) { - /* TODO: See GL_ARB_draw_buffers */ - FIXME("Unsupported write to render target %u\n", reg); - } } else { /* On older cards with GLSL support like the GeforceFX there's only one buffer. */ - if (reg > 0) - WARN("This OpenGL implementation doesn't support writing to multiple render targets!\n"); - else - sprintf(tmpStr, "gl_FragColor"); + sprintf(tmpStr, "gl_FragColor"); } break; case WINED3DSPR_RASTOUT: -- 2.11.4.GIT