[PATCH vkd3d 1/5] vkd3d: Implement set name for query heaps.

Zhiyi Zhang zzhang at codeweavers.com
Sat Jan 26 02:31:15 CST 2019


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 Makefile.am                    |   5 +-
 include/private/vkd3d_string.h |  57 ++++++++
 include/private/vkd3d_utf8.h   |   8 ++
 libs/vkd3d-common/utf8.c       | 248 +++++++++++++++++++++++++++++++++
 libs/vkd3d/device.c            |   1 +
 libs/vkd3d/resource.c          |  11 +-
 libs/vkd3d/utils.c             |  61 ++++++++
 libs/vkd3d/vkd3d_private.h     |   8 ++
 libs/vkd3d/vulkan_procs.h      |   2 +
 9 files changed, 398 insertions(+), 3 deletions(-)
 create mode 100644 include/private/vkd3d_string.h
 create mode 100644 include/private/vkd3d_utf8.h
 create mode 100644 libs/vkd3d-common/utf8.c

diff --git a/Makefile.am b/Makefile.am
index 7869b2e..abba599 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -59,7 +59,8 @@ noinst_LTLIBRARIES = libvkd3d-common.la
 libvkd3d_common_la_SOURCES = \
 	include/private/vkd3d_debug.h \
 	libs/vkd3d-common/debug.c \
-	libs/vkd3d-common/memory.c
+	libs/vkd3d-common/memory.c \
+	libs/vkd3d-common/utf8.c
 
 lib_LTLIBRARIES = libvkd3d-shader.la libvkd3d.la libvkd3d-utils.la
 
@@ -88,6 +89,8 @@ libvkd3d_la_SOURCES = \
 	include/private/vkd3d_common.h \
 	include/private/vkd3d_debug.h \
 	include/private/vkd3d_memory.h \
+	include/private/vkd3d_string.h \
+	include/private/vkd3d_utf8.h \
 	include/private/vkd3d_test.h \
 	include/vkd3d_d3d12.idl \
 	include/vkd3d_d3dcommon.idl \
