[PATCH 5/5] wined3d: Store render target info instead of surfaces in "blit_targets".

Józef Kucia jkucia at codeweavers.com
Wed Apr 5 08:38:07 CDT 2017


In preparation for extending render target views support.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/wined3d/context.c         | 112 ++++++++++++++++++++++++++++-------------
 dlls/wined3d/surface.c         |  21 ++++++--
 dlls/wined3d/wined3d_private.h |  12 ++++-
 3 files changed, 102 insertions(+), 43 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 2e9b38a..61c82b6 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -427,26 +427,44 @@ static inline void context_set_fbo_key_for_surface(const struct wined3d_context
 }
 
 static void context_generate_fbo_key(const struct wined3d_context *context,
-        struct wined3d_fbo_entry_key *key, struct wined3d_surface **render_targets,
+        struct wined3d_fbo_entry_key *key, struct wined3d_rendertarget_info *render_targets,
         struct wined3d_surface *depth_stencil, DWORD color_location,
         DWORD ds_location)
 {
-    UINT i;
+    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)
-        context_set_fbo_key_for_surface(context, key, i + 1, render_targets[i], color_location);
+    {
+        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);
+    }
 }
 
 static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
-        struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil,
+        struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
         DWORD color_location, DWORD ds_location)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned int object_count = gl_info->limits.buffers + 1;
     struct fbo_entry *entry;
-    UINT object_count = gl_info->limits.buffers + 1;
 
     entry = HeapAlloc(GetProcessHeap(), 0,
             FIELD_OFFSET(struct fbo_entry, key.objects[object_count]));
@@ -470,7 +488,7 @@ static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *
 
 /* Context activation is done by the caller. */
 static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target,
-        struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil,
+        struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
         DWORD color_location, DWORD ds_location, struct fbo_entry *entry)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -504,24 +522,25 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb
 
 /* Context activation is done by the caller. */
 static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target,
-        struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil,
+        struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
         DWORD color_location, DWORD ds_location)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int object_count = gl_info->limits.buffers + 1;
     struct wined3d_texture *rt_texture, *ds_texture;
     struct fbo_entry *entry;
-    unsigned int i;
+    unsigned int i, level;
 
-    if (depth_stencil && render_targets[0])
+    if (depth_stencil && render_targets[0].resource && render_targets[0].resource->type != WINED3D_RTYPE_BUFFER)
     {
-        rt_texture = render_targets[0]->container;
+        rt_texture = wined3d_texture_from_resource(render_targets[0].resource);
+        level = render_targets[0].sub_resource_idx % rt_texture->level_count;
         ds_texture = depth_stencil->container;
 
         if (wined3d_texture_get_level_width(ds_texture, depth_stencil->texture_level)
-                < wined3d_texture_get_level_width(rt_texture, render_targets[0]->texture_level)
+                < wined3d_texture_get_level_width(rt_texture, level)
                 || wined3d_texture_get_level_height(ds_texture, depth_stencil->texture_level)
-                < wined3d_texture_get_level_height(rt_texture, render_targets[0]->texture_level))
+                < wined3d_texture_get_level_height(rt_texture, level))
         {
             WARN("Depth stencil is smaller than the primary color buffer, disabling.\n");
             depth_stencil = NULL;
@@ -535,7 +554,7 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
             depth_stencil = NULL;
         }
         else
-            surface_set_compatible_renderbuffer(depth_stencil, render_targets[0]);
+            surface_set_compatible_renderbuffer(depth_stencil, &render_targets[0]);
     }
 
     context_generate_fbo_key(context, context->fbo_key, render_targets, depth_stencil, color_location,
@@ -546,16 +565,31 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context,
         TRACE("Dumping FBO attachments:\n");
         for (i = 0; i < gl_info->limits.buffers; ++i)
         {
-            if (render_targets[i])
+            struct wined3d_resource *resource;
+            if ((resource = render_targets[i].resource))
             {
-                rt_texture = render_targets[i]->container;
-                TRACE("    Color attachment %u: %p format %s, %s %u, %ux%u, %u samples.\n",
-                        i, render_targets[i], debug_d3dformat(rt_texture->resource.format->id),
-                        context->fbo_key->rb_namespace & (1 << (i + 1)) ? "renderbuffer" : "texture",
-                        context->fbo_key->objects[i + 1].object,
-                        wined3d_texture_get_level_pow2_width(rt_texture, render_targets[i]->texture_level),
-                        wined3d_texture_get_level_pow2_height(rt_texture, render_targets[i]->texture_level),
-                        rt_texture->resource.multisample_type);
+                unsigned int width, height;
+                const char *resource_type;
+
+                if (resource->type == WINED3D_RTYPE_BUFFER)
+                {
+                    width = resource->size;
+                    height = 1;
+                    resource_type = "buffer";
+                }
+                else
+                {
+                    rt_texture = wined3d_texture_from_resource(resource);
+                    level = render_targets[i].sub_resource_idx % rt_texture->level_count;
+                    width = wined3d_texture_get_level_pow2_width(rt_texture, level);
+                    height = wined3d_texture_get_level_pow2_height(rt_texture, level);
+                    resource_type = "texture";
+                }
+
+                TRACE("    Color attachment %u: %p, %u format %s, %s %u, %ux%u, %u samples.\n",
+                        i, resource, render_targets[i].sub_resource_idx, debug_d3dformat(resource->format->id),
+                        context->fbo_key->rb_namespace & (1 << (i + 1)) ? "renderbuffer" : resource_type,
+                        context->fbo_key->objects[i + 1].object, width, height, resource->multisample_type);
             }
         }
         if (depth_stencil)
@@ -642,7 +676,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ
 
 /* Context activation is done by the caller. */
 static void context_apply_fbo_state(struct wined3d_context *context, GLenum target,
-        struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil,
+        struct wined3d_rendertarget_info *render_targets, struct wined3d_surface *depth_stencil,
         DWORD color_location, DWORD ds_location)
 {
     struct fbo_entry *entry, *entry2;
@@ -675,11 +709,12 @@ static void context_apply_fbo_state(struct wined3d_context *context, GLenum targ
 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
         struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location)
 {
-    UINT clear_size = (context->gl_info->limits.buffers - 1) * sizeof(*context->blit_targets);
-
-    context->blit_targets[0] = render_target;
-    if (clear_size)
-        memset(&context->blit_targets[1], 0, clear_size);
+    memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof(*context->blit_targets));
+    if (render_target)
+    {
+        context->blit_targets[0].resource = &render_target->container->resource;
+        context->blit_targets[0].sub_resource_idx = surface_get_sub_resource_idx(render_target);
+    }
     context_apply_fbo_state(context, target, context->blit_targets, depth_stencil, location, location);
 }
 
@@ -2664,7 +2699,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
     struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     DWORD rt_mask = 0, *cur_mask;
-    UINT i;
+    unsigned int i;
 
     if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb
             || rt_count != gl_info->limits.buffers)
@@ -2678,17 +2713,17 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
 
             if (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))
             {
+                memset(context->blit_targets, 0, gl_info->limits.buffers * sizeof(context->blit_targets));
                 for (i = 0; i < rt_count; ++i)
                 {
-                    context->blit_targets[i] = wined3d_rendertarget_view_get_surface(rts[i]);
+                    if (rts[i])
+                    {
+                        context->blit_targets[i].resource = rts[i]->resource;
+                        context->blit_targets[i].sub_resource_idx = rts[i]->sub_resource_idx;
+                    }
                     if (rts[i] && rts[i]->format->id != WINED3DFMT_NULL)
                         rt_mask |= (1u << i);
                 }
-                while (i < gl_info->limits.buffers)
-                {
-                    context->blit_targets[i] = NULL;
-                    ++i;
-                }
                 context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
                         wined3d_rendertarget_view_get_surface(dsv),
                         rt_count ? rts[0]->resource->draw_binding : 0,
@@ -2811,9 +2846,14 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat
         {
             unsigned int i;
 
+            memset(context->blit_targets, 0, context->gl_info->limits.buffers * sizeof (*context->blit_targets));
             for (i = 0; i < context->gl_info->limits.buffers; ++i)
             {
-                context->blit_targets[i] = wined3d_rendertarget_view_get_surface(fb->render_targets[i]);
+                if (fb->render_targets[i])
+                {
+                    context->blit_targets[i].resource = fb->render_targets[i]->resource;
+                    context->blit_targets[i].sub_resource_idx = fb->render_targets[i]->sub_resource_idx;
+                }
             }
             context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets,
                     wined3d_rendertarget_view_get_surface(fb->depth_stencil),
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index cc5444b..8a1ad4e 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -980,18 +980,29 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
  * render target dimensions. With FBOs, the dimensions have to be an exact match. */
 /* TODO: We should synchronize the renderbuffer's content with the texture's content. */
 /* Context activation is done by the caller. */
-void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_surface *rt)
+void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_rendertarget_info *rt)
 {
     const struct wined3d_gl_info *gl_info = &surface->container->resource.device->adapter->gl_info;
     struct wined3d_renderbuffer_entry *entry;
-    GLuint renderbuffer = 0;
     unsigned int src_width, src_height;
     unsigned int width, height;
+    GLuint renderbuffer = 0;
 
-    if (rt && rt->container->resource.format->id != WINED3DFMT_NULL)
+    if (rt && rt->resource->format->id != WINED3DFMT_NULL)
     {
-        width = wined3d_texture_get_level_pow2_width(rt->container, rt->texture_level);
-        height = wined3d_texture_get_level_pow2_height(rt->container, rt->texture_level);
+        struct wined3d_texture *texture;
+        unsigned int level;
+
+        if (rt->resource->type == WINED3D_RTYPE_BUFFER)
+        {
+            FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type));
+            return;
+        }
+        texture = wined3d_texture_from_resource(rt->resource);
+        level = rt->sub_resource_idx % texture->level_count;
+
+        width = wined3d_texture_get_level_pow2_width(texture, level);
+        height = wined3d_texture_get_level_pow2_height(texture, level);
     }
     else
     {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 91cabbd..8394509 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1632,6 +1632,12 @@ struct wined3d_timestamp_query
 void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN;
 void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN;
 
+struct wined3d_rendertarget_info
+{
+    struct wined3d_resource *resource;
+    unsigned int sub_resource_idx;
+};
+
 #define MAX_GL_FRAGMENT_SAMPLERS 32
 
 struct wined3d_context
@@ -1728,7 +1734,7 @@ struct wined3d_context
     struct fbo_entry        *current_fbo;
     GLuint                  fbo_read_binding;
     GLuint                  fbo_draw_binding;
-    struct wined3d_surface **blit_targets;
+    struct wined3d_rendertarget_info *blit_targets;
     struct wined3d_fbo_entry_key *fbo_key;
     GLenum *draw_buffers;
     DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */
@@ -1858,6 +1864,8 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
         const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
         const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
 
+struct wined3d_surface;
+
 enum wined3d_blit_op
 {
     WINED3D_BLIT_OP_COLOR_BLIT,
@@ -3064,7 +3072,7 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb,
 BOOL surface_load_location(struct wined3d_surface *surface,
         struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
 void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
-        const struct wined3d_surface *rt) DECLSPEC_HIDDEN;
+        const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
 void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
 HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point,
         struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN;
-- 
2.10.2




More information about the wine-patches mailing list