Commit 879d4bff authored by Józef Kucia's avatar Józef Kucia Committed by Alexandre Julliard

wined3d: Add support for rendering to 2D array textures.

parent 8f42343c
...@@ -118,6 +118,36 @@ static void context_attach_depth_stencil_rb(const struct wined3d_gl_info *gl_inf ...@@ -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. */ /* Context activation is done by the caller. */
static void context_attach_depth_stencil_fbo(struct wined3d_context *context, static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
GLenum fbo_target, const struct wined3d_fbo_resource *resource, BOOL rb_namespace, 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, ...@@ -137,41 +167,24 @@ static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
else else
{ {
if (flags & WINED3D_FBO_ENTRY_FLAG_DEPTH) if (flags & WINED3D_FBO_ENTRY_FLAG_DEPTH)
{ context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, resource);
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT,
resource->target, resource->object, resource->level);
checkGLcall("glFramebufferTexture2D()");
}
if (flags & WINED3D_FBO_ENTRY_FLAG_STENCIL) if (flags & WINED3D_FBO_ENTRY_FLAG_STENCIL)
{ context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, resource);
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT,
resource->target, resource->object, resource->level);
checkGLcall("glFramebufferTexture2D()");
}
} }
if (!(flags & WINED3D_FBO_ENTRY_FLAG_DEPTH)) if (!(flags & WINED3D_FBO_ENTRY_FLAG_DEPTH))
{ context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, NULL);
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
checkGLcall("glFramebufferTexture2D()");
}
if (!(flags & WINED3D_FBO_ENTRY_FLAG_STENCIL)) if (!(flags & WINED3D_FBO_ENTRY_FLAG_STENCIL))
{ context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, NULL);
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
checkGLcall("glFramebufferTexture2D()");
}
} }
else else
{ {
TRACE("Attach depth stencil 0.\n"); TRACE("Attach depth stencil 0.\n");
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); context_attach_gl_texture_fbo(context, fbo_target, GL_DEPTH_ATTACHMENT, NULL);
checkGLcall("glFramebufferTexture2D()"); context_attach_gl_texture_fbo(context, fbo_target, GL_STENCIL_ATTACHMENT, NULL);
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
checkGLcall("glFramebufferTexture2D()");
} }
} }
...@@ -194,15 +207,12 @@ static void context_attach_surface_fbo(struct wined3d_context *context, ...@@ -194,15 +207,12 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
} }
else else
{ {
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, context_attach_gl_texture_fbo(context, fbo_target, GL_COLOR_ATTACHMENT0 + idx, resource);
resource->target, resource->object, resource->level);
checkGLcall("glFramebufferTexture2D()");
} }
} }
else else
{ {
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_TEXTURE_2D, 0, 0); context_attach_gl_texture_fbo(context, fbo_target, GL_COLOR_ATTACHMENT0 + idx, NULL);
checkGLcall("glFramebufferTexture2D()");
} }
} }
...@@ -353,12 +363,14 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context ...@@ -353,12 +363,14 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context
if (!surface) if (!surface)
{ {
key->objects[idx].object = 0; 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) else if (surface->current_renderbuffer)
{ {
key->objects[idx].object = surface->current_renderbuffer->id; 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; key->rb_namespace |= 1 << idx;
} }
else else
...@@ -367,25 +379,29 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context ...@@ -367,25 +379,29 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context
{ {
case WINED3D_LOCATION_TEXTURE_RGB: case WINED3D_LOCATION_TEXTURE_RGB:
key->objects[idx].object = surface_get_texture_name(surface, context, FALSE); 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].target = surface->texture_target;
key->objects[idx].level = surface->texture_level;
key->objects[idx].layer = surface->texture_layer;
break; break;
case WINED3D_LOCATION_TEXTURE_SRGB: case WINED3D_LOCATION_TEXTURE_SRGB:
key->objects[idx].object = surface_get_texture_name(surface, context, TRUE); 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].target = surface->texture_target;
key->objects[idx].level = surface->texture_level;
key->objects[idx].layer = surface->texture_layer;
break; break;
case WINED3D_LOCATION_RB_MULTISAMPLE: case WINED3D_LOCATION_RB_MULTISAMPLE:
key->objects[idx].object = surface->container->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; key->rb_namespace |= 1 << idx;
break; break;
case WINED3D_LOCATION_RB_RESOLVED: case WINED3D_LOCATION_RB_RESOLVED:
key->objects[idx].object = surface->container->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; key->rb_namespace |= 1 << idx;
break; break;
} }
......
...@@ -3835,6 +3835,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD ...@@ -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.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1D;
gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2D; 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.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.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbuffer;
gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv
= gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv; = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv;
...@@ -3869,6 +3870,11 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD ...@@ -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"); WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; 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]) if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
{ {
gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT; gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT;
......
...@@ -1870,6 +1870,8 @@ struct wined3d_fbo_ops ...@@ -1870,6 +1870,8 @@ struct wined3d_fbo_ops
GLenum textarget, GLuint texture, GLint level); GLenum textarget, GLuint texture, GLint level);
void (WINE_GLAPI *glFramebufferTexture3D)(GLenum target, GLenum attachment, void (WINE_GLAPI *glFramebufferTexture3D)(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level, GLint layer); 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, void (WINE_GLAPI *glFramebufferRenderbuffer)(GLenum target, GLenum attachment,
GLenum renderbuffertarget, GLuint renderbuffer); GLenum renderbuffertarget, GLuint renderbuffer);
void (WINE_GLAPI *glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, void (WINE_GLAPI *glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment,
...@@ -2626,7 +2628,8 @@ struct wined3d_renderbuffer_entry ...@@ -2626,7 +2628,8 @@ struct wined3d_renderbuffer_entry
struct wined3d_fbo_resource struct wined3d_fbo_resource
{ {
GLuint object; GLuint object;
GLuint level, target; GLenum target;
GLuint level, layer;
}; };
#define WINED3D_FBO_ENTRY_FLAG_ATTACHED 0x1 #define WINED3D_FBO_ENTRY_FLAG_ATTACHED 0x1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment