Signed-off-by: Zebediah Figura z.figura12@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)