H. Verbeet : wined3d: Implement ColorFill using FBOs,
if they're being used .
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Apr 17 08:12:20 CDT 2007
Module: wine
Branch: master
Commit: e0a94b906cbc04d5c42044bc2a6226020e8c197d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e0a94b906cbc04d5c42044bc2a6226020e8c197d
Author: H. Verbeet <hverbeet at gmail.com>
Date: Mon Apr 16 21:21:13 2007 +0200
wined3d: Implement ColorFill using FBOs, if they're being used.
---
dlls/wined3d/device.c | 158 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 109 insertions(+), 49 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 1e3d18a..90c311e 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4974,6 +4974,105 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DeletePatch(IWineD3DDevice *iface, UINT
return WINED3D_OK;
}
+static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
+ HRESULT hr;
+ IWineD3DSwapChain *swapchain;
+
+ hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain);
+ if (SUCCEEDED(hr)) {
+ IWineD3DSwapChain_Release((IUnknown *)swapchain);
+ return swapchain;
+ }
+
+ return NULL;
+}
+
+static void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+
+ if (!*fbo) {
+ GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
+ checkGLcall("glGenFramebuffersEXT()");
+ }
+ GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
+ checkGLcall("glBindFramebuffer()");
+}
+
+static void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) {
+ const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
+ GLenum texttarget, target;
+ GLint old_binding;
+
+ texttarget = surface_impl->glDescription.target;
+ target = texttarget == GL_TEXTURE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP_ARB;
+ glGetIntegerv(texttarget == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
+
+ IWineD3DSurface_PreLoad(surface);
+
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glBindTexture(target, old_binding);
+
+ GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget, surface_impl->glDescription.textureName, 0));
+
+ checkGLcall("attach_surface_fbo");
+}
+
+static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, CONST WINED3DRECT *rect, WINED3DCOLOR color) {
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+ IWineD3DSwapChain *swapchain;
+
+ swapchain = get_swapchain(surface);
+ if (swapchain) {
+ GLenum buffer;
+
+ TRACE("Surface %p is onscreen\n", surface);
+
+ GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
+ buffer = surface_get_gl_buffer(surface, swapchain);
+ glDrawBuffer(buffer);
+ checkGLcall("glDrawBuffer()");
+ } else {
+ TRACE("Surface %p is offscreen\n", surface);
+ bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->dst_fbo);
+ attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, surface);
+ }
+
+ if (rect) {
+ glEnable(GL_SCISSOR_TEST);
+ if(!swapchain) {
+ glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1);
+ } else {
+ glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2,
+ rect->x2 - rect->x1, rect->y2 - rect->y1);
+ }
+ checkGLcall("glScissor");
+ } else {
+ glDisable(GL_SCISSOR_TEST);
+ }
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE));
+
+ glClearColor(D3DCOLOR_R(color), D3DCOLOR_G(color), D3DCOLOR_B(color), D3DCOLOR_A(color));
+ glClear(GL_COLOR_BUFFER_BIT);
+ checkGLcall("glClear");
+
+ if (This->render_offscreen) {
+ bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->fbo);
+ } else {
+ GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+ checkGLcall("glBindFramebuffer()");
+ }
+
+ if (swapchain && surface == ((IWineD3DSwapChainImpl *)swapchain)->frontBuffer
+ && ((IWineD3DSwapChainImpl *)swapchain)->backBuffer) {
+ glDrawBuffer(GL_BACK);
+ checkGLcall("glDrawBuffer()");
+ }
+}
+
static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD3DSurface *pSurface, CONST WINED3DRECT* pRect, WINED3DCOLOR color) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *) pSurface;
@@ -4985,11 +5084,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD
return WINED3DERR_INVALIDCALL;
}
- /* Just forward this to the DirectDraw blitting engine */
- memset(&BltFx, 0, sizeof(BltFx));
- BltFx.dwSize = sizeof(BltFx);
- BltFx.u5.dwFillColor = color;
- return IWineD3DSurface_Blt(pSurface, (RECT *) pRect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
+ color_fill_fbo(iface, pSurface, pRect, color);
+ return WINED3DERR_INVALIDCALL;
+ } else {
+ /* Just forward this to the DirectDraw blitting engine */
+ memset(&BltFx, 0, sizeof(BltFx));
+ BltFx.dwSize = sizeof(BltFx);
+ BltFx.u5.dwFillColor = color;
+ return IWineD3DSurface_Blt(pSurface, (RECT *) pRect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
+ }
}
/* rendertarget and deptth stencil functions */
@@ -5108,17 +5212,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice
return WINED3D_OK;
}
-static void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
- if (!*fbo) {
- GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
- checkGLcall("glGenFramebuffersEXT()");
- }
- GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
- checkGLcall("glBindFramebuffer()");
-}
-
/* TODO: Handle stencil attachments */
static void set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_stencil) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
@@ -5154,26 +5247,6 @@ static void set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_
}
}
-static void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) {
- const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
- GLenum texttarget, target;
- GLint old_binding;
-
- texttarget = surface_impl->glDescription.target;
- target = texttarget == GL_TEXTURE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP_ARB;
- glGetIntegerv(texttarget == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
-
- IWineD3DSurface_PreLoad(surface);
-
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glBindTexture(target, old_binding);
-
- GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget, surface_impl->glDescription.textureName, 0));
-
- checkGLcall("attach_surface_fbo");
-}
-
static void set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DSurfaceImpl *rtimpl = (IWineD3DSurfaceImpl *)render_target;
@@ -5280,19 +5353,6 @@ void apply_fbo_state(IWineD3DDevice *iface) {
check_fbo_status(iface);
}
-static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
- HRESULT hr;
- IWineD3DSwapChain *swapchain;
-
- hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain);
- if (SUCCEEDED(hr)) {
- IWineD3DSwapChain_Release((IUnknown *)swapchain);
- return swapchain;
- }
-
- return NULL;
-}
-
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const WINED3DRECT *src_rect,
IWineD3DSurface *dst_surface, const WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
More information about the wine-cvs
mailing list