wined3d: Move FBO handling functions to context.c.
This commit is contained in:
parent
2e8dec4115
commit
a269236649
|
@ -36,6 +36,268 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
|||
*/
|
||||
static IWineD3DDeviceImpl *last_device;
|
||||
|
||||
/* FBO helper functions */
|
||||
|
||||
void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo)
|
||||
{
|
||||
const IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
||||
if (!*fbo)
|
||||
{
|
||||
GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
|
||||
checkGLcall("glGenFramebuffersEXT()");
|
||||
TRACE("Created FBO %d\n", *fbo);
|
||||
}
|
||||
|
||||
GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
}
|
||||
|
||||
static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
for (i = 0; i < GL_LIMITS(buffers); ++i)
|
||||
{
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
|
||||
checkGLcall("glFramebufferTexture2D()");
|
||||
}
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
|
||||
checkGLcall("glFramebufferTexture2D()");
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
|
||||
checkGLcall("glDeleteFramebuffers()");
|
||||
}
|
||||
|
||||
/* TODO: Handle stencil attachments */
|
||||
void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer)
|
||||
{
|
||||
IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil;
|
||||
|
||||
if (use_render_buffer && depth_stencil_impl->current_renderbuffer)
|
||||
{
|
||||
GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
|
||||
checkGLcall("glFramebufferRenderbufferEXT()");
|
||||
} else {
|
||||
IWineD3DBaseTextureImpl *texture_impl;
|
||||
GLenum texttarget, target;
|
||||
GLint old_binding = 0;
|
||||
|
||||
texttarget = depth_stencil_impl->glDescription.target;
|
||||
if (texttarget == GL_TEXTURE_2D)
|
||||
{
|
||||
target = GL_TEXTURE_2D;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
|
||||
} else if (texttarget == GL_TEXTURE_RECTANGLE_ARB) {
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
|
||||
} else {
|
||||
target = GL_TEXTURE_CUBE_MAP_ARB;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
|
||||
}
|
||||
|
||||
IWineD3DSurface_PreLoad(depth_stencil);
|
||||
|
||||
glBindTexture(target, depth_stencil_impl->glDescription.textureName);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
|
||||
glBindTexture(target, old_binding);
|
||||
|
||||
/* Update base texture states array */
|
||||
if (SUCCEEDED(IWineD3DSurface_GetContainer(depth_stencil, &IID_IWineD3DBaseTexture, (void **)&texture_impl)))
|
||||
{
|
||||
texture_impl->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
|
||||
texture_impl->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
|
||||
if (texture_impl->baseTexture.bindCount)
|
||||
{
|
||||
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
|
||||
}
|
||||
|
||||
IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
|
||||
}
|
||||
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, texttarget,
|
||||
depth_stencil_impl->glDescription.textureName, depth_stencil_impl->glDescription.level));
|
||||
checkGLcall("glFramebufferTexture2DEXT()");
|
||||
}
|
||||
}
|
||||
|
||||
void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface)
|
||||
{
|
||||
const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
|
||||
IWineD3DBaseTextureImpl *texture_impl;
|
||||
GLenum texttarget, target;
|
||||
GLint old_binding;
|
||||
|
||||
texttarget = surface_impl->glDescription.target;
|
||||
if (texttarget == GL_TEXTURE_2D)
|
||||
{
|
||||
target = GL_TEXTURE_2D;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
|
||||
} else if (texttarget == GL_TEXTURE_RECTANGLE_ARB) {
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
|
||||
} else {
|
||||
target = GL_TEXTURE_CUBE_MAP_ARB;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
|
||||
}
|
||||
|
||||
IWineD3DSurface_PreLoad(surface);
|
||||
|
||||
glBindTexture(target, surface_impl->glDescription.textureName);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glBindTexture(target, old_binding);
|
||||
|
||||
/* Update base texture states array */
|
||||
if (SUCCEEDED(IWineD3DSurface_GetContainer(surface, &IID_IWineD3DBaseTexture, (void **)&texture_impl)))
|
||||
{
|
||||
texture_impl->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
|
||||
texture_impl->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
|
||||
if (texture_impl->baseTexture.bindCount)
|
||||
{
|
||||
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
|
||||
}
|
||||
|
||||
IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
|
||||
}
|
||||
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget,
|
||||
surface_impl->glDescription.textureName, surface_impl->glDescription.level));
|
||||
|
||||
checkGLcall("attach_surface_fbo");
|
||||
}
|
||||
|
||||
/* TODO: Handle stencil attachments */
|
||||
static void context_set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_stencil)
|
||||
{
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
||||
TRACE("Set depth stencil to %p\n", depth_stencil);
|
||||
|
||||
if (depth_stencil)
|
||||
{
|
||||
context_attach_depth_stencil_fbo(This, GL_FRAMEBUFFER_EXT, depth_stencil, TRUE);
|
||||
} else {
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
|
||||
checkGLcall("glFramebufferTexture2DEXT()");
|
||||
}
|
||||
}
|
||||
|
||||
static void context_set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target)
|
||||
{
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
||||
TRACE("Set render target %u to %p\n", idx, render_target);
|
||||
|
||||
if (render_target)
|
||||
{
|
||||
context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, idx, render_target);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void context_check_fbo_status(IWineD3DDevice *iface)
|
||||
{
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
GLenum status;
|
||||
|
||||
status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
TRACE("FBO complete\n");
|
||||
} else {
|
||||
IWineD3DSurfaceImpl *attachment;
|
||||
int i;
|
||||
FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status);
|
||||
|
||||
/* Dump the FBO attachments */
|
||||
for (i = 0; i < GL_LIMITS(buffers); ++i)
|
||||
{
|
||||
attachment = (IWineD3DSurfaceImpl *)This->activeContext->fbo_color_attachments[i];
|
||||
if (attachment)
|
||||
{
|
||||
FIXME("\tColor attachment %d: (%p) %s %ux%u\n", i, attachment, debug_d3dformat(attachment->resource.format),
|
||||
attachment->pow2Width, attachment->pow2Height);
|
||||
}
|
||||
}
|
||||
attachment = (IWineD3DSurfaceImpl *)This->activeContext->fbo_depth_attachment;
|
||||
if (attachment)
|
||||
{
|
||||
FIXME("\tDepth attachment: (%p) %s %ux%u\n", attachment, debug_d3dformat(attachment->resource.format),
|
||||
attachment->pow2Width, attachment->pow2Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL context_depth_mismatch_fbo(IWineD3DDevice *iface)
|
||||
{
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
IWineD3DSurfaceImpl *rt_impl = (IWineD3DSurfaceImpl *)This->render_targets[0];
|
||||
IWineD3DSurfaceImpl *ds_impl = (IWineD3DSurfaceImpl *)This->stencilBufferTarget;
|
||||
|
||||
if (!ds_impl) return FALSE;
|
||||
|
||||
if (ds_impl->current_renderbuffer)
|
||||
{
|
||||
return (rt_impl->pow2Width != ds_impl->current_renderbuffer->width ||
|
||||
rt_impl->pow2Height != ds_impl->current_renderbuffer->height);
|
||||
}
|
||||
|
||||
return (rt_impl->pow2Width != ds_impl->pow2Width ||
|
||||
rt_impl->pow2Height != ds_impl->pow2Height);
|
||||
}
|
||||
|
||||
void context_apply_fbo_state(IWineD3DDevice *iface)
|
||||
{
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
WineD3DContext *context = This->activeContext;
|
||||
unsigned int i;
|
||||
|
||||
if (This->render_offscreen)
|
||||
{
|
||||
context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &context->fbo);
|
||||
|
||||
/* Apply render targets */
|
||||
for (i = 0; i < GL_LIMITS(buffers); ++i)
|
||||
{
|
||||
IWineD3DSurface *render_target = This->render_targets[i];
|
||||
if (context->fbo_color_attachments[i] != render_target)
|
||||
{
|
||||
context_set_render_target_fbo(iface, i, render_target);
|
||||
context->fbo_color_attachments[i] = render_target;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply depth targets */
|
||||
if (context->fbo_depth_attachment != This->stencilBufferTarget || context_depth_mismatch_fbo(iface))
|
||||
{
|
||||
unsigned int w = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Width;
|
||||
unsigned int h = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Height;
|
||||
|
||||
if (This->stencilBufferTarget)
|
||||
{
|
||||
surface_set_compatible_renderbuffer(This->stencilBufferTarget, w, h);
|
||||
}
|
||||
context_set_depth_stencil_fbo(iface, This->stencilBufferTarget);
|
||||
context->fbo_depth_attachment = This->stencilBufferTarget;
|
||||
}
|
||||
} else {
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
}
|
||||
|
||||
context_check_fbo_status(iface);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Context_MarkStateDirty
|
||||
*
|
||||
|
@ -632,25 +894,6 @@ static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *con
|
|||
HeapFree(GetProcessHeap(), 0, oldArray);
|
||||
}
|
||||
|
||||
static void destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
for (i = 0; i < GL_LIMITS(buffers); ++i)
|
||||
{
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
|
||||
checkGLcall("glFramebufferTexture2D()");
|
||||
}
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
|
||||
checkGLcall("glFramebufferTexture2D()");
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
|
||||
checkGLcall("glDeleteFramebuffers()");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DestroyContext
|
||||
*
|
||||
|
@ -675,15 +918,15 @@ void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) {
|
|||
|
||||
if (context->fbo) {
|
||||
TRACE("Destroy FBO %d\n", context->fbo);
|
||||
destroy_fbo(This, &context->fbo);
|
||||
context_destroy_fbo(This, &context->fbo);
|
||||
}
|
||||
if (context->src_fbo) {
|
||||
TRACE("Destroy src FBO %d\n", context->src_fbo);
|
||||
destroy_fbo(This, &context->src_fbo);
|
||||
context_destroy_fbo(This, &context->src_fbo);
|
||||
}
|
||||
if (context->dst_fbo) {
|
||||
TRACE("Destroy dst FBO %d\n", context->dst_fbo);
|
||||
destroy_fbo(This, &context->dst_fbo);
|
||||
context_destroy_fbo(This, &context->dst_fbo);
|
||||
}
|
||||
|
||||
LEAVE_GL();
|
||||
|
@ -1225,7 +1468,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
|||
case CTXUSAGE_CLEAR:
|
||||
case CTXUSAGE_DRAWPRIM:
|
||||
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
|
||||
apply_fbo_state((IWineD3DDevice *)This);
|
||||
context_apply_fbo_state((IWineD3DDevice *)This);
|
||||
}
|
||||
if (context->draw_buffer_dirty) {
|
||||
apply_draw_buffer(This, target, FALSE);
|
||||
|
@ -1237,8 +1480,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
|||
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
|
||||
if (This->render_offscreen) {
|
||||
FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
|
||||
bind_fbo((IWineD3DDevice *)This, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
|
||||
attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, target);
|
||||
context_bind_fbo((IWineD3DDevice *)This, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
|
||||
context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, target);
|
||||
GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
|
||||
checkGLcall("glFramebufferRenderbufferEXT");
|
||||
} else {
|
||||
|
|
|
@ -6122,109 +6122,6 @@ static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
||||
if (!*fbo) {
|
||||
GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
|
||||
checkGLcall("glGenFramebuffersEXT()");
|
||||
TRACE("Created FBO %d\n", *fbo);
|
||||
}
|
||||
GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
}
|
||||
|
||||
/* TODO: Handle stencil attachments */
|
||||
void attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) {
|
||||
IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil;
|
||||
|
||||
if (use_render_buffer && depth_stencil_impl->current_renderbuffer) {
|
||||
GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
|
||||
checkGLcall("glFramebufferRenderbufferEXT()");
|
||||
} else {
|
||||
IWineD3DBaseTextureImpl *texture_impl;
|
||||
GLenum texttarget, target;
|
||||
GLint old_binding = 0;
|
||||
|
||||
texttarget = depth_stencil_impl->glDescription.target;
|
||||
if(texttarget == GL_TEXTURE_2D) {
|
||||
target = GL_TEXTURE_2D;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
|
||||
} else if(texttarget == GL_TEXTURE_RECTANGLE_ARB) {
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
|
||||
} else {
|
||||
target = GL_TEXTURE_CUBE_MAP_ARB;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
|
||||
}
|
||||
|
||||
IWineD3DSurface_PreLoad(depth_stencil);
|
||||
|
||||
glBindTexture(target, depth_stencil_impl->glDescription.textureName);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
|
||||
glBindTexture(target, old_binding);
|
||||
|
||||
/* Update base texture states array */
|
||||
if (SUCCEEDED(IWineD3DSurface_GetContainer(depth_stencil, &IID_IWineD3DBaseTexture, (void **)&texture_impl))) {
|
||||
texture_impl->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
|
||||
texture_impl->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
|
||||
if (texture_impl->baseTexture.bindCount) {
|
||||
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
|
||||
}
|
||||
|
||||
IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
|
||||
}
|
||||
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, texttarget,
|
||||
depth_stencil_impl->glDescription.textureName, depth_stencil_impl->glDescription.level));
|
||||
checkGLcall("glFramebufferTexture2DEXT()");
|
||||
}
|
||||
}
|
||||
|
||||
void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) {
|
||||
const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
|
||||
IWineD3DBaseTextureImpl *texture_impl;
|
||||
GLenum texttarget, target;
|
||||
GLint old_binding;
|
||||
|
||||
texttarget = surface_impl->glDescription.target;
|
||||
if(texttarget == GL_TEXTURE_2D) {
|
||||
target = GL_TEXTURE_2D;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
|
||||
} else if(texttarget == GL_TEXTURE_RECTANGLE_ARB) {
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
|
||||
} else {
|
||||
target = GL_TEXTURE_CUBE_MAP_ARB;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
|
||||
}
|
||||
|
||||
IWineD3DSurface_PreLoad(surface);
|
||||
|
||||
glBindTexture(target, surface_impl->glDescription.textureName);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glBindTexture(target, old_binding);
|
||||
|
||||
/* Update base texture states array */
|
||||
if (SUCCEEDED(IWineD3DSurface_GetContainer(surface, &IID_IWineD3DBaseTexture, (void **)&texture_impl))) {
|
||||
texture_impl->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
|
||||
texture_impl->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
|
||||
if (texture_impl->baseTexture.bindCount) {
|
||||
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
|
||||
}
|
||||
|
||||
IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
|
||||
}
|
||||
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget,
|
||||
surface_impl->glDescription.textureName, surface_impl->glDescription.level));
|
||||
|
||||
checkGLcall("attach_surface_fbo");
|
||||
}
|
||||
|
||||
static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, CONST WINED3DRECT *rect, WINED3DCOLOR color) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
|
||||
IWineD3DSwapChain *swapchain;
|
||||
|
@ -6246,8 +6143,8 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, CONS
|
|||
|
||||
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
ENTER_GL();
|
||||
bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
|
||||
attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, surface);
|
||||
context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
|
||||
context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, surface);
|
||||
GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
|
||||
checkGLcall("glFramebufferRenderbufferEXT");
|
||||
}
|
||||
|
@ -6278,7 +6175,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, CONS
|
|||
checkGLcall("glClear");
|
||||
|
||||
if (This->render_offscreen) {
|
||||
bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->fbo);
|
||||
context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->fbo);
|
||||
} else {
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
|
@ -6542,115 +6439,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: Handle stencil attachments */
|
||||
static void set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_stencil) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
||||
TRACE("Set depth stencil to %p\n", depth_stencil);
|
||||
|
||||
if (depth_stencil) {
|
||||
attach_depth_stencil_fbo(This, GL_FRAMEBUFFER_EXT, depth_stencil, TRUE);
|
||||
} else {
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
|
||||
checkGLcall("glFramebufferTexture2DEXT()");
|
||||
}
|
||||
}
|
||||
|
||||
static void set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
||||
TRACE("Set render target %u to %p\n", idx, render_target);
|
||||
|
||||
if (render_target) {
|
||||
attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, idx, render_target);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void check_fbo_status(IWineD3DDevice *iface) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
GLenum status;
|
||||
|
||||
status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
TRACE("FBO complete\n");
|
||||
} else {
|
||||
IWineD3DSurfaceImpl *attachment;
|
||||
int i;
|
||||
FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status);
|
||||
|
||||
/* Dump the FBO attachments */
|
||||
for (i = 0; i < GL_LIMITS(buffers); ++i) {
|
||||
attachment = (IWineD3DSurfaceImpl *)This->activeContext->fbo_color_attachments[i];
|
||||
if (attachment) {
|
||||
FIXME("\tColor attachment %d: (%p) %s %ux%u\n", i, attachment, debug_d3dformat(attachment->resource.format),
|
||||
attachment->pow2Width, attachment->pow2Height);
|
||||
}
|
||||
}
|
||||
attachment = (IWineD3DSurfaceImpl *)This->activeContext->fbo_depth_attachment;
|
||||
if (attachment) {
|
||||
FIXME("\tDepth attachment: (%p) %s %ux%u\n", attachment, debug_d3dformat(attachment->resource.format),
|
||||
attachment->pow2Width, attachment->pow2Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL depth_mismatch_fbo(IWineD3DDevice *iface) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
IWineD3DSurfaceImpl *rt_impl = (IWineD3DSurfaceImpl *)This->render_targets[0];
|
||||
IWineD3DSurfaceImpl *ds_impl = (IWineD3DSurfaceImpl *)This->stencilBufferTarget;
|
||||
|
||||
if (!ds_impl) return FALSE;
|
||||
|
||||
if (ds_impl->current_renderbuffer) {
|
||||
return (rt_impl->pow2Width != ds_impl->current_renderbuffer->width ||
|
||||
rt_impl->pow2Height != ds_impl->current_renderbuffer->height);
|
||||
}
|
||||
|
||||
return (rt_impl->pow2Width != ds_impl->pow2Width ||
|
||||
rt_impl->pow2Height != ds_impl->pow2Height);
|
||||
}
|
||||
|
||||
void apply_fbo_state(IWineD3DDevice *iface) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
WineD3DContext *context = This->activeContext;
|
||||
unsigned int i;
|
||||
|
||||
if (This->render_offscreen) {
|
||||
bind_fbo(iface, GL_FRAMEBUFFER_EXT, &context->fbo);
|
||||
|
||||
/* Apply render targets */
|
||||
for (i = 0; i < GL_LIMITS(buffers); ++i) {
|
||||
IWineD3DSurface *render_target = This->render_targets[i];
|
||||
if (context->fbo_color_attachments[i] != render_target) {
|
||||
set_render_target_fbo(iface, i, render_target);
|
||||
context->fbo_color_attachments[i] = render_target;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply depth targets */
|
||||
if (context->fbo_depth_attachment != This->stencilBufferTarget || depth_mismatch_fbo(iface)) {
|
||||
unsigned int w = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Width;
|
||||
unsigned int h = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Height;
|
||||
|
||||
if (This->stencilBufferTarget) {
|
||||
surface_set_compatible_renderbuffer(This->stencilBufferTarget, w, h);
|
||||
}
|
||||
set_depth_stencil_fbo(iface, This->stencilBufferTarget);
|
||||
context->fbo_depth_attachment = This->stencilBufferTarget;
|
||||
}
|
||||
} else {
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
}
|
||||
|
||||
check_fbo_status(iface);
|
||||
}
|
||||
|
||||
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
|
||||
IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
@ -6709,8 +6497,8 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
|
|||
} else {
|
||||
TRACE("Source surface %p is offscreen\n", src_surface);
|
||||
ENTER_GL();
|
||||
bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->activeContext->src_fbo);
|
||||
attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
|
||||
context_bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->activeContext->src_fbo);
|
||||
context_attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
checkGLcall("glReadBuffer()");
|
||||
GL_EXTCALL(glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
|
||||
|
@ -6757,8 +6545,8 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
|
|||
}
|
||||
|
||||
ENTER_GL();
|
||||
bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
|
||||
attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
|
||||
context_bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
|
||||
context_attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
checkGLcall("glDrawBuffer()");
|
||||
GL_EXTCALL(glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
|
||||
|
@ -6780,7 +6568,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
|
|||
IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE);
|
||||
|
||||
if (This->render_offscreen) {
|
||||
bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->fbo);
|
||||
context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->fbo);
|
||||
} else {
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
|
|
|
@ -3995,17 +3995,17 @@ void surface_load_ds_location(IWineD3DSurface *iface, DWORD location) {
|
|||
device->depth_blt_rb_h = This->currentDesc.Height;
|
||||
}
|
||||
|
||||
bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->dst_fbo);
|
||||
context_bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->dst_fbo);
|
||||
GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, device->depth_blt_rb));
|
||||
checkGLcall("glFramebufferRenderbufferEXT");
|
||||
attach_depth_stencil_fbo(device, GL_FRAMEBUFFER_EXT, iface, FALSE);
|
||||
context_attach_depth_stencil_fbo(device, GL_FRAMEBUFFER_EXT, iface, FALSE);
|
||||
|
||||
/* Do the actual blit */
|
||||
depth_blt((IWineD3DDevice *)device, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height);
|
||||
checkGLcall("depth_blt");
|
||||
|
||||
if (device->render_offscreen) {
|
||||
bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->fbo);
|
||||
context_bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->fbo);
|
||||
} else {
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
|
|
|
@ -630,7 +630,9 @@ typedef enum ContextUsage {
|
|||
void ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage);
|
||||
WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms);
|
||||
void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
|
||||
void apply_fbo_state(IWineD3DDevice *iface);
|
||||
void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo);
|
||||
void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer);
|
||||
void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface);
|
||||
|
||||
void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
|
||||
HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
|
||||
|
@ -2431,9 +2433,6 @@ static inline BOOL use_ps(IWineD3DDeviceImpl *device) {
|
|||
|
||||
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
|
||||
IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip);
|
||||
void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo);
|
||||
void attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer);
|
||||
void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface);
|
||||
void depth_blt(IWineD3DDevice *iface, GLuint texture, GLsizei w, GLsizei h);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue