[PATCH 2/5] wined3d: Store sub-resource dimensions in a separate wined3d_sub_resource structure.

Zebediah Figura z.figura12 at gmail.com
Wed Jun 23 16:38:48 CDT 2021


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
I don't know if there's an advantage to caching these, although it seems
plausible, but mostly this is just for ease of access.

 dlls/wined3d/buffer.c          | 13 +++++++++++++
 dlls/wined3d/device.c          | 32 +++++++-------------------------
 dlls/wined3d/texture.c         | 19 +++++++++++++++++++
 dlls/wined3d/wined3d_private.h | 16 ++++++++++++++++
 4 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 7b8c8904961..33f2bf7994b 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1080,6 +1080,14 @@ static void wined3d_buffer_init_data(struct wined3d_buffer *buffer,
     }
 }
 
+static struct wined3d_sub_resource *buffer_resource_get_sub_resource(struct wined3d_resource *resource,
+        unsigned int sub_resource_idx)
+{
+    if (!sub_resource_idx)
+        return &buffer_from_resource(resource)->sub_resource;
+    return NULL;
+}
+
 static ULONG buffer_resource_incref(struct wined3d_resource *resource)
 {
     return wined3d_buffer_incref(buffer_from_resource(resource));
@@ -1101,6 +1109,7 @@ static void buffer_resource_preload(struct wined3d_resource *resource)
 
 static const struct wined3d_resource_ops buffer_resource_ops =
 {
+    buffer_resource_get_sub_resource,
     buffer_resource_incref,
     buffer_resource_decref,
     buffer_resource_preload,
@@ -1209,6 +1218,10 @@ static HRESULT wined3d_buffer_init(struct wined3d_buffer *buffer, struct wined3d
     }
     buffer->maps_size = 1;
 
+    buffer->sub_resource.width = buffer->resource.size;
+    buffer->sub_resource.height = 1;
+    buffer->sub_resource.depth = 1;
+
     if (data)
         wined3d_buffer_init_data(buffer, device, data);
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a11f137729f..fa035af2e13 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4649,6 +4649,7 @@ void CDECL wined3d_device_context_update_sub_resource(struct wined3d_device_cont
         struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box,
         const void *data, unsigned int row_pitch, unsigned int depth_pitch, unsigned int flags)
 {
+    struct wined3d_sub_resource *sub_resource;
     unsigned int width, height, depth;
     struct wined3d_box b;
 
@@ -4664,34 +4665,15 @@ void CDECL wined3d_device_context_update_sub_resource(struct wined3d_device_cont
         return;
     }
 
-    if (resource->type == WINED3D_RTYPE_BUFFER)
+    if (!(sub_resource = wined3d_resource_get_sub_resource(resource, sub_resource_idx)))
     {
-        if (sub_resource_idx > 0)
-        {
-            WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
-            return;
-        }
-
-        width = resource->size;
-        height = 1;
-        depth = 1;
+        WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
+        return;
     }
-    else
-    {
-        struct wined3d_texture *texture = texture_from_resource(resource);
-        unsigned int level;
 
-        if (sub_resource_idx >= texture->level_count * texture->layer_count)
-        {
-            WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
-            return;
-        }
-
-        level = sub_resource_idx % texture->level_count;
-        width = wined3d_texture_get_level_width(texture, level);
-        height = wined3d_texture_get_level_height(texture, level);
-        depth = wined3d_texture_get_level_depth(texture, level);
-    }
+    width = sub_resource->width;
+    height = sub_resource->height;
+    depth = sub_resource->depth;
 
     if (!box)
     {
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index ad34e44b406..62788419ede 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -2006,6 +2006,10 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, unsig
         sub_resource->size = texture->slice_pitch;
         sub_resource->locations = WINED3D_LOCATION_DISCARDED;
 
+        sub_resource->sub_resource.width = wined3d_texture_get_level_width(texture, level);
+        sub_resource->sub_resource.height = wined3d_texture_get_level_height(texture, level);
+        sub_resource->sub_resource.depth = wined3d_texture_get_level_depth(texture, level);
+
         wined3d_texture_get_map_pitch(texture, level, &sub_resource->map_row_pitch, &sub_resource->map_slice_pitch);
 
         if (texture->texture_ops == &texture_gl_ops)
@@ -3447,6 +3451,16 @@ struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_re
     return texture_from_resource(resource);
 }
 
+static struct wined3d_sub_resource *texture_resource_get_sub_resource(struct wined3d_resource *resource,
+        unsigned int sub_resource_idx)
+{
+    struct wined3d_texture *texture = texture_from_resource(resource);
+
+    if (sub_resource_idx < texture->level_count * texture->layer_count)
+        return &texture->sub_resources[sub_resource_idx].sub_resource;
+    return NULL;
+}
+
 static ULONG texture_resource_incref(struct wined3d_resource *resource)
 {
     return wined3d_texture_incref(texture_from_resource(resource));
@@ -3697,6 +3711,7 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso
 
 static const struct wined3d_resource_ops texture_resource_ops =
 {
+    texture_resource_get_sub_resource,
     texture_resource_incref,
     texture_resource_decref,
     texture_resource_preload,
@@ -3970,6 +3985,10 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
             wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM);
         }
 
+        sub_resource->sub_resource.width = wined3d_texture_get_level_width(texture, level);
+        sub_resource->sub_resource.height = wined3d_texture_get_level_height(texture, level);
+        sub_resource->sub_resource.depth = wined3d_texture_get_level_depth(texture, level);
+
         wined3d_texture_get_map_pitch(texture, level, &sub_resource->map_row_pitch, &sub_resource->map_slice_pitch);
 
         if (FAILED(hr = device_parent->ops->texture_sub_resource_created(device_parent,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1e6a315e72c..dd73b564452 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4044,8 +4044,14 @@ static inline BOOL wined3d_resource_access_is_managed(unsigned int access)
     return !(~access & (WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU));
 }
 
+struct wined3d_sub_resource
+{
+    unsigned int width, height, depth;
+};
+
 struct wined3d_resource_ops
 {
+    struct wined3d_sub_resource *(*resource_get_sub_resource)(struct wined3d_resource *resource, unsigned int sub_resource_idx);
     ULONG (*resource_incref)(struct wined3d_resource *resource);
     ULONG (*resource_decref)(struct wined3d_resource *resource);
     void (*resource_preload)(struct wined3d_resource *resource);
@@ -4110,6 +4116,12 @@ static inline void wined3d_resource_release(struct wined3d_resource *resource)
     InterlockedDecrement(&resource->access_count);
 }
 
+static inline struct wined3d_sub_resource *wined3d_resource_get_sub_resource(struct wined3d_resource *resource,
+        unsigned int sub_resource_idx)
+{
+    return resource->resource_ops->resource_get_sub_resource(resource, sub_resource_idx);
+}
+
 void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
         enum wined3d_resource_type type, const struct wined3d_format *format,
@@ -4248,6 +4260,8 @@ struct wined3d_texture
 
     struct wined3d_texture_sub_resource
     {
+        struct wined3d_sub_resource sub_resource;
+
         void *parent;
         const struct wined3d_parent_ops *parent_ops;
 
@@ -4891,6 +4905,8 @@ struct wined3d_buffer
     UINT stride;                                            /* 0 if no conversion */
     enum wined3d_buffer_conversion_type *conversion_map;    /* NULL if no conversion */
     UINT conversion_stride;                                 /* 0 if no shifted conversion */
+
+    struct wined3d_sub_resource sub_resource;
 };
 
 static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resource *resource)
-- 
2.30.2




More information about the wine-devel mailing list