Module: wine Branch: master Commit: 879d4bffeb1c978d03a9925a85d5ec06f525e6c8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=879d4bffeb1c978d03a9925a85...
Author: Józef Kucia jkucia@codeweavers.com Date: Wed Apr 20 11:42:17 2016 +0200
wined3d: Add support for rendering to 2D array textures.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wined3d/context.c | 84 +++++++++++++++++++++++++----------------- dlls/wined3d/directx.c | 6 +++ dlls/wined3d/wined3d_private.h | 5 ++- 3 files changed, 60 insertions(+), 35 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 50456b4..07ddf1c 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -118,6 +118,36 @@ static void context_attach_depth_stencil_rb(const struct wined3d_gl_info *gl_inf } }
+static void context_attach_gl_texture_fbo(struct wined3d_context *context, + GLenum fbo_target, GLenum attachment, const struct wined3d_fbo_resource *resource) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + if (!resource) + { + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment, GL_TEXTURE_2D, 0, 0); + checkGLcall("glFramebufferTexture2D()"); + } + else if (resource->target == GL_TEXTURE_2D_ARRAY) + { + if (!gl_info->fbo_ops.glFramebufferTextureLayer) + { + FIXME("OpenGL implementation doesn't support glFramebufferTextureLayer().\n"); + return; + } + + gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment, + resource->object, resource->level, resource->layer); + checkGLcall("glFramebufferTextureLayer()"); + } + else + { + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment, + resource->target, resource->object, resource->level); + checkGLcall("glFramebufferTexture2D()"); + } +} + /* Context activation is done by the caller. */ static void context_attach_depth_stencil_fbo(struct wined3d_context *context, GLenum fbo_target, const struct wined3d_fbo_resource *resource, BOOL rb_namespace, @@ -137,41 +167,24 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context, else { if (flags & WINED3D_FBO_ENTRY_FLAG_DEPTH) - { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, - resource->target, resource->object, resource->level); - checkGLcall("glFramebufferTexture2D()"); - } + context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, resource);
if (flags & WINED3D_FBO_ENTRY_FLAG_STENCIL) - { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, - resource->target, resource->object, resource->level); - checkGLcall("glFramebufferTexture2D()"); - } + context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, resource); }
if (!(flags & WINED3D_FBO_ENTRY_FLAG_DEPTH)) - { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); - } + context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, NULL);
if (!(flags & WINED3D_FBO_ENTRY_FLAG_STENCIL)) - { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); - } + context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, NULL); } else { TRACE("Attach depth stencil 0.\n");
- gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); - - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); + context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, NULL); + context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, NULL); } }
@@ -194,15 +207,12 @@ static void context_attach_surface_fbo(struct wined3d_context *context, } else { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, - resource->target, resource->object, resource->level); - checkGLcall("glFramebufferTexture2D()"); + context_attach_gl_texture_fbo(context, fbo_target, GL_COLOR_ATTACHMENT0 + idx, resource); } } else { - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_TEXTURE_2D, 0, 0); - checkGLcall("glFramebufferTexture2D()"); + context_attach_gl_texture_fbo(context, fbo_target, GL_COLOR_ATTACHMENT0 + idx, NULL); } }
@@ -353,12 +363,14 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context if (!surface) { key->objects[idx].object = 0; - key->objects[idx].level = key->objects[idx].target = 0; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; } else if (surface->current_renderbuffer) { key->objects[idx].object = surface->current_renderbuffer->id; - key->objects[idx].level = key->objects[idx].target = 0; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; key->rb_namespace |= 1 << idx; } else @@ -367,25 +379,29 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context { case WINED3D_LOCATION_TEXTURE_RGB: key->objects[idx].object = surface_get_texture_name(surface, context, FALSE); - key->objects[idx].level = surface->texture_level; key->objects[idx].target = surface->texture_target; + key->objects[idx].level = surface->texture_level; + key->objects[idx].layer = surface->texture_layer; break;
case WINED3D_LOCATION_TEXTURE_SRGB: key->objects[idx].object = surface_get_texture_name(surface, context, TRUE); - key->objects[idx].level = surface->texture_level; key->objects[idx].target = surface->texture_target; + key->objects[idx].level = surface->texture_level; + key->objects[idx].layer = surface->texture_layer; break;
case WINED3D_LOCATION_RB_MULTISAMPLE: key->objects[idx].object = surface->container->rb_multisample; - key->objects[idx].level = key->objects[idx].target = 0; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; key->rb_namespace |= 1 << idx; break;
case WINED3D_LOCATION_RB_RESOLVED: key->objects[idx].object = surface->container->rb_resolved; - key->objects[idx].level = key->objects[idx].target = 0; + key->objects[idx].target = 0; + key->objects[idx].level = key->objects[idx].layer = 0; key->rb_namespace |= 1 << idx; break; } diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c6167b6..3f80225 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3835,6 +3835,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1D; gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2D; gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3D; + gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayer; gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbuffer; gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv; @@ -3869,6 +3870,11 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n"); wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; } + + if (gl_info->supported[ARB_GEOMETRY_SHADER4]) + { + gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayerARB; + } if (gl_info->supported[EXT_FRAMEBUFFER_BLIT]) { gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c70a6f3..f630223 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1870,6 +1870,8 @@ struct wined3d_fbo_ops GLenum textarget, GLuint texture, GLint level); void (WINE_GLAPI *glFramebufferTexture3D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); + void (WINE_GLAPI *glFramebufferTextureLayer)(GLenum target, GLenum attachment, + GLuint texture, GLint level, GLint layer); void (WINE_GLAPI *glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); void (WINE_GLAPI *glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, @@ -2626,7 +2628,8 @@ struct wined3d_renderbuffer_entry struct wined3d_fbo_resource { GLuint object; - GLuint level, target; + GLenum target; + GLuint level, layer; };
#define WINED3D_FBO_ENTRY_FLAG_ATTACHED 0x1