[PATCH 6/8] wined3d: Add basic support for rendering to 3D textures.
Józef Kucia
jkucia at codeweavers.com
Thu Apr 6 04:47:51 CDT 2017
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
dlls/wined3d/context.c | 132 +++++++++++++++++++++++------------------
dlls/wined3d/directx.c | 5 ++
dlls/wined3d/wined3d_private.h | 8 ++-
3 files changed, 83 insertions(+), 62 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index a472a1e..c74f7c0 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -126,7 +126,6 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
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)
{
@@ -138,14 +137,24 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment,
resource->object, resource->level, resource->layer);
- checkGLcall("glFramebufferTextureLayer()");
+ }
+ else if (resource->target == GL_TEXTURE_3D)
+ {
+ if (!gl_info->fbo_ops.glFramebufferTexture)
+ {
+ FIXME("OpenGL implementation doesn't support glFramebufferTexture().\n");
+ return;
+ }
+
+ gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment,
+ resource->object, resource->level);
}
else
{
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment,
resource->target, resource->object, resource->level);
- checkGLcall("glFramebufferTexture2D()");
}
+ checkGLcall("attach texture to fbo");
}
/* Context activation is done by the caller. */
@@ -374,88 +383,93 @@ static inline DWORD context_generate_rt_mask_from_resource(struct wined3d_resour
return (1u << 31) | wined3d_texture_get_gl_buffer(texture_from_resource(resource));
}
-static inline void context_set_fbo_key_for_surface(const struct wined3d_context *context,
- struct wined3d_fbo_entry_key *key, UINT idx, struct wined3d_surface *surface,
+static inline void context_set_fbo_key_for_render_target(const struct wined3d_context *context,
+ struct wined3d_fbo_entry_key *key, unsigned int idx, struct wined3d_rendertarget_info *render_target,
DWORD location)
{
- if (!surface || surface->container->resource.format->id == WINED3DFMT_NULL)
+ unsigned int sub_resource_idx = render_target->sub_resource_idx;
+ struct wined3d_resource *resource = render_target->resource;
+ struct wined3d_texture *texture;
+
+ if (!resource || resource->format->id == WINED3DFMT_NULL || resource->type == WINED3D_RTYPE_BUFFER)
{
+ if (resource && resource->type == WINED3D_RTYPE_BUFFER)
+ FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
key->objects[idx].object = 0;
key->objects[idx].target = 0;
key->objects[idx].level = key->objects[idx].layer = 0;
+ return;
}
- else if (surface->current_renderbuffer)
+
+ texture = wined3d_texture_from_resource(resource);
+ if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
{
- key->objects[idx].object = surface->current_renderbuffer->id;
- key->objects[idx].target = 0;
- key->objects[idx].level = key->objects[idx].layer = 0;
- key->rb_namespace |= 1 << idx;
+ struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
+
+ if (surface->current_renderbuffer)
+ {
+ key->objects[idx].object = surface->current_renderbuffer->id;
+ key->objects[idx].target = 0;
+ key->objects[idx].level = key->objects[idx].layer = 0;
+ key->rb_namespace |= 1 << idx;
+ return;
+ }
+
+ key->objects[idx].target = surface->texture_target;
+ key->objects[idx].level = surface->texture_level;
+ key->objects[idx].layer = surface->texture_layer;
}
else
{
- switch (location)
- {
- case WINED3D_LOCATION_TEXTURE_RGB:
- key->objects[idx].object = surface_get_texture_name(surface, context, FALSE);
- key->objects[idx].target = surface->texture_target;
- key->objects[idx].level = surface->texture_level;
- key->objects[idx].layer = surface->texture_layer;
- break;
+ key->objects[idx].target = texture->target;
+ key->objects[idx].level = sub_resource_idx % texture->level_count;
+ key->objects[idx].layer = 0;
+ }
- case WINED3D_LOCATION_TEXTURE_SRGB:
- key->objects[idx].object = surface_get_texture_name(surface, context, TRUE);
- key->objects[idx].target = surface->texture_target;
- key->objects[idx].level = surface->texture_level;
- key->objects[idx].layer = surface->texture_layer;
- break;
+ switch (location)
+ {
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ key->objects[idx].object = wined3d_texture_get_texture_name(texture, context, FALSE);
+ break;
- case WINED3D_LOCATION_RB_MULTISAMPLE:
- key->objects[idx].object = surface->container->rb_multisample;
- key->objects[idx].target = 0;
- key->objects[idx].level = key->objects[idx].layer = 0;
- key->rb_namespace |= 1 << idx;
- break;
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ key->objects[idx].object = wined3d_texture_get_texture_name(texture, context, TRUE);
+ break;
- case WINED3D_LOCATION_RB_RESOLVED:
- key->objects[idx].object = surface->container->rb_resolved;
- key->objects[idx].target = 0;
- key->objects[idx].level = key->objects[idx].layer = 0;
- key->rb_namespace |= 1 << idx;
- break;
- }
+ case WINED3D_LOCATION_RB_MULTISAMPLE:
+ key->objects[idx].object = texture->rb_multisample;
+ 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 = texture->rb_resolved;
+ key->objects[idx].target = 0;
+ key->objects[idx].level = key->objects[idx].layer = 0;
+ key->rb_namespace |= 1 << idx;
+ break;
}
}
static void context_generate_fbo_key(const struct wined3d_context *context,
struct wined3d_fbo_entry_key *key, struct wined3d_rendertarget_info *render_targets,
- struct wined3d_surface *depth_stencil, DWORD color_location,
+ struct wined3d_surface *depth_stencil_surface, DWORD color_location,
DWORD ds_location)
{
+ struct wined3d_rendertarget_info depth_stencil = {0};
unsigned int i;
key->rb_namespace = 0;
- context_set_fbo_key_for_surface(context, key, 0, depth_stencil, ds_location);
-
- for (i = 0; i < context->gl_info->limits.buffers; ++i)
+ if (depth_stencil_surface)
{
- struct wined3d_surface *surface = NULL;
- struct wined3d_resource *resource;
-
- if ((resource = render_targets[i].resource))
- {
- if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
- {
- struct wined3d_texture *texture = wined3d_texture_from_resource(resource);
- surface = texture->sub_resources[render_targets[i].sub_resource_idx].u.surface;
- }
- else
- {
- FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
- }
- }
-
- context_set_fbo_key_for_surface(context, key, i + 1, surface, color_location);
+ depth_stencil.resource = &depth_stencil_surface->container->resource;
+ depth_stencil.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil_surface);
}
+ context_set_fbo_key_for_render_target(context, key, 0, &depth_stencil, ds_location);
+
+ for (i = 0; i < context->gl_info->limits.buffers; ++i)
+ context_set_fbo_key_for_render_target(context, key, i + 1, &render_targets[i], color_location);
}
static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 3d70507..0d5a476 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2713,6 +2713,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
USE_GL_FUNC(glDeleteFramebuffers)
USE_GL_FUNC(glDeleteRenderbuffers)
USE_GL_FUNC(glFramebufferRenderbuffer)
+ USE_GL_FUNC(glFramebufferTexture)
USE_GL_FUNC(glFramebufferTexture1D)
USE_GL_FUNC(glFramebufferTexture2D)
USE_GL_FUNC(glFramebufferTexture3D)
@@ -3202,6 +3203,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
USE_GL_FUNC(glEnableVertexAttribArray) /* OpenGL 2.0 */
USE_GL_FUNC(glEndQuery) /* OpenGL 1.5 */
USE_GL_FUNC(glEndTransformFeedback) /* OpenGL 3.0 */
+ USE_GL_FUNC(glFramebufferTexture) /* OpenGL 3.2 */
USE_GL_FUNC(glGenBuffers) /* OpenGL 1.5 */
USE_GL_FUNC(glGenQueries) /* OpenGL 1.5 */
USE_GL_FUNC(glGenVertexArrays) /* OpenGL 3.0 */
@@ -3331,6 +3333,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
MAP_GL_FUNCTION(glEnablei, glEnableIndexedEXT);
MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB);
MAP_GL_FUNCTION(glEndQuery, glEndQueryARB);
+ MAP_GL_FUNCTION(glFramebufferTexture, glFramebufferTextureARB);
MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB);
MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB);
MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB);
@@ -4221,6 +4224,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
= gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv;
gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebuffer;
gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmap;
+ gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTexture;
}
else
{
@@ -4253,6 +4257,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
if (gl_info->supported[ARB_GEOMETRY_SHADER4])
{
+ gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTextureARB;
gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayerARB;
}
if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 4d7b9de..29a1d66 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2261,6 +2261,8 @@ struct wined3d_fbo_ops
void (WINE_GLAPI *glDeleteFramebuffers)(GLsizei n, const GLuint *framebuffers);
void (WINE_GLAPI *glGenFramebuffers)(GLsizei n, GLuint *framebuffers);
GLenum (WINE_GLAPI *glCheckFramebufferStatus)(GLenum target);
+ void (WINE_GLAPI *glFramebufferTexture)(GLenum target, GLenum attachment,
+ GLuint texture, GLint level);
void (WINE_GLAPI *glFramebufferTexture1D)(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
void (WINE_GLAPI *glFramebufferTexture2D)(GLenum target, GLenum attachment,
@@ -3980,11 +3982,11 @@ static inline BOOL needs_srgb_write(const struct wined3d_context *context,
&& fb->render_targets[0] && fb->render_targets[0]->format_flags & WINED3DFMT_FLAG_SRGB_WRITE;
}
-static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface,
+static inline GLuint wined3d_texture_get_texture_name(const struct wined3d_texture *texture,
const struct wined3d_context *context, BOOL srgb)
{
- return srgb && needs_separate_srgb_gl_texture(context, surface->container)
- ? surface->container->texture_srgb.name : surface->container->texture_rgb.name;
+ return srgb && needs_separate_srgb_gl_texture(context, texture)
+ ? texture->texture_srgb.name : texture->texture_rgb.name;
}
static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info, const struct wined3d_format *format)
--
2.10.2
More information about the wine-patches
mailing list