[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