diff --git a/include/private/vkd3d_string.h b/include/private/vkd3d_string.h
new file mode 100644
index 0000000..07adc98
--- /dev/null
+++ b/include/private/vkd3d_string.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 Zhiyi Zhang for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __VKD3D_STRING_H
+#define __VKD3D_STRING_H
+
+#include "vkd3d_memory.h"
+
+#include <inttypes.h>
+
+static inline size_t vkd3d_strlen_w16(const uint16_t *wstr)
+{
+    const uint16_t *s = wstr;
+    while (*s) s++;
+    return s - wstr;
+}
+
+static inline size_t vkd3d_strlen_w32(const uint32_t *wstr)
+{
+    const uint32_t *s = wstr;
+    while (*s) s++;
+    return s - wstr;
+}
+
+static inline WCHAR *vkd3d_strdup_w(const WCHAR *src, size_t wchar_size)
+{
+    size_t size;
+    WCHAR *dst;
+
+    if (wchar_size == 2)
+        size = (vkd3d_strlen_w16((const uint16_t *)src) + 1) * wchar_size;
+    else
+        size = (vkd3d_strlen_w32((const uint32_t *)src) + 1) * wchar_size;
+
+    if (!(dst = vkd3d_malloc(size)))
+        return NULL;
+
+    memcpy(dst, src, size);
+    return dst;
+}
+
+#endif /* __VKD3D_STRING_H */
\ No newline at end of file
diff --git a/include/private/vkd3d_utf8.h b/include/private/vkd3d_utf8.h
new file mode 100644
index 0000000..c7f1a07
--- /dev/null
+++ b/include/private/vkd3d_utf8.h
@@ -0,0 +1,8 @@
+#include "vkd3d_common.h"
+
+#include <inttypes.h>
+
+#define WC_ERR_INVALID_CHARS 0x0080
+
+int wine_utf8_wcstombs_w16(int flags, const uint16_t *src, int srclen, char *dst, int dstlen) DECLSPEC_HIDDEN;
+int wine_utf8_wcstombs_w32(int flags, const uint32_t *src, int srclen, char *dst, int dstlen) DECLSPEC_HIDDEN;
\ No newline at end of file
diff --git a/libs/vkd3d-common/utf8.c b/libs/vkd3d-common/utf8.c
new file mode 100644
index 0000000..da3e682
--- /dev/null
+++ b/libs/vkd3d-common/utf8.c
@@ -0,0 +1,248 @@
+/*
+ * UTF-8 support routines
+ *
+ * Copyright 2000 Alexandre Julliard
+ * Copyright 2019 Zhiyi Zhang for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "vkd3d_utf8.h"
+
+/* get the next char value taking surrogates into account */
+static inline unsigned int get_surrogate_value_w16( const uint16_t *src, unsigned int srclen )
+{
+    if (src[0] >= 0xd800 && src[0] <= 0xdfff)  /* surrogate pair */
+    {
+        if (src[0] > 0xdbff || /* invalid high surrogate */
+            srclen <= 1 ||     /* missing low surrogate */
+            src[1] < 0xdc00 || src[1] > 0xdfff) /* invalid low surrogate */
+            return 0;
+        return 0x10000 + ((src[0] & 0x3ff) << 10) + (src[1] & 0x3ff);
+    }
+    return src[0];
+}
+
+/* query necessary dst length for src string */
+static inline int get_length_wcs_utf8_w16( int flags, const uint16_t *src, unsigned int srclen )
+{
+    int len;
+    unsigned int val;
+
+    for (len = 0; srclen; srclen--, src++)
+    {
+        if (*src < 0x80)  /* 0x00-0x7f: 1 byte */
+        {
+            len++;
+            continue;
+        }
+        if (*src < 0x800)  /* 0x80-0x7ff: 2 bytes */
+        {
+            len += 2;
+            continue;
+        }
+        if (!(val = get_surrogate_value_w16( src, srclen )))
+        {
+            if (flags & WC_ERR_INVALID_CHARS) return -2;
+            continue;
+        }
+        if (val < 0x10000)  /* 0x800-0xffff: 3 bytes */
+            len += 3;
+        else   /* 0x10000-0x10ffff: 4 bytes */
+        {
+            len += 4;
+            src++;
+            srclen--;
+        }
+    }
+    return len;
+}
+
+/* wide char to UTF-8 string conversion */
+/* return -1 on dst buffer overflow, -2 on invalid input char */
+int wine_utf8_wcstombs_w16( int flags, const uint16_t *src, int srclen, char *dst, int dstlen )
+{
+    int len;
+
+    if (!dstlen) return get_length_wcs_utf8_w16( flags, src, srclen );
+
+    for (len = dstlen; srclen; srclen--, src++)
+    {
+        uint16_t ch = *src;
+        unsigned int val;
+
+        if (ch < 0x80)  /* 0x00-0x7f: 1 byte */
+        {
+            if (!len--) return -1;  /* overflow */
+            *dst++ = ch;
+            continue;
+        }
+
+        if (ch < 0x800)  /* 0x80-0x7ff: 2 bytes */
+        {
+            if ((len -= 2) < 0) return -1;  /* overflow */
+            dst[1] = 0x80 | (ch & 0x3f);
+            ch >>= 6;
+            dst[0] = 0xc0 | ch;
+            dst += 2;
+            continue;
+        }
+
+        if (!(val = get_surrogate_value_w16( src, srclen )))
+        {
+            if (flags & WC_ERR_INVALID_CHARS) return -2;
+            continue;
+        }
+
+        if (val < 0x10000)  /* 0x800-0xffff: 3 bytes */
+        {
+            if ((len -= 3) < 0) return -1;  /* overflow */
+            dst[2] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[1] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[0] = 0xe0 | val;
+            dst += 3;
+        }
+        else   /* 0x10000-0x10ffff: 4 bytes */
+        {
+            if ((len -= 4) < 0) return -1;  /* overflow */
+            dst[3] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[2] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[1] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[0] = 0xf0 | val;
+            dst += 4;
+            src++;
+            srclen--;
+        }
+    }
+    return dstlen - len;
+}
+
+/* get the next char value taking surrogates into account */
+static inline unsigned int get_surrogate_value_w32( const uint32_t *src, unsigned int srclen )
+{
+    if (src[0] >= 0xd800 && src[0] <= 0xdfff)  /* surrogate pair */
+    {
+        if (src[0] > 0xdbff || /* invalid high surrogate */
+            srclen <= 1 ||     /* missing low surrogate */
+            src[1] < 0xdc00 || src[1] > 0xdfff) /* invalid low surrogate */
+            return 0;
+        return 0x10000 + ((src[0] & 0x3ff) << 10) + (src[1] & 0x3ff);
+    }
+    return src[0];
+}
+
+/* query necessary dst length for src string */
+static inline int get_length_wcs_utf8_w32( int flags, const uint32_t *src, unsigned int srclen )
+{
+    int len;
+    unsigned int val;
+
+    for (len = 0; srclen; srclen--, src++)
+    {
+        if (*src < 0x80)  /* 0x00-0x7f: 1 byte */
+        {
+            len++;
+            continue;
+        }
+        if (*src < 0x800)  /* 0x80-0x7ff: 2 bytes */
+        {
+            len += 2;
+            continue;
+        }
+        if (!(val = get_surrogate_value_w32( src, srclen )))
+        {
+            if (flags & WC_ERR_INVALID_CHARS) return -2;
+            continue;
+        }
+        if (val < 0x10000)  /* 0x800-0xffff: 3 bytes */
+            len += 3;
+        else   /* 0x10000-0x10ffff: 4 bytes */
+        {
+            len += 4;
+            src++;
+            srclen--;
+        }
+    }
+    return len;
+}
+
+/* wide char to UTF-8 string conversion */
+/* return -1 on dst buffer overflow, -2 on invalid input char */
+int wine_utf8_wcstombs_w32( int flags, const uint32_t *src, int srclen, char *dst, int dstlen )
+{
+    int len;
+
+    if (!dstlen) return get_length_wcs_utf8_w32( flags, src, srclen );
+
+    for (len = dstlen; srclen; srclen--, src++)
+    {
+        uint32_t ch = *src;
+        unsigned int val;
+
+        if (ch < 0x80)  /* 0x00-0x7f: 1 byte */
+        {
+            if (!len--) return -1;  /* overflow */
+            *dst++ = ch;
+            continue;
+        }
+
+        if (ch < 0x800)  /* 0x80-0x7ff: 2 bytes */
+        {
+            if ((len -= 2) < 0) return -1;  /* overflow */
+            dst[1] = 0x80 | (ch & 0x3f);
+            ch >>= 6;
+            dst[0] = 0xc0 | ch;
+            dst += 2;
+            continue;
+        }
+
+        if (!(val = get_surrogate_value_w32( src, srclen )))
+        {
+            if (flags & WC_ERR_INVALID_CHARS) return -2;
+            continue;
+        }
+
+        if (val < 0x10000)  /* 0x800-0xffff: 3 bytes */
+        {
+            if ((len -= 3) < 0) return -1;  /* overflow */
+            dst[2] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[1] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[0] = 0xe0 | val;
+            dst += 3;
+        }
+        else   /* 0x10000-0x10ffff: 4 bytes */
+        {
+            if ((len -= 4) < 0) return -1;  /* overflow */
+            dst[3] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[2] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[1] = 0x80 | (val & 0x3f);
+            val >>= 6;
+            dst[0] = 0xf0 | val;
+            dst += 4;
+            src++;
+            srclen--;
+        }
+    }
+    return dstlen - len;
+}
\ No newline at end of file
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 64c8391..ff0c8c1 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -83,6 +83,7 @@ static const char * const required_device_extensions[] =
 
 static const struct vkd3d_optional_extension_info optional_device_extensions[] =
 {
+    {VK_EXT_DEBUG_MARKER_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, EXT_debug_marker)},
     {VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, KHR_push_descriptor)},
     {VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME,
             offsetof(struct vkd3d_vulkan_info, EXT_transform_feedback)},
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 6eba450..4ebfe30 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -2684,6 +2684,7 @@ static ULONG STDMETHODCALLTYPE d3d12_query_heap_Release(ID3D12QueryHeap *iface)
         struct d3d12_device *device = heap->device;
         const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
 
