Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2021
- 83 participants
- 2620 messages
[PATCH v2 6/6] wined3d: Try to allocate new Vulkan BOs from the client thread for DISCARD maps.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v2: Actually move location management to wined3d_buffer_update_sub_resource().
dlls/wined3d/adapter_gl.c | 13 +++++++++
dlls/wined3d/adapter_vk.c | 50 ++++++++++++++++++++++++++++++++++
dlls/wined3d/buffer.c | 37 +++++++++++++++++++++++--
dlls/wined3d/cs.c | 13 ++++++++-
dlls/wined3d/directx.c | 12 ++++++++
dlls/wined3d/wined3d_private.h | 11 ++++++++
6 files changed, 133 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 7ec30cb4356..85b40b19896 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4606,6 +4606,17 @@ static void adapter_gl_flush_bo_address(struct wined3d_context *context,
wined3d_context_gl_flush_bo_address(wined3d_context_gl(context), data, size);
}
+static bool adapter_gl_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, struct wined3d_bo_address *addr)
+{
+ return false;
+}
+
+static void adapter_gl_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ wined3d_context_gl_destroy_bo(wined3d_context_gl(context), wined3d_bo_gl(bo));
+}
+
static HRESULT adapter_gl_create_swapchain(struct wined3d_device *device,
struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -5059,6 +5070,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
.adapter_unmap_bo_address = adapter_gl_unmap_bo_address,
.adapter_copy_bo_address = adapter_gl_copy_bo_address,
.adapter_flush_bo_address = adapter_gl_flush_bo_address,
+ .adapter_alloc_bo = adapter_gl_alloc_bo,
+ .adapter_destroy_bo = adapter_gl_destroy_bo,
.adapter_create_swapchain = adapter_gl_create_swapchain,
.adapter_destroy_swapchain = adapter_gl_destroy_swapchain,
.adapter_create_buffer = adapter_gl_create_buffer,
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 62a9a342e9b..e83f0a012d6 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -23,6 +23,7 @@
#include "wine/vulkan_driver.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
static const struct wined3d_state_entry_template misc_state_template_vk[] =
{
@@ -1216,6 +1217,53 @@ static void adapter_vk_flush_bo_address(struct wined3d_context *context,
flush_bo_range(context_vk, bo, (uintptr_t)data->addr, size);
}
+static bool adapter_vk_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, struct wined3d_bo_address *addr)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(device);
+ struct wined3d_context_vk *context_vk = &device_vk->context_vk;
+
+ wined3d_not_from_cs(device->cs);
+ assert(device->context_count);
+
+ if (resource->type == WINED3D_RTYPE_BUFFER)
+ {
+ struct wined3d_bo_vk *bo_vk;
+
+ if (!(bo_vk = heap_alloc(sizeof(*bo_vk))))
+ return false;
+
+ if (!(wined3d_context_vk_create_bo(context_vk, resource->size,
+ vk_buffer_usage_from_bind_flags(resource->bind_flags),
+ vk_memory_type_from_access_flags(resource->access, resource->usage), bo_vk)))
+ {
+ WARN("Failed to create Vulkan buffer.\n");
+ heap_free(bo_vk);
+ return false;
+ }
+
+ if (!bo_vk->b.map_ptr)
+ {
+ WARN_(d3d_perf)("BO %p (chunk %p, slab %p) is not persistently mapped.\n",
+ bo_vk, bo_vk->memory ? bo_vk->memory->chunk : NULL, bo_vk->slab);
+
+ if (!wined3d_bo_vk_map(bo_vk, context_vk))
+ ERR("Failed to map bo.\n");
+ }
+
+ addr->buffer_object = (uintptr_t)bo_vk;
+ addr->addr = NULL;
+ return true;
+ }
+
+ return false;
+}
+
+static void adapter_vk_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ wined3d_context_vk_destroy_bo(wined3d_context_vk(context), wined3d_bo_vk(bo));
+}
+
static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device,
struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -1868,6 +1916,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
.adapter_unmap_bo_address = adapter_vk_unmap_bo_address,
.adapter_copy_bo_address = adapter_vk_copy_bo_address,
.adapter_flush_bo_address = adapter_vk_flush_bo_address,
+ .adapter_alloc_bo = adapter_vk_alloc_bo,
+ .adapter_destroy_bo = adapter_vk_destroy_bo,
.adapter_create_swapchain = adapter_vk_create_swapchain,
.adapter_destroy_swapchain = adapter_vk_destroy_swapchain,
.adapter_create_buffer = adapter_vk_create_buffer,
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index fca8ab707f2..d5840a488b5 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1069,6 +1069,32 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou
return WINED3D_OK;
}
+static void wined3d_buffer_set_bo(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ struct wined3d_bo *prev_bo = buffer->buffer_object;
+
+ TRACE("buffer %p, context %p, bo %p.\n", buffer, context, bo);
+
+ if (prev_bo)
+ {
+ struct wined3d_bo_user *bo_user;
+
+ LIST_FOR_EACH_ENTRY(bo_user, &prev_bo->users, struct wined3d_bo_user, entry)
+ bo_user->valid = false;
+ assert(list_empty(&bo->users));
+ list_move_head(&bo->users, &prev_bo->users);
+
+ wined3d_context_destroy_bo(context, prev_bo);
+ heap_free(prev_bo);
+ }
+ else
+ {
+ list_add_head(&bo->users, &buffer->bo_user.entry);
+ }
+
+ buffer->buffer_object = bo;
+}
+
void wined3d_buffer_copy_bo_address(struct wined3d_buffer *dst_buffer, struct wined3d_context *context,
unsigned int dst_offset, const struct wined3d_const_bo_address *src_addr, unsigned int size)
{
@@ -1104,6 +1130,13 @@ void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_off
void wined3d_buffer_update_sub_resource(struct wined3d_buffer *buffer, struct wined3d_context *context,
const struct upload_bo *upload_bo, unsigned int offset, unsigned int size)
{
+ if (upload_bo->flags & UPLOAD_BO_RENAME_ON_UNMAP)
+ {
+ wined3d_buffer_set_bo(buffer, context, (struct wined3d_bo *)upload_bo->addr.buffer_object);
+ wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER);
+ wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER);
+ }
+
if (upload_bo->addr.buffer_object && upload_bo->addr.buffer_object == (uintptr_t)buffer->buffer_object)
wined3d_context_flush_bo_address(context, &upload_bo->addr, size);
else
@@ -1418,7 +1451,7 @@ HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined
return wined3d_buffer_init(&buffer_gl->b, device, desc, data, parent, parent_ops, &wined3d_buffer_gl_ops);
}
-static VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags)
+VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags)
{
VkBufferUsageFlags usage;
@@ -1442,7 +1475,7 @@ static VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags)
return usage;
}
-static VkMemoryPropertyFlags vk_memory_type_from_access_flags(uint32_t access, uint32_t usage)
+VkMemoryPropertyFlags vk_memory_type_from_access_flags(uint32_t access, uint32_t usage)
{
VkMemoryPropertyFlags memory_type = 0;
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 1d909e0c706..262123b5d90 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -3116,12 +3116,20 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str
{
/* Limit NOOVERWRITE maps to buffers for now; there are too many ways that
* a texture can be invalidated to even count. */
- if (wined3d_map_persistent() && resource->type == WINED3D_RTYPE_BUFFER && (flags & WINED3D_MAP_NOOVERWRITE))
+ if (wined3d_map_persistent() && resource->type == WINED3D_RTYPE_BUFFER
+ && (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
{
struct wined3d_client_resource *client = &resource->client;
+ struct wined3d_device *device = context->device;
const struct wined3d_bo *bo;
uint8_t *map_ptr;
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ if (!device->adapter->adapter_ops->adapter_alloc_bo(device, resource, sub_resource_idx, &client->addr))
+ return false;
+ }
+
bo = (const struct wined3d_bo *)client->addr.buffer_object;
map_ptr = bo ? bo->map_ptr : NULL;
map_ptr += (uintptr_t)client->addr.addr;
@@ -3145,6 +3153,9 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str
}
map_desc->data = resource_offset_map_pointer(resource, sub_resource_idx, map_ptr, box);
+ if (flags & WINED3D_MAP_DISCARD)
+ client->mapped_upload.flags |= UPLOAD_BO_UPLOAD_ON_UNMAP | UPLOAD_BO_RENAME_ON_UNMAP;
+
client->mapped_box = *box;
TRACE("Returning bo %s, flags %#x.\n", debug_const_bo_address(&client->mapped_upload.addr),
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index c265bdc8c95..06387452b89 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2805,6 +2805,16 @@ static void adapter_no3d_flush_bo_address(struct wined3d_context *context,
{
}
+static bool adapter_no3d_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, struct wined3d_bo_address *addr)
+{
+ return false;
+}
+
+static void adapter_no3d_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
+{
+}
+
static HRESULT adapter_no3d_create_swapchain(struct wined3d_device *device,
struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -3075,6 +3085,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
.adapter_unmap_bo_address = adapter_no3d_unmap_bo_address,
.adapter_copy_bo_address = adapter_no3d_copy_bo_address,
.adapter_flush_bo_address = adapter_no3d_flush_bo_address,
+ .adapter_alloc_bo = adapter_no3d_alloc_bo,
+ .adapter_destroy_bo = adapter_no3d_destroy_bo,
.adapter_create_swapchain = adapter_no3d_create_swapchain,
.adapter_destroy_swapchain = adapter_no3d_destroy_swapchain,
.adapter_create_buffer = adapter_no3d_create_buffer,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index fc950cda3c3..0c5f7dda228 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -331,6 +331,8 @@ VkPipelineStageFlags vk_pipeline_stage_mask_from_bind_flags(uint32_t bind_flags)
VkShaderStageFlagBits vk_shader_stage_from_wined3d(enum wined3d_shader_type shader_type) DECLSPEC_HIDDEN;
VkAccessFlags vk_access_mask_from_buffer_usage(VkBufferUsageFlags usage) DECLSPEC_HIDDEN;
VkPipelineStageFlags vk_pipeline_stage_mask_from_buffer_usage(VkBufferUsageFlags usage) DECLSPEC_HIDDEN;
+VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags) DECLSPEC_HIDDEN;
+VkMemoryPropertyFlags vk_memory_type_from_access_flags(uint32_t access, uint32_t usage) DECLSPEC_HIDDEN;
static inline enum wined3d_cmp_func wined3d_sanitize_cmp_func(enum wined3d_cmp_func func)
{
@@ -3353,6 +3355,7 @@ bool wined3d_driver_info_init(struct wined3d_driver_info *driver_info,
UINT64 vram_bytes, UINT64 sysmem_bytes) DECLSPEC_HIDDEN;
#define UPLOAD_BO_UPLOAD_ON_UNMAP 0x1
+#define UPLOAD_BO_RENAME_ON_UNMAP 0x2
struct upload_bo
{
@@ -3385,6 +3388,9 @@ struct wined3d_adapter_ops
const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size);
void (*adapter_flush_bo_address)(struct wined3d_context *context,
const struct wined3d_const_bo_address *data, size_t size);
+ bool (*adapter_alloc_bo)(struct wined3d_device *device, struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, struct wined3d_bo_address *addr);
+ void (*adapter_destroy_bo)(struct wined3d_context *context, struct wined3d_bo *bo);
HRESULT (*adapter_create_swapchain)(struct wined3d_device *device,
struct wined3d_swapchain_desc *desc,
struct wined3d_swapchain_state_parent *state_parent, void *parent,
@@ -6307,6 +6313,11 @@ static inline void wined3d_context_flush_bo_address(struct wined3d_context *cont
context->device->adapter->adapter_ops->adapter_flush_bo_address(context, data, size);
}
+static inline void wined3d_context_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ context->device->adapter->adapter_ops->adapter_destroy_bo(context, bo);
+}
+
static inline void wined3d_context_vk_reference_bo(const struct wined3d_context_vk *context_vk,
struct wined3d_bo_vk *bo)
{
--
2.33.0
Nov. 9, 2021
[PATCH v2 5/6] wined3d: Introduce a wined3d_buffer_update_sub_resource() helper.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v2: No changes.
dlls/wined3d/buffer.c | 9 +++++++++
dlls/wined3d/cs.c | 9 ++-------
dlls/wined3d/wined3d_private.h | 2 ++
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 0634dd93e2d..fca8ab707f2 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1101,6 +1101,15 @@ void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_off
context_release(context);
}
+void wined3d_buffer_update_sub_resource(struct wined3d_buffer *buffer, struct wined3d_context *context,
+ const struct upload_bo *upload_bo, unsigned int offset, unsigned int size)
+{
+ if (upload_bo->addr.buffer_object && upload_bo->addr.buffer_object == (uintptr_t)buffer->buffer_object)
+ wined3d_context_flush_bo_address(context, &upload_bo->addr, size);
+ else
+ wined3d_buffer_copy_bo_address(buffer, context, offset, &upload_bo->addr, size);
+}
+
static void wined3d_buffer_init_data(struct wined3d_buffer *buffer,
struct wined3d_device *device, const struct wined3d_sub_resource_data *data)
{
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 3143865c469..1d909e0c706 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -2744,13 +2744,8 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
if (resource->type == WINED3D_RTYPE_BUFFER)
{
- struct wined3d_buffer *buffer = buffer_from_resource(resource);
- size_t size = box->right - box->left;
-
- if (op->bo.addr.buffer_object && op->bo.addr.buffer_object == (uintptr_t)buffer->buffer_object)
- wined3d_context_flush_bo_address(context, &op->bo.addr, size);
- else
- wined3d_buffer_copy_bo_address(buffer, context, box->left, &op->bo.addr, size);
+ wined3d_buffer_update_sub_resource(buffer_from_resource(resource),
+ context, &op->bo, box->left, box->right - box->left);
goto done;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0b5165dbb5e..fc950cda3c3 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -5077,6 +5077,8 @@ BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN;
BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, unsigned int location) DECLSPEC_HIDDEN;
+void wined3d_buffer_update_sub_resource(struct wined3d_buffer *buffer, struct wined3d_context *context,
+ const struct upload_bo *upload_bo, unsigned int offset, unsigned int size) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_no3d_init(struct wined3d_buffer *buffer_no3d, struct wined3d_device *device,
const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
--
2.33.0
Nov. 9, 2021
[PATCH v2 4/6] wined3d: Allocate all OpenGL buffer BOs from heap.
by Zebediah Figura
That is, no longer allocate a wined3d_bo_gl as part of the wined3d_buffer_gl
structure.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v2: No changes.
dlls/wined3d/buffer.c | 10 ++++++++--
dlls/wined3d/wined3d_private.h | 2 --
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index a3004fcecff..0634dd93e2d 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -171,9 +171,11 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
struct wined3d_context_gl *context_gl)
{
struct wined3d_resource *resource = &buffer_gl->b.resource;
+ struct wined3d_bo_gl *bo_gl;
if (!buffer_gl->b.buffer_object)
return;
+ bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
if (context_gl->c.transform_feedback_active && (resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT)
&& wined3d_context_is_graphics_state_dirty(&context_gl->c, STATE_STREAM_OUTPUT))
@@ -191,7 +193,8 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
buffer_gl->b.bo_user.valid = false;
list_remove(&buffer_gl->b.bo_user.entry);
- wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_destroy_bo(context_gl, bo_gl);
+ heap_free(bo_gl);
buffer_gl->b.buffer_object = NULL;
}
@@ -210,6 +213,9 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
TRACE("Creating an OpenGL buffer object for wined3d buffer %p with usage %s.\n",
buffer_gl, debug_d3dusage(buffer_gl->b.resource.usage));
+ if (!(bo = heap_alloc(sizeof(*bo))))
+ return FALSE;
+
size = buffer_gl->b.resource.size;
binding = wined3d_buffer_gl_binding_from_bind_flags(gl_info, buffer_gl->b.resource.bind_flags);
if (buffer_gl->b.resource.usage & WINED3DUSAGE_DYNAMIC)
@@ -218,12 +224,12 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
coherent = false;
}
gl_storage_flags = wined3d_resource_gl_storage_flags(&buffer_gl->b.resource);
- bo = &buffer_gl->bo;
if (!wined3d_context_gl_create_bo(context_gl, size, binding, usage, coherent, gl_storage_flags, bo))
{
ERR("Failed to create OpenGL buffer object.\n");
buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO;
buffer_clear_dirty_areas(&buffer_gl->b);
+ heap_free(bo);
return FALSE;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e04f2682c88..0b5165dbb5e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -5085,8 +5085,6 @@ HRESULT wined3d_buffer_no3d_init(struct wined3d_buffer *buffer_no3d, struct wine
struct wined3d_buffer_gl
{
struct wined3d_buffer b;
-
- struct wined3d_bo_gl bo;
};
static inline struct wined3d_buffer_gl *wined3d_buffer_gl(struct wined3d_buffer *buffer)
--
2.33.0
Nov. 9, 2021
[PATCH v2 3/6] wined3d: Avoid accessing the "bo" member of struct wined3d_buffer_gl.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v2: Remove a redundant cast, avoid calling wined3d_bo_gl(NULL).
dlls/wined3d/buffer.c | 14 +++++++++-----
dlls/wined3d/context_gl.c | 22 ++++++++++++----------
dlls/wined3d/state.c | 21 +++++++++++++++++----
dlls/wined3d/view.c | 22 +++++++++++++++-------
dlls/wined3d/wined3d_private.h | 11 +++++++++++
5 files changed, 64 insertions(+), 26 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index be4d095eba0..a3004fcecff 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -133,7 +133,9 @@ void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD loc
/* Context activation is done by the caller. */
static void wined3d_buffer_gl_bind(struct wined3d_buffer_gl *buffer_gl, struct wined3d_context_gl *context_gl)
{
- wined3d_context_gl_bind_bo(context_gl, buffer_gl->bo.binding, buffer_gl->bo.id);
+ const struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
+
+ wined3d_context_gl_bind_bo(context_gl, bo_gl->binding, bo_gl->id);
}
static GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info, uint32_t bind_flags)
@@ -225,7 +227,7 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
return FALSE;
}
- list_add_head(&buffer_gl->bo.b.users, &buffer_gl->b.bo_user.entry);
+ list_add_head(&bo->b.users, &buffer_gl->b.bo_user.entry);
buffer_gl->b.buffer_object = &bo->b;
buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);
@@ -1324,6 +1326,7 @@ static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struc
const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges)
{
struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+ struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer->buffer_object);
struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer);
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
const struct wined3d_range *range;
@@ -1336,10 +1339,10 @@ static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struc
while (range_count--)
{
range = &ranges[range_count];
- GL_EXTCALL(glBufferSubData(buffer_gl->bo.binding,
+ GL_EXTCALL(glBufferSubData(bo_gl->binding,
range->offset, range->size, (BYTE *)data + range->offset - data_offset));
}
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_bo(context_gl, bo_gl);
checkGLcall("buffer upload");
}
@@ -1348,6 +1351,7 @@ static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, str
void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges)
{
struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+ struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer->buffer_object);
struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer);
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
const struct wined3d_range *range;
@@ -1360,7 +1364,7 @@ static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, str
while (range_count--)
{
range = &ranges[range_count];
- GL_EXTCALL(glGetBufferSubData(buffer_gl->bo.binding,
+ GL_EXTCALL(glGetBufferSubData(bo_gl->binding,
range->offset, range->size, (BYTE *)data + range->offset - data_offset));
}
checkGLcall("buffer download");
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 09c871efcd4..22e82302b9d 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -3815,7 +3815,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
buffer_gl = wined3d_buffer_gl(state->cb[i][j].buffer);
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b);
if (!buffer_gl->b.bo_user.valid)
device_invalidate_state(context_gl->c.device, STATE_CONSTANT_BUFFER(i));
}
@@ -3831,7 +3831,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
{
buffer_gl = wined3d_buffer_gl(buffer_from_resource(view->resource));
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b);
srv_gl = wined3d_shader_resource_view_gl(view);
if (!srv_gl->bo_user.valid)
@@ -3869,7 +3869,7 @@ static void context_gl_load_unordered_access_resources(struct wined3d_context_gl
buffer_gl = wined3d_buffer_gl(buffer_from_resource(view->resource));
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER);
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b);
uav_gl = wined3d_unordered_access_view_gl(view);
if (!uav_gl->bo_user.valid)
@@ -3901,7 +3901,7 @@ static void context_gl_load_stream_output_buffers(struct wined3d_context_gl *con
buffer_gl = wined3d_buffer_gl(state->stream_output[i].buffer);
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
wined3d_buffer_invalidate_location(&buffer_gl->b, ~WINED3D_LOCATION_BUFFER);
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b);
if (!buffer_gl->b.bo_user.valid)
device_invalidate_state(context_gl->c.device, STATE_STREAM_OUTPUT);
}
@@ -3977,7 +3977,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
e = &context->stream_info.elements[wined3d_bit_scan(&map)];
buffer_gl = wined3d_buffer_gl(state->streams[e->stream_idx].buffer);
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b);
}
if (indexed && state->index_buffer)
@@ -3989,7 +3989,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
wined3d_buffer_load(&buffer_gl->b, context, state);
if (!buffer_gl->b.bo_user.valid)
device_invalidate_state(device, STATE_INDEXBUFFER);
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_buffer(context_gl, &buffer_gl->b);
}
else
{
@@ -4338,11 +4338,12 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state
{
const struct wined3d_indirect_dispatch_parameters *indirect = ¶meters->u.indirect;
struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(indirect->buffer);
+ struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
- GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer_gl->bo.id));
+ GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, bo_gl->id));
GL_EXTCALL(glDispatchComputeIndirect((GLintptr)indirect->offset));
GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0));
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_bo(context_gl, bo_gl);
}
else
{
@@ -4725,6 +4726,7 @@ static void wined3d_context_gl_draw_indirect(struct wined3d_context_gl *context_
{
GLenum gl_primitive_type = gl_primitive_type_from_d3d(state->primitive_type);
struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(parameters->buffer);
+ struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
const void *offset;
@@ -4734,7 +4736,7 @@ static void wined3d_context_gl_draw_indirect(struct wined3d_context_gl *context_
return;
}
- GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer_gl->bo.id));
+ GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, bo_gl->id));
offset = (void *)(GLintptr)parameters->offset;
if (idx_size)
@@ -4750,7 +4752,7 @@ static void wined3d_context_gl_draw_indirect(struct wined3d_context_gl *context_
}
GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0));
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_bo(context_gl, bo_gl);
checkGLcall("draw indirect");
}
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 5e41f681c75..712ef2fa9e4 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4474,8 +4474,17 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st
}
buffer_gl = wined3d_buffer_gl(state->index_buffer);
- GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_gl->bo.id));
- buffer_gl->b.bo_user.valid = true;
+ if (buffer_gl->b.buffer_object)
+ {
+ const struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
+
+ GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo_gl->id));
+ buffer_gl->b.bo_user.valid = true;
+ }
+ else
+ {
+ GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ }
}
static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info)
@@ -4569,6 +4578,7 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
enum wined3d_shader_type shader_type;
struct wined3d_buffer_gl *buffer_gl;
+ struct wined3d_bo_gl *bo_gl;
unsigned int i, base, count;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
@@ -4590,7 +4600,8 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
}
buffer_gl = wined3d_buffer_gl(buffer_state->buffer);
- GL_EXTCALL(glBindBufferRange(GL_UNIFORM_BUFFER, base + i, buffer_gl->bo.id,
+ bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
+ GL_EXTCALL(glBindBufferRange(GL_UNIFORM_BUFFER, base + i, bo_gl->id,
buffer_state->offset, buffer_state->size));
buffer_gl->b.bo_user.valid = true;
}
@@ -4644,6 +4655,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_buffer_gl *buffer_gl;
unsigned int offset, size, i;
+ struct wined3d_bo_gl *bo_gl;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
@@ -4658,6 +4670,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
}
buffer_gl = wined3d_buffer_gl(state->stream_output[i].buffer);
+ bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
offset = state->stream_output[i].offset;
if (offset == ~0u)
{
@@ -4665,7 +4678,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
offset = 0;
}
size = buffer_gl->b.resource.size - offset;
- GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, buffer_gl->bo.id, offset, size));
+ GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, bo_gl->id, offset, size));
buffer_gl->b.bo_user.valid = true;
}
checkGLcall("bind transform feedback buffers");
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 8746d9168c2..14025df2c20 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -249,6 +249,7 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c
unsigned int offset, unsigned int size)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
+ const struct wined3d_bo_gl *bo_gl;
if (!gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
{
@@ -264,6 +265,7 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c
}
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
+ bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
view->target = GL_TEXTURE_BUFFER;
if (!view->name)
@@ -272,13 +274,13 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c
wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name);
if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
{
- GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format_gl->internal, buffer_gl->bo.id, offset, size));
+ GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format_gl->internal, bo_gl->id, offset, size));
}
else
{
if (offset || size != buffer_gl->b.resource.size)
FIXME("OpenGL implementation does not support ARB_texture_buffer_range.\n");
- GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format_gl->internal, buffer_gl->bo.id));
+ GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format_gl->internal, bo_gl->id));
}
checkGLcall("Create buffer texture");
@@ -972,11 +974,13 @@ static void wined3d_shader_resource_view_gl_cs_init(void *object)
{
struct wined3d_buffer *buffer = buffer_from_resource(resource);
struct wined3d_context *context;
+ struct wined3d_bo *bo;
context = context_acquire(resource->device, NULL, 0);
create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format);
+ bo = (struct wined3d_bo *)buffer->buffer_object;
view_gl->bo_user.valid = true;
- list_add_head(&wined3d_buffer_gl(buffer)->bo.b.users, &view_gl->bo_user.entry);
+ list_add_head(&bo->users, &view_gl->bo_user.entry);
context_release(context);
}
else
@@ -1482,6 +1486,7 @@ void wined3d_unordered_access_view_gl_clear(struct wined3d_unordered_access_view
const struct wined3d_format_gl *format_gl;
struct wined3d_buffer_gl *buffer_gl;
struct wined3d_resource *resource;
+ struct wined3d_bo_gl *bo_gl;
unsigned int offset, size;
resource = view_gl->v.resource;
@@ -1591,11 +1596,12 @@ void wined3d_unordered_access_view_gl_clear(struct wined3d_unordered_access_view
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
wined3d_unordered_access_view_invalidate_location(&view_gl->v, ~WINED3D_LOCATION_BUFFER);
+ bo_gl = wined3d_bo_gl(buffer_gl->b.buffer_object);
get_buffer_view_range(&buffer_gl->b, &view_gl->v.desc, &format_gl->f, &offset, &size);
- wined3d_context_gl_bind_bo(context_gl, buffer_gl->bo.binding, buffer_gl->bo.id);
- GL_EXTCALL(glClearBufferSubData(buffer_gl->bo.binding, format_gl->internal,
+ wined3d_context_gl_bind_bo(context_gl, bo_gl->binding, bo_gl->id);
+ GL_EXTCALL(glClearBufferSubData(bo_gl->binding, format_gl->internal,
offset, size, format_gl->format, format_gl->type, clear_value));
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ wined3d_context_gl_reference_bo(context_gl, bo_gl);
checkGLcall("clear unordered access view");
}
@@ -1658,11 +1664,13 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object)
{
struct wined3d_buffer *buffer = buffer_from_resource(resource);
struct wined3d_context_gl *context_gl;
+ struct wined3d_bo *bo;
context_gl = wined3d_context_gl(context_acquire(resource->device, NULL, 0));
create_buffer_view(&view_gl->gl_view, &context_gl->c, desc, buffer, view_gl->v.format);
+ bo = buffer->buffer_object;
view_gl->bo_user.valid = true;
- list_add_head(&wined3d_buffer_gl(buffer)->bo.b.users, &view_gl->bo_user.entry);
+ list_add_head(&bo->users, &view_gl->bo_user.entry);
if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
{
struct wined3d_bo_gl *bo = &view_gl->counter_bo;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 63fea9da0e7..e04f2682c88 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1612,6 +1612,11 @@ struct wined3d_bo_gl
uint64_t command_fence_id;
};
+static inline struct wined3d_bo_gl *wined3d_bo_gl(struct wined3d_bo *bo)
+{
+ return CONTAINING_RECORD(bo, struct wined3d_bo_gl, b);
+}
+
static inline GLuint wined3d_bo_gl_id(uintptr_t bo)
{
return bo ? ((struct wined3d_bo_gl *)bo)->id : 0;
@@ -6579,6 +6584,12 @@ static inline void wined3d_context_gl_reference_bo(struct wined3d_context_gl *co
bo_gl->command_fence_id = device_gl->current_fence_id;
}
+static inline void wined3d_context_gl_reference_buffer(struct wined3d_context_gl *context_gl,
+ struct wined3d_buffer *buffer)
+{
+ wined3d_context_gl_reference_bo(context_gl, wined3d_bo_gl(buffer->buffer_object));
+}
+
static inline bool wined3d_map_persistent(void)
{
return sizeof(void *) >= sizeof(uint64_t);
--
2.33.0
Nov. 9, 2021
[PATCH v2 2/6] wined3d: Make the "buffer_object" field of struct wined3d_buffer a wined3d_bo pointer.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v2: No changes.
dlls/wined3d/adapter_vk.c | 4 ++--
dlls/wined3d/buffer.c | 24 ++++++++++++------------
dlls/wined3d/context_vk.c | 8 ++++----
dlls/wined3d/cs.c | 2 +-
dlls/wined3d/view.c | 6 +++---
dlls/wined3d/wined3d_private.h | 9 +++++++--
6 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 8335a030b6b..62a9a342e9b 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1745,7 +1745,7 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device,
if (parameters->indirect)
{
- struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)indirect_vk->b.buffer_object;
+ struct wined3d_bo_vk *bo = wined3d_bo_vk(indirect_vk->b.buffer_object);
uint32_t stride, size;
wined3d_context_vk_reference_bo(context_vk, bo);
@@ -1817,7 +1817,7 @@ static void adapter_vk_dispatch_compute(struct wined3d_device *device,
if (parameters->indirect)
{
- struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)indirect_vk->b.buffer_object;
+ struct wined3d_bo_vk *bo = wined3d_bo_vk(indirect_vk->b.buffer_object);
wined3d_context_vk_reference_bo(context_vk, bo);
VK_CALL(vkCmdDispatchIndirect(vk_command_buffer, bo->vk_buffer,
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 56069cb9f16..be4d095eba0 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -190,7 +190,7 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
buffer_gl->b.bo_user.valid = false;
list_remove(&buffer_gl->b.bo_user.entry);
wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo);
- buffer_gl->b.buffer_object = 0;
+ buffer_gl->b.buffer_object = NULL;
}
/* Context activation is done by the caller. */
@@ -226,7 +226,7 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
}
list_add_head(&buffer_gl->bo.b.users, &buffer_gl->b.bo_user.entry);
- buffer_gl->b.buffer_object = (uintptr_t)bo;
+ buffer_gl->b.buffer_object = &bo->b;
buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);
return TRUE;
@@ -657,7 +657,7 @@ DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_co
}
if (locations & WINED3D_LOCATION_BUFFER)
{
- data->buffer_object = buffer->buffer_object;
+ data->buffer_object = (uintptr_t)buffer->buffer_object;
data->addr = NULL;
return WINED3D_LOCATION_BUFFER;
}
@@ -969,7 +969,7 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
if (count == 1)
{
- addr.buffer_object = buffer->buffer_object;
+ addr.buffer_object = (uintptr_t)buffer->buffer_object;
addr.addr = 0;
buffer->map_ptr = wined3d_context_map_bo_address(context, &addr, resource->size, flags);
/* We are accessing buffer->resource.client from the CS thread,
@@ -1049,7 +1049,7 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou
context = context_acquire(device, NULL, 0);
- addr.buffer_object = buffer->buffer_object;
+ addr.buffer_object = (uintptr_t)buffer->buffer_object;
addr.addr = 0;
wined3d_context_unmap_bo_address(context, &addr, range_count, buffer->maps);
@@ -1455,7 +1455,7 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
list_init(&buffer_vk->b.bo_user.entry);
list_add_head(&bo_vk->b.users, &buffer_vk->b.bo_user.entry);
- buffer_vk->b.buffer_object = (uintptr_t)bo_vk;
+ buffer_vk->b.buffer_object = &bo_vk->b;
buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
return TRUE;
@@ -1463,7 +1463,7 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk)
{
- struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
+ struct wined3d_bo_vk *bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
if (buffer_vk->b.bo_user.valid)
return &buffer_vk->buffer_info;
@@ -1499,8 +1499,8 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, unsigned int location)
{
- struct wined3d_bo_vk *bo_vk = (struct wined3d_bo_vk *)buffer->buffer_object;
struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
+ struct wined3d_bo_vk *bo_vk = wined3d_bo_vk(buffer->buffer_object);
TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
@@ -1511,7 +1511,7 @@ static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer,
list_remove(&buffer->bo_user.entry);
wined3d_context_vk_destroy_bo(context_vk, bo_vk);
heap_free(bo_vk);
- buffer->buffer_object = 0u;
+ buffer->buffer_object = NULL;
break;
default:
@@ -1535,14 +1535,14 @@ static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struc
if (!range_count)
return;
- dst.buffer_object = buffer->buffer_object;
+ dst.buffer_object = (uintptr_t)buffer->buffer_object;
dst.addr = NULL;
flags = WINED3D_MAP_WRITE;
if (!ranges->offset && ranges->size == resource->size)
flags |= WINED3D_MAP_DISCARD;
- dst_bo = (struct wined3d_bo_vk *)buffer->buffer_object;
+ dst_bo = wined3d_bo_vk(buffer->buffer_object);
if (!(dst_bo->memory_type & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) || (!(flags & WINED3D_MAP_DISCARD)
&& dst_bo->command_buffer_id > context_vk->completed_command_buffer_id))
{
@@ -1634,7 +1634,7 @@ void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
if (src_bind_mask)
{
- const struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
+ const struct wined3d_bo_vk *bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
VkBufferMemoryBarrier vk_barrier;
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 46769be516e..ec3554ddc30 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -2519,7 +2519,7 @@ static void wined3d_context_vk_bind_vertex_buffers(struct wined3d_context_vk *co
{
buffer_vk = wined3d_buffer_vk(buffer);
buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk);
- wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object);
+ wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer->buffer_object));
buffers[count] = buffer_info->buffer;
offsets[count] = buffer_info->offset + stream->offset;
++count;
@@ -2558,7 +2558,7 @@ static void wined3d_context_vk_bind_stream_output_buffers(struct wined3d_context
{
buffer_vk = wined3d_buffer_vk(buffer);
buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk);
- wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object);
+ wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer->buffer_object));
buffers[count] = buffer_info->buffer;
if ((offsets[count] = stream->offset) == ~0u)
{
@@ -2760,7 +2760,7 @@ static bool wined3d_shader_descriptor_writes_vk_add_cbv_write(struct wined3d_sha
if (!wined3d_shader_descriptor_writes_vk_add_write(writes, vk_descriptor_set,
binding->binding_idx, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, buffer_info, NULL, NULL))
return false;
- wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object);
+ wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer->buffer_object));
return true;
}
@@ -3408,7 +3408,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
idx_type = VK_INDEX_TYPE_UINT32;
buffer_vk = wined3d_buffer_vk(state->index_buffer);
buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk);
- wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer_vk->b.buffer_object);
+ wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer_vk->b.buffer_object));
VK_CALL(vkCmdBindIndexBuffer(vk_command_buffer, buffer_info->buffer,
buffer_info->offset + state->index_offset, idx_type));
}
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index e6ff448b028..3143865c469 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -2747,7 +2747,7 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
struct wined3d_buffer *buffer = buffer_from_resource(resource);
size_t size = box->right - box->left;
- if (op->bo.addr.buffer_object && op->bo.addr.buffer_object == buffer->buffer_object)
+ if (op->bo.addr.buffer_object && op->bo.addr.buffer_object == (uintptr_t)buffer->buffer_object)
wined3d_context_flush_bo_address(context, &op->bo.addr, size);
else
wined3d_buffer_copy_bo_address(buffer, context, box->left, &op->bo.addr, size);
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index ee398be15f0..8746d9168c2 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -677,7 +677,7 @@ static VkBufferView wined3d_view_vk_create_vk_buffer_view(struct wined3d_context
get_buffer_view_range(&buffer_vk->b, desc, &view_format_vk->f, &offset, &size);
wined3d_buffer_prepare_location(&buffer_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER);
- bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
+ bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
create_info.pNext = NULL;
@@ -1102,7 +1102,7 @@ static void wined3d_shader_resource_view_vk_cs_init(void *object)
if (!vk_buffer_view)
return;
- bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
+ bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(vk_buffer_view));
@@ -2208,7 +2208,7 @@ static void wined3d_unordered_access_view_vk_cs_init(void *object)
if ((vk_buffer_view = wined3d_view_vk_create_vk_buffer_view(context_vk, desc, buffer_vk, format_vk)))
{
- struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
+ struct wined3d_bo_vk *bo = wined3d_bo_vk(buffer_vk->b.buffer_object);
TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(vk_buffer_view));
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 398bd73c5c0..63fea9da0e7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1642,6 +1642,11 @@ struct wined3d_bo_vk
bool host_synced;
};
+static inline struct wined3d_bo_vk *wined3d_bo_vk(struct wined3d_bo *bo)
+{
+ return CONTAINING_RECORD(bo, struct wined3d_bo_vk, b);
+}
+
struct wined3d_bo_slab_vk_key
{
VkMemoryPropertyFlags memory_type;
@@ -5033,7 +5038,7 @@ struct wined3d_buffer
DWORD flags;
DWORD locations;
void *map_ptr;
- uintptr_t buffer_object;
+ struct wined3d_bo *buffer_object;
struct wined3d_bo_user bo_user;
struct wined3d_range *maps;
@@ -6319,7 +6324,7 @@ static inline void wined3d_context_vk_reference_resource(const struct wined3d_co
struct wined3d_resource *resource)
{
if (resource->type == WINED3D_RTYPE_BUFFER)
- wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer_from_resource(resource)->buffer_object);
+ wined3d_context_vk_reference_bo(context_vk, wined3d_bo_vk(buffer_from_resource(resource)->buffer_object));
else
wined3d_context_vk_reference_texture(context_vk, wined3d_texture_vk(texture_from_resource(resource)));
}
--
2.33.0
Nov. 9, 2021
[PATCH v2 1/6] wined3d: Reference vertex buffer objects only after calling context_update_stream_info().
by Zebediah Figura
It may load buffers into a different location.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v2: No changes.
dlls/wined3d/context_gl.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index d2dd9e0bd09..09c871efcd4 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -3963,12 +3963,23 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
device_invalidate_state(device, STATE_STREAMSRC);
else
wined3d_buffer_load(&buffer_gl->b, context, state);
- wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
}
/* Loading the buffers above may have invalidated the stream info. */
if (wined3d_context_is_graphics_state_dirty(context, STATE_STREAMSRC))
context_update_stream_info(context, state);
+ map = context->stream_info.use_map;
+ while (map)
+ {
+ const struct wined3d_stream_info_element *e;
+ struct wined3d_buffer_gl *buffer_gl;
+
+ e = &context->stream_info.elements[wined3d_bit_scan(&map)];
+ buffer_gl = wined3d_buffer_gl(state->streams[e->stream_idx].buffer);
+
+ wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ }
+
if (indexed && state->index_buffer)
{
struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(state->index_buffer);
--
2.33.0
Nov. 9, 2021
[PATCH v5 2/2] ntdll: Prevent loading Wine system dependencies in place of identically named application DLLs.
by Zebediah Figura
That is, load Wine system dependencies only when they are imported from Wine
builtins or other system dependencies, and do not match a Wine system dependency
by its base name when looking for already-loaded modules.
The reasoning is that it is possible for an application to ship, and expect to
use, a newer version of a MinGW-compiled library, or one with custom patches, or
possibly an unrelated library with the same name. We don't want to offer Wine's
system dependencies in place of the application's, or vice versa.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v5: Only set the system flag if the module was actually loaded from a system
path.
dlls/ntdll/loader.c | 56 +++++++++++++++++++++++++++++----------------
1 file changed, 36 insertions(+), 20 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index a9578ae86bf..3ddfeb43ff7 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -135,6 +135,7 @@ typedef struct _wine_modref
LDR_DATA_TABLE_ENTRY ldr;
struct file_id id;
ULONG CheckSum;
+ BOOL system;
} WINE_MODREF;
static UINT tls_module_count; /* number of modules with TLS directory */
@@ -186,7 +187,7 @@ static WINE_MODREF *last_failed_modref;
static LDR_DDAG_NODE *node_ntdll, *node_kernel32;
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
- DWORD flags, WINE_MODREF** pwm );
+ DWORD flags, WINE_MODREF **pwm, BOOL system );
static NTSTATUS process_attach( LDR_DDAG_NODE *node, LPVOID lpReserved );
static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
DWORD exp_size, DWORD ordinal, LPCWSTR load_path );
@@ -505,21 +506,22 @@ static WINE_MODREF *get_modref( HMODULE hmod )
* Find a module from its base name.
* The loader_section must be locked while calling this function
*/
-static WINE_MODREF *find_basename_module( LPCWSTR name )
+static WINE_MODREF *find_basename_module( const WCHAR *name, BOOL system )
{
PLIST_ENTRY mark, entry;
UNICODE_STRING name_str;
RtlInitUnicodeString( &name_str, name );
- if (cached_modref && RtlEqualUnicodeString( &name_str, &cached_modref->ldr.BaseDllName, TRUE ))
+ if (cached_modref && RtlEqualUnicodeString( &name_str, &cached_modref->ldr.BaseDllName, TRUE )
+ && system == cached_modref->system)
return cached_modref;
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
{
- LDR_DATA_TABLE_ENTRY *mod = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
- if (RtlEqualUnicodeString( &name_str, &mod->BaseDllName, TRUE ))
+ WINE_MODREF *mod = CONTAINING_RECORD(entry, WINE_MODREF, ldr.InLoadOrderLinks);
+ if (RtlEqualUnicodeString( &name_str, &mod->ldr.BaseDllName, TRUE ) && system == mod->system)
{
cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
return cached_modref;
@@ -714,6 +716,8 @@ static NTSTATUS walk_node_dependencies( LDR_DDAG_NODE *node, void *context,
*/
static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWSTR load_path )
{
+ WINE_MODREF *imp = get_modref( module );
+ BOOL system = imp->system || (imp->ldr.Flags & LDR_WINE_INTERNAL);
const IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
WINE_MODREF *wm;
@@ -733,10 +737,10 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
if (!wcschr( mod_name, '.' ))
memcpy( mod_name + (end - forward), L".dll", sizeof(L".dll") );
- if (!(wm = find_basename_module( mod_name )))
+ if (!(wm = find_basename_module( mod_name, system )))
{
TRACE( "delay loading %s for '%s'\n", debugstr_w(mod_name), forward );
- if (load_dll( load_path, mod_name, L".dll", 0, &wm ) == STATUS_SUCCESS &&
+ if (load_dll( load_path, mod_name, L".dll", 0, &wm, system ) == STATUS_SUCCESS &&
!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
{
if (!imports_fixup_done && current_modref)
@@ -903,6 +907,7 @@ void * WINAPI RtlFindExportedRoutineByName( HMODULE module, const char *name )
*/
static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LPCWSTR load_path, WINE_MODREF **pwm )
{
+ BOOL system = current_modref->system || (current_modref->ldr.Flags & LDR_WINE_INTERNAL);
NTSTATUS status;
WINE_MODREF *wmImp;
HMODULE imp_mod;
@@ -936,7 +941,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
{
ascii_to_unicode( buffer, name, len );
buffer[len] = 0;
- status = load_dll( load_path, buffer, L".dll", 0, &wmImp );
+ status = load_dll( load_path, buffer, L".dll", 0, &wmImp, system );
}
else /* need to allocate a larger buffer */
{
@@ -944,7 +949,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
if (!ptr) return FALSE;
ascii_to_unicode( ptr, name, len );
ptr[len] = 0;
- status = load_dll( load_path, ptr, L".dll", 0, &wmImp );
+ status = load_dll( load_path, ptr, L".dll", 0, &wmImp, system );
RtlFreeHeap( GetProcessHeap(), 0, ptr );
}
@@ -1216,7 +1221,7 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
prev = current_modref;
current_modref = wm;
assert( !wm->ldr.DdagNode->Dependencies.Tail );
- if (!(status = load_dll( load_path, L"mscoree.dll", NULL, 0, &imp ))
+ if (!(status = load_dll( load_path, L"mscoree.dll", NULL, 0, &imp, FALSE ))
&& !add_module_dependency_after( wm->ldr.DdagNode, imp->ldr.DdagNode, NULL ))
status = STATUS_NO_MEMORY;
current_modref = prev;
@@ -2902,7 +2907,7 @@ done:
*/
static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
UNICODE_STRING *nt_name, WINE_MODREF **pwm, HANDLE *mapping,
- SECTION_IMAGE_INFORMATION *image_info, struct file_id *id )
+ SECTION_IMAGE_INFORMATION *image_info, struct file_id *id, BOOL system )
{
WCHAR *ext, *dllname;
NTSTATUS status;
@@ -2943,7 +2948,7 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, con
else
{
if (status != STATUS_SXS_KEY_NOT_FOUND) goto done;
- if ((*pwm = find_basename_module( libname )) != NULL)
+ if ((*pwm = find_basename_module( libname, system )) != NULL)
{
status = STATUS_SUCCESS;
goto done;
@@ -2976,7 +2981,7 @@ done:
* The loader_section must be locked while calling this function.
*/
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
- DWORD flags, WINE_MODREF** pwm )
+ DWORD flags, WINE_MODREF **pwm, BOOL system )
{
UNICODE_STRING nt_name;
struct file_id id;
@@ -2987,10 +2992,13 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
- if (system_dll_path.Buffer)
- nts = find_dll_file( system_dll_path.Buffer, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
+ if (system && system_dll_path.Buffer)
+ nts = find_dll_file( system_dll_path.Buffer, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id, TRUE );
if (nts)
- nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
+ {
+ nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id, FALSE );
+ system = FALSE;
+ }
if (*pwm) /* found already loaded module */
{
@@ -3027,6 +3035,14 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
break;
}
+ /* mark the DLL as system only if it was loaded from a system path and is
+ * not builtin. note that builtins can appear to be loaded from a system
+ * path during prefix bootstrap */
+ if (!((*pwm)->ldr.Flags & LDR_WINE_INTERNAL))
+ (*pwm)->system = system;
+
+ if ((*pwm)->system) FIXME( "%s is a system dependency\n", debugstr_us(&nt_name));
+
if (NtCurrentTeb64())
NtCurrentTeb64()->Tib.ArbitraryUserPointer = prev;
else
@@ -3084,7 +3100,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
RtlEnterCriticalSection( &loader_section );
- nts = load_dll( path_name, libname->Buffer, L".dll", flags, &wm );
+ nts = load_dll( path_name, libname->Buffer, L".dll", flags, &wm, FALSE );
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
{
@@ -3159,7 +3175,7 @@ NTSTATUS WINAPI LdrGetDllHandleEx( ULONG flags, LPCWSTR load_path, ULONG *dll_ch
RtlEnterCriticalSection( &loader_section );
- status = find_dll_file( load_path, name->Buffer, L".dll", &nt_name, &wm, &mapping, &image_info, &id );
+ status = find_dll_file( load_path, name->Buffer, L".dll", &nt_name, &wm, &mapping, &image_info, &id, FALSE );
if (wm) *base = wm->ldr.DllBase;
else
@@ -3860,7 +3876,7 @@ static void init_wow64( CONTEXT *context )
NTSTATUS status;
static const WCHAR wow64_path[] = L"C:\\windows\\system32\\wow64.dll";
- if ((status = load_dll( NULL, wow64_path, NULL, 0, &wm )))
+ if ((status = load_dll( NULL, wow64_path, NULL, 0, &wm, FALSE )))
{
ERR( "could not load %s, status %x\n", debugstr_w(wow64_path), status );
NtTerminateProcess( GetCurrentProcess(), status );
@@ -4010,7 +4026,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
if (NtCurrentTeb()->WowTebOffset) init_wow64( context );
- if ((status = load_dll( NULL, L"kernel32.dll", NULL, 0, &kernel32 )) != STATUS_SUCCESS)
+ if ((status = load_dll( NULL, L"kernel32.dll", NULL, 0, &kernel32, FALSE )) != STATUS_SUCCESS)
{
MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
NtTerminateProcess( GetCurrentProcess(), status );
--
2.33.0
Nov. 9, 2021
[PATCH v5 1/2] ntdll: Allow loading system DLLs from a path specified at configure time.
by Zebediah Figura
Many distributions provide MinGW-compiled system DLLs which are currently
bundled with Wine. Unfortunately, while MinGW pkg-config can be used to detect
the linking path, there is no standardized runtime path, and many distributions
in fact use different paths.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
Makefile.in | 1 +
configure.ac | 3 +++
dlls/ntdll/Makefile.in | 1 +
dlls/ntdll/loader.c | 10 ++++++++--
dlls/ntdll/unix/env.c | 1 +
dlls/ntdll/unix/loader.c | 3 +++
dlls/ntdll/unix/unix_private.h | 1 +
7 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/Makefile.in b/Makefile.in
index 42f161e3af9..c4b0fbda616 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -32,6 +32,7 @@ nlsdir = ${datadir}/wine/nls
dlldir = ${libdir}/wine
srcdir = @srcdir@
host_cpu = @host_cpu@
+system_dlldir = @system_dlldir@
SHELL = /bin/sh
CC = @CC@
CXX = @CXX@
diff --git a/configure.ac b/configure.ac
index 39c8e3a2a4d..4ecc3cce05f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -103,6 +103,7 @@ AC_ARG_WITH(xshm, AS_HELP_STRING([--without-xshm],[do not use XShm (shared
AC_ARG_WITH(xxf86vm, AS_HELP_STRING([--without-xxf86vm],[do not use XFree video mode extension]),
[if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_xf86vmode_h=no; ac_cv_header_X11_extensions_xf86vmproto_h=no; fi])
+AC_ARG_WITH(system-dlldir, AS_HELP_STRING([--with-system-dlldir=DIR],[load external PE dependencies from directory DIR]))
AC_ARG_WITH(wine-tools,AS_HELP_STRING([--with-wine-tools=DIR],[use Wine tools from directory DIR]))
AC_ARG_WITH(wine64, AS_HELP_STRING([--with-wine64=DIR],[use the 64-bit Wine in DIR for a Wow64 build]))
@@ -256,6 +257,8 @@ then
TARGETFLAGS="-b $host_alias $TARGETFLAGS"
fi
+AC_SUBST(system_dlldir,"$with_system_dlldir")
+
dnl Check for flex
AC_CHECK_PROGS(FLEX,flex,none)
if test "$FLEX" = "none"
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index d3be1fad0bc..bce141bc14b 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -72,5 +72,6 @@ EXTRA_OBJS = unix/version.o
unix_loader_EXTRADEFS = \
-DBINDIR=\"${bindir}\" \
+ -DSYSTEMDLLDIR=\"${system_dlldir}\" \
-DDLL_TO_BINDIR=\"`${MAKEDEP} -R ${dlldir} ${bindir}`\" \
-DBIN_TO_DATADIR=\"`${MAKEDEP} -R ${bindir} ${datadir}/wine`\"
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 255d5afef79..a9578ae86bf 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -95,6 +95,7 @@ static int free_lib_count; /* recursion depth of LdrUnloadDll calls */
static ULONG path_safe_mode; /* path mode set by RtlSetSearchPathMode */
static ULONG dll_safe_mode = 1; /* dll search mode */
static UNICODE_STRING dll_directory; /* extra path for LdrSetDllDirectory */
+static UNICODE_STRING system_dll_path; /* path to search for system dependency dlls */
static DWORD default_search_flags; /* default flags set by LdrSetDefaultDllDirectories */
static WCHAR *default_load_path; /* default dll search path */
@@ -2981,12 +2982,15 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
struct file_id id;
HANDLE mapping = 0;
SECTION_IMAGE_INFORMATION image_info;
- NTSTATUS nts;
+ NTSTATUS nts = STATUS_DLL_NOT_FOUND;
ULONG64 prev;
TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
- nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
+ if (system_dll_path.Buffer)
+ nts = find_dll_file( system_dll_path.Buffer, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
+ if (nts)
+ nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
if (*pwm) /* found already loaded module */
{
@@ -3997,6 +4001,8 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
load_global_options();
version_init();
+ get_env_var( L"WINESYSTEMDLLDIR", 0, &system_dll_path );
+
wm = build_main_module();
wm->ldr.LoadCount = -1;
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
index 24f4fa5a588..f9e6e625cbb 100644
--- a/dlls/ntdll/unix/env.c
+++ b/dlls/ntdll/unix/env.c
@@ -1296,6 +1296,7 @@ static void add_dynamic_environment( WCHAR **env, SIZE_T *pos, SIZE_T *size )
add_path_var( env, pos, size, "WINEHOMEDIR", home_dir );
add_path_var( env, pos, size, "WINEBUILDDIR", build_dir );
add_path_var( env, pos, size, "WINECONFIGDIR", config_dir );
+ add_path_var( env, pos, size, "WINESYSTEMDLLDIR", system_dll_path );
for (i = 0; dll_paths[i]; i++)
{
sprintf( str, "WINEDLLDIR%u", i );
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index ea7f18602da..04e3dedc615 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -387,6 +387,7 @@ const char *data_dir = NULL;
const char *build_dir = NULL;
const char *config_dir = NULL;
const char **dll_paths = NULL;
+const char *system_dll_path = NULL;
const char *user_name = NULL;
SECTION_IMAGE_INFORMATION main_image_info = { NULL };
static HMODULE ntdll_module;
@@ -618,6 +619,8 @@ static void init_paths( char *argv[] )
data_dir = build_path( bin_dir, BIN_TO_DATADIR );
}
+ if (strlen(SYSTEMDLLDIR)) system_dll_path = SYSTEMDLLDIR;
+
set_dll_path();
set_home_dir();
set_config_dir();
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 6b8835bcba0..15a3da9ce8e 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -127,6 +127,7 @@ extern const char *build_dir DECLSPEC_HIDDEN;
extern const char *config_dir DECLSPEC_HIDDEN;
extern const char *user_name DECLSPEC_HIDDEN;
extern const char **dll_paths DECLSPEC_HIDDEN;
+extern const char *system_dll_path DECLSPEC_HIDDEN;
extern PEB *peb DECLSPEC_HIDDEN;
extern USHORT *uctable DECLSPEC_HIDDEN;
extern USHORT *lctable DECLSPEC_HIDDEN;
--
2.33.0
Nov. 9, 2021
[PATCH v4 2/2] mshtml: Populate the element props properly.
by Gabriel Ivăncescu
For IE modes 8 and above, IHTMLElement::setAttribute uses the underlying
nsIDOMElement::SetAttribute, which does nothing since we're already
enumerating the ns attributes, and we're supposed to create the DISPIDs
for them.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/mshtml/htmlelem.c | 5 ++++-
dlls/mshtml/tests/documentmode.js | 2 --
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index 91ccfb9..9133a46 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -6516,7 +6516,10 @@ static HRESULT HTMLElement_populate_props(DispatchEx *dispex)
} else
V_BSTR(&value) = NULL;
- IHTMLElement_setAttribute(&This->IHTMLElement_iface, name, value, 0);
+ hres = IDispatchEx_GetDispID(&dispex->IDispatchEx_iface, name, fdexNameEnsure | fdexNameCaseInsensitive, &id);
+ if(SUCCEEDED(hres))
+ set_elem_attr_value_by_dispid(This, id, &value);
+
SysFreeString(name);
VariantClear(&value);
}
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 1458068..1a44206 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -518,9 +518,7 @@ sync_test("createElement_inline_attr", function() {
for(var i = 0; i < tags.length; i++) {
e = document.createElement("<" + tags[i] + " test='a\"' abcd=\""b"\">");
ok(e.tagName === tags[i].toUpperCase(), "<" + tags[i] + " test=\"a\" abcd=\"b\">.tagName returned " + e.tagName);
- todo_wine_if(v == 8).
ok(e.test === "a\"", "<" + tags[i] + " test='a\"' abcd=\""b"\">.test returned " + e.test);
- todo_wine_if(v == 8).
ok(e.abcd === "\"b\"", "<" + tags[i] + " test='a\"' abcd=\""b"\">.abcd returned " + e.abcd);
}
}else {
--
2.31.1
Nov. 9, 2021
[PATCH v4 1/2] mshtml: Implement inline attributes parsing for createElement.
by Gabriel Ivăncescu
We let gecko parse a dummy unknown tag (after validation) using a contextual
fragment, and then copy its attributes to the proper element with correct tag.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/mshtml/htmlelem.c | 134 +++++++++++++++++++++++++++++-
dlls/mshtml/tests/documentmode.js | 63 ++++++++++++++
2 files changed, 196 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index de69e2f..91ccfb9 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -355,6 +355,134 @@ static inline HTMLElement *impl_from_IHTMLElement(IHTMLElement *iface)
return CONTAINING_RECORD(iface, HTMLElement, IHTMLElement_iface);
}
+static HRESULT copy_nselem_attrs(nsIDOMElement *nselem_with_attrs, nsIDOMElement *nselem)
+{
+ nsIDOMMozNamedAttrMap *attrs;
+ nsAString name_str, val_str;
+ nsresult nsres, nsres2;
+ nsIDOMAttr *attr;
+ UINT32 i, length;
+
+ nsres = nsIDOMElement_GetAttributes(nselem_with_attrs, &attrs);
+ if(NS_FAILED(nsres))
+ return E_FAIL;
+
+ nsres = nsIDOMMozNamedAttrMap_GetLength(attrs, &length);
+ if(NS_FAILED(nsres)) {
+ nsIDOMMozNamedAttrMap_Release(attrs);
+ return E_FAIL;
+ }
+
+ nsAString_Init(&name_str, NULL);
+ nsAString_Init(&val_str, NULL);
+ for(i = 0; i < length; i++) {
+ nsres = nsIDOMMozNamedAttrMap_Item(attrs, i, &attr);
+ if(NS_FAILED(nsres))
+ continue;
+
+ nsres = nsIDOMAttr_GetNodeName(attr, &name_str);
+ nsres2 = nsIDOMAttr_GetNodeValue(attr, &val_str);
+ nsIDOMAttr_Release(attr);
+ if(NS_FAILED(nsres) || NS_FAILED(nsres2))
+ continue;
+
+ nsIDOMElement_SetAttribute(nselem, &name_str, &val_str);
+ }
+ nsAString_Finish(&name_str);
+ nsAString_Finish(&val_str);
+
+ nsIDOMMozNamedAttrMap_Release(attrs);
+ return S_OK;
+}
+
+static HRESULT create_nselem_parse(HTMLDocumentNode *doc, const WCHAR *tag, nsIDOMElement **ret)
+{
+ static const WCHAR prefix[4] = L"<FOO";
+ nsIDOMDocumentFragment *nsfragment;
+ WCHAR *p = wcschr(tag + 1, '>');
+ UINT32 i, name_len, size;
+ nsIDOMElement *nselem;
+ nsIDOMRange *nsrange;
+ nsIDOMNode *nsnode;
+ nsresult nsres;
+ nsAString str;
+ HRESULT hres;
+
+ if(!p || p[1] || wcschr(tag + 1, '<'))
+ return E_FAIL;
+ if(!doc->nsdoc) {
+ WARN("NULL nsdoc\n");
+ return E_UNEXPECTED;
+ }
+
+ /* Ignore the starting token and > or /> end token */
+ name_len = p - tag - 1 - (p[-1] == '/');
+
+ /* Get the tag name using HTML whitespace rules */
+ for(i = 1; i <= name_len; i++) {
+ if((tag[i] >= 0x09 && tag[i] <= 0x0d) || tag[i] == ' ') {
+ name_len = i - 1;
+ break;
+ }
+ }
+ if(!name_len)
+ return E_FAIL;
+ size = (p + 2 - (tag + 1 + name_len)) * sizeof(WCHAR);
+
+ /* Parse the input via a contextual fragment, using a dummy unknown tag */
+ nsres = nsIDOMHTMLDocument_CreateRange(doc->nsdoc, &nsrange);
+ if(NS_FAILED(nsres))
+ return map_nsresult(nsres);
+
+ if(!(p = heap_alloc(sizeof(prefix) + size))) {
+ nsIDOMRange_Release(nsrange);
+ return E_OUTOFMEMORY;
+ }
+ memcpy(p, prefix, sizeof(prefix));
+ memcpy(p + ARRAY_SIZE(prefix), tag + 1 + name_len, size);
+
+ nsAString_InitDepend(&str, p);
+ nsIDOMRange_CreateContextualFragment(nsrange, &str, &nsfragment);
+ nsIDOMRange_Release(nsrange);
+ nsAString_Finish(&str);
+ heap_free(p);
+ if(NS_FAILED(nsres))
+ return map_nsresult(nsres);
+
+ /* Grab the parsed element and copy its attributes into the proper element */
+ nsres = nsIDOMDocumentFragment_GetFirstChild(nsfragment, &nsnode);
+ nsIDOMDocumentFragment_Release(nsfragment);
+ if(NS_FAILED(nsres) || !nsnode)
+ return E_FAIL;
+
+ nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&nselem);
+ nsIDOMNode_Release(nsnode);
+ if(NS_FAILED(nsres))
+ return E_FAIL;
+
+ if(!(p = heap_alloc((name_len + 1) * sizeof(WCHAR))))
+ hres = E_OUTOFMEMORY;
+ else {
+ memcpy(p, tag + 1, name_len * sizeof(WCHAR));
+ p[name_len] = '\0';
+
+ nsAString_InitDepend(&str, p);
+ nsres = nsIDOMHTMLDocument_CreateElement(doc->nsdoc, &str, ret);
+ nsAString_Finish(&str);
+ heap_free(p);
+
+ if(NS_FAILED(nsres))
+ hres = map_nsresult(nsres);
+ else {
+ hres = copy_nselem_attrs(nselem, *ret);
+ if(FAILED(hres))
+ nsIDOMElement_Release(*ret);
+ }
+ }
+ nsIDOMElement_Release(nselem);
+ return hres;
+}
+
HRESULT create_nselem(HTMLDocumentNode *doc, const WCHAR *tag, nsIDOMElement **ret)
{
nsAString tag_str;
@@ -385,7 +513,11 @@ HRESULT create_element(HTMLDocumentNode *doc, const WCHAR *tag, HTMLElement **re
if(!doc->nsdoc)
doc = doc->node.doc;
- hres = create_nselem(doc, tag, &nselem);
+ /* IE8 and below allow creating elements with attributes, such as <div class="a"> */
+ if(tag[0] == '<' && dispex_compat_mode(&doc->node.event_target.dispex) <= COMPAT_MODE_IE8)
+ hres = create_nselem_parse(doc, tag, &nselem);
+ else
+ hres = create_nselem(doc, tag, &nselem);
if(FAILED(hres))
return hres;
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 02a5f5f..1458068 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -488,6 +488,69 @@ sync_test("style_props", function() {
}
});
+sync_test("createElement_inline_attr", function() {
+ var v = document.documentMode, e, s;
+
+ if(v < 9) {
+ s = document.createElement("<div>").tagName;
+ ok(s === "DIV", "<div>.tagName returned " + s);
+ s = document.createElement("<div >").tagName;
+ ok(s === "DIV", "<div >.tagName returned " + s);
+ s = document.createElement("<div/>").tagName;
+ ok(s === "DIV", "<div/>.tagName returned " + s);
+ e = 0;
+ try {
+ document.createElement("<div");
+ }catch(ex) {
+ e = ex.number;
+ }
+ ok(e === 0x4005 - 0x80000000, "<div e = " + e);
+ e = 0;
+ try {
+ document.createElement("<div test=1");
+ }catch(ex) {
+ e = ex.number;
+ }
+ ok(e === 0x4005 - 0x80000000, "<div test=1 e = " + e);
+
+ var tags = [ "div", "template", "head", "body", "title", "html", "foo" ];
+
+ for(var i = 0; i < tags.length; i++) {
+ e = document.createElement("<" + tags[i] + " test='a\"' abcd=\""b"\">");
+ ok(e.tagName === tags[i].toUpperCase(), "<" + tags[i] + " test=\"a\" abcd=\"b\">.tagName returned " + e.tagName);
+ todo_wine_if(v == 8).
+ ok(e.test === "a\"", "<" + tags[i] + " test='a\"' abcd=\""b"\">.test returned " + e.test);
+ todo_wine_if(v == 8).
+ ok(e.abcd === "\"b\"", "<" + tags[i] + " test='a\"' abcd=\""b"\">.abcd returned " + e.abcd);
+ }
+ }else {
+ s = "";
+ e = 0;
+ try {
+ document.createElement("<div>");
+ }catch(ex) {
+ s = ex.toString();
+ e = ex.number;
+ }
+ todo_wine.
+ ok(e === undefined, "<div> e = " + e);
+ todo_wine.
+ ok(s === "InvalidCharacterError", "<div> s = " + s);
+ s = "";
+ e = 0;
+ try {
+ document.createElement("<div test=\"a\">");
+ }catch(ex) {
+ s = ex.toString();
+ e = ex.number;
+ }
+ todo_wine.
+ ok(e === undefined, "<div test=\"a\"> e = " + e);
+ todo_wine.
+ ok(s === "InvalidCharacterError", "<div test=\"a\"> s = " + s);
+ }
+});
+
sync_test("JS objs", function() {
var g = window;
--
2.31.1
Nov. 9, 2021