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 3/7] wined3d: Separate a vk_memory_type_from_access_flags() helper.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 886fb95f3e5..62f84c96f96 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1423,22 +1423,27 @@ 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 memory_type = 0;
+
+ if (access & WINED3D_RESOURCE_ACCESS_MAP_R)
+ memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
+ else if (access & WINED3D_RESOURCE_ACCESS_MAP_W)
+ memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ else if (!(usage & WINED3DUSAGE_DYNAMIC))
+ memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+ return memory_type;
+}
+
static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buffer_vk,
struct wined3d_context_vk *context_vk)
{
struct wined3d_resource *resource = &buffer_vk->b.resource;
- VkMemoryPropertyFlags memory_type;
-
- memory_type = 0;
- if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_R)
- memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
- else if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_W)
- memory_type |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
- else if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
- memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
if (!(wined3d_context_vk_create_bo(context_vk, resource->size,
- vk_buffer_usage_from_bind_flags(resource->bind_flags), memory_type, &buffer_vk->bo)))
+ vk_buffer_usage_from_bind_flags(resource->bind_flags),
+ vk_memory_type_from_access_flags(resource->access, resource->usage), &buffer_vk->bo)))
{
WARN("Failed to create Vulkan buffer.\n");
return FALSE;
--
2.33.0
Nov. 4, 2021
[PATCH v2 2/7] wined3d: Separate a vk_buffer_usage_from_bind_flags() helper.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 55dcd9e67e8..886fb95f3e5 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1399,12 +1399,8 @@ 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 BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buffer_vk,
- struct wined3d_context_vk *context_vk)
+static VkBufferUsageFlags vk_buffer_usage_from_bind_flags(uint32_t bind_flags)
{
- struct wined3d_resource *resource = &buffer_vk->b.resource;
- uint32_t bind_flags = resource->bind_flags;
- VkMemoryPropertyFlags memory_type;
VkBufferUsageFlags usage;
usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
@@ -1424,6 +1420,14 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
if (bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL))
FIXME("Ignoring some bind flags %#x.\n", bind_flags);
+ return usage;
+}
+
+static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buffer_vk,
+ struct wined3d_context_vk *context_vk)
+{
+ struct wined3d_resource *resource = &buffer_vk->b.resource;
+ VkMemoryPropertyFlags memory_type;
memory_type = 0;
if (resource->access & WINED3D_RESOURCE_ACCESS_MAP_R)
@@ -1433,7 +1437,8 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
else if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
- if (!(wined3d_context_vk_create_bo(context_vk, resource->size, usage, memory_type, &buffer_vk->bo)))
+ if (!(wined3d_context_vk_create_bo(context_vk, resource->size,
+ vk_buffer_usage_from_bind_flags(resource->bind_flags), memory_type, &buffer_vk->bo)))
{
WARN("Failed to create Vulkan buffer.\n");
return FALSE;
--
2.33.0
Nov. 4, 2021
[PATCH v2 1/7] wined3d: Protect access to the Vulkan wined3d_allocator with a mutex.
by Zebediah Figura
So that it can be accessed from the client thread.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 9 ++++++
dlls/wined3d/context_vk.c | 52 ++++++++++++++++++++++++++--------
dlls/wined3d/wined3d_private.h | 11 +++++++
3 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 02a359c4f07..cbf7c94fd3a 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -521,6 +521,10 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
goto fail;
}
+ InitializeCriticalSection(&device_vk->allocator_cs);
+ if (device_vk->allocator_cs.DebugInfo != (RTL_CRITICAL_SECTION_DEBUG *)-1)
+ device_vk->allocator_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wined3d_device_vk.allocator_cs");
+
*device = &device_vk->d;
return WINED3D_OK;
@@ -538,6 +542,11 @@ static void adapter_vk_destroy_device(struct wined3d_device *device)
wined3d_device_cleanup(&device_vk->d);
wined3d_allocator_cleanup(&device_vk->allocator);
+
+ if (device_vk->allocator_cs.DebugInfo != (RTL_CRITICAL_SECTION_DEBUG *)-1)
+ device_vk->allocator_cs.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&device_vk->allocator_cs);
+
VK_CALL(vkDestroyDevice(device_vk->vk_device, NULL));
heap_free(device_vk);
}
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index ad7b0a8ba86..54c5eb6bc24 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -313,27 +313,43 @@ static struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct
struct wined3d_allocator *allocator = &device_vk->allocator;
struct wined3d_allocator_block *block;
+ wined3d_device_vk_allocator_lock(device_vk);
+
if (size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
{
*vk_memory = wined3d_context_vk_allocate_vram_chunk_memory(context_vk, memory_type, size);
+ wined3d_device_vk_allocator_unlock(device_vk);
return NULL;
}
if (!(block = wined3d_allocator_allocate(allocator, &context_vk->c, memory_type, size)))
{
+ wined3d_device_vk_allocator_unlock(device_vk);
*vk_memory = VK_NULL_HANDLE;
return NULL;
}
*vk_memory = wined3d_allocator_chunk_vk(block->chunk)->vk_memory;
+ wined3d_device_vk_allocator_unlock(device_vk);
return block;
}
+static void wined3d_context_vk_free_memory(struct wined3d_context_vk *context_vk, struct wined3d_allocator_block *block)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+
+ assert(block->chunk->allocator == &device_vk->allocator);
+ wined3d_device_vk_allocator_lock(device_vk);
+ wined3d_allocator_block_free(block);
+ wined3d_device_vk_allocator_unlock(device_vk);
+}
+
static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context_vk,
VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(context_vk->c.device->adapter);
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
const VkPhysicalDeviceLimits *limits = &adapter_vk->device_limits;
struct wined3d_bo_slab_vk_key key;
struct wined3d_bo_slab_vk *slab;
@@ -360,6 +376,8 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
key.usage = usage;
key.size = 32 * object_size;
+ wined3d_device_vk_allocator_lock(device_vk);
+
if ((entry = wine_rb_get(&context_vk->bo_slab_available, &key)))
{
slab = WINE_RB_ENTRY_VALUE(entry, struct wined3d_bo_slab_vk, entry);
@@ -369,27 +387,30 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
{
if (!(slab = heap_alloc_zero(sizeof(*slab))))
{
+ wined3d_device_vk_allocator_unlock(device_vk);
ERR("Failed to allocate bo slab.\n");
return false;
}
+ if (wine_rb_put(&context_vk->bo_slab_available, &key, &slab->entry) < 0)
+ {
+ wined3d_device_vk_allocator_unlock(device_vk);
+ ERR("Failed to add slab to available tree.\n");
+ heap_free(slab);
+ return false;
+ }
+
slab->requested_memory_type = memory_type;
if (!wined3d_context_vk_create_bo(context_vk, key.size, usage, memory_type, &slab->bo))
{
+ wined3d_device_vk_allocator_unlock(device_vk);
ERR("Failed to create slab bo.\n");
+ wine_rb_remove(&context_vk->bo_slab_available, &slab->entry);
heap_free(slab);
return false;
}
slab->map = ~0u;
- if (wine_rb_put(&context_vk->bo_slab_available, &key, &slab->entry) < 0)
- {
- ERR("Failed to add slab to available tree.\n");
- wined3d_context_vk_destroy_bo(context_vk, &slab->bo);
- heap_free(slab);
- return false;
- }
-
TRACE("Created new bo slab %p.\n", slab);
}
@@ -407,6 +428,8 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
}
}
+ wined3d_device_vk_allocator_unlock(device_vk);
+
*bo = slab->bo;
bo->memory = NULL;
bo->slab = slab;
@@ -480,7 +503,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic
{
ERR("Failed to bind buffer memory, vr %s.\n", wined3d_debug_vkresult(vr));
if (bo->memory)
- wined3d_allocator_block_free(bo->memory);
+ wined3d_context_vk_free_memory(context_vk, bo->memory);
else
VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL));
VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL));
@@ -574,7 +597,7 @@ BOOL wined3d_context_vk_create_image(struct wined3d_context_vk *context_vk, VkIm
{
VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
if (image->memory)
- wined3d_allocator_block_free(image->memory);
+ wined3d_context_vk_free_memory(context_vk, image->memory);
else
VK_CALL(vkFreeMemory(device_vk->vk_device, image->vk_memory, NULL));
ERR("Failed to bind image memory, vr %s.\n", wined3d_debug_vkresult(vr));
@@ -688,7 +711,7 @@ void wined3d_context_vk_destroy_allocator_block(struct wined3d_context_vk *conte
if (context_vk->completed_command_buffer_id > command_buffer_id)
{
- wined3d_allocator_block_free(block);
+ wined3d_context_vk_free_memory(context_vk, block);
TRACE("Freed block %p.\n", block);
return;
}
@@ -707,11 +730,14 @@ void wined3d_context_vk_destroy_allocator_block(struct wined3d_context_vk *conte
static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
SIZE_T idx, struct wined3d_context_vk *context_vk)
{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
struct wined3d_bo_slab_vk_key key;
struct wine_rb_entry *entry;
TRACE("slab %p, idx %lu, context_vk %p.\n", slab, idx, context_vk);
+ wined3d_device_vk_allocator_lock(device_vk);
+
if (!slab->map)
{
key.memory_type = slab->requested_memory_type;
@@ -729,6 +755,8 @@ static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
}
}
slab->map |= 1u << idx;
+
+ wined3d_device_vk_allocator_unlock(device_vk);
}
static void wined3d_context_vk_destroy_bo_slab_slice(struct wined3d_context_vk *context_vk,
@@ -1000,7 +1028,7 @@ static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *cont
case WINED3D_RETIRED_ALLOCATOR_BLOCK_VK:
TRACE("Destroying block %p.\n", o->u.block);
- wined3d_allocator_block_free(o->u.block);
+ wined3d_context_vk_free_memory(context_vk, o->u.block);
break;
case WINED3D_RETIRED_BO_SLAB_SLICE_VK:
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index aa8974366a6..62b92ce7c34 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4084,6 +4084,7 @@ struct wined3d_device_vk
struct wined3d_null_resources_vk null_resources_vk;
struct wined3d_null_views_vk null_views_vk;
+ CRITICAL_SECTION allocator_cs;
struct wined3d_allocator allocator;
struct wined3d_uav_clear_state_vk uav_clear_state;
@@ -4094,6 +4095,16 @@ static inline struct wined3d_device_vk *wined3d_device_vk(struct wined3d_device
return CONTAINING_RECORD(device, struct wined3d_device_vk, d);
}
+static inline void wined3d_device_vk_allocator_lock(struct wined3d_device_vk *device_vk)
+{
+ EnterCriticalSection(&device_vk->allocator_cs);
+}
+
+static inline void wined3d_device_vk_allocator_unlock(struct wined3d_device_vk *device_vk)
+{
+ LeaveCriticalSection(&device_vk->allocator_cs);
+}
+
bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk,
struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
bool wined3d_device_vk_create_null_views(struct wined3d_device_vk *device_vk,
--
2.33.0
Nov. 4, 2021
[PATCH v2 3/3] 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>
---
dlls/ntdll/loader.c | 45 ++++++++++++++++++++++++++-------------------
include/winternl.h | 1 +
2 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index c83f7980572..a8ecf58ab37 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -186,7 +186,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 +505,23 @@ 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->ldr.Flags & LDR_WINE_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 ))
+ if (RtlEqualUnicodeString( &name_str, &mod->BaseDllName, TRUE )
+ && system == !!(mod->Flags & LDR_WINE_SYSTEM))
{
cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
return cached_modref;
@@ -714,6 +716,7 @@ static NTSTATUS walk_node_dependencies( LDR_DDAG_NODE *node, void *context,
*/
static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWSTR load_path )
{
+ BOOL system = !!(get_modref( module )->ldr.Flags & (LDR_WINE_SYSTEM | LDR_WINE_BUILTIN));
const IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
WINE_MODREF *wm;
@@ -733,10 +736,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 +906,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->ldr.Flags & (LDR_WINE_SYSTEM | LDR_WINE_BUILTIN));
NTSTATUS status;
WINE_MODREF *wmImp;
HMODULE imp_mod;
@@ -936,7 +940,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 +948,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 +1220,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 +2906,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 +2947,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 +2980,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 +2991,10 @@ 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 );
if (*pwm) /* found already loaded module */
{
@@ -3027,6 +3031,9 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
break;
}
+ if (system)
+ (*pwm)->ldr.Flags |= LDR_WINE_SYSTEM;
+
if (NtCurrentTeb64())
NtCurrentTeb64()->Tib.ArbitraryUserPointer = prev;
else
@@ -3084,7 +3091,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 +3166,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 +3867,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 +4017,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 );
diff --git a/include/winternl.h b/include/winternl.h
index 216a3b3fdaa..4bf9f0a8b11 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -3393,6 +3393,7 @@ typedef void (CALLBACK *PLDR_DLL_NOTIFICATION_FUNCTION)(ULONG, LDR_DLL_NOTIFICAT
#define LDR_COR_ILONLY 0x01000000
/* these ones is Wine specific */
+#define LDR_WINE_SYSTEM 0x20000000
#define LDR_DONT_RESOLVE_REFS 0x40000000
#define LDR_WINE_BUILTIN 0x80000000
--
2.33.0
Nov. 4, 2021
[PATCH v2 2/3] 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>
---
To be clear I don't necessarily think this is *clearly* the best option.
Obviously it'd be nice to establish some sort of standard along the lines of
ld.so's standardized search location, but this may be a length process.
An environment variable configurable at runtime would also be useful, as
LD_LIBRARY_PATH often is. I could see arguments for specifying it in addition
to, or in lieu of, a path supplied at configure time.
It's also possible that we should allow specifying multiple paths here.
Nevertheless, I believe we should allow some way to load DLLs from an external
path, rather than forcing the user to manually copy them into the prefix (or
forcing Wine to be built with bundled dependencies.) I readily welcome consensus
on any of the above questions, but in lieu thereof, since it is relatively easy
to effect incremental improvement here, I propose this solution for now.
configure.ac | 4 ++++
dlls/ntdll/loader.c | 10 ++++++++--
dlls/ntdll/unix/env.c | 1 +
dlls/ntdll/unix/loader.c | 5 +++++
dlls/ntdll/unix/unix_private.h | 1 +
5 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 57383fb2e31..a00f2ebc11f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,8 @@ AC_ARG_ENABLE(maintainer-mode, AS_HELP_STRING([--enable-maintainer-mode],[enable
AC_ARG_ENABLE(silent-rules, AS_HELP_STRING([--enable-silent-rules],[use silent build rules (override: "make V=1")]))
AC_ARG_ENABLE(werror, AS_HELP_STRING([--enable-werror],[treat compilation warnings as errors]))
+AC_ARG_VAR([SYSTEMDLLDIR], [path containing system dependency shared libraries])
+
AC_ARG_WITH(alsa, AS_HELP_STRING([--without-alsa],[do not use the Alsa sound support]))
AC_ARG_WITH(capi, AS_HELP_STRING([--without-capi],[do not use CAPI (ISDN support)]))
AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the CoreAudio sound support]),
@@ -108,6 +110,8 @@ AC_ARG_WITH(wine64, AS_HELP_STRING([--with-wine64=DIR],[use the 64-bit Wine i
AC_CANONICAL_HOST
+AS_VAR_IF([SYSTEMDLLDIR],[],[],[AC_DEFINE_UNQUOTED([SYSTEMDLLDIR],["$SYSTEMDLLDIR"],[Define to the path containing system dependency shared libraries.])])
+
dnl **** Check for some programs ****
AC_PROG_MAKE_SET
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 17c8d7f7485..c83f7980572 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 43a34bf831b..1647603efa5 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 0ca4b1ea6dd..5dfe7191dbe 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -388,6 +388,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;
@@ -619,6 +620,10 @@ static void init_paths( char *argv[] )
data_dir = build_path( bin_dir, BIN_TO_DATADIR );
}
+#ifdef SYSTEMDLLDIR
+ system_dll_path = SYSTEMDLLDIR;
+#endif
+
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 792cb33710d..01c7cc1c103 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -125,6 +125,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. 4, 2021
[PATCH v2 1/3] include: Rename LDR_WINE_INTERNAL to LDR_WINE_BUILTIN.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
This series makes it possible to use dynamic libraries from an external path
without needing to first copy them into a prefix. As an example, on Debian I am
able to install the "libz-minw-w64-dev" package, and then use the following
configure command to compile Wine:
configure --enable-win64 ZLIB_PE_CFLAGS="$(x86_64-w64-mingw32-pkg-config --cflags zlib)" ZLIB_PE_LIBS="$(x86_64-w64-mingw32-pkg-config --libs zlib)" SYSTEMDLLDIR=/usr/x86_64-w64-mingw32/lib/
whereafter libraries are linked directly to system zlib1.dll, and no further
configuration is needed
I would like to submit patches in the future to allow the use of pkg-config for
automatically detecting compile flags and libraries. I would also like to find
some way to obviate manual specification of DLL bindirs.
v2: Rebased on top of current git; no other change.
dlls/kernel32/kernel_main.c | 2 +-
dlls/krnl386.exe16/ne_module.c | 2 +-
dlls/ntdll/loader.c | 10 +++++-----
dlls/ntdll/signal_arm64.c | 2 +-
dlls/ntdll/signal_x86_64.c | 2 +-
include/winternl.h | 2 +-
6 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/kernel32/kernel_main.c b/dlls/kernel32/kernel_main.c
index 4467af739e0..317ee782d7a 100644
--- a/dlls/kernel32/kernel_main.c
+++ b/dlls/kernel32/kernel_main.c
@@ -136,7 +136,7 @@ static BOOL process_attach( HMODULE module )
{
LDR_DATA_TABLE_ENTRY *ldr;
- if (LdrFindEntryForAddress( GetModuleHandleW( 0 ), &ldr ) || !(ldr->Flags & LDR_WINE_INTERNAL))
+ if (LdrFindEntryForAddress( GetModuleHandleW( 0 ), &ldr ) || !(ldr->Flags & LDR_WINE_BUILTIN))
LoadLibraryA( "krnl386.exe16" );
}
#endif
diff --git a/dlls/krnl386.exe16/ne_module.c b/dlls/krnl386.exe16/ne_module.c
index c26fe778253..108e88e5546 100644
--- a/dlls/krnl386.exe16/ne_module.c
+++ b/dlls/krnl386.exe16/ne_module.c
@@ -982,7 +982,7 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
return ERROR_FILE_NOT_FOUND;
}
/* check if module was loaded native */
- if (LdrFindEntryForAddress( main_owner, &ldr ) || !(ldr->Flags & LDR_WINE_INTERNAL))
+ if (LdrFindEntryForAddress( main_owner, &ldr ) || !(ldr->Flags & LDR_WINE_BUILTIN))
{
FreeLibrary( mod32 );
descr = NULL;
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 255d5afef79..17c8d7f7485 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1081,7 +1081,7 @@ static BOOL is_dll_native_subsystem( LDR_DATA_TABLE_ENTRY *mod, const IMAGE_NT_H
if (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_NATIVE) return FALSE;
if (nt->OptionalHeader.SectionAlignment < page_size) return TRUE;
- if (mod->Flags & LDR_WINE_INTERNAL) return TRUE;
+ if (mod->Flags & LDR_WINE_BUILTIN) return TRUE;
if ((imports = RtlImageDirectoryEntryToData( mod->DllBase, TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT, &size )))
@@ -1310,7 +1310,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
wm->ldr.DllBase = hModule;
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
- wm->ldr.Flags = LDR_DONT_RESOLVE_REFS | (builtin ? LDR_WINE_INTERNAL : 0);
+ wm->ldr.Flags = LDR_DONT_RESOLVE_REFS | (builtin ? LDR_WINE_BUILTIN : 0);
wm->ldr.TlsIndex = -1;
wm->ldr.LoadCount = 1;
wm->CheckSum = nt->OptionalHeader.CheckSum;
@@ -1454,7 +1454,7 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return STATUS_SUCCESS;
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.DllBase, reason );
- if (wm->ldr.Flags & LDR_WINE_INTERNAL && reason == DLL_PROCESS_ATTACH)
+ if (wm->ldr.Flags & LDR_WINE_BUILTIN && reason == DLL_PROCESS_ATTACH)
unix_funcs->init_builtin_dll( wm->ldr.DllBase );
if (!entry) return STATUS_SUCCESS;
@@ -3643,7 +3643,7 @@ static void free_modref( WINE_MODREF *wm )
if (!TRACE_ON(module))
TRACE_(loaddll)("Unloaded module %s : %s\n",
debugstr_w(wm->ldr.FullDllName.Buffer),
- (wm->ldr.Flags & LDR_WINE_INTERNAL) ? "builtin" : "native" );
+ (wm->ldr.Flags & LDR_WINE_BUILTIN) ? "builtin" : "native" );
free_tls_slot( &wm->ldr );
RtlReleaseActivationContext( wm->ldr.ActivationContext );
@@ -4079,7 +4079,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
}
release_address_space();
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.DllBase, DLL_PROCESS_ATTACH );
- if (wm->ldr.Flags & LDR_WINE_INTERNAL) unix_funcs->init_builtin_dll( wm->ldr.DllBase );
+ if (wm->ldr.Flags & LDR_WINE_BUILTIN) unix_funcs->init_builtin_dll( wm->ldr.DllBase );
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
process_breakpoint();
}
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index 290639b676b..bfbaeab47c9 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -191,7 +191,7 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
/* then look for host system exception information */
- if (!module || (module->Flags & LDR_WINE_INTERNAL))
+ if (!module || (module->Flags & LDR_WINE_BUILTIN))
{
status = unix_funcs->unwind_builtin_dll( type, dispatch, context );
if (status != STATUS_SUCCESS) return status;
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index ef32eba68b7..8515b176e5d 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -275,7 +275,7 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
/* then look for host system exception information */
- if (!module || (module->Flags & LDR_WINE_INTERNAL))
+ if (!module || (module->Flags & LDR_WINE_BUILTIN))
{
status = unix_funcs->unwind_builtin_dll( type, dispatch, context );
diff --git a/include/winternl.h b/include/winternl.h
index eea97f1238b..216a3b3fdaa 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -3394,7 +3394,7 @@ typedef void (CALLBACK *PLDR_DLL_NOTIFICATION_FUNCTION)(ULONG, LDR_DLL_NOTIFICAT
/* these ones is Wine specific */
#define LDR_DONT_RESOLVE_REFS 0x40000000
-#define LDR_WINE_INTERNAL 0x80000000
+#define LDR_WINE_BUILTIN 0x80000000
/* flag for LdrAddRefDll */
#define LDR_ADDREF_DLL_PIN 0x00000001
--
2.33.0
Nov. 4, 2021
Re: [PATCH 1/2] dmime: Parse Wave track stream
by Michael Stefaniuc
Hello Alistair,
what about the attached patch? It got only basic testing aka Tron 2.0 demo
doesn't crashes straight ahead on me and I see the code being hit in the TRACEs.
I ended up re-implementing some parts of it due to multiple issues:
- While it made sense to merge in parse_wavetrack_list() I missed the part to
split out parse_wave_part().
The generic idea is to keep a single chunk nesting level per function,
basically not having to keep track of nesting. Means just one "cursor" chunk per
function with an optional extra parent chunk that gets read at the very beginning.
- According to
https://docs.microsoft.com/en-us/previous-versions/ms811352(v=msdn.10) both the
wave parts as well as the wave items are actual arrays. Tron seems to just have
a single entry of each but the code should deal with arrays in both cases.
- The headers weren't stored.
thanks
bye
michael
On 11/1/21 07:30, Alistair Leslie-Hughes wrote:
> Tron 2.0
>
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
> ---
> dlls/dmime/dmime_private.h | 6 ++
> dlls/dmime/wavetrack.c | 148 ++++++++++++++++++++++++++++++++++++-
> 2 files changed, 152 insertions(+), 2 deletions(-)
>
> diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h
> index c2221a15fd2..6ab47292b39 100644
> --- a/dlls/dmime/dmime_private.h
> +++ b/dlls/dmime/dmime_private.h
> @@ -86,6 +86,12 @@ typedef struct _DMUS_PRIVATE_TEMPO_ITEM {
> DMUS_IO_TEMPO_ITEM item;
> } DMUS_PRIVATE_TEMPO_ITEM, *LPDMUS_PRIVATE_TEMPO_ITEM;
>
> +struct wave_item {
> + struct list entry;
> + DMUS_IO_WAVE_TRACK_HEADER header;
> + IDirectMusicObject *object;
> +};
> +
> typedef struct _DMUS_PRIVATE_GRAPH_TOOL {
> struct list entry; /* for listing elements */
> DWORD dwIndex;
> diff --git a/dlls/dmime/wavetrack.c b/dlls/dmime/wavetrack.c
> index 1c6b08b5235..da7ef37d2c8 100644
> --- a/dlls/dmime/wavetrack.c
> +++ b/dlls/dmime/wavetrack.c
> @@ -20,6 +20,8 @@
> #include "dmime_private.h"
> #include "dmobject.h"
>
> +#include "wine/heap.h"
> +
> WINE_DEFAULT_DEBUG_CHANNEL(dmime);
>
> /*****************************************************************************
> @@ -32,6 +34,8 @@ typedef struct IDirectMusicWaveTrack {
> IDirectMusicTrack8 IDirectMusicTrack8_iface;
> struct dmobject dmobj; /* IPersistStream only */
> LONG ref;
> +
> + struct list items;
> } IDirectMusicWaveTrack;
>
> /* IDirectMusicWaveTrack IDirectMusicTrack8 part: */
> @@ -40,6 +44,11 @@ static inline IDirectMusicWaveTrack *impl_from_IDirectMusicTrack8(IDirectMusicTr
> return CONTAINING_RECORD(iface, IDirectMusicWaveTrack, IDirectMusicTrack8_iface);
> }
>
> +static inline IDirectMusicWaveTrack *impl_from_IPersistStream(IPersistStream *iface)
> +{
> + return CONTAINING_RECORD(iface, IDirectMusicWaveTrack, dmobj.IPersistStream_iface);
> +}
> +
> static HRESULT WINAPI wave_track_QueryInterface(IDirectMusicTrack8 *iface, REFIID riid,
> void **ret_iface)
> {
> @@ -81,6 +90,19 @@ static ULONG WINAPI wave_track_Release(IDirectMusicTrack8 *iface)
> TRACE("(%p) ref=%d\n", This, ref);
>
> if (!ref) {
> + struct list *cursor, *cursor2;
> + struct wave_item *item;
> +
> + LIST_FOR_EACH_SAFE(cursor, cursor2, &This->items) {
> + item = LIST_ENTRY(cursor, struct wave_item, entry);
> + list_remove(cursor);
> +
> + if (item->object)
> + IDirectMusicObject_Release(item->object);
> +
> + heap_free(item);
> + }
> +
> HeapFree(GetProcessHeap(), 0, This);
> DMIME_UnlockModule();
> }
> @@ -280,10 +302,131 @@ static const IDirectMusicTrack8Vtbl dmtrack8_vtbl = {
> wave_track_Join
> };
>
> +static HRESULT parse_wave_item(IDirectMusicWaveTrack *This, IStream *stream,
> + struct chunk_entry *wave, struct wave_item *item)
> +{
> + HRESULT hr;
> + struct chunk_entry chunk = {.parent = wave};
> +
> + if (FAILED(hr = stream_next_chunk(stream, &chunk)))
> + return hr;
> +
> + if(chunk.id == FOURCC_LIST && chunk.type == DMUS_FOURCC_WAVE_LIST)
> + {
> + struct chunk_entry child = {.parent = &chunk};
> + DMUS_IO_WAVE_ITEM_HEADER header;
> +
> + if (FAILED(hr = stream_next_chunk(stream, &child)))
> + return hr;
> +
> + if(child.id != DMUS_FOURCC_WAVEITEM_CHUNK)
> + return DMUS_E_UNSUPPORTED_STREAM;
> +
> + if (FAILED(hr = stream_chunk_get_data(stream, &child, &header, sizeof(header)))) {
> + WARN("Failed to read data of %s\n", debugstr_chunk(&child));
> + return hr;
> + }
> +
> + TRACE("Found DMUS_IO_WAVE_ITEM_HEADER\n");
> + TRACE(" - lVolume %d\n", header.lVolume);
> + TRACE(" - dwVariations %d\n", header.dwVariations);
> + TRACE(" - rtTime %s\n", wine_dbgstr_longlong(header.rtTime));
> + TRACE(" - rtStartOffset %s\n", wine_dbgstr_longlong(header.rtStartOffset));
> + TRACE(" - rtReserved %s\n", wine_dbgstr_longlong(header.rtReserved));
> + TRACE(" - rtDuration %s\n", wine_dbgstr_longlong(header.rtDuration));
> + TRACE(" - dwLoopStart %d\n", header.dwLoopStart);
> + TRACE(" - dwLoopEnd %d\n", header.dwLoopEnd);
> + TRACE(" - dwFlags 0x%08x\n", header.dwFlags);
> + TRACE(" - wVolumeRange %d\n", header.wVolumeRange);
> + TRACE(" - wPitchRange %d\n", header.wPitchRange);
> +
> + if (FAILED(hr = stream_next_chunk(stream, &child)))
> + return hr;
> +
> + if (FAILED(hr = dmobj_parsereference(stream, &chunk, &item->object)))
> + return hr;
> + }
> + else
> + hr = DMUS_E_UNSUPPORTED_STREAM;
> +
> + return SUCCEEDED(hr) ? S_OK : hr;
> +}
> +
> static HRESULT WINAPI wave_IPersistStream_Load(IPersistStream *iface, IStream *stream)
> {
> - FIXME(": Loading not implemented yet\n");
> - return S_OK;
> + IDirectMusicWaveTrack *This = impl_from_IPersistStream(iface);
> + HRESULT hr;
> + struct chunk_entry chunk = {0};
> +
> + TRACE("%p, %p\n", This, stream);
> +
> + if (!stream)
> + return E_POINTER;
> +
> + if ((hr = stream_get_chunk(stream, &chunk) != S_OK))
> + return hr;
> +
> + if (chunk.id == FOURCC_LIST && chunk.type == DMUS_FOURCC_WAVETRACK_LIST)
> + {
> + struct chunk_entry chunklist = {.parent = &chunk};
> + struct wave_item *item = NULL;
> +
> + TRACE("Parsing segment form in %p: %s\n", stream, debugstr_chunk(&chunklist));
> +
> + if (FAILED(hr = stream_next_chunk(stream, &chunklist)))
> + return hr;
> +
> + if (chunklist.id != DMUS_FOURCC_WAVETRACK_CHUNK)
> + return DMUS_E_UNSUPPORTED_STREAM;
> +
> + item = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(struct wave_item));
> + if (!item)
> + return E_OUTOFMEMORY;
> +
> + list_add_tail (&This->items, &item->entry);
> +
> + if (FAILED(hr = stream_next_chunk(stream, &chunklist)))
> + return hr;
> +
> + if (chunklist.id == FOURCC_LIST && chunklist.type == DMUS_FOURCC_WAVEPART_LIST)
> + {
> + struct chunk_entry child = {.parent = &chunklist};
> + DMUS_IO_WAVE_PART_HEADER header;
> +
> + if (FAILED(hr = stream_next_chunk(stream, &child)))
> + return hr;
> +
> + if (child.id != DMUS_FOURCC_WAVEPART_CHUNK)
> + return DMUS_E_UNSUPPORTED_STREAM;
> +
> + if (FAILED(hr = stream_chunk_get_data(stream, &child, &header, sizeof(header)))) {
> + WARN("Failed to read data of %s\n", debugstr_chunk(&child));
> + return hr;
> + }
> +
> + TRACE("Found DMUS_IO_WAVE_PART_HEADER\n");
> + TRACE(" - lVolume %d\n", header.lVolume);
> + TRACE(" - dwVariations %d\n", header.dwVariations);
> + TRACE(" - dwPChannel %d\n", header.dwPChannel);
> + TRACE(" - dwLockToPart %d\n", header.dwLockToPart);
> + TRACE(" - dwFlags 0x%08x\n", header.dwFlags);
> + TRACE(" - dwIndex %d\n", header.dwIndex);
> +
> + if (FAILED(hr = stream_next_chunk(stream, &child)))
> + return hr;
> +
> + if(child.id != FOURCC_LIST || child.type != DMUS_FOURCC_WAVEITEM_LIST)
> + return DMUS_E_UNSUPPORTED_STREAM;
> +
> + hr = parse_wave_item(This, stream, &child, item);
> + }
> + else
> + hr = DMUS_E_UNSUPPORTED_STREAM;
> + }
> + else
> + hr = DMUS_E_UNSUPPORTED_STREAM;
> +
> + return hr;
> }
>
> static const IPersistStreamVtbl persiststream_vtbl = {
> @@ -313,6 +456,7 @@ HRESULT WINAPI create_dmwavetrack(REFIID lpcGUID, void **ppobj)
> dmobject_init(&track->dmobj, &CLSID_DirectMusicWaveTrack,
> (IUnknown *)&track->IDirectMusicTrack8_iface);
> track->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
> + list_init(&track->items);
>
> DMIME_LockModule();
> hr = IDirectMusicTrack8_QueryInterface(&track->IDirectMusicTrack8_iface, lpcGUID, ppobj);
>
Nov. 4, 2021
Re: [PATCH 4/8] wined3d: Pass a wined3d_bo_vk pointer to wined3d_buffer_vk_create_buffer_object().
by Zebediah Figura
On 11/3/21 12:11 PM, Henri Verbeet wrote:
> On Wed, 3 Nov 2021 at 00:20, Zebediah Figura <zfigura(a)codeweavers.com> wrote:
>> -static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buffer_vk,
>> - struct wined3d_context_vk *context_vk)
>> +static BOOL wined3d_buffer_vk_create_buffer_object(const struct wined3d_buffer_vk *buffer_vk,
>> + struct wined3d_context_vk *context_vk, struct wined3d_bo_vk *bo)
>> {
> "bo_vk" by convention, although we're not terribly consistent about
> that everywhere. "BOOL" -> "bool" if we're touching it.
>
>> @@ -1433,19 +1433,8 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
>> else if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
>> memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
>>
>> - if (!(wined3d_device_vk_create_bo(wined3d_device_vk(resource->device),
>> - context_vk, resource->size, usage, memory_type, &buffer_vk->bo)))
>> - {
>> - WARN("Failed to create Vulkan buffer.\n");
>> - return FALSE;
>> - }
>> -
>> - list_init(&buffer_vk->b.bo_user.entry);
>> - list_add_head(&buffer_vk->bo.b.users, &buffer_vk->b.bo_user.entry);
>> - buffer_vk->b.buffer_object = (uintptr_t)&buffer_vk->bo;
>> - buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
>> -
>> - return TRUE;
>> + return wined3d_device_vk_create_bo(wined3d_device_vk(resource->device),
>> + context_vk, resource->size, usage, memory_type, bo);
>> }
>>
> Is this the best way to handle this particular issue? I gather we're
> doing this primarily in order to create a bo with the correct "usage"
> and "memory_type" in patch 8/8. However, we could also achieve that by
> introducing helpers along the lines of
> vk_access_mask_from_bind_flags() to determine the correct "usage" and
> "memory_type", and then just call wined3d_device_vk_create_bo()
> directly from adapter_vk_alloc_bo() in patch 8/8. We may not
> necessarily need to pass a resource to adapter_alloc_bo() in that case
> either.
>
Sure, that looks reasonable to me.
Nov. 3, 2021
Re: [PATCH 6/8] wined3d: Allow passing a NULL context to wined3d_device_vk_create_bo().
by Zebediah Figura
On 11/3/21 12:11 PM, Henri Verbeet wrote:
> On Wed, 3 Nov 2021 at 00:37, Zebediah Figura <zfigura(a)codeweavers.com> wrote:
>> ---
>> dlls/wined3d/context_vk.c | 19 +++++++------------
>> dlls/wined3d/utils.c | 3 +++
>> 2 files changed, 10 insertions(+), 12 deletions(-)
>>
> As mentioned in 1/8 and 3/8, this should essentially never happen in
> the Vulkan backend.
>
>> @@ -314,14 +314,14 @@ static struct wined3d_allocator_block *wined3d_device_vk_allocate_memory(struct
>>
>> EnterCriticalSection(&device_vk->allocator_cs);
>>
>> - if (size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
>> + if (context_vk && size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
>> {
>> *vk_memory = wined3d_context_vk_allocate_vram_chunk_memory(context_vk, memory_type, size);
>> LeaveCriticalSection(&device_vk->allocator_cs);
>> return NULL;
>> }
>>
> I suppose this works, but I think we should just enter this block and
> fail if we have a NULL context here. We're not going to successfully
> allocate a block larger than WINED3D_ALLOCATOR_CHUNK_SIZE / 2 below
> either, so there doesn't seem much point in trying.
Right, that makes sense...
>
>> @@ -398,14 +399,8 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
>> }
>> slab->map = ~0u;
>>
>> - if (wine_rb_put(&device_vk->bo_slab_available, &key, &slab->entry) < 0)
>> - {
>> - ERR("Failed to add slab to available tree.\n");
>> - wined3d_context_vk_destroy_bo(context_vk, &slab->bo);
>> - heap_free(slab);
>> - return false;
>> - }
>> -
>> + ret = wine_rb_put(&device_vk->bo_slab_available, &key, &slab->entry);
>> + assert(!ret);
>> TRACE("Created new bo slab %p.\n", slab);
>> }
> It doesn't seem quite right that we'd be able to create a bo without a
> context, but would then be unable to destroy it again...
No, nor did it seem quite right to me when I wrote this, but
wined3d_context_vk_destroy_bo() touches more parts of the
wined3d_context than I was confident about moving (plus, wine_rb_put()
seems assert-worthy in general...)
I suppose the better solution here is to factor out part of
wined3d_context_vk_destroy_bo(), the part that assumes the BO isn't in
use by the GPU.
>
>> @@ -7408,6 +7408,9 @@ struct wined3d_allocator_block *wined3d_allocator_allocate(struct wined3d_alloca
>> return block;
>> }
>>
>> + if (!context)
>> + return NULL;
>> +
>> if (!(chunk = allocator->ops->allocator_create_chunk(allocator,
>> context, memory_type, WINED3D_ALLOCATOR_CHUNK_SIZE)))
>> return NULL;
>
> Arguably, we could handle the NULL context in
> allocator_create_chunk(). It's somewhat moot though; in the Vulkan
> backend we should never have a NULL context, and in the OpenGL backend
> we can't do anything particularly useful with it.
>
Nov. 3, 2021