+        if (heap->name) vkd3d_free(heap->name);
         vkd3d_private_store_destroy(&heap->private_store);
 
         VK_CALL(vkDestroyQueryPool(device->vk_device, heap->vk_query_pool, NULL));
@@ -2729,10 +2730,15 @@ static HRESULT STDMETHODCALLTYPE d3d12_query_heap_SetPrivateDataInterface(ID3D12
 static HRESULT STDMETHODCALLTYPE d3d12_query_heap_SetName(ID3D12QueryHeap *iface, const WCHAR *name)
 {
     struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface);
+    HRESULT hr;
 
-    FIXME("iface %p, name %s stub!\n", iface, debugstr_w(name, heap->device->wchar_size));
+    TRACE("iface %p, name %s.\n", iface, debugstr_w(name, heap->device->wchar_size));
 
-    return E_NOTIMPL;
+    hr = vkd3d_set_vk_object_name(heap->device, (uint64_t)heap->vk_query_pool,
+                                  VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, name);
+    if (FAILED(hr)) return hr;
+
+    return vkd3d_set_name(&heap->name, name, heap->device->wchar_size);
 }
 
 static HRESULT STDMETHODCALLTYPE d3d12_query_heap_GetDevice(ID3D12QueryHeap *iface,
@@ -2784,6 +2790,7 @@ HRESULT d3d12_query_heap_create(struct d3d12_device *device, const D3D12_QUERY_H
 
     object->ID3D12QueryHeap_iface.lpVtbl = &d3d12_query_heap_vtbl;
     object->refcount = 1;
+    object->name = NULL;
     object->device = device;
     memset(object->availability_mask, 0, element_count * sizeof(*object->availability_mask));
 
diff --git a/libs/vkd3d/utils.c b/libs/vkd3d/utils.c
index 0144fdc..10ed88f 100644
--- a/libs/vkd3d/utils.c
+++ b/libs/vkd3d/utils.c
@@ -642,3 +642,64 @@ HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store,
     pthread_mutex_unlock(&store->mutex);
     return hr;
 }
+
+HRESULT vkd3d_set_vk_object_name(struct d3d12_device *device, uint64_t vk_object,
+                                 VkDebugReportObjectTypeEXT vk_object_type, const WCHAR *name)
+{
+    const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+    VkDebugMarkerObjectNameInfoEXT info = {0};
+    char *buffer;
+    int length;
+    int size;
+    VkResult vr;
+
+    if (!name)
+        return E_INVALIDARG;
+
+    if (!device->vk_info.EXT_debug_marker)
+        return S_OK;
+
+    if (device->wchar_size == 2)
+    {
+        length = vkd3d_strlen_w16((const uint16_t *)name);
+        size = wine_utf8_wcstombs_w16(0, (const uint16_t *)name, length + 1, NULL, 0);
+    }
+    else
+    {
+        length = vkd3d_strlen_w32((const uint32_t *)name);
+        size = wine_utf8_wcstombs_w32(0, (const uint32_t *)name, length + 1, NULL, 0);
+    }
+
+    if (!(buffer = vkd3d_malloc(size)))
+        return E_OUTOFMEMORY;
+
+    if (device->wchar_size == 2)
+        wine_utf8_wcstombs_w16(0, (const uint16_t *)name, length + 1, buffer, size);
+    else
+        wine_utf8_wcstombs_w32(0, (const uint32_t *)name, length + 1, buffer, size);
+
+    info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT;
+    info.objectType = vk_object_type;
+    info.object = vk_object;
+    info.pObjectName = buffer;
+    vr = VK_CALL(vkDebugMarkerSetObjectNameEXT(device->vk_device, &info));
+
+    vkd3d_free(buffer);
+    return vr == VK_SUCCESS ? S_OK : E_OUTOFMEMORY;
+}
+
+HRESULT vkd3d_set_name(WCHAR **dst, const WCHAR *src, size_t wchar_size)
+{
+    if (!src)
+        return E_INVALIDARG;
+
+    if (*dst)
+        vkd3d_free(*dst);
+
+    *dst = vkd3d_strdup_w(src, wchar_size);
+
+    if (!*dst)
+        return E_OUTOFMEMORY;
+
+    return S_OK;
+}
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 73825bb..80e909d 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -25,6 +25,8 @@
 
 #include "vkd3d_common.h"
 #include "vkd3d_memory.h"
+#include "vkd3d_string.h"
+#include "vkd3d_utf8.h"
 #include "list.h"
 #include "rbtree.h"
 
@@ -86,6 +88,7 @@ struct vkd3d_vulkan_info
     bool KHR_get_physical_device_properties2;
     bool EXT_debug_report;
     /* device extensions */
+    bool EXT_debug_marker;
     bool KHR_push_descriptor;
     bool EXT_transform_feedback;
     bool EXT_vertex_attribute_divisor;
@@ -480,6 +483,7 @@ struct d3d12_query_heap
 {
     ID3D12QueryHeap ID3D12QueryHeap_iface;
     LONG refcount;
+    WCHAR *name;
 
     VkQueryPool vk_query_pool;
 
@@ -1026,4 +1030,8 @@ static inline void vkd3d_set_thread_name(const char *name)
 #endif
 }
 
+HRESULT vkd3d_set_vk_object_name(struct d3d12_device *device, uint64_t vk_object,
+                                 VkDebugReportObjectTypeEXT vk_object_type, const WCHAR *name) DECLSPEC_HIDDEN;
+HRESULT vkd3d_set_name(WCHAR **dst, const WCHAR *src, size_t wchar_size) DECLSPEC_HIDDEN;
+
 #endif  /* __VKD3D_PRIVATE_H */
diff --git a/libs/vkd3d/vulkan_procs.h b/libs/vkd3d/vulkan_procs.h
index be983ec..b62af4e 100644
--- a/libs/vkd3d/vulkan_procs.h
+++ b/libs/vkd3d/vulkan_procs.h
@@ -174,6 +174,8 @@ VK_DEVICE_PFN(vkSetEvent)
 VK_DEVICE_PFN(vkUnmapMemory)
 VK_DEVICE_PFN(vkUpdateDescriptorSets)
 VK_DEVICE_PFN(vkWaitForFences)
+/* VK_EXT_debug_marker */
+VK_DEVICE_EXT_PFN(vkDebugMarkerSetObjectNameEXT)
 /* VK_KHR_push_descriptor */
 VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR)
 /* VK_EXT_transform_feedback */
-- 
2.19.2





More information about the wine-devel mailing list