[3/5] wined3d: Allow the FBO code to handle multiple render targets
H. Verbeet
hverbeet at gmail.com
Tue Dec 19 12:25:35 CST 2006
Note that as of this patch, the limit for the number of draw buffers,
and by extension render targets, is still hardcoded to 1. The next
patch will take care of handling that.
Changelog:
- Allow the FBO code to handle multiple render targets
-------------- next part --------------
---
dlls/wined3d/device.c | 32 ++++++++++++++++++++++++++------
dlls/wined3d/directx.c | 2 ++
dlls/wined3d/wined3d_private.h | 1 +
3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index fc15ca3..bc5fd32 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -574,6 +574,8 @@ static ULONG WINAPI IWineD3DDeviceImpl_R
HeapFree(GetProcessHeap(), 0, This->render_targets);
+ HeapFree(GetProcessHeap(), 0, This->draw_buffers);
+
/* TODO: Clean up all the surfaces and textures! */
/* NOTE: You must release the parent if the object was created via a callback
** ***************************/
@@ -5794,14 +5796,18 @@ static void set_depth_stencil_fbo(IWineD
}
}
-static void set_render_target_fbo(IWineD3DDevice *iface, IWineD3DSurface *render_target) {
+static void set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DSurfaceImpl *rtimpl = (IWineD3DSurfaceImpl *)render_target;
- if (This->render_offscreen) {
- GLenum texttarget, target;
+ if (idx >= GL_LIMITS(buffers)) {
+ ERR("%p : Trying to set render target %d, but only %d supported\n", This, idx, GL_LIMITS(buffers));
+ }
- bind_fbo(iface);
+ bind_fbo(iface);
+
+ if (rtimpl) {
+ GLenum texttarget, target;
IWineD3DSurface_PreLoad(render_target);
texttarget = rtimpl->glDescription.target;
@@ -5812,9 +5818,23 @@ static void set_render_target_fbo(IWineD
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(target, 0);
- GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texttarget, rtimpl->glDescription.textureName, 0));
+ GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget, rtimpl->glDescription.textureName, 0));
checkGLcall("glFramebufferTexture2DEXT()");
+
+ This->draw_buffers[idx] = GL_COLOR_ATTACHMENT0_EXT + idx;
} else {
+ GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + idx, GL_TEXTURE_2D, 0, 0));
+ checkGLcall("glFramebufferTexture2DEXT()");
+
+ This->draw_buffers[idx] = GL_NONE;
+ }
+
+ if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
+ GL_EXTCALL(glDrawBuffersARB(GL_LIMITS(buffers), This->draw_buffers));
+ checkGLcall("glDrawBuffers()");
+ }
+
+ if (!This->render_offscreen) {
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
checkGLcall("glBindFramebuffer()");
}
@@ -5878,7 +5898,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
if (pRenderTarget) IWineD3DSurface_AddRef(pRenderTarget);
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
- set_render_target_fbo(iface, pRenderTarget);
+ set_render_target_fbo(iface, RenderTargetIndex, pRenderTarget);
}
}
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 839b648..b3b891f 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2450,6 +2450,8 @@ static HRESULT WINAPI IWineD3DImpl_Crea
object->render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *) * GL_LIMITS(buffers));
+ object->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLenum) * GL_LIMITS(buffers));
+
/* set the state of the device to valid */
object->state = WINED3D_OK;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 13d79ed..906619a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -587,6 +587,7 @@ #define NEEDS_DI
BOOL render_offscreen;
WINED3D_DEPTHCOPYSTATE depth_copy_state;
GLuint fbo;
+ GLenum *draw_buffers;
/* Cursor management */
BOOL bCursorVisible;
More information about the wine-patches
mailing list