2023-10-12 15:57:25 -07:00
|
|
|
From b7cf024c15c33db9f98f4c23e6ed0c151e61de9a Mon Sep 17 00:00:00 2001
|
2023-09-23 15:30:07 -07:00
|
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
|
|
Date: Wed, 17 May 2023 08:35:40 +1000
|
2023-10-12 15:57:25 -07:00
|
|
|
Subject: [PATCH] Updated vkd3d to ca05e57e67306e9b97eb22a35cd77728e3e91db9
|
2023-09-23 15:30:07 -07:00
|
|
|
|
|
|
|
---
|
|
|
|
libs/vkd3d/include/list.h | 270 +++++++++++
|
|
|
|
libs/vkd3d/include/private/list.h | 270 +++++++++++
|
|
|
|
libs/vkd3d/include/private/rbtree.h | 378 +++++++++++++++
|
|
|
|
libs/vkd3d/include/private/vkd3d_common.h | 2 +-
|
|
|
|
libs/vkd3d/include/private/vkd3d_test.h | 432 ++++++++++++++++++
|
|
|
|
libs/vkd3d/include/vkd3d_d3d9types.h | 237 ++++++++++
|
|
|
|
libs/vkd3d/include/vkd3d_d3dcompiler.h | 74 +++
|
|
|
|
libs/vkd3d/include/vkd3d_utils.h | 108 +++++
|
|
|
|
libs/vkd3d/include/vkd3d_windows.h | 289 ++++++++++++
|
|
|
|
libs/vkd3d/libs/vkd3d-common/blob.c | 1 +
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 30 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 10 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 2 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 35 +-
|
|
|
|
.../libs/vkd3d-shader/hlsl_constant_ops.c | 187 +++++++-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 150 +++++-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/preproc.h | 2 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 14 +-
|
|
|
|
.../libs/vkd3d-shader/vkd3d_shader_main.c | 22 +
|
|
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 35 +-
|
|
|
|
libs/vkd3d/libs/vkd3d/command.c | 1 +
|
|
|
|
libs/vkd3d/libs/vkd3d/device.c | 199 ++++----
|
|
|
|
libs/vkd3d/libs/vkd3d/resource.c | 2 +-
|
|
|
|
libs/vkd3d/libs/vkd3d/vkd3d_main.c | 4 +-
|
|
|
|
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 16 +-
|
|
|
|
27 files changed, 2597 insertions(+), 177 deletions(-)
|
|
|
|
create mode 100644 libs/vkd3d/include/list.h
|
|
|
|
create mode 100644 libs/vkd3d/include/private/list.h
|
|
|
|
create mode 100644 libs/vkd3d/include/private/rbtree.h
|
|
|
|
create mode 100644 libs/vkd3d/include/private/vkd3d_test.h
|
|
|
|
create mode 100644 libs/vkd3d/include/vkd3d_d3d9types.h
|
|
|
|
create mode 100644 libs/vkd3d/include/vkd3d_d3dcompiler.h
|
|
|
|
create mode 100644 libs/vkd3d/include/vkd3d_utils.h
|
|
|
|
create mode 100644 libs/vkd3d/include/vkd3d_windows.h
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/include/list.h b/libs/vkd3d/include/list.h
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..2e1d95f3fd4
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libs/vkd3d/include/list.h
|
|
|
|
@@ -0,0 +1,270 @@
|
|
|
|
+/*
|
|
|
|
+ * Linked lists support
|
|
|
|
+ *
|
|
|
|
+ * Copyright (C) 2002 Alexandre Julliard
|
|
|
|
+ *
|
|
|
|
+ * 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 __WINE_SERVER_LIST_H
|
|
|
|
+#define __WINE_SERVER_LIST_H
|
|
|
|
+
|
|
|
|
+#include <stddef.h>
|
|
|
|
+
|
|
|
|
+struct list
|
|
|
|
+{
|
|
|
|
+ struct list *next;
|
|
|
|
+ struct list *prev;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/* Define a list like so:
|
|
|
|
+ *
|
|
|
|
+ * struct gadget
|
|
|
|
+ * {
|
|
|
|
+ * struct list entry; <-- doesn't have to be the first item in the struct
|
|
|
|
+ * int a, b;
|
|
|
|
+ * };
|
|
|
|
+ *
|
|
|
|
+ * static struct list global_gadgets = LIST_INIT( global_gadgets );
|
|
|
|
+ *
|
|
|
|
+ * or
|
|
|
|
+ *
|
|
|
|
+ * struct some_global_thing
|
|
|
|
+ * {
|
|
|
|
+ * struct list gadgets;
|
|
|
|
+ * };
|
|
|
|
+ *
|
|
|
|
+ * list_init( &some_global_thing->gadgets );
|
|
|
|
+ *
|
|
|
|
+ * Manipulate it like this:
|
|
|
|
+ *
|
|
|
|
+ * list_add_head( &global_gadgets, &new_gadget->entry );
|
|
|
|
+ * list_remove( &new_gadget->entry );
|
|
|
|
+ * list_add_after( &some_random_gadget->entry, &new_gadget->entry );
|
|
|
|
+ *
|
|
|
|
+ * And to iterate over it:
|
|
|
|
+ *
|
|
|
|
+ * struct gadget *gadget;
|
|
|
|
+ * LIST_FOR_EACH_ENTRY( gadget, &global_gadgets, struct gadget, entry )
|
|
|
|
+ * {
|
|
|
|
+ * ...
|
|
|
|
+ * }
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+/* add an element after the specified one */
|
|
|
|
+static inline void list_add_after( struct list *elem, struct list *to_add )
|
|
|
|
+{
|
|
|
|
+ to_add->next = elem->next;
|
|
|
|
+ to_add->prev = elem;
|
|
|
|
+ elem->next->prev = to_add;
|
|
|
|
+ elem->next = to_add;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* add an element before the specified one */
|
|
|
|
+static inline void list_add_before( struct list *elem, struct list *to_add )
|
|
|
|
+{
|
|
|
|
+ to_add->next = elem;
|
|
|
|
+ to_add->prev = elem->prev;
|
|
|
|
+ elem->prev->next = to_add;
|
|
|
|
+ elem->prev = to_add;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* add element at the head of the list */
|
|
|
|
+static inline void list_add_head( struct list *list, struct list *elem )
|
|
|
|
+{
|
|
|
|
+ list_add_after( list, elem );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* add element at the tail of the list */
|
|
|
|
+static inline void list_add_tail( struct list *list, struct list *elem )
|
|
|
|
+{
|
|
|
|
+ list_add_before( list, elem );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* remove an element from its list */
|
|
|
|
+static inline void list_remove( struct list *elem )
|
|
|
|
+{
|
|
|
|
+ elem->next->prev = elem->prev;
|
|
|
|
+ elem->prev->next = elem->next;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* get the next element */
|
|
|
|
+static inline struct list *list_next( const struct list *list, const struct list *elem )
|
|
|
|
+{
|
|
|
|
+ struct list *ret = elem->next;
|
|
|
|
+ if (elem->next == list) ret = NULL;
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* get the previous element */
|
|
|
|
+static inline struct list *list_prev( const struct list *list, const struct list *elem )
|
|
|
|
+{
|
|
|
|
+ struct list *ret = elem->prev;
|
|
|
|
+ if (elem->prev == list) ret = NULL;
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* get the first element */
|
|
|
|
+static inline struct list *list_head( const struct list *list )
|
|
|
|
+{
|
|
|
|
+ return list_next( list, list );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* get the last element */
|
|
|
|
+static inline struct list *list_tail( const struct list *list )
|
|
|
|
+{
|
|
|
|
+ return list_prev( list, list );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* check if a list is empty */
|
|
|
|
+static inline int list_empty( const struct list *list )
|
|
|
|
+{
|
|
|
|
+ return list->next == list;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* initialize a list */
|
|
|
|
+static inline void list_init( struct list *list )
|
|
|
|
+{
|
|
|
|
+ list->next = list->prev = list;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* count the elements of a list */
|
|
|
|
+static inline unsigned int list_count( const struct list *list )
|
|
|
|
+{
|
|
|
|
+ unsigned count = 0;
|
|
|
|
+ const struct list *ptr;
|
|
|
|
+ for (ptr = list->next; ptr != list; ptr = ptr->next) count++;
|
|
|
|
+ return count;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move all elements from src to before the specified element */
|
|
|
|
+static inline void list_move_before( struct list *dst, struct list *src )
|
|
|
|
+{
|
|
|
|
+ if (list_empty(src)) return;
|
|
|
|
+
|
|
|
|
+ dst->prev->next = src->next;
|
|
|
|
+ src->next->prev = dst->prev;
|
|
|
|
+ dst->prev = src->prev;
|
|
|
|
+ src->prev->next = dst;
|
|
|
|
+ list_init(src);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move all elements from src to after the specified element */
|
|
|
|
+static inline void list_move_after( struct list *dst, struct list *src )
|
|
|
|
+{
|
|
|
|
+ if (list_empty(src)) return;
|
|
|
|
+
|
|
|
|
+ dst->next->prev = src->prev;
|
|
|
|
+ src->prev->next = dst->next;
|
|
|
|
+ dst->next = src->next;
|
|
|
|
+ src->next->prev = dst;
|
|
|
|
+ list_init(src);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move all elements from src to the head of dst */
|
|
|
|
+static inline void list_move_head( struct list *dst, struct list *src )
|
|
|
|
+{
|
|
|
|
+ list_move_after( dst, src );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move all elements from src to the tail of dst */
|
|
|
|
+static inline void list_move_tail( struct list *dst, struct list *src )
|
|
|
|
+{
|
|
|
|
+ list_move_before( dst, src );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move the slice of elements from begin to end inclusive to the head of dst */
|
|
|
|
+static inline void list_move_slice_head( struct list *dst, struct list *begin, struct list *end )
|
|
|
|
+{
|
|
|
|
+ struct list *dst_next = dst->next;
|
|
|
|
+ begin->prev->next = end->next;
|
|
|
|
+ end->next->prev = begin->prev;
|
|
|
|
+ dst->next = begin;
|
|
|
|
+ dst_next->prev = end;
|
|
|
|
+ begin->prev = dst;
|
|
|
|
+ end->next = dst_next;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move the slice of elements from begin to end inclusive to the tail of dst */
|
|
|
|
+static inline void list_move_slice_tail( struct list *dst, struct list *begin, struct list *end )
|
|
|
|
+{
|
|
|
|
+ struct list *dst_prev = dst->prev;
|
|
|
|
+ begin->prev->next = end->next;
|
|
|
|
+ end->next->prev = begin->prev;
|
|
|
|
+ dst_prev->next = begin;
|
|
|
|
+ dst->prev = end;
|
|
|
|
+ begin->prev = dst_prev;
|
|
|
|
+ end->next = dst;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* iterate through the list */
|
|
|
|
+#define LIST_FOR_EACH(cursor,list) \
|
|
|
|
+ for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
|
|
|
|
+
|
|
|
|
+/* iterate through the list, with safety against removal */
|
|
|
|
+#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
|
|
|
|
+ for ((cursor) = (list)->next, (cursor2) = (cursor)->next; \
|
|
|
|
+ (cursor) != (list); \
|
|
|
|
+ (cursor) = (cursor2), (cursor2) = (cursor)->next)
|
|
|
|
+
|
|
|
|
+/* iterate through the list using a list entry */
|
|
|
|
+#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
|
|
|
|
+ for ((elem) = LIST_ENTRY((list)->next, type, field); \
|
|
|
|
+ &(elem)->field != (list); \
|
|
|
|
+ (elem) = LIST_ENTRY((elem)->field.next, type, field))
|
|
|
|
+
|
|
|
|
+/* iterate through the list using a list entry, with safety against removal */
|
|
|
|
+#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
|
|
|
|
+ for ((cursor) = LIST_ENTRY((list)->next, type, field), \
|
|
|
|
+ (cursor2) = LIST_ENTRY((cursor)->field.next, type, field); \
|
|
|
|
+ &(cursor)->field != (list); \
|
|
|
|
+ (cursor) = (cursor2), \
|
|
|
|
+ (cursor2) = LIST_ENTRY((cursor)->field.next, type, field))
|
|
|
|
+
|
|
|
|
+/* iterate through the list in reverse order */
|
|
|
|
+#define LIST_FOR_EACH_REV(cursor,list) \
|
|
|
|
+ for ((cursor) = (list)->prev; (cursor) != (list); (cursor) = (cursor)->prev)
|
|
|
|
+
|
|
|
|
+/* iterate through the list in reverse order, with safety against removal */
|
|
|
|
+#define LIST_FOR_EACH_SAFE_REV(cursor, cursor2, list) \
|
|
|
|
+ for ((cursor) = (list)->prev, (cursor2) = (cursor)->prev; \
|
|
|
|
+ (cursor) != (list); \
|
|
|
|
+ (cursor) = (cursor2), (cursor2) = (cursor)->prev)
|
|
|
|
+
|
|
|
|
+/* iterate through the list in reverse order using a list entry */
|
|
|
|
+#define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) \
|
|
|
|
+ for ((elem) = LIST_ENTRY((list)->prev, type, field); \
|
|
|
|
+ &(elem)->field != (list); \
|
|
|
|
+ (elem) = LIST_ENTRY((elem)->field.prev, type, field))
|
|
|
|
+
|
|
|
|
+/* iterate through the list in reverse order using a list entry, with safety against removal */
|
|
|
|
+#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field) \
|
|
|
|
+ for ((cursor) = LIST_ENTRY((list)->prev, type, field), \
|
|
|
|
+ (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field); \
|
|
|
|
+ &(cursor)->field != (list); \
|
|
|
|
+ (cursor) = (cursor2), \
|
|
|
|
+ (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field))
|
|
|
|
+
|
|
|
|
+/* macros for statically initialized lists */
|
|
|
|
+#undef LIST_INIT
|
|
|
|
+#define LIST_INIT(list) { &(list), &(list) }
|
|
|
|
+
|
|
|
|
+/* get pointer to object containing list element */
|
|
|
|
+#undef LIST_ENTRY
|
|
|
|
+#define LIST_ENTRY(elem, type, field) \
|
|
|
|
+ ((type *)((char *)(elem) - offsetof(type, field)))
|
|
|
|
+
|
|
|
|
+#endif /* __WINE_SERVER_LIST_H */
|
|
|
|
diff --git a/libs/vkd3d/include/private/list.h b/libs/vkd3d/include/private/list.h
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..2e1d95f3fd4
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libs/vkd3d/include/private/list.h
|
|
|
|
@@ -0,0 +1,270 @@
|
|
|
|
+/*
|
|
|
|
+ * Linked lists support
|
|
|
|
+ *
|
|
|
|
+ * Copyright (C) 2002 Alexandre Julliard
|
|
|
|
+ *
|
|
|
|
+ * 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 __WINE_SERVER_LIST_H
|
|
|
|
+#define __WINE_SERVER_LIST_H
|
|
|
|
+
|
|
|
|
+#include <stddef.h>
|
|
|
|
+
|
|
|
|
+struct list
|
|
|
|
+{
|
|
|
|
+ struct list *next;
|
|
|
|
+ struct list *prev;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/* Define a list like so:
|
|
|
|
+ *
|
|
|
|
+ * struct gadget
|
|
|
|
+ * {
|
|
|
|
+ * struct list entry; <-- doesn't have to be the first item in the struct
|
|
|
|
+ * int a, b;
|
|
|
|
+ * };
|
|
|
|
+ *
|
|
|
|
+ * static struct list global_gadgets = LIST_INIT( global_gadgets );
|
|
|
|
+ *
|
|
|
|
+ * or
|
|
|
|
+ *
|
|
|
|
+ * struct some_global_thing
|
|
|
|
+ * {
|
|
|
|
+ * struct list gadgets;
|
|
|
|
+ * };
|
|
|
|
+ *
|
|
|
|
+ * list_init( &some_global_thing->gadgets );
|
|
|
|
+ *
|
|
|
|
+ * Manipulate it like this:
|
|
|
|
+ *
|
|
|
|
+ * list_add_head( &global_gadgets, &new_gadget->entry );
|
|
|
|
+ * list_remove( &new_gadget->entry );
|
|
|
|
+ * list_add_after( &some_random_gadget->entry, &new_gadget->entry );
|
|
|
|
+ *
|
|
|
|
+ * And to iterate over it:
|
|
|
|
+ *
|
|
|
|
+ * struct gadget *gadget;
|
|
|
|
+ * LIST_FOR_EACH_ENTRY( gadget, &global_gadgets, struct gadget, entry )
|
|
|
|
+ * {
|
|
|
|
+ * ...
|
|
|
|
+ * }
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+/* add an element after the specified one */
|
|
|
|
+static inline void list_add_after( struct list *elem, struct list *to_add )
|
|
|
|
+{
|
|
|
|
+ to_add->next = elem->next;
|
|
|
|
+ to_add->prev = elem;
|
|
|
|
+ elem->next->prev = to_add;
|
|
|
|
+ elem->next = to_add;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* add an element before the specified one */
|
|
|
|
+static inline void list_add_before( struct list *elem, struct list *to_add )
|
|
|
|
+{
|
|
|
|
+ to_add->next = elem;
|
|
|
|
+ to_add->prev = elem->prev;
|
|
|
|
+ elem->prev->next = to_add;
|
|
|
|
+ elem->prev = to_add;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* add element at the head of the list */
|
|
|
|
+static inline void list_add_head( struct list *list, struct list *elem )
|
|
|
|
+{
|
|
|
|
+ list_add_after( list, elem );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* add element at the tail of the list */
|
|
|
|
+static inline void list_add_tail( struct list *list, struct list *elem )
|
|
|
|
+{
|
|
|
|
+ list_add_before( list, elem );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* remove an element from its list */
|
|
|
|
+static inline void list_remove( struct list *elem )
|
|
|
|
+{
|
|
|
|
+ elem->next->prev = elem->prev;
|
|
|
|
+ elem->prev->next = elem->next;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* get the next element */
|
|
|
|
+static inline struct list *list_next( const struct list *list, const struct list *elem )
|
|
|
|
+{
|
|
|
|
+ struct list *ret = elem->next;
|
|
|
|
+ if (elem->next == list) ret = NULL;
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* get the previous element */
|
|
|
|
+static inline struct list *list_prev( const struct list *list, const struct list *elem )
|
|
|
|
+{
|
|
|
|
+ struct list *ret = elem->prev;
|
|
|
|
+ if (elem->prev == list) ret = NULL;
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* get the first element */
|
|
|
|
+static inline struct list *list_head( const struct list *list )
|
|
|
|
+{
|
|
|
|
+ return list_next( list, list );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* get the last element */
|
|
|
|
+static inline struct list *list_tail( const struct list *list )
|
|
|
|
+{
|
|
|
|
+ return list_prev( list, list );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* check if a list is empty */
|
|
|
|
+static inline int list_empty( const struct list *list )
|
|
|
|
+{
|
|
|
|
+ return list->next == list;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* initialize a list */
|
|
|
|
+static inline void list_init( struct list *list )
|
|
|
|
+{
|
|
|
|
+ list->next = list->prev = list;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* count the elements of a list */
|
|
|
|
+static inline unsigned int list_count( const struct list *list )
|
|
|
|
+{
|
|
|
|
+ unsigned count = 0;
|
|
|
|
+ const struct list *ptr;
|
|
|
|
+ for (ptr = list->next; ptr != list; ptr = ptr->next) count++;
|
|
|
|
+ return count;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move all elements from src to before the specified element */
|
|
|
|
+static inline void list_move_before( struct list *dst, struct list *src )
|
|
|
|
+{
|
|
|
|
+ if (list_empty(src)) return;
|
|
|
|
+
|
|
|
|
+ dst->prev->next = src->next;
|
|
|
|
+ src->next->prev = dst->prev;
|
|
|
|
+ dst->prev = src->prev;
|
|
|
|
+ src->prev->next = dst;
|
|
|
|
+ list_init(src);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move all elements from src to after the specified element */
|
|
|
|
+static inline void list_move_after( struct list *dst, struct list *src )
|
|
|
|
+{
|
|
|
|
+ if (list_empty(src)) return;
|
|
|
|
+
|
|
|
|
+ dst->next->prev = src->prev;
|
|
|
|
+ src->prev->next = dst->next;
|
|
|
|
+ dst->next = src->next;
|
|
|
|
+ src->next->prev = dst;
|
|
|
|
+ list_init(src);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move all elements from src to the head of dst */
|
|
|
|
+static inline void list_move_head( struct list *dst, struct list *src )
|
|
|
|
+{
|
|
|
|
+ list_move_after( dst, src );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move all elements from src to the tail of dst */
|
|
|
|
+static inline void list_move_tail( struct list *dst, struct list *src )
|
|
|
|
+{
|
|
|
|
+ list_move_before( dst, src );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move the slice of elements from begin to end inclusive to the head of dst */
|
|
|
|
+static inline void list_move_slice_head( struct list *dst, struct list *begin, struct list *end )
|
|
|
|
+{
|
|
|
|
+ struct list *dst_next = dst->next;
|
|
|
|
+ begin->prev->next = end->next;
|
|
|
|
+ end->next->prev = begin->prev;
|
|
|
|
+ dst->next = begin;
|
|
|
|
+ dst_next->prev = end;
|
|
|
|
+ begin->prev = dst;
|
|
|
|
+ end->next = dst_next;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* move the slice of elements from begin to end inclusive to the tail of dst */
|
|
|
|
+static inline void list_move_slice_tail( struct list *dst, struct list *begin, struct list *end )
|
|
|
|
+{
|
|
|
|
+ struct list *dst_prev = dst->prev;
|
|
|
|
+ begin->prev->next = end->next;
|
|
|
|
+ end->next->prev = begin->prev;
|
|
|
|
+ dst_prev->next = begin;
|
|
|
|
+ dst->prev = end;
|
|
|
|
+ begin->prev = dst_prev;
|
|
|
|
+ end->next = dst;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* iterate through the list */
|
|
|
|
+#define LIST_FOR_EACH(cursor,list) \
|
|
|
|
+ for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
|
|
|
|
+
|
|
|
|
+/* iterate through the list, with safety against removal */
|
|
|
|
+#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
|
|
|
|
+ for ((cursor) = (list)->next, (cursor2) = (cursor)->next; \
|
|
|
|
+ (cursor) != (list); \
|
|
|
|
+ (cursor) = (cursor2), (cursor2) = (cursor)->next)
|
|
|
|
+
|
|
|
|
+/* iterate through the list using a list entry */
|
|
|
|
+#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
|
|
|
|
+ for ((elem) = LIST_ENTRY((list)->next, type, field); \
|
|
|
|
+ &(elem)->field != (list); \
|
|
|
|
+ (elem) = LIST_ENTRY((elem)->field.next, type, field))
|
|
|
|
+
|
|
|
|
+/* iterate through the list using a list entry, with safety against removal */
|
|
|
|
+#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
|
|
|
|
+ for ((cursor) = LIST_ENTRY((list)->next, type, field), \
|
|
|
|
+ (cursor2) = LIST_ENTRY((cursor)->field.next, type, field); \
|
|
|
|
+ &(cursor)->field != (list); \
|
|
|
|
+ (cursor) = (cursor2), \
|
|
|
|
+ (cursor2) = LIST_ENTRY((cursor)->field.next, type, field))
|
|
|
|
+
|
|
|
|
+/* iterate through the list in reverse order */
|
|
|
|
+#define LIST_FOR_EACH_REV(cursor,list) \
|
|
|
|
+ for ((cursor) = (list)->prev; (cursor) != (list); (cursor) = (cursor)->prev)
|
|
|
|
+
|
|
|
|
+/* iterate through the list in reverse order, with safety against removal */
|
|
|
|
+#define LIST_FOR_EACH_SAFE_REV(cursor, cursor2, list) \
|
|
|
|
+ for ((cursor) = (list)->prev, (cursor2) = (cursor)->prev; \
|
|
|
|
+ (cursor) != (list); \
|
|
|
|
+ (cursor) = (cursor2), (cursor2) = (cursor)->prev)
|
|
|
|
+
|
|
|
|
+/* iterate through the list in reverse order using a list entry */
|
|
|
|
+#define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) \
|
|
|
|
+ for ((elem) = LIST_ENTRY((list)->prev, type, field); \
|
|
|
|
+ &(elem)->field != (list); \
|
|
|
|
+ (elem) = LIST_ENTRY((elem)->field.prev, type, field))
|
|
|
|
+
|
|
|
|
+/* iterate through the list in reverse order using a list entry, with safety against removal */
|
|
|
|
+#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field) \
|
|
|
|
+ for ((cursor) = LIST_ENTRY((list)->prev, type, field), \
|
|
|
|
+ (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field); \
|
|
|
|
+ &(cursor)->field != (list); \
|
|
|
|
+ (cursor) = (cursor2), \
|
|
|
|
+ (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field))
|
|
|
|
+
|
|
|
|
+/* macros for statically initialized lists */
|
|
|
|
+#undef LIST_INIT
|
|
|
|
+#define LIST_INIT(list) { &(list), &(list) }
|
|
|
|
+
|
|
|
|
+/* get pointer to object containing list element */
|
|
|
|
+#undef LIST_ENTRY
|
|
|
|
+#define LIST_ENTRY(elem, type, field) \
|
|
|
|
+ ((type *)((char *)(elem) - offsetof(type, field)))
|
|
|
|
+
|
|
|
|
+#endif /* __WINE_SERVER_LIST_H */
|
|
|
|
diff --git a/libs/vkd3d/include/private/rbtree.h b/libs/vkd3d/include/private/rbtree.h
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..b5d38bca54c
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libs/vkd3d/include/private/rbtree.h
|
|
|
|
@@ -0,0 +1,378 @@
|
|
|
|
+/*
|
|
|
|
+ * Red-black search tree support
|
|
|
|
+ *
|
|
|
|
+ * Copyright 2009 Henri Verbeet
|
|
|
|
+ * Copyright 2009 Andrew Riedi
|
|
|
|
+ * Copyright 2016 Jacek Caban 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 __WINE_WINE_RBTREE_H
|
|
|
|
+#define __WINE_WINE_RBTREE_H
|
|
|
|
+
|
|
|
|
+#define RB_ENTRY_VALUE(element, type, field) \
|
|
|
|
+ ((type *)((char *)(element) - offsetof(type, field)))
|
|
|
|
+
|
|
|
|
+struct rb_entry
|
|
|
|
+{
|
|
|
|
+ struct rb_entry *parent;
|
|
|
|
+ struct rb_entry *left;
|
|
|
|
+ struct rb_entry *right;
|
|
|
|
+ unsigned int flags;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+typedef int (*rb_compare_func)(const void *key, const struct rb_entry *entry);
|
|
|
|
+
|
|
|
|
+struct rb_tree
|
|
|
|
+{
|
|
|
|
+ rb_compare_func compare;
|
|
|
|
+ struct rb_entry *root;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+typedef void (rb_traverse_func)(struct rb_entry *entry, void *context);
|
|
|
|
+
|
|
|
|
+#define RB_FLAG_RED 0x1
|
|
|
|
+
|
|
|
|
+static inline int rb_is_red(struct rb_entry *entry)
|
|
|
|
+{
|
|
|
|
+ return entry && (entry->flags & RB_FLAG_RED);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_rotate_left(struct rb_tree *tree, struct rb_entry *e)
|
|
|
|
+{
|
|
|
|
+ struct rb_entry *right = e->right;
|
|
|
|
+
|
|
|
|
+ if (!e->parent)
|
|
|
|
+ tree->root = right;
|
|
|
|
+ else if (e->parent->left == e)
|
|
|
|
+ e->parent->left = right;
|
|
|
|
+ else
|
|
|
|
+ e->parent->right = right;
|
|
|
|
+
|
|
|
|
+ e->right = right->left;
|
|
|
|
+ if (e->right) e->right->parent = e;
|
|
|
|
+ right->left = e;
|
|
|
|
+ right->parent = e->parent;
|
|
|
|
+ e->parent = right;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_rotate_right(struct rb_tree *tree, struct rb_entry *e)
|
|
|
|
+{
|
|
|
|
+ struct rb_entry *left = e->left;
|
|
|
|
+
|
|
|
|
+ if (!e->parent)
|
|
|
|
+ tree->root = left;
|
|
|
|
+ else if (e->parent->left == e)
|
|
|
|
+ e->parent->left = left;
|
|
|
|
+ else
|
|
|
|
+ e->parent->right = left;
|
|
|
|
+
|
|
|
|
+ e->left = left->right;
|
|
|
|
+ if (e->left) e->left->parent = e;
|
|
|
|
+ left->right = e;
|
|
|
|
+ left->parent = e->parent;
|
|
|
|
+ e->parent = left;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_flip_color(struct rb_entry *entry)
|
|
|
|
+{
|
|
|
|
+ entry->flags ^= RB_FLAG_RED;
|
|
|
|
+ entry->left->flags ^= RB_FLAG_RED;
|
|
|
|
+ entry->right->flags ^= RB_FLAG_RED;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline struct rb_entry *rb_head(struct rb_entry *iter)
|
|
|
|
+{
|
|
|
|
+ if (!iter) return NULL;
|
|
|
|
+ while (iter->left) iter = iter->left;
|
|
|
|
+ return iter;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline struct rb_entry *rb_next(struct rb_entry *iter)
|
|
|
|
+{
|
|
|
|
+ if (iter->right) return rb_head(iter->right);
|
|
|
|
+ while (iter->parent && iter->parent->right == iter) iter = iter->parent;
|
|
|
|
+ return iter->parent;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline struct rb_entry *rb_postorder_head(struct rb_entry *iter)
|
|
|
|
+{
|
|
|
|
+ if (!iter) return NULL;
|
|
|
|
+
|
|
|
|
+ for (;;) {
|
|
|
|
+ while (iter->left) iter = iter->left;
|
|
|
|
+ if (!iter->right) return iter;
|
|
|
|
+ iter = iter->right;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline struct rb_entry *rb_postorder_next(struct rb_entry *iter)
|
|
|
|
+{
|
|
|
|
+ if (!iter->parent) return NULL;
|
|
|
|
+ if (iter == iter->parent->right || !iter->parent->right) return iter->parent;
|
|
|
|
+ return rb_postorder_head(iter->parent->right);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* iterate through the tree */
|
|
|
|
+#define RB_FOR_EACH(cursor, tree) \
|
|
|
|
+ for ((cursor) = rb_head((tree)->root); (cursor); (cursor) = rb_next(cursor))
|
|
|
|
+
|
|
|
|
+/* iterate through the tree using a tree entry */
|
|
|
|
+#define RB_FOR_EACH_ENTRY(elem, tree, type, field) \
|
|
|
|
+ for ((elem) = RB_ENTRY_VALUE(rb_head((tree)->root), type, field); \
|
|
|
|
+ (elem) != RB_ENTRY_VALUE(0, type, field); \
|
|
|
|
+ (elem) = RB_ENTRY_VALUE(rb_next(&elem->field), type, field))
|
|
|
|
+
|
|
|
|
+/* iterate through the tree using using postorder, making it safe to free the entry */
|
|
|
|
+#define RB_FOR_EACH_DESTRUCTOR(cursor, cursor2, tree) \
|
|
|
|
+ for ((cursor) = rb_postorder_head((tree)->root); \
|
|
|
|
+ (cursor) && (((cursor2) = rb_postorder_next(cursor)) || 1); \
|
|
|
|
+ (cursor) = (cursor2))
|
|
|
|
+
|
|
|
|
+/* iterate through the tree using a tree entry and postorder, making it safe to free the entry */
|
|
|
|
+#define RB_FOR_EACH_ENTRY_DESTRUCTOR(elem, elem2, tree, type, field) \
|
|
|
|
+ for ((elem) = RB_ENTRY_VALUE(rb_postorder_head((tree)->root), type, field); \
|
|
|
|
+ (elem) != WINE_RB_ENTRY_VALUE(0, type, field) \
|
|
|
|
+ && (((elem2) = RB_ENTRY_VALUE(rb_postorder_next(&(elem)->field), type, field)) || 1); \
|
|
|
|
+ (elem) = (elem2))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static inline void rb_postorder(struct rb_tree *tree, rb_traverse_func *callback, void *context)
|
|
|
|
+{
|
|
|
|
+ struct rb_entry *iter, *next;
|
|
|
|
+ RB_FOR_EACH_DESTRUCTOR(iter, next, tree) callback(iter, context);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_init(struct rb_tree *tree, rb_compare_func compare)
|
|
|
|
+{
|
|
|
|
+ tree->compare = compare;
|
|
|
|
+ tree->root = NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_for_each_entry(struct rb_tree *tree, rb_traverse_func *callback, void *context)
|
|
|
|
+{
|
|
|
|
+ struct rb_entry *iter;
|
|
|
|
+ RB_FOR_EACH(iter, tree) callback(iter, context);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_clear(struct rb_tree *tree, rb_traverse_func *callback, void *context)
|
|
|
|
+{
|
|
|
|
+ /* Note that we use postorder here because the callback will likely free the entry. */
|
|
|
|
+ if (callback) rb_postorder(tree, callback, context);
|
|
|
|
+ tree->root = NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_destroy(struct rb_tree *tree, rb_traverse_func *callback, void *context)
|
|
|
|
+{
|
|
|
|
+ rb_clear(tree, callback, context);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline struct rb_entry *rb_get(const struct rb_tree *tree, const void *key)
|
|
|
|
+{
|
|
|
|
+ struct rb_entry *entry = tree->root;
|
|
|
|
+ while (entry)
|
|
|
|
+ {
|
|
|
|
+ int c = tree->compare(key, entry);
|
|
|
|
+ if (!c) return entry;
|
|
|
|
+ entry = c < 0 ? entry->left : entry->right;
|
|
|
|
+ }
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline int rb_put(struct rb_tree *tree, const void *key, struct rb_entry *entry)
|
|
|
|
+{
|
|
|
|
+ struct rb_entry **iter = &tree->root, *parent = tree->root;
|
|
|
|
+
|
|
|
|
+ while (*iter)
|
|
|
|
+ {
|
|
|
|
+ int c;
|
|
|
|
+
|
|
|
|
+ parent = *iter;
|
|
|
|
+ c = tree->compare(key, parent);
|
|
|
|
+ if (!c) return -1;
|
|
|
|
+ else if (c < 0) iter = &parent->left;
|
|
|
|
+ else iter = &parent->right;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ entry->flags = RB_FLAG_RED;
|
|
|
|
+ entry->parent = parent;
|
|
|
|
+ entry->left = NULL;
|
|
|
|
+ entry->right = NULL;
|
|
|
|
+ *iter = entry;
|
|
|
|
+
|
|
|
|
+ while (rb_is_red(entry->parent))
|
|
|
|
+ {
|
|
|
|
+ if (entry->parent == entry->parent->parent->left)
|
|
|
|
+ {
|
|
|
|
+ if (rb_is_red(entry->parent->parent->right))
|
|
|
|
+ {
|
|
|
|
+ rb_flip_color(entry->parent->parent);
|
|
|
|
+ entry = entry->parent->parent;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (entry == entry->parent->right)
|
|
|
|
+ {
|
|
|
|
+ entry = entry->parent;
|
|
|
|
+ rb_rotate_left(tree, entry);
|
|
|
|
+ }
|
|
|
|
+ entry->parent->flags &= ~RB_FLAG_RED;
|
|
|
|
+ entry->parent->parent->flags |= RB_FLAG_RED;
|
|
|
|
+ rb_rotate_right(tree, entry->parent->parent);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (rb_is_red(entry->parent->parent->left))
|
|
|
|
+ {
|
|
|
|
+ rb_flip_color(entry->parent->parent);
|
|
|
|
+ entry = entry->parent->parent;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (entry == entry->parent->left)
|
|
|
|
+ {
|
|
|
|
+ entry = entry->parent;
|
|
|
|
+ rb_rotate_right(tree, entry);
|
|
|
|
+ }
|
|
|
|
+ entry->parent->flags &= ~RB_FLAG_RED;
|
|
|
|
+ entry->parent->parent->flags |= RB_FLAG_RED;
|
|
|
|
+ rb_rotate_left(tree, entry->parent->parent);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ tree->root->flags &= ~RB_FLAG_RED;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_remove(struct rb_tree *tree, struct rb_entry *entry)
|
|
|
|
+{
|
|
|
|
+ struct rb_entry *iter, *child, *parent, *w;
|
|
|
|
+ int need_fixup;
|
|
|
|
+
|
|
|
|
+ if (entry->right && entry->left)
|
|
|
|
+ for(iter = entry->right; iter->left; iter = iter->left);
|
|
|
|
+ else
|
|
|
|
+ iter = entry;
|
|
|
|
+
|
|
|
|
+ child = iter->left ? iter->left : iter->right;
|
|
|
|
+
|
|
|
|
+ if (!iter->parent)
|
|
|
|
+ tree->root = child;
|
|
|
|
+ else if (iter == iter->parent->left)
|
|
|
|
+ iter->parent->left = child;
|
|
|
|
+ else
|
|
|
|
+ iter->parent->right = child;
|
|
|
|
+
|
|
|
|
+ if (child) child->parent = iter->parent;
|
|
|
|
+ parent = iter->parent;
|
|
|
|
+
|
|
|
|
+ need_fixup = !rb_is_red(iter);
|
|
|
|
+
|
|
|
|
+ if (entry != iter)
|
|
|
|
+ {
|
|
|
|
+ *iter = *entry;
|
|
|
|
+ if (!iter->parent)
|
|
|
|
+ tree->root = iter;
|
|
|
|
+ else if (entry == iter->parent->left)
|
|
|
|
+ iter->parent->left = iter;
|
|
|
|
+ else
|
|
|
|
+ iter->parent->right = iter;
|
|
|
|
+
|
|
|
|
+ if (iter->right) iter->right->parent = iter;
|
|
|
|
+ if (iter->left) iter->left->parent = iter;
|
|
|
|
+ if (parent == entry) parent = iter;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (need_fixup)
|
|
|
|
+ {
|
|
|
|
+ while (parent && !rb_is_red(child))
|
|
|
|
+ {
|
|
|
|
+ if (child == parent->left)
|
|
|
|
+ {
|
|
|
|
+ w = parent->right;
|
|
|
|
+ if (rb_is_red(w))
|
|
|
|
+ {
|
|
|
|
+ w->flags &= ~RB_FLAG_RED;
|
|
|
|
+ parent->flags |= RB_FLAG_RED;
|
|
|
|
+ rb_rotate_left(tree, parent);
|
|
|
|
+ w = parent->right;
|
|
|
|
+ }
|
|
|
|
+ if (rb_is_red(w->left) || rb_is_red(w->right))
|
|
|
|
+ {
|
|
|
|
+ if (!rb_is_red(w->right))
|
|
|
|
+ {
|
|
|
|
+ w->left->flags &= ~RB_FLAG_RED;
|
|
|
|
+ w->flags |= RB_FLAG_RED;
|
|
|
|
+ rb_rotate_right(tree, w);
|
|
|
|
+ w = parent->right;
|
|
|
|
+ }
|
|
|
|
+ w->flags = (w->flags & ~RB_FLAG_RED) | (parent->flags & RB_FLAG_RED);
|
|
|
|
+ parent->flags &= ~RB_FLAG_RED;
|
|
|
|
+ if (w->right)
|
|
|
|
+ w->right->flags &= ~RB_FLAG_RED;
|
|
|
|
+ rb_rotate_left(tree, parent);
|
|
|
|
+ child = NULL;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ w = parent->left;
|
|
|
|
+ if (rb_is_red(w))
|
|
|
|
+ {
|
|
|
|
+ w->flags &= ~RB_FLAG_RED;
|
|
|
|
+ parent->flags |= RB_FLAG_RED;
|
|
|
|
+ rb_rotate_right(tree, parent);
|
|
|
|
+ w = parent->left;
|
|
|
|
+ }
|
|
|
|
+ if (rb_is_red(w->left) || rb_is_red(w->right))
|
|
|
|
+ {
|
|
|
|
+ if (!rb_is_red(w->left))
|
|
|
|
+ {
|
|
|
|
+ w->right->flags &= ~RB_FLAG_RED;
|
|
|
|
+ w->flags |= RB_FLAG_RED;
|
|
|
|
+ rb_rotate_left(tree, w);
|
|
|
|
+ w = parent->left;
|
|
|
|
+ }
|
|
|
|
+ w->flags = (w->flags & ~RB_FLAG_RED) | (parent->flags & RB_FLAG_RED);
|
|
|
|
+ parent->flags &= ~RB_FLAG_RED;
|
|
|
|
+ if (w->left)
|
|
|
|
+ w->left->flags &= ~RB_FLAG_RED;
|
|
|
|
+ rb_rotate_right(tree, parent);
|
|
|
|
+ child = NULL;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ w->flags |= RB_FLAG_RED;
|
|
|
|
+ child = parent;
|
|
|
|
+ parent = child->parent;
|
|
|
|
+ }
|
|
|
|
+ if (child) child->flags &= ~RB_FLAG_RED;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (tree->root) tree->root->flags &= ~RB_FLAG_RED;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void rb_remove_key(struct rb_tree *tree, const void *key)
|
|
|
|
+{
|
|
|
|
+ struct rb_entry *entry = rb_get(tree, key);
|
|
|
|
+ if (entry) rb_remove(tree, entry);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#endif /* __WINE_WINE_RBTREE_H */
|
|
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
|
|
|
|
index ee733ee0d76..f7d98f327f1 100644
|
|
|
|
--- a/libs/vkd3d/include/private/vkd3d_common.h
|
|
|
|
+++ b/libs/vkd3d/include/private/vkd3d_common.h
|
|
|
|
@@ -86,7 +86,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v)
|
|
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
return __popcnt(v);
|
|
|
|
-#elif defined(__MINGW32__)
|
|
|
|
+#elif defined(HAVE_BUILTIN_POPCOUNT)
|
|
|
|
return __builtin_popcount(v);
|
|
|
|
#else
|
|
|
|
v -= (v >> 1) & 0x55555555;
|
|
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_test.h b/libs/vkd3d/include/private/vkd3d_test.h
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..081443c4fa6
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libs/vkd3d/include/private/vkd3d_test.h
|
|
|
|
@@ -0,0 +1,432 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright 2016 Józef Kucia 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_TEST_H
|
|
|
|
+#define __VKD3D_TEST_H
|
|
|
|
+
|
|
|
|
+#include "vkd3d_common.h"
|
|
|
|
+#include <assert.h>
|
|
|
|
+#include <inttypes.h>
|
|
|
|
+#include <stdarg.h>
|
|
|
|
+#include <stdbool.h>
|
|
|
|
+#include <stdio.h>
|
|
|
|
+#include <stdlib.h>
|
|
|
|
+#include <string.h>
|
|
|
|
+
|
|
|
|
+extern const char *vkd3d_test_name;
|
|
|
|
+extern const char *vkd3d_test_platform;
|
|
|
|
+
|
|
|
|
+static void vkd3d_test_start_todo(bool is_todo);
|
|
|
|
+static int vkd3d_test_loop_todo(void);
|
|
|
|
+static void vkd3d_test_end_todo(void);
|
|
|
|
+
|
|
|
|
+#define START_TEST(name) \
|
|
|
|
+ const char *vkd3d_test_name = #name; \
|
|
|
|
+ static void vkd3d_test_main(int argc, char **argv)
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Use assert_that() for conditions that should always be true.
|
|
|
|
+ * todo_if() and bug_if() do not influence assert_that().
|
|
|
|
+ */
|
|
|
|
+#define assert_that assert_that_(__LINE__)
|
|
|
|
+
|
|
|
|
+#define ok ok_(__LINE__)
|
|
|
|
+
|
|
|
|
+#define skip skip_(__LINE__)
|
|
|
|
+
|
|
|
|
+#define trace trace_(__LINE__)
|
|
|
|
+
|
|
|
|
+#define assert_that_(line) \
|
|
|
|
+ do { \
|
|
|
|
+ unsigned int vkd3d_line = line; \
|
|
|
|
+ VKD3D_TEST_ASSERT_THAT
|
|
|
|
+
|
|
|
|
+#define VKD3D_TEST_ASSERT_THAT(...) \
|
|
|
|
+ vkd3d_test_assert_that(vkd3d_line, __VA_ARGS__); } while (0)
|
|
|
|
+
|
|
|
|
+#define ok_(line) \
|
|
|
|
+ do { \
|
|
|
|
+ unsigned int vkd3d_line = line; \
|
|
|
|
+ VKD3D_TEST_OK
|
|
|
|
+
|
|
|
|
+#define VKD3D_TEST_OK(...) \
|
|
|
|
+ vkd3d_test_ok(vkd3d_line, __VA_ARGS__); } while (0)
|
|
|
|
+
|
|
|
|
+#define todo_(line) \
|
|
|
|
+ do { \
|
|
|
|
+ unsigned int vkd3d_line = line; \
|
|
|
|
+ VKD3D_TEST_TODO
|
|
|
|
+
|
|
|
|
+#define VKD3D_TEST_TODO(...) \
|
|
|
|
+ vkd3d_test_todo(vkd3d_line, __VA_ARGS__); } while (0)
|
|
|
|
+
|
|
|
|
+#define skip_(line) \
|
|
|
|
+ do { \
|
|
|
|
+ unsigned int vkd3d_line = line; \
|
|
|
|
+ VKD3D_TEST_SKIP
|
|
|
|
+
|
|
|
|
+#define VKD3D_TEST_SKIP(...) \
|
|
|
|
+ vkd3d_test_skip(vkd3d_line, __VA_ARGS__); } while (0)
|
|
|
|
+
|
|
|
|
+#define trace_(line) \
|
|
|
|
+ do { \
|
|
|
|
+ unsigned int vkd3d_line = line; \
|
|
|
|
+ VKD3D_TEST_TRACE
|
|
|
|
+
|
|
|
|
+#define VKD3D_TEST_TRACE(...) \
|
|
|
|
+ vkd3d_test_trace(vkd3d_line, __VA_ARGS__); } while (0)
|
|
|
|
+
|
|
|
|
+#define todo_if(is_todo) \
|
|
|
|
+ for (vkd3d_test_start_todo(is_todo); vkd3d_test_loop_todo(); vkd3d_test_end_todo())
|
|
|
|
+
|
|
|
|
+#define bug_if(is_bug) \
|
|
|
|
+ for (vkd3d_test_start_bug(is_bug); vkd3d_test_loop_bug(); vkd3d_test_end_bug())
|
|
|
|
+
|
|
|
|
+#define todo todo_if(true)
|
|
|
|
+
|
|
|
|
+struct vkd3d_test_state
|
|
|
|
+{
|
|
|
|
+ LONG success_count;
|
|
|
|
+ LONG failure_count;
|
|
|
|
+ LONG skip_count;
|
|
|
|
+ LONG todo_count;
|
|
|
|
+ LONG todo_success_count;
|
|
|
|
+ LONG bug_count;
|
|
|
|
+
|
|
|
|
+ unsigned int debug_level;
|
|
|
|
+
|
|
|
|
+ unsigned int todo_level;
|
|
|
|
+ bool todo_do_loop;
|
|
|
|
+
|
|
|
|
+ unsigned int bug_level;
|
|
|
|
+ bool bug_do_loop;
|
|
|
|
+ bool bug_enabled;
|
|
|
|
+
|
|
|
|
+ const char *test_name_filter;
|
|
|
|
+ char context[8][128];
|
|
|
|
+ unsigned int context_count;
|
|
|
|
+};
|
|
|
|
+extern struct vkd3d_test_state vkd3d_test_state;
|
|
|
|
+
|
|
|
|
+static bool
|
|
|
|
+vkd3d_test_platform_is_windows(void)
|
|
|
|
+{
|
|
|
|
+ return !strcmp(vkd3d_test_platform, "windows");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline bool
|
|
|
|
+broken(bool condition)
|
|
|
|
+{
|
|
|
|
+ return condition && vkd3d_test_platform_is_windows();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void vkd3d_test_printf(unsigned int line, const char *msg)
|
|
|
|
+{
|
|
|
|
+ unsigned int i;
|
|
|
|
+
|
|
|
|
+ printf("%s:%u: ", vkd3d_test_name, line);
|
|
|
|
+ for (i = 0; i < vkd3d_test_state.context_count; ++i)
|
|
|
|
+ printf("%s: ", vkd3d_test_state.context[i]);
|
|
|
|
+ printf("%s", msg);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+vkd3d_test_check_assert_that(unsigned int line, bool result, const char *fmt, va_list args)
|
|
|
|
+{
|
|
|
|
+ if (result)
|
|
|
|
+ {
|
|
|
|
+ InterlockedIncrement(&vkd3d_test_state.success_count);
|
|
|
|
+ if (vkd3d_test_state.debug_level > 1)
|
|
|
|
+ vkd3d_test_printf(line, "Test succeeded.\n");
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ InterlockedIncrement(&vkd3d_test_state.failure_count);
|
|
|
|
+ vkd3d_test_printf(line, "Test failed: ");
|
|
|
|
+ vprintf(fmt, args);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void VKD3D_PRINTF_FUNC(3, 4) VKD3D_UNUSED
|
|
|
|
+vkd3d_test_assert_that(unsigned int line, bool result, const char *fmt, ...)
|
|
|
|
+{
|
|
|
|
+ va_list args;
|
|
|
|
+
|
|
|
|
+ va_start(args, fmt);
|
|
|
|
+ vkd3d_test_check_assert_that(line, result, fmt, args);
|
|
|
|
+ va_end(args);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+vkd3d_test_check_ok(unsigned int line, bool result, const char *fmt, va_list args)
|
|
|
|
+{
|
|
|
|
+ bool is_todo = vkd3d_test_state.todo_level && !vkd3d_test_platform_is_windows();
|
|
|
|
+ bool is_bug = vkd3d_test_state.bug_level && !vkd3d_test_platform_is_windows();
|
|
|
|
+
|
|
|
|
+ if (is_bug && vkd3d_test_state.bug_enabled)
|
|
|
|
+ {
|
|
|
|
+ InterlockedIncrement(&vkd3d_test_state.bug_count);
|
|
|
|
+ if (is_todo)
|
|
|
|
+ result = !result;
|
|
|
|
+ if (result)
|
|
|
|
+ vkd3d_test_printf(line, "Fixed bug: ");
|
|
|
|
+ else
|
|
|
|
+ vkd3d_test_printf(line, "Bug: ");
|
|
|
|
+ vprintf(fmt, args);
|
|
|
|
+ }
|
|
|
|
+ else if (is_todo)
|
|
|
|
+ {
|
|
|
|
+ if (result)
|
|
|
|
+ {
|
|
|
|
+ InterlockedIncrement(&vkd3d_test_state.todo_success_count);
|
|
|
|
+ vkd3d_test_printf(line, "Todo succeeded: ");
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ InterlockedIncrement(&vkd3d_test_state.todo_count);
|
|
|
|
+ vkd3d_test_printf(line, "Todo: ");
|
|
|
|
+ }
|
|
|
|
+ vprintf(fmt, args);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ vkd3d_test_check_assert_that(line, result, fmt, args);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void VKD3D_PRINTF_FUNC(3, 4) VKD3D_UNUSED
|
|
|
|
+vkd3d_test_ok(unsigned int line, bool result, const char *fmt, ...)
|
|
|
|
+{
|
|
|
|
+ va_list args;
|
|
|
|
+
|
|
|
|
+ va_start(args, fmt);
|
|
|
|
+ vkd3d_test_check_ok(line, result, fmt, args);
|
|
|
|
+ va_end(args);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void VKD3D_PRINTF_FUNC(2, 3) VKD3D_UNUSED
|
|
|
|
+vkd3d_test_skip(unsigned int line, const char *fmt, ...)
|
|
|
|
+{
|
|
|
|
+ va_list args;
|
|
|
|
+ va_start(args, fmt);
|
|
|
|
+ vkd3d_test_printf(line, "Test skipped: ");
|
|
|
|
+ vprintf(fmt, args);
|
|
|
|
+ va_end(args);
|
|
|
|
+ InterlockedIncrement(&vkd3d_test_state.skip_count);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void VKD3D_PRINTF_FUNC(2, 3) VKD3D_UNUSED
|
|
|
|
+vkd3d_test_trace(unsigned int line, const char *fmt, ...)
|
|
|
|
+{
|
|
|
|
+ va_list args;
|
|
|
|
+ va_start(args, fmt);
|
|
|
|
+ vkd3d_test_printf(line, "");
|
|
|
|
+ vprintf(fmt, args);
|
|
|
|
+ va_end(args);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void VKD3D_PRINTF_FUNC(1, 2) VKD3D_UNUSED
|
|
|
|
+vkd3d_test_debug(const char *fmt, ...)
|
|
|
|
+{
|
|
|
|
+ char buffer[512];
|
|
|
|
+ va_list args;
|
|
|
|
+ int size;
|
|
|
|
+
|
|
|
|
+ size = snprintf(buffer, sizeof(buffer), "%s: ", vkd3d_test_name);
|
|
|
|
+ if (0 < size && size < sizeof(buffer))
|
|
|
|
+ {
|
|
|
|
+ va_start(args, fmt);
|
|
|
|
+ vsnprintf(buffer + size, sizeof(buffer) - size, fmt, args);
|
|
|
|
+ va_end(args);
|
|
|
|
+ }
|
|
|
|
+ buffer[sizeof(buffer) - 1] = '\0';
|
|
|
|
+
|
|
|
|
+#ifdef _WIN32
|
|
|
|
+ OutputDebugStringA(buffer);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (vkd3d_test_state.debug_level > 0)
|
|
|
|
+ printf("%s\n", buffer);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#ifndef VKD3D_TEST_NO_DEFS
|
|
|
|
+const char *vkd3d_test_platform = "other";
|
|
|
|
+struct vkd3d_test_state vkd3d_test_state;
|
|
|
|
+
|
|
|
|
+static void vkd3d_test_main(int argc, char **argv);
|
|
|
|
+
|
|
|
|
+int main(int argc, char **argv)
|
|
|
|
+{
|
|
|
|
+ const char *test_filter = getenv("VKD3D_TEST_FILTER");
|
|
|
|
+ const char *debug_level = getenv("VKD3D_TEST_DEBUG");
|
|
|
|
+ char *test_platform = getenv("VKD3D_TEST_PLATFORM");
|
|
|
|
+ const char *bug = getenv("VKD3D_TEST_BUG");
|
|
|
|
+
|
|
|
|
+ memset(&vkd3d_test_state, 0, sizeof(vkd3d_test_state));
|
|
|
|
+ vkd3d_test_state.debug_level = debug_level ? atoi(debug_level) : 0;
|
|
|
|
+ vkd3d_test_state.bug_enabled = bug ? atoi(bug) : true;
|
|
|
|
+ vkd3d_test_state.test_name_filter = test_filter;
|
|
|
|
+
|
|
|
|
+ if (test_platform)
|
|
|
|
+ {
|
|
|
|
+ test_platform = strdup(test_platform);
|
|
|
|
+ vkd3d_test_platform = test_platform;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (vkd3d_test_state.debug_level > 1)
|
|
|
|
+ printf("Test platform: '%s'.\n", vkd3d_test_platform);
|
|
|
|
+
|
|
|
|
+ vkd3d_test_main(argc, argv);
|
|
|
|
+
|
|
|
|
+ printf("%s: %lu tests executed (%lu failures, %lu skipped, %lu todo, %lu bugs).\n",
|
|
|
|
+ vkd3d_test_name,
|
|
|
|
+ (unsigned long)(vkd3d_test_state.success_count
|
|
|
|
+ + vkd3d_test_state.failure_count + vkd3d_test_state.todo_count
|
|
|
|
+ + vkd3d_test_state.todo_success_count),
|
|
|
|
+ (unsigned long)(vkd3d_test_state.failure_count
|
|
|
|
+ + vkd3d_test_state.todo_success_count),
|
|
|
|
+ (unsigned long)vkd3d_test_state.skip_count,
|
|
|
|
+ (unsigned long)vkd3d_test_state.todo_count,
|
|
|
|
+ (unsigned long)vkd3d_test_state.bug_count);
|
|
|
|
+
|
|
|
|
+ if (test_platform)
|
|
|
|
+ free(test_platform);
|
|
|
|
+
|
|
|
|
+ return vkd3d_test_state.failure_count || vkd3d_test_state.todo_success_count;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#ifdef _WIN32
|
|
|
|
+static char *vkd3d_test_strdupWtoA(WCHAR *str)
|
|
|
|
+{
|
|
|
|
+ char *out;
|
|
|
|
+ int len;
|
|
|
|
+
|
|
|
|
+ if (!(len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL)))
|
|
|
|
+ return NULL;
|
|
|
|
+ if (!(out = malloc(len)))
|
|
|
|
+ return NULL;
|
|
|
|
+ WideCharToMultiByte(CP_ACP, 0, str, -1, out, len, NULL, NULL);
|
|
|
|
+
|
|
|
|
+ return out;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static bool running_under_wine(void)
|
|
|
|
+{
|
|
|
|
+ HMODULE module = GetModuleHandleA("ntdll.dll");
|
|
|
|
+ return module && GetProcAddress(module, "wine_server_call");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int wmain(int argc, WCHAR **wargv)
|
|
|
|
+{
|
|
|
|
+ char **argv;
|
|
|
|
+ int i, ret;
|
|
|
|
+
|
|
|
|
+ argv = malloc(argc * sizeof(*argv));
|
|
|
|
+ assert(argv);
|
|
|
|
+ for (i = 0; i < argc; ++i)
|
|
|
|
+ {
|
|
|
|
+ if (!(argv[i] = vkd3d_test_strdupWtoA(wargv[i])))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ assert(i == argc);
|
|
|
|
+
|
|
|
|
+ vkd3d_test_platform = running_under_wine() ? "wine" : "windows";
|
|
|
|
+
|
|
|
|
+ ret = main(argc, argv);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < argc; ++i)
|
|
|
|
+ free(argv[i]);
|
|
|
|
+ free(argv);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+#endif /* _WIN32 */
|
|
|
|
+#endif /* VKD3D_TEST_NO_DEFS */
|
|
|
|
+
|
|
|
|
+typedef void (*vkd3d_test_pfn)(void);
|
|
|
|
+
|
|
|
|
+static inline void vkd3d_run_test(const char *name, vkd3d_test_pfn test_pfn)
|
|
|
|
+{
|
|
|
|
+ if (vkd3d_test_state.test_name_filter && !strstr(name, vkd3d_test_state.test_name_filter))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ vkd3d_test_debug("%s", name);
|
|
|
|
+ test_pfn();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void vkd3d_test_start_todo(bool is_todo)
|
|
|
|
+{
|
|
|
|
+ vkd3d_test_state.todo_level = (vkd3d_test_state.todo_level << 1) | is_todo;
|
|
|
|
+ vkd3d_test_state.todo_do_loop = true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline int vkd3d_test_loop_todo(void)
|
|
|
|
+{
|
|
|
|
+ bool do_loop = vkd3d_test_state.todo_do_loop;
|
|
|
|
+ vkd3d_test_state.todo_do_loop = false;
|
|
|
|
+ return do_loop;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void vkd3d_test_end_todo(void)
|
|
|
|
+{
|
|
|
|
+ vkd3d_test_state.todo_level >>= 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void vkd3d_test_start_bug(bool is_bug)
|
|
|
|
+{
|
|
|
|
+ vkd3d_test_state.bug_level = (vkd3d_test_state.bug_level << 1) | is_bug;
|
|
|
|
+ vkd3d_test_state.bug_do_loop = true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline int vkd3d_test_loop_bug(void)
|
|
|
|
+{
|
|
|
|
+ bool do_loop = vkd3d_test_state.bug_do_loop;
|
|
|
|
+ vkd3d_test_state.bug_do_loop = false;
|
|
|
|
+ return do_loop;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void vkd3d_test_end_bug(void)
|
|
|
|
+{
|
|
|
|
+ vkd3d_test_state.bug_level >>= 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void vkd3d_test_push_context(const char *fmt, ...)
|
|
|
|
+{
|
|
|
|
+ va_list args;
|
|
|
|
+
|
|
|
|
+ if (vkd3d_test_state.context_count < ARRAY_SIZE(vkd3d_test_state.context))
|
|
|
|
+ {
|
|
|
|
+ va_start(args, fmt);
|
|
|
|
+ vsnprintf(vkd3d_test_state.context[vkd3d_test_state.context_count],
|
|
|
|
+ sizeof(vkd3d_test_state.context), fmt, args);
|
|
|
|
+ va_end(args);
|
|
|
|
+ vkd3d_test_state.context[vkd3d_test_state.context_count][sizeof(vkd3d_test_state.context[0]) - 1] = '\0';
|
|
|
|
+ }
|
|
|
|
+ ++vkd3d_test_state.context_count;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void vkd3d_test_pop_context(void)
|
|
|
|
+{
|
|
|
|
+ if (vkd3d_test_state.context_count)
|
|
|
|
+ --vkd3d_test_state.context_count;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define run_test(test_pfn) \
|
|
|
|
+ vkd3d_run_test(#test_pfn, test_pfn)
|
|
|
|
+
|
|
|
|
+#endif /* __VKD3D_TEST_H */
|
|
|
|
diff --git a/libs/vkd3d/include/vkd3d_d3d9types.h b/libs/vkd3d/include/vkd3d_d3d9types.h
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..75d0461409d
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libs/vkd3d/include/vkd3d_d3d9types.h
|
|
|
|
@@ -0,0 +1,237 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright 2002-2003 Jason Edmeades
|
|
|
|
+ * Copyright 2002-2003 Raphael Junqueira
|
|
|
|
+ *
|
|
|
|
+ * 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_D3D9TYPES_H
|
|
|
|
+#define __VKD3D_D3D9TYPES_H
|
|
|
|
+#ifndef _d3d9TYPES_H_
|
|
|
|
+
|
|
|
|
+#ifndef MAKEFOURCC
|
|
|
|
+#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
|
|
|
+ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
|
|
|
|
+ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#define D3DSI_INSTLENGTH_SHIFT 24
|
|
|
|
+
|
|
|
|
+#define D3DSP_DCL_USAGE_SHIFT 0
|
|
|
|
+#define D3DSP_DCL_USAGEINDEX_SHIFT 16
|
|
|
|
+#define D3DSP_DSTMOD_SHIFT 20
|
|
|
|
+
|
|
|
|
+#define D3DSP_SRCMOD_SHIFT 24
|
|
|
|
+
|
|
|
|
+#define D3DSP_REGTYPE_SHIFT 28
|
|
|
|
+#define D3DSP_REGTYPE_SHIFT2 8
|
|
|
|
+#define D3DSP_REGTYPE_MASK (0x7 << D3DSP_REGTYPE_SHIFT)
|
|
|
|
+#define D3DSP_REGTYPE_MASK2 0x00001800
|
|
|
|
+
|
|
|
|
+#define D3DSP_WRITEMASK_0 0x00010000
|
|
|
|
+#define D3DSP_WRITEMASK_1 0x00020000
|
|
|
|
+#define D3DSP_WRITEMASK_2 0x00040000
|
|
|
|
+#define D3DSP_WRITEMASK_3 0x00080000
|
|
|
|
+#define D3DSP_WRITEMASK_ALL 0x000f0000
|
|
|
|
+
|
|
|
|
+#define D3DPS_VERSION(major, minor) (0xffff0000 | ((major) << 8) | (minor))
|
|
|
|
+#define D3DVS_VERSION(major, minor) (0xfffe0000 | ((major) << 8) | (minor))
|
|
|
|
+
|
|
|
|
+typedef enum _D3DDECLUSAGE
|
|
|
|
+{
|
|
|
|
+ D3DDECLUSAGE_POSITION = 0x0,
|
|
|
|
+ D3DDECLUSAGE_BLENDWEIGHT = 0x1,
|
|
|
|
+ D3DDECLUSAGE_BLENDINDICES = 0x2,
|
|
|
|
+ D3DDECLUSAGE_NORMAL = 0x3,
|
|
|
|
+ D3DDECLUSAGE_PSIZE = 0x4,
|
|
|
|
+ D3DDECLUSAGE_TEXCOORD = 0x5,
|
|
|
|
+ D3DDECLUSAGE_TANGENT = 0x6,
|
|
|
|
+ D3DDECLUSAGE_BINORMAL = 0x7,
|
|
|
|
+ D3DDECLUSAGE_TESSFACTOR = 0x8,
|
|
|
|
+ D3DDECLUSAGE_POSITIONT = 0x9,
|
|
|
|
+ D3DDECLUSAGE_COLOR = 0xa,
|
|
|
|
+ D3DDECLUSAGE_FOG = 0xb,
|
|
|
|
+ D3DDECLUSAGE_DEPTH = 0xc,
|
|
|
|
+ D3DDECLUSAGE_SAMPLE = 0xd,
|
|
|
|
+} D3DDECLUSAGE;
|
|
|
|
+
|
|
|
|
+typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE
|
|
|
|
+{
|
|
|
|
+ D3DSIO_NOP = 0x00,
|
|
|
|
+ D3DSIO_MOV = 0x01,
|
|
|
|
+ D3DSIO_ADD = 0x02,
|
|
|
|
+ D3DSIO_SUB = 0x03,
|
|
|
|
+ D3DSIO_MAD = 0x04,
|
|
|
|
+ D3DSIO_MUL = 0x05,
|
|
|
|
+ D3DSIO_RCP = 0x06,
|
|
|
|
+ D3DSIO_RSQ = 0x07,
|
|
|
|
+ D3DSIO_DP3 = 0x08,
|
|
|
|
+ D3DSIO_DP4 = 0x09,
|
|
|
|
+ D3DSIO_MIN = 0x0a,
|
|
|
|
+ D3DSIO_MAX = 0x0b,
|
|
|
|
+ D3DSIO_SLT = 0x0c,
|
|
|
|
+ D3DSIO_SGE = 0x0d,
|
|
|
|
+ D3DSIO_EXP = 0x0e,
|
|
|
|
+ D3DSIO_LOG = 0x0f,
|
|
|
|
+ D3DSIO_LIT = 0x10,
|
|
|
|
+ D3DSIO_DST = 0x11,
|
|
|
|
+ D3DSIO_LRP = 0x12,
|
|
|
|
+ D3DSIO_FRC = 0x13,
|
|
|
|
+ D3DSIO_M4x4 = 0x14,
|
|
|
|
+ D3DSIO_M4x3 = 0x15,
|
|
|
|
+ D3DSIO_M3x4 = 0x16,
|
|
|
|
+ D3DSIO_M3x3 = 0x17,
|
|
|
|
+ D3DSIO_M3x2 = 0x18,
|
|
|
|
+ D3DSIO_CALL = 0x19,
|
|
|
|
+ D3DSIO_CALLNZ = 0x1a,
|
|
|
|
+ D3DSIO_LOOP = 0x1b,
|
|
|
|
+ D3DSIO_RET = 0x1c,
|
|
|
|
+ D3DSIO_ENDLOOP = 0x1d,
|
|
|
|
+ D3DSIO_LABEL = 0x1e,
|
|
|
|
+ D3DSIO_DCL = 0x1f,
|
|
|
|
+ D3DSIO_POW = 0x20,
|
|
|
|
+ D3DSIO_CRS = 0x21,
|
|
|
|
+ D3DSIO_SGN = 0x22,
|
|
|
|
+ D3DSIO_ABS = 0x23,
|
|
|
|
+ D3DSIO_NRM = 0x24,
|
|
|
|
+ D3DSIO_SINCOS = 0x25,
|
|
|
|
+ D3DSIO_REP = 0x26,
|
|
|
|
+ D3DSIO_ENDREP = 0x27,
|
|
|
|
+ D3DSIO_IF = 0x28,
|
|
|
|
+ D3DSIO_IFC = 0x29,
|
|
|
|
+ D3DSIO_ELSE = 0x2a,
|
|
|
|
+ D3DSIO_ENDIF = 0x2b,
|
|
|
|
+ D3DSIO_BREAK = 0x2c,
|
|
|
|
+ D3DSIO_BREAKC = 0x2d,
|
|
|
|
+ D3DSIO_MOVA = 0x2e,
|
|
|
|
+ D3DSIO_DEFB = 0x2f,
|
|
|
|
+ D3DSIO_DEFI = 0x30,
|
|
|
|
+
|
|
|
|
+ D3DSIO_TEXCOORD = 0x40,
|
|
|
|
+ D3DSIO_TEXKILL = 0x41,
|
|
|
|
+ D3DSIO_TEX = 0x42,
|
|
|
|
+ D3DSIO_TEXBEM = 0x43,
|
|
|
|
+ D3DSIO_TEXBEML = 0x44,
|
|
|
|
+ D3DSIO_TEXREG2AR = 0x45,
|
|
|
|
+ D3DSIO_TEXREG2GB = 0x46,
|
|
|
|
+ D3DSIO_TEXM3x2PAD = 0x47,
|
|
|
|
+ D3DSIO_TEXM3x2TEX = 0x48,
|
|
|
|
+ D3DSIO_TEXM3x3PAD = 0x49,
|
|
|
|
+ D3DSIO_TEXM3x3TEX = 0x4a,
|
|
|
|
+ D3DSIO_TEXM3x3DIFF = 0x4b,
|
|
|
|
+ D3DSIO_TEXM3x3SPEC = 0x4c,
|
|
|
|
+ D3DSIO_TEXM3x3VSPEC = 0x4d,
|
|
|
|
+ D3DSIO_EXPP = 0x4e,
|
|
|
|
+ D3DSIO_LOGP = 0x4f,
|
|
|
|
+ D3DSIO_CND = 0x50,
|
|
|
|
+ D3DSIO_DEF = 0x51,
|
|
|
|
+ D3DSIO_TEXREG2RGB = 0x52,
|
|
|
|
+ D3DSIO_TEXDP3TEX = 0x53,
|
|
|
|
+ D3DSIO_TEXM3x2DEPTH = 0x54,
|
|
|
|
+ D3DSIO_TEXDP3 = 0x55,
|
|
|
|
+ D3DSIO_TEXM3x3 = 0x56,
|
|
|
|
+ D3DSIO_TEXDEPTH = 0x57,
|
|
|
|
+ D3DSIO_CMP = 0x58,
|
|
|
|
+ D3DSIO_BEM = 0x59,
|
|
|
|
+ D3DSIO_DP2ADD = 0x5a,
|
|
|
|
+ D3DSIO_DSX = 0x5b,
|
|
|
|
+ D3DSIO_DSY = 0x5c,
|
|
|
|
+ D3DSIO_TEXLDD = 0x5d,
|
|
|
|
+ D3DSIO_SETP = 0x5e,
|
|
|
|
+ D3DSIO_TEXLDL = 0x5f,
|
|
|
|
+ D3DSIO_BREAKP = 0x60,
|
|
|
|
+
|
|
|
|
+ D3DSIO_PHASE = 0xfffd,
|
|
|
|
+ D3DSIO_COMMENT = 0xfffe,
|
|
|
|
+ D3DSIO_END = 0xffff,
|
|
|
|
+
|
|
|
|
+ D3DSIO_FORCE_DWORD = 0x7fffffff,
|
|
|
|
+} D3DSHADER_INSTRUCTION_OPCODE_TYPE;
|
|
|
|
+
|
|
|
|
+typedef enum _D3DSHADER_PARAM_DSTMOD_TYPE
|
|
|
|
+{
|
|
|
|
+ D3DSPDM_NONE = 0 << D3DSP_DSTMOD_SHIFT,
|
|
|
|
+ D3DSPDM_SATURATE = 1 << D3DSP_DSTMOD_SHIFT,
|
|
|
|
+ D3DSPDM_PARTIALPRECISION = 2 << D3DSP_DSTMOD_SHIFT,
|
|
|
|
+ D3DSPDM_MSAMPCENTROID = 4 << D3DSP_DSTMOD_SHIFT,
|
|
|
|
+
|
|
|
|
+ D3DSPDM_FORCE_DWORD = 0x7fffffff,
|
|
|
|
+} D3DSHADER_PARAM_DSTMOD_TYPE;
|
|
|
|
+
|
|
|
|
+typedef enum _D3DSHADER_PARAM_REGISTER_TYPE
|
|
|
|
+{
|
|
|
|
+ D3DSPR_TEMP = 0x00,
|
|
|
|
+ D3DSPR_INPUT = 0x01,
|
|
|
|
+ D3DSPR_CONST = 0x02,
|
|
|
|
+ D3DSPR_ADDR = 0x03,
|
|
|
|
+ D3DSPR_TEXTURE = 0x03,
|
|
|
|
+ D3DSPR_RASTOUT = 0x04,
|
|
|
|
+ D3DSPR_ATTROUT = 0x05,
|
|
|
|
+ D3DSPR_TEXCRDOUT = 0x06,
|
|
|
|
+ D3DSPR_OUTPUT = 0x06,
|
|
|
|
+ D3DSPR_CONSTINT = 0x07,
|
|
|
|
+ D3DSPR_COLOROUT = 0x08,
|
|
|
|
+ D3DSPR_DEPTHOUT = 0x09,
|
|
|
|
+ D3DSPR_SAMPLER = 0x0a,
|
|
|
|
+ D3DSPR_CONST2 = 0x0b,
|
|
|
|
+ D3DSPR_CONST3 = 0x0c,
|
|
|
|
+ D3DSPR_CONST4 = 0x0d,
|
|
|
|
+ D3DSPR_CONSTBOOL = 0x0e,
|
|
|
|
+ D3DSPR_LOOP = 0x0f,
|
|
|
|
+ D3DSPR_TEMPFLOAT16 = 0x10,
|
|
|
|
+ D3DSPR_MISCTYPE = 0x11,
|
|
|
|
+ D3DSPR_LABEL = 0x12,
|
|
|
|
+ D3DSPR_PREDICATE = 0x13,
|
|
|
|
+
|
|
|
|
+ D3DSPR_FORCE_DWORD = 0x7fffffff,
|
|
|
|
+} D3DSHADER_PARAM_REGISTER_TYPE;
|
|
|
|
+
|
|
|
|
+typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE
|
|
|
|
+{
|
|
|
|
+ D3DSPSM_NONE = 0x0 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_NEG = 0x1 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_BIAS = 0x2 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_BIASNEG = 0x3 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_SIGN = 0x4 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_SIGNNEG = 0x5 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_COMP = 0x6 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_X2 = 0x7 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_X2NEG = 0x8 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_DZ = 0x9 << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_DW = 0xa << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_ABS = 0xb << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_ABSNEG = 0xc << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+ D3DSPSM_NOT = 0xd << D3DSP_SRCMOD_SHIFT,
|
|
|
|
+
|
|
|
|
+ D3DSPSM_FORCE_DWORD = 0x7fffffff,
|
|
|
|
+} D3DSHADER_PARAM_SRCMOD_TYPE;
|
|
|
|
+
|
|
|
|
+typedef enum _D3DSHADER_MISCTYPE_OFFSETS
|
|
|
|
+{
|
|
|
|
+ D3DSMO_POSITION = 0x0,
|
|
|
|
+ D3DSMO_FACE = 0x1,
|
|
|
|
+} D3DSHADER_MISCTYPE_OFFSETS;
|
|
|
|
+
|
|
|
|
+typedef enum _D3DVS_RASTOUT_OFFSETS
|
|
|
|
+{
|
|
|
|
+ D3DSRO_POSITION = 0x0,
|
|
|
|
+ D3DSRO_FOG = 0x1,
|
|
|
|
+ D3DSRO_POINT_SIZE = 0x2,
|
|
|
|
+
|
|
|
|
+ D3DSRO_FORCE_DWORD = 0x7fffffff,
|
|
|
|
+} D3DVS_RASTOUT_OFFSETS;
|
|
|
|
+
|
|
|
|
+#endif /* _d3d9TYPES_H_ */
|
|
|
|
+#endif /* __VKD3D_D3D9TYPES_H */
|
|
|
|
diff --git a/libs/vkd3d/include/vkd3d_d3dcompiler.h b/libs/vkd3d/include/vkd3d_d3dcompiler.h
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..c934835dc0a
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libs/vkd3d/include/vkd3d_d3dcompiler.h
|
|
|
|
@@ -0,0 +1,74 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright 2010 Matteo Bruni 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_D3DCOMPILER_H
|
|
|
|
+#define __VKD3D_D3DCOMPILER_H
|
|
|
|
+#ifndef __D3DCOMPILER_H__
|
|
|
|
+
|
|
|
|
+#define D3DCOMPILE_DEBUG 0x00000001
|
|
|
|
+#define D3DCOMPILE_SKIP_VALIDATION 0x00000002
|
|
|
|
+#define D3DCOMPILE_SKIP_OPTIMIZATION 0x00000004
|
|
|
|
+#define D3DCOMPILE_PACK_MATRIX_ROW_MAJOR 0x00000008
|
|
|
|
+#define D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR 0x00000010
|
|
|
|
+#define D3DCOMPILE_PARTIAL_PRECISION 0x00000020
|
|
|
|
+#define D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT 0x00000040
|
|
|
|
+#define D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT 0x00000080
|
|
|
|
+#define D3DCOMPILE_NO_PRESHADER 0x00000100
|
|
|
|
+#define D3DCOMPILE_AVOID_FLOW_CONTROL 0x00000200
|
|
|
|
+#define D3DCOMPILE_PREFER_FLOW_CONTROL 0x00000400
|
|
|
|
+#define D3DCOMPILE_ENABLE_STRICTNESS 0x00000800
|
|
|
|
+#define D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY 0x00001000
|
|
|
|
+#define D3DCOMPILE_IEEE_STRICTNESS 0x00002000
|
|
|
|
+#define D3DCOMPILE_OPTIMIZATION_LEVEL0 0x00004000
|
|
|
|
+#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0x00000000
|
|
|
|
+#define D3DCOMPILE_OPTIMIZATION_LEVEL2 0x0000c000
|
|
|
|
+#define D3DCOMPILE_OPTIMIZATION_LEVEL3 0x00008000
|
|
|
|
+#define D3DCOMPILE_RESERVED16 0x00010000
|
|
|
|
+#define D3DCOMPILE_RESERVED17 0x00020000
|
|
|
|
+#define D3DCOMPILE_WARNINGS_ARE_ERRORS 0x00040000
|
|
|
|
+#define D3DCOMPILE_RESOURCES_MAY_ALIAS 0x00080000
|
|
|
|
+#define D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES 0x00100000
|
|
|
|
+#define D3DCOMPILE_ALL_RESOURCES_BOUND 0x00200000
|
|
|
|
+#define D3DCOMPILE_DEBUG_NAME_FOR_SOURCE 0x00400000
|
|
|
|
+#define D3DCOMPILE_DEBUG_NAME_FOR_BINARY 0x00800000
|
|
|
|
+
|
|
|
|
+#define D3DCOMPILE_EFFECT_CHILD_EFFECT 0x00000001
|
|
|
|
+#define D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS 0x00000002
|
|
|
|
+
|
|
|
|
+#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_LATEST 0x00000000
|
|
|
|
+#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_0 0x00000010
|
|
|
|
+#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_1 0x00000020
|
|
|
|
+
|
|
|
|
+#define D3DCOMPILE_SECDATA_MERGE_UAV_SLOTS 0x00000001
|
|
|
|
+#define D3DCOMPILE_SECDATA_PRESERVE_TEMPLATE_SLOTS 0x00000002
|
|
|
|
+#define D3DCOMPILE_SECDATA_REQUIRE_TEMPLATE_MATCH 0x00000004
|
|
|
|
+
|
|
|
|
+HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
|
|
|
|
+ const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint,
|
|
|
|
+ const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages);
|
|
|
|
+HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename,
|
|
|
|
+ const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint,
|
|
|
|
+ const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags,
|
|
|
|
+ const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader,
|
|
|
|
+ ID3DBlob **error_messages);
|
|
|
|
+HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob);
|
|
|
|
+HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, const D3D_SHADER_MACRO *macros,
|
|
|
|
+ ID3DInclude *include, ID3DBlob **shader, ID3DBlob **error_messages);
|
|
|
|
+
|
|
|
|
+#endif /* __D3DCOMPILER_H__ */
|
|
|
|
+#endif /* __VKD3D_D3DCOMPILER_H */
|
|
|
|
diff --git a/libs/vkd3d/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..e8462563576
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libs/vkd3d/include/vkd3d_utils.h
|
|
|
|
@@ -0,0 +1,108 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright 2016 Józef Kucia 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_UTILS_H
|
|
|
|
+#define __VKD3D_UTILS_H
|
|
|
|
+
|
|
|
|
+#include <vkd3d.h>
|
|
|
|
+
|
|
|
|
+#ifndef VKD3D_UTILS_API_VERSION
|
|
|
|
+#define VKD3D_UTILS_API_VERSION VKD3D_API_VERSION_1_0
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
+extern "C" {
|
|
|
|
+#endif /* __cplusplus */
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * \file vkd3d_utils.h
|
|
|
|
+ *
|
|
|
|
+ * This file contains definitions for the vkd3d-utils library.
|
|
|
|
+ *
|
|
|
|
+ * The vkd3d-utils library is a collections of routines to ease the
|
|
|
|
+ * porting of a Direct3D 12 application to vkd3d.
|
|
|
|
+ *
|
|
|
|
+ * \since 1.0
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#define VKD3D_WAIT_OBJECT_0 (0)
|
|
|
|
+#define VKD3D_WAIT_TIMEOUT (1)
|
|
|
|
+#define VKD3D_WAIT_FAILED (~0u)
|
|
|
|
+#define VKD3D_INFINITE (~0u)
|
|
|
|
+
|
|
|
|
+#ifdef LIBVKD3D_UTILS_SOURCE
|
|
|
|
+# define VKD3D_UTILS_API VKD3D_EXPORT
|
|
|
|
+#else
|
|
|
|
+# define VKD3D_UTILS_API VKD3D_IMPORT
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+/* 1.0 */
|
|
|
|
+VKD3D_UTILS_API HANDLE vkd3d_create_event(void);
|
|
|
|
+VKD3D_UTILS_API HRESULT vkd3d_signal_event(HANDLE event);
|
|
|
|
+VKD3D_UTILS_API unsigned int vkd3d_wait_event(HANDLE event, unsigned int milliseconds);
|
|
|
|
+VKD3D_UTILS_API void vkd3d_destroy_event(HANDLE event);
|
|
|
|
+
|
|
|
|
+#define D3D12CreateDevice(a, b, c, d) D3D12CreateDeviceVKD3D(a, b, c, d, VKD3D_UTILS_API_VERSION)
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3D12CreateRootSignatureDeserializer(
|
|
|
|
+ const void *data, SIZE_T data_size, REFIID iid, void **deserializer);
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3D12GetDebugInterface(REFIID iid, void **debug);
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *desc,
|
|
|
|
+ D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob);
|
|
|
|
+
|
|
|
|
+/* 1.2 */
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3D12CreateDeviceVKD3D(IUnknown *adapter, D3D_FEATURE_LEVEL feature_level,
|
|
|
|
+ REFIID iid, void **device, enum vkd3d_api_version api_version);
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3D12CreateVersionedRootSignatureDeserializer(const void *data,
|
|
|
|
+ SIZE_T data_size, REFIID iid, void **deserializer);
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc,
|
|
|
|
+ ID3DBlob **blob, ID3DBlob **error_blob);
|
|
|
|
+
|
|
|
|
+/* 1.3 */
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
|
|
|
|
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
|
|
|
|
+ const char *target, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages);
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename,
|
|
|
|
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
|
|
|
|
+ const char *target, UINT flags, UINT effect_flags, UINT secondary_flags,
|
|
|
|
+ const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader,
|
|
|
|
+ ID3DBlob **error_messages);
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DCreateBlob(SIZE_T data_size, ID3DBlob **blob);
|
|
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename,
|
|
|
|
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include,
|
|
|
|
+ ID3DBlob **shader, ID3DBlob **error_messages);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Set a callback to be called when vkd3d-utils outputs debug logging.
|
|
|
|
+ *
|
|
|
|
+ * If NULL, or if this function has not been called, libvkd3d-utils will print
|
|
|
|
+ * all enabled log output to stderr.
|
|
|
|
+ *
|
|
|
|
+ * Calling this function will also set the log callback for libvkd3d and
|
|
|
|
+ * libvkd3d-shader.
|
|
|
|
+ *
|
|
|
|
+ * \param callback Callback function to set.
|
|
|
|
+ *
|
|
|
|
+ * \since 1.4
|
|
|
|
+ */
|
|
|
|
+VKD3D_UTILS_API void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback);
|
|
|
|
+
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
+}
|
|
|
|
+#endif /* __cplusplus */
|
|
|
|
+
|
|
|
|
+#endif /* __VKD3D_UTILS_H */
|
|
|
|
diff --git a/libs/vkd3d/include/vkd3d_windows.h b/libs/vkd3d/include/vkd3d_windows.h
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..7b0e972d828
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libs/vkd3d/include/vkd3d_windows.h
|
|
|
|
@@ -0,0 +1,289 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright 2016 Józef Kucia 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_WINDOWS_H
|
|
|
|
+#define __VKD3D_WINDOWS_H
|
|
|
|
+#ifndef _INC_WINDOWS
|
|
|
|
+
|
|
|
|
+/* Nameless unions */
|
|
|
|
+#ifndef __C89_NAMELESS
|
|
|
|
+# ifdef NONAMELESSUNION
|
|
|
|
+# define __C89_NAMELESS
|
|
|
|
+# define __C89_NAMELESSUNIONNAME u
|
|
|
|
+# else
|
|
|
|
+# define __C89_NAMELESS
|
|
|
|
+# define __C89_NAMELESSUNIONNAME
|
|
|
|
+# endif /* NONAMELESSUNION */
|
|
|
|
+#endif /* __C89_NAMELESS */
|
|
|
|
+
|
|
|
|
+#if !defined(_WIN32) || defined(__WIDL__)
|
|
|
|
+
|
|
|
|
+# if !defined(__WIDL__)
|
|
|
|
+# if !defined(VKD3D_WIN32_WCHAR)
|
|
|
|
+# include <wchar.h>
|
|
|
|
+# endif
|
|
|
|
+# include <stdint.h>
|
|
|
|
+# endif
|
|
|
|
+
|
|
|
|
+# ifdef __GNUC__
|
|
|
|
+# define DECLSPEC_ALIGN(x) __attribute__((aligned(x)))
|
|
|
|
+# endif
|
|
|
|
+
|
|
|
|
+/* HRESULT */
|
|
|
|
+typedef int HRESULT;
|
|
|
|
+# define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
|
|
|
|
+# define FAILED(hr) ((HRESULT)(hr) < 0)
|
|
|
|
+
|
|
|
|
+# define _HRESULT_TYPEDEF_(x) ((HRESULT)x)
|
|
|
|
+
|
|
|
|
+# define S_OK _HRESULT_TYPEDEF_(0)
|
|
|
|
+# define S_FALSE _HRESULT_TYPEDEF_(1)
|
|
|
|
+
|
|
|
|
+# define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001)
|
|
|
|
+# define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002)
|
|
|
|
+# define E_POINTER _HRESULT_TYPEDEF_(0x80004003)
|
|
|
|
+# define E_ABORT _HRESULT_TYPEDEF_(0x80004004)
|
|
|
|
+# define E_FAIL _HRESULT_TYPEDEF_(0x80004005)
|
|
|
|
+# define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000E)
|
|
|
|
+# define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057)
|
|
|
|
+
|
|
|
|
+# define DXGI_ERROR_NOT_FOUND _HRESULT_TYPEDEF_(0x887a0002)
|
|
|
|
+# define DXGI_ERROR_MORE_DATA _HRESULT_TYPEDEF_(0x887a0003)
|
|
|
|
+# define DXGI_ERROR_UNSUPPORTED _HRESULT_TYPEDEF_(0x887a0004)
|
|
|
|
+
|
|
|
|
+# define D3DERR_INVALIDCALL _HRESULT_TYPEDEF_(0x8876086c)
|
|
|
|
+
|
|
|
|
+/* Basic types */
|
|
|
|
+typedef unsigned char BYTE;
|
|
|
|
+typedef unsigned int DWORD;
|
|
|
|
+typedef int INT;
|
|
|
|
+typedef unsigned int UINT;
|
|
|
|
+typedef int LONG;
|
|
|
|
+typedef unsigned int ULONG;
|
|
|
|
+typedef float FLOAT;
|
|
|
|
+typedef LONG BOOL;
|
|
|
|
+
|
|
|
|
+/* Assuming LP64 model */
|
|
|
|
+typedef char INT8;
|
|
|
|
+typedef unsigned char UINT8;
|
|
|
|
+typedef short INT16;
|
|
|
|
+typedef unsigned short UINT16;
|
|
|
|
+typedef int INT32;
|
|
|
|
+typedef unsigned int UINT32;
|
|
|
|
+# if defined(__WIDL__)
|
|
|
|
+typedef __int64 INT64;
|
|
|
|
+typedef unsigned __int64 UINT64;
|
|
|
|
+# else
|
|
|
|
+typedef int64_t DECLSPEC_ALIGN(8) INT64;
|
|
|
|
+typedef uint64_t DECLSPEC_ALIGN(8) UINT64;
|
|
|
|
+# endif
|
|
|
|
+typedef INT64 LONG64;
|
|
|
|
+typedef long LONG_PTR;
|
|
|
|
+typedef unsigned long ULONG_PTR;
|
|
|
|
+
|
|
|
|
+typedef ULONG_PTR SIZE_T;
|
|
|
|
+
|
|
|
|
+# ifdef VKD3D_WIN32_WCHAR
|
|
|
|
+typedef unsigned short WCHAR;
|
|
|
|
+# else
|
|
|
|
+typedef wchar_t WCHAR;
|
|
|
|
+# endif /* VKD3D_WIN32_WCHAR */
|
|
|
|
+typedef void *HANDLE;
|
|
|
|
+
|
|
|
|
+/* GUID */
|
|
|
|
+# ifdef __WIDL__
|
|
|
|
+typedef struct
|
|
|
|
+{
|
|
|
|
+ unsigned long Data1;
|
|
|
|
+ unsigned short Data2;
|
|
|
|
+ unsigned short Data3;
|
|
|
|
+ unsigned char Data4[8];
|
|
|
|
+} GUID;
|
|
|
|
+# else
|
|
|
|
+typedef struct _GUID
|
|
|
|
+{
|
|
|
|
+ unsigned int Data1;
|
|
|
|
+ unsigned short Data2;
|
|
|
|
+ unsigned short Data3;
|
|
|
|
+ unsigned char Data4[8];
|
|
|
|
+} GUID;
|
|
|
|
+# endif
|
|
|
|
+
|
|
|
|
+typedef GUID IID;
|
|
|
|
+typedef GUID CLSID;
|
|
|
|
+typedef GUID UUID;
|
|
|
|
+
|
|
|
|
+# ifdef INITGUID
|
|
|
|
+# ifndef __cplusplus
|
|
|
|
+# define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
|
|
|
+ const GUID name DECLSPEC_HIDDEN; \
|
|
|
|
+ const GUID name = \
|
|
|
|
+ { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 }}
|
|
|
|
+# else
|
|
|
|
+# define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
|
|
|
+ EXTERN_C const GUID name DECLSPEC_HIDDEN; \
|
|
|
|
+ EXTERN_C const GUID name = \
|
|
|
|
+ { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 }}
|
|
|
|
+# endif
|
|
|
|
+# else
|
|
|
|
+# define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
|
|
|
+ EXTERN_C const GUID name DECLSPEC_HIDDEN;
|
|
|
|
+# endif /* INITGUID */
|
|
|
|
+
|
|
|
|
+/* __uuidof emulation */
|
|
|
|
+#if defined(__cplusplus) && !defined(_MSC_VER)
|
|
|
|
+
|
|
|
|
+extern "C++"
|
|
|
|
+{
|
|
|
|
+ template<typename T> const GUID &__vkd3d_uuidof();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+# define __CRT_UUID_DECL(type, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
|
|
|
+ extern "C++" \
|
|
|
|
+ { \
|
|
|
|
+ template<> inline const GUID &__vkd3d_uuidof<type>() \
|
|
|
|
+ { \
|
|
|
|
+ static const IID __uuid_inst = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}; \
|
|
|
|
+ return __uuid_inst; \
|
|
|
|
+ } \
|
|
|
|
+ template<> inline const GUID &__vkd3d_uuidof<type *>() \
|
|
|
|
+ { \
|
|
|
|
+ return __vkd3d_uuidof<type>(); \
|
|
|
|
+ } \
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+# define __uuidof(type) __vkd3d_uuidof<typeof(type)>()
|
|
|
|
+#else
|
|
|
|
+# define __CRT_UUID_DECL(type, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
|
|
|
|
+#endif /* defined(__cplusplus) && !defined(_MSC_VER) */
|
|
|
|
+
|
|
|
|
+typedef struct SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES;
|
|
|
|
+#endif /* !defined(_WIN32) || defined(__WIDL__) */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+#ifndef _WIN32
|
|
|
|
+# include <stddef.h>
|
|
|
|
+# include <stdlib.h>
|
|
|
|
+# include <string.h>
|
|
|
|
+
|
|
|
|
+# define COM_NO_WINDOWS_H
|
|
|
|
+
|
|
|
|
+# define FORCEINLINE inline
|
|
|
|
+
|
|
|
|
+# define CONTAINING_RECORD(address, type, field) \
|
|
|
|
+ ((type *)((char *)(address) - offsetof(type, field)))
|
|
|
|
+
|
|
|
|
+# ifdef __x86_64__
|
|
|
|
+# define __stdcall __attribute__((ms_abi))
|
|
|
|
+# else
|
|
|
|
+# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || defined(__APPLE__)
|
|
|
|
+# define __stdcall __attribute__((__stdcall__)) __attribute__((__force_align_arg_pointer__))
|
|
|
|
+# else
|
|
|
|
+# define __stdcall __attribute__((__stdcall__))
|
|
|
|
+# endif
|
|
|
|
+# endif
|
|
|
|
+
|
|
|
|
+# define WINAPI __stdcall
|
|
|
|
+# define STDMETHODCALLTYPE __stdcall
|
|
|
|
+
|
|
|
|
+# ifdef __GNUC__
|
|
|
|
+# define DECLSPEC_SELECTANY __attribute__((weak))
|
|
|
|
+# endif
|
|
|
|
+
|
|
|
|
+/* Macros for COM interfaces */
|
|
|
|
+# define interface struct
|
|
|
|
+# define BEGIN_INTERFACE
|
|
|
|
+# define END_INTERFACE
|
|
|
|
+# define MIDL_INTERFACE(x) struct
|
|
|
|
+
|
|
|
|
+# ifdef __cplusplus
|
|
|
|
+# define EXTERN_C extern "C"
|
|
|
|
+# else
|
|
|
|
+# define EXTERN_C extern
|
|
|
|
+# endif
|
|
|
|
+
|
|
|
|
+# define CONST_VTBL const
|
|
|
|
+
|
|
|
|
+# define TRUE 1
|
|
|
|
+# define FALSE 0
|
|
|
|
+
|
|
|
|
+# if defined(__cplusplus) && !defined(CINTERFACE)
|
|
|
|
+# define REFIID const IID &
|
|
|
|
+# define REFGUID const GUID &
|
|
|
|
+# define REFCLSID const CLSID &
|
|
|
|
+# else
|
|
|
|
+# define REFIID const IID * const
|
|
|
|
+# define REFGUID const GUID * const
|
|
|
|
+# define REFCLSID const CLSID * const
|
|
|
|
+# endif
|
|
|
|
+
|
|
|
|
+#if defined(__cplusplus) && !defined(CINTERFACE)
|
|
|
|
+# define IsEqualGUID(guid1, guid2) (!memcmp(&(guid1), &(guid2), sizeof(GUID)))
|
|
|
|
+#else
|
|
|
|
+# define IsEqualGUID(guid1, guid2) (!memcmp(guid1, guid2, sizeof(GUID)))
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#elif !defined(__WIDL__)
|
|
|
|
+
|
|
|
|
+# include <windows.h>
|
|
|
|
+
|
|
|
|
+#endif /* _WIN32 */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/* Define DECLSPEC_HIDDEN */
|
|
|
|
+#ifndef DECLSPEC_HIDDEN
|
|
|
|
+# if defined(__MINGW32__)
|
|
|
|
+# define DECLSPEC_HIDDEN
|
|
|
|
+# elif defined(__GNUC__)
|
|
|
|
+# define DECLSPEC_HIDDEN __attribute__((visibility("hidden")))
|
|
|
|
+# else
|
|
|
|
+# define DECLSPEC_HIDDEN
|
|
|
|
+# endif
|
|
|
|
+#endif /* DECLSPEC_HIDDEN */
|
|
|
|
+
|
|
|
|
+/* Define min() & max() macros */
|
|
|
|
+#ifndef NOMINMAX
|
|
|
|
+# ifndef min
|
|
|
|
+# define min(a, b) (((a) <= (b)) ? (a) : (b))
|
|
|
|
+# endif
|
|
|
|
+
|
|
|
|
+# ifndef max
|
|
|
|
+# define max(a, b) (((a) >= (b)) ? (a) : (b))
|
|
|
|
+# endif
|
|
|
|
+#endif /* NOMINMAX */
|
|
|
|
+
|
|
|
|
+#ifndef DEFINE_ENUM_FLAG_OPERATORS
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
+# define DEFINE_ENUM_FLAG_OPERATORS(type) \
|
|
|
|
+extern "C++" \
|
|
|
|
+{ \
|
|
|
|
+ inline type operator &(type x, type y) { return (type)((int)x & (int)y); } \
|
|
|
|
+ inline type operator &=(type &x, type y) { return (type &)((int &)x &= (int)y); } \
|
|
|
|
+ inline type operator ~(type x) { return (type)~(int)x; } \
|
|
|
|
+ inline type operator |(type x, type y) { return (type)((int)x | (int)y); } \
|
|
|
|
+ inline type operator |=(type &x, type y) { return (type &)((int &)x |= (int)y); } \
|
|
|
|
+ inline type operator ^(type x, type y) { return (type)((int)x ^ (int)y); } \
|
|
|
|
+ inline type operator ^=(type &x, type y) { return (type &)((int &)x ^= (int)y); } \
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+# define DEFINE_ENUM_FLAG_OPERATORS(type)
|
|
|
|
+#endif
|
|
|
|
+#endif /* DEFINE_ENUM_FLAG_OPERATORS */
|
|
|
|
+
|
|
|
|
+#endif /* _INC_WINDOWS */
|
|
|
|
+#endif /* __VKD3D_WINDOWS_H */
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
|
|
index 30205088b1b..ce00e536d39 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
|
|
@@ -17,6 +17,7 @@
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
+
|
|
|
|
#include "vkd3d.h"
|
|
|
|
#include "vkd3d_blob.h"
|
|
|
|
#include "vkd3d_debug.h"
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
|
|
index f0c386f1b3a..2c5108095d5 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
|
|
@@ -1374,7 +1374,7 @@ static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
|
|
|
|
if (mmask & VKD3DSPDM_PARTIALPRECISION) shader_addline(buffer, "_pp");
|
|
|
|
if (mmask & VKD3DSPDM_MSAMPCENTROID) shader_addline(buffer, "_centroid");
|
|
|
|
|
|
|
|
- mmask &= ~(VKD3DSPDM_SATURATE | VKD3DSPDM_PARTIALPRECISION | VKD3DSPDM_MSAMPCENTROID);
|
|
|
|
+ mmask &= ~VKD3DSPDM_MASK;
|
|
|
|
if (mmask) FIXME("Unrecognised modifier %#x.\n", mmask);
|
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
|
|
index 1fd5ab2446d..0d2b8d248d1 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
|
|
@@ -261,7 +261,7 @@ static const struct vkd3d_sm1_opcode_info vs_opcode_table[] =
|
|
|
|
{VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3},
|
|
|
|
{VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2},
|
|
|
|
/* Declarations */
|
|
|
|
- {VKD3D_SM1_OP_DCL, 0, 2, VKD3DSIH_DCL},
|
|
|
|
+ {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL},
|
|
|
|
/* Constant definitions */
|
|
|
|
{VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF},
|
|
|
|
{VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB},
|
|
|
|
@@ -328,7 +328,7 @@ static const struct vkd3d_sm1_opcode_info ps_opcode_table[] =
|
|
|
|
{VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3},
|
|
|
|
{VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2},
|
|
|
|
/* Declarations */
|
|
|
|
- {VKD3D_SM1_OP_DCL, 0, 2, VKD3DSIH_DCL},
|
|
|
|
+ {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL},
|
|
|
|
/* Constant definitions */
|
|
|
|
{VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF},
|
|
|
|
{VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB},
|
|
|
|
@@ -853,6 +853,14 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ /* DCL instructions do not have sources or destinations, but they
|
|
|
|
+ * read two tokens to a semantic. See
|
|
|
|
+ * shader_sm1_read_semantic(). */
|
|
|
|
+ if (opcode_info->vkd3d_opcode == VKD3DSIH_DCL)
|
|
|
|
+ {
|
|
|
|
+ *ptr += 2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
*ptr += (opcode_info->dst_count + opcode_info->src_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1090,7 +1098,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
- ins->handler_idx = opcode_info->vkd3d_opcode;
|
|
|
|
+ vsir_instruction_init(ins, &sm1->p.location, opcode_info->vkd3d_opcode);
|
|
|
|
ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
|
|
|
|
ins->coissue = opcode_token & VKD3D_SM1_COISSUE;
|
|
|
|
ins->raw = false;
|
|
|
|
@@ -1333,12 +1341,22 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
|
|
|
|
++instructions->count;
|
|
|
|
}
|
|
|
|
|
|
|
|
- *parser = &sm1->p;
|
|
|
|
-
|
|
|
|
for (i = 0; i < ARRAY_SIZE(sm1->p.shader_desc.flat_constant_count); ++i)
|
|
|
|
sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i);
|
|
|
|
|
|
|
|
- return sm1->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK;
|
|
|
|
+ if (!sm1->p.failed)
|
|
|
|
+ vsir_validate(&sm1->p);
|
|
|
|
+
|
|
|
|
+ if (sm1->p.failed)
|
|
|
|
+ {
|
|
|
|
+ WARN("Failed to parse shader.\n");
|
|
|
|
+ shader_sm1_destroy(&sm1->p);
|
|
|
|
+ return VKD3D_ERROR_INVALID_SHADER;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *parser = &sm1->p;
|
|
|
|
+
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic,
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
index b78c78d34a7..b778f6abed3 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
@@ -1999,7 +1999,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa
|
|
|
|
{
|
|
|
|
struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1);
|
|
|
|
assert(ins);
|
|
|
|
- shader_instruction_init(ins, handler_idx);
|
|
|
|
+ vsir_instruction_init(ins, &sm6->p.location, handler_idx);
|
|
|
|
++sm6->p.instructions.count;
|
|
|
|
return ins;
|
|
|
|
}
|
|
|
|
@@ -2190,7 +2190,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_b
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
- shader_instruction_init(ins, VKD3DSIH_MOV);
|
|
|
|
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
|
|
|
|
|
|
|
|
if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6)))
|
|
|
|
return;
|
|
|
|
@@ -2955,6 +2955,12 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi
|
|
|
|
compile_info->source_name, message_context);
|
|
|
|
vkd3d_free(byte_code);
|
|
|
|
|
|
|
|
+ if (!sm6->p.failed && ret >= 0)
|
|
|
|
+ vsir_validate(&sm6->p);
|
|
|
|
+
|
|
|
|
+ if (sm6->p.failed && ret >= 0)
|
|
|
|
+ ret = VKD3D_ERROR_INVALID_SHADER;
|
|
|
|
+
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
WARN("Failed to initialise shader parser.\n");
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
|
|
index 743a746f2bf..2cde5d58eba 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
|
|
@@ -21,7 +21,7 @@
|
|
|
|
#define __VKD3D_SHADER_HLSL_H
|
|
|
|
|
|
|
|
#include "vkd3d_shader_private.h"
|
|
|
|
-#include "wine/rbtree.h"
|
|
|
|
+#include "rbtree.h"
|
|
|
|
#include "d3dcommon.h"
|
|
|
|
#include "d3dx9shader.h"
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
|
|
index be024842164..ed31efc3f0b 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
|
|
@@ -2523,36 +2523,19 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
|
|
|
|
struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
|
|
|
|
struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false)
|
|
|
|
{
|
|
|
|
- struct hlsl_block then_block, else_block;
|
|
|
|
- struct hlsl_ir_node *iff, *store;
|
|
|
|
- struct hlsl_ir_load *load;
|
|
|
|
- struct hlsl_ir_var *var;
|
|
|
|
+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS];
|
|
|
|
+ struct hlsl_ir_node *cond;
|
|
|
|
|
|
|
|
assert(hlsl_types_are_equal(if_true->data_type, if_false->data_type));
|
|
|
|
|
|
|
|
- if (!(var = hlsl_new_synthetic_var(ctx, "conditional", if_true->data_type, &condition->loc)))
|
|
|
|
- return NULL;
|
|
|
|
-
|
|
|
|
- hlsl_block_init(&then_block);
|
|
|
|
- hlsl_block_init(&else_block);
|
|
|
|
-
|
|
|
|
- if (!(store = hlsl_new_simple_store(ctx, var, if_true)))
|
|
|
|
- return NULL;
|
|
|
|
- hlsl_block_add_instr(&then_block, store);
|
|
|
|
-
|
|
|
|
- if (!(store = hlsl_new_simple_store(ctx, var, if_false)))
|
|
|
|
- return NULL;
|
|
|
|
- hlsl_block_add_instr(&else_block, store);
|
|
|
|
-
|
|
|
|
- if (!(iff = hlsl_new_if(ctx, condition, &then_block, &else_block, &condition->loc)))
|
|
|
|
- return NULL;
|
|
|
|
- hlsl_block_add_instr(instrs, iff);
|
|
|
|
-
|
|
|
|
- if (!(load = hlsl_new_var_load(ctx, var, &condition->loc)))
|
|
|
|
- return NULL;
|
|
|
|
- hlsl_block_add_instr(instrs, &load->node);
|
|
|
|
+ operands[0] = condition;
|
|
|
|
+ operands[1] = if_true;
|
|
|
|
+ operands[2] = if_false;
|
|
|
|
+ if (!(cond = hlsl_new_expr(ctx, HLSL_OP3_TERNARY, operands, if_true->data_type, &condition->loc)))
|
|
|
|
+ return false;
|
|
|
|
+ hlsl_block_add_instr(instrs, cond);
|
|
|
|
|
|
|
|
- return &load->node;
|
|
|
|
+ return cond;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
|
|
|
|
index 41a72ab6c0d..cff0ba31efb 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
|
|
|
|
@@ -63,6 +63,56 @@ static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static uint32_t float_to_uint(float x)
|
|
|
|
+{
|
|
|
|
+ if (isnan(x) || x <= 0)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (x >= 4294967296.0f)
|
|
|
|
+ return UINT32_MAX;
|
|
|
|
+
|
|
|
|
+ return x;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int32_t float_to_int(float x)
|
|
|
|
+{
|
|
|
|
+ if (isnan(x))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (x <= -2147483648.0f)
|
|
|
|
+ return INT32_MIN;
|
|
|
|
+
|
|
|
|
+ if (x >= 2147483648.0f)
|
|
|
|
+ return INT32_MAX;
|
|
|
|
+
|
|
|
|
+ return x;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static uint32_t double_to_uint(double x)
|
|
|
|
+{
|
|
|
|
+ if (isnan(x) || x <= 0)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (x >= 4294967296.0)
|
|
|
|
+ return UINT32_MAX;
|
|
|
|
+
|
|
|
|
+ return x;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int32_t double_to_int(double x)
|
|
|
|
+{
|
|
|
|
+ if (isnan(x))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (x <= -2147483648.0)
|
|
|
|
+ return INT32_MIN;
|
|
|
|
+
|
|
|
|
+ if (x >= 2147483648.0)
|
|
|
|
+ return INT32_MAX;
|
|
|
|
+
|
|
|
|
+ return x;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
|
|
|
|
const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
|
|
|
|
{
|
|
|
|
@@ -86,15 +136,15 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
|
|
|
|
{
|
|
|
|
case HLSL_TYPE_FLOAT:
|
|
|
|
case HLSL_TYPE_HALF:
|
|
|
|
- u = src->value.u[k].f;
|
|
|
|
- i = src->value.u[k].f;
|
|
|
|
+ u = float_to_uint(src->value.u[k].f);
|
|
|
|
+ i = float_to_int(src->value.u[k].f);
|
|
|
|
f = src->value.u[k].f;
|
|
|
|
d = src->value.u[k].f;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HLSL_TYPE_DOUBLE:
|
|
|
|
- u = src->value.u[k].d;
|
|
|
|
- i = src->value.u[k].d;
|
|
|
|
+ u = double_to_uint(src->value.u[k].d);
|
|
|
|
+ i = double_to_int(src->value.u[k].d);
|
|
|
|
f = src->value.u[k].d;
|
|
|
|
d = src->value.u[k].d;
|
|
|
|
break;
|
|
|
|
@@ -152,6 +202,59 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
|
|
|
|
+ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
|
|
|
|
+{
|
|
|
|
+ enum hlsl_base_type type = dst_type->base_type;
|
|
|
|
+ unsigned int k;
|
|
|
|
+
|
|
|
|
+ assert(type == src->node.data_type->base_type);
|
|
|
|
+
|
|
|
|
+ for (k = 0; k < dst_type->dimx; ++k)
|
|
|
|
+ {
|
|
|
|
+ switch (type)
|
|
|
|
+ {
|
|
|
|
+ case HLSL_TYPE_FLOAT:
|
|
|
|
+ case HLSL_TYPE_HALF:
|
|
|
|
+ dst->u[k].f = exp2f(src->value.u[k].f);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ FIXME("Fold 'exp2' for type %s.\n", debug_hlsl_type(ctx, dst_type));
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
|
|
|
|
+ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
|
|
|
|
+{
|
|
|
|
+ enum hlsl_base_type type = dst_type->base_type;
|
|
|
|
+ unsigned int k;
|
|
|
|
+ float i;
|
|
|
|
+
|
|
|
|
+ assert(type == src->node.data_type->base_type);
|
|
|
|
+
|
|
|
|
+ for (k = 0; k < dst_type->dimx; ++k)
|
|
|
|
+ {
|
|
|
|
+ switch (type)
|
|
|
|
+ {
|
|
|
|
+ case HLSL_TYPE_FLOAT:
|
|
|
|
+ case HLSL_TYPE_HALF:
|
|
|
|
+ dst->u[k].f = modff(src->value.u[k].f, &i);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ FIXME("Fold 'fract' for type %s.\n", debug_hlsl_type(ctx, dst_type));
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static bool fold_log2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
|
|
|
|
const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
|
|
|
|
{
|
|
|
|
@@ -276,6 +379,32 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
|
|
|
|
+ const struct hlsl_ir_constant *src)
|
|
|
|
+{
|
|
|
|
+ enum hlsl_base_type type = dst_type->base_type;
|
|
|
|
+ unsigned int k;
|
|
|
|
+
|
|
|
|
+ assert(type == src->node.data_type->base_type);
|
|
|
|
+
|
|
|
|
+ for (k = 0; k < dst_type->dimx; ++k)
|
|
|
|
+ {
|
|
|
|
+ switch (type)
|
|
|
|
+ {
|
|
|
|
+ case HLSL_TYPE_FLOAT:
|
|
|
|
+ case HLSL_TYPE_HALF:
|
|
|
|
+ dst->u[k].f = min(max(0.0f, src->value.u[k].f), 1.0f);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ FIXME("Fold 'sat' for type %s.\n", debug_hlsl_type(ctx, dst_type));
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
|
|
|
|
const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
|
|
|
|
{
|
|
|
|
@@ -869,6 +998,40 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
|
|
|
|
+ const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3)
|
|
|
|
+{
|
|
|
|
+ unsigned int k;
|
|
|
|
+
|
|
|
|
+ assert(dst_type->base_type == src2->node.data_type->base_type);
|
|
|
|
+ assert(dst_type->base_type == src3->node.data_type->base_type);
|
|
|
|
+
|
|
|
|
+ for (k = 0; k < dst_type->dimx; ++k)
|
|
|
|
+ {
|
|
|
|
+ switch (src1->node.data_type->base_type)
|
|
|
|
+ {
|
|
|
|
+ case HLSL_TYPE_FLOAT:
|
|
|
|
+ case HLSL_TYPE_HALF:
|
|
|
|
+ dst->u[k] = src1->value.u[k].f != 0.0f ? src2->value.u[k] : src3->value.u[k];
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case HLSL_TYPE_DOUBLE:
|
|
|
|
+ dst->u[k] = src1->value.u[k].d != 0.0 ? src2->value.u[k] : src3->value.u[k];
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case HLSL_TYPE_INT:
|
|
|
|
+ case HLSL_TYPE_UINT:
|
|
|
|
+ case HLSL_TYPE_BOOL:
|
|
|
|
+ dst->u[k] = src1->value.u[k].u ? src2->value.u[k] : src3->value.u[k];
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ vkd3d_unreachable();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
|
|
{
|
|
|
|
struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL;
|
|
|
|
@@ -912,6 +1075,14 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
|
|
success = fold_cast(ctx, &res, instr->data_type, arg1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
+ case HLSL_OP1_EXP2:
|
|
|
|
+ success = fold_exp2(ctx, &res, instr->data_type, arg1);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case HLSL_OP1_FRACT:
|
|
|
|
+ success = fold_fract(ctx, &res, instr->data_type, arg1);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
case HLSL_OP1_LOG2:
|
|
|
|
success = fold_log2(ctx, &res, instr->data_type, arg1, &instr->loc);
|
|
|
|
break;
|
|
|
|
@@ -924,6 +1095,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
|
|
success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc);
|
|
|
|
break;
|
|
|
|
|
|
|
|
+ case HLSL_OP1_SAT:
|
|
|
|
+ success = fold_sat(ctx, &res, instr->data_type, arg1);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
case HLSL_OP1_SQRT:
|
|
|
|
success = fold_sqrt(ctx, &res, instr->data_type, arg1, &instr->loc);
|
|
|
|
break;
|
|
|
|
@@ -990,6 +1165,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
|
|
success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3);
|
|
|
|
break;
|
|
|
|
|
|
|
|
+ case HLSL_OP3_TERNARY:
|
|
|
|
+ success = fold_ternary(ctx, &res, instr->data_type, arg1, arg2, arg3);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
default:
|
|
|
|
FIXME("Fold \"%s\" expression.\n", debug_hlsl_expr_op(expr->op));
|
|
|
|
success = false;
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
index d2bfb933edc..9ee38ffee37 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
@@ -31,11 +31,9 @@ static bool shader_instruction_is_dcl(const struct vkd3d_shader_instruction *ins
|
|
|
|
|
|
|
|
static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins)
|
|
|
|
{
|
|
|
|
- ins->handler_idx = VKD3DSIH_NOP;
|
|
|
|
- ins->dst_count = 0;
|
|
|
|
- ins->src_count = 0;
|
|
|
|
- ins->dst = NULL;
|
|
|
|
- ins->src = NULL;
|
|
|
|
+ struct vkd3d_shader_location location = ins->location;
|
|
|
|
+
|
|
|
|
+ vsir_instruction_init(ins, &location, VKD3DSIH_NOP);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg,
|
|
|
|
@@ -161,6 +159,7 @@ struct hull_flattener
|
|
|
|
unsigned int instance_count;
|
|
|
|
unsigned int phase_body_idx;
|
|
|
|
enum vkd3d_shader_opcode phase;
|
|
|
|
+ struct vkd3d_shader_location last_ret_location;
|
|
|
|
};
|
|
|
|
|
|
|
|
static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flattener)
|
|
|
|
@@ -233,6 +232,7 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal
|
|
|
|
|
|
|
|
if (ins->handler_idx == VKD3DSIH_RET)
|
|
|
|
{
|
|
|
|
+ normaliser->last_ret_location = ins->location;
|
|
|
|
vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
if (locations->count >= ARRAY_SIZE(locations->locations))
|
|
|
|
{
|
|
|
|
@@ -313,9 +313,11 @@ void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_r
|
|
|
|
reg->immconst_type = VKD3D_IMMCONST_SCALAR;
|
|
|
|
}
|
|
|
|
|
|
|
|
-void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx)
|
|
|
|
+void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
|
|
|
|
+ enum vkd3d_shader_opcode handler_idx)
|
|
|
|
{
|
|
|
|
memset(ins, 0, sizeof(*ins));
|
|
|
|
+ ins->location = *location;
|
|
|
|
ins->handler_idx = handler_idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -343,7 +345,7 @@ static enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd
|
|
|
|
|
|
|
|
if (!shader_instruction_array_reserve(&flattener.instructions, flattener.instructions.count + 1))
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
- shader_instruction_init(&instructions->elements[instructions->count++], VKD3DSIH_RET);
|
|
|
|
+ vsir_instruction_init(&instructions->elements[instructions->count++], &flattener.last_ret_location, VKD3DSIH_RET);
|
|
|
|
}
|
|
|
|
|
|
|
|
*src_instructions = flattener.instructions;
|
|
|
|
@@ -404,7 +406,8 @@ static void shader_dst_param_io_init(struct vkd3d_shader_dst_param *param, const
|
|
|
|
}
|
|
|
|
|
|
|
|
static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser,
|
|
|
|
- const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst)
|
|
|
|
+ const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst,
|
|
|
|
+ const struct vkd3d_shader_location *location)
|
|
|
|
{
|
|
|
|
struct vkd3d_shader_instruction *ins;
|
|
|
|
struct vkd3d_shader_dst_param *param;
|
|
|
|
@@ -422,7 +425,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
|
|
|
|
normaliser->instructions.count += count;
|
|
|
|
|
|
|
|
ins = &normaliser->instructions.elements[dst];
|
|
|
|
- shader_instruction_init(ins, VKD3DSIH_HS_CONTROL_POINT_PHASE);
|
|
|
|
+ vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE);
|
|
|
|
ins->flags = 1;
|
|
|
|
++ins;
|
|
|
|
|
|
|
|
@@ -434,13 +437,13 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
|
|
|
|
|
|
|
|
if (e->sysval_semantic != VKD3D_SHADER_SV_NONE)
|
|
|
|
{
|
|
|
|
- shader_instruction_init(ins, VKD3DSIH_DCL_INPUT_SIV);
|
|
|
|
+ vsir_instruction_init(ins, location, VKD3DSIH_DCL_INPUT_SIV);
|
|
|
|
param = &ins->declaration.register_semantic.reg;
|
|
|
|
ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
- shader_instruction_init(ins, VKD3DSIH_DCL_INPUT);
|
|
|
|
+ vsir_instruction_init(ins, location, VKD3DSIH_DCL_INPUT);
|
|
|
|
param = &ins->declaration.dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -511,7 +514,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
|
|
|
|
case VKD3DSIH_HS_FORK_PHASE:
|
|
|
|
case VKD3DSIH_HS_JOIN_PHASE:
|
|
|
|
ret = control_point_normaliser_emit_hs_input(&normaliser, input_signature,
|
|
|
|
- input_control_point_count, i);
|
|
|
|
+ input_control_point_count, i, &ins->location);
|
|
|
|
*src_instructions = normaliser.instructions;
|
|
|
|
return ret;
|
|
|
|
default:
|
|
|
|
@@ -1014,7 +1017,6 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
|
|
|
|
struct io_normaliser *normaliser)
|
|
|
|
{
|
|
|
|
struct vkd3d_shader_register *reg;
|
|
|
|
- bool keep = true;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
switch (ins->handler_idx)
|
|
|
|
@@ -1033,15 +1035,16 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
|
|
|
|
/* fall through */
|
|
|
|
case VKD3DSIH_DCL_INPUT_PS:
|
|
|
|
case VKD3DSIH_DCL_OUTPUT:
|
|
|
|
- keep = shader_dst_param_io_normalise(&ins->declaration.dst, true, normaliser);
|
|
|
|
+ if (!shader_dst_param_io_normalise(&ins->declaration.dst, true, normaliser))
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
break;
|
|
|
|
case VKD3DSIH_DCL_INPUT_SGV:
|
|
|
|
case VKD3DSIH_DCL_INPUT_SIV:
|
|
|
|
case VKD3DSIH_DCL_INPUT_PS_SGV:
|
|
|
|
case VKD3DSIH_DCL_INPUT_PS_SIV:
|
|
|
|
case VKD3DSIH_DCL_OUTPUT_SIV:
|
|
|
|
- keep = shader_dst_param_io_normalise(&ins->declaration.register_semantic.reg, true,
|
|
|
|
- normaliser);
|
|
|
|
+ if (!shader_dst_param_io_normalise(&ins->declaration.register_semantic.reg, true, normaliser))
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
break;
|
|
|
|
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
|
|
|
|
case VKD3DSIH_HS_FORK_PHASE:
|
|
|
|
@@ -1060,9 +1063,6 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
|
|
|
|
shader_src_param_io_normalise((struct vkd3d_shader_src_param *)&ins->src[i], normaliser);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
-
|
|
|
|
- if (!keep)
|
|
|
|
- shader_instruction_init(ins, VKD3DSIH_NOP);
|
|
|
|
}
|
|
|
|
|
|
|
|
static enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions,
|
|
|
|
@@ -1290,5 +1290,117 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
|
|
|
|
if (result >= 0 && TRACE_ON())
|
|
|
|
vkd3d_shader_trace(instructions, &parser->shader_version);
|
|
|
|
|
|
|
|
+ if (result >= 0 && !parser->failed)
|
|
|
|
+ vsir_validate(parser);
|
|
|
|
+
|
|
|
|
+ if (result >= 0 && parser->failed)
|
|
|
|
+ result = VKD3D_ERROR_INVALID_SHADER;
|
|
|
|
+
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+struct validation_context
|
|
|
|
+{
|
|
|
|
+ struct vkd3d_shader_parser *parser;
|
|
|
|
+ size_t instruction_idx;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *ctx,
|
|
|
|
+ enum vkd3d_shader_error error, const char *format, ...)
|
|
|
|
+{
|
|
|
|
+ struct vkd3d_string_buffer buf;
|
|
|
|
+ va_list args;
|
|
|
|
+
|
|
|
|
+ vkd3d_string_buffer_init(&buf);
|
|
|
|
+
|
|
|
|
+ va_start(args, format);
|
|
|
|
+ vkd3d_string_buffer_vprintf(&buf, format, args);
|
|
|
|
+ va_end(args);
|
|
|
|
+
|
|
|
|
+ vkd3d_shader_parser_error(ctx->parser, error, "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer);
|
|
|
|
+
|
|
|
|
+ vkd3d_string_buffer_cleanup(&buf);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void vsir_validate_register(struct validation_context *ctx,
|
|
|
|
+ const struct vkd3d_shader_register *reg)
|
|
|
|
+{
|
|
|
|
+ if (reg->type >= VKD3DSPR_COUNT)
|
|
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, "Invalid register type %#x.",
|
|
|
|
+ reg->type);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void vsir_validate_dst_param(struct validation_context *ctx,
|
|
|
|
+ const struct vkd3d_shader_dst_param *dst)
|
|
|
|
+{
|
|
|
|
+ vsir_validate_register(ctx, &dst->reg);
|
|
|
|
+
|
|
|
|
+ if (dst->write_mask & ~VKD3DSP_WRITEMASK_ALL)
|
|
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, "Destination has invalid write mask %#x.",
|
|
|
|
+ dst->write_mask);
|
|
|
|
+
|
|
|
|
+ if (dst->modifiers & ~VKD3DSPDM_MASK)
|
|
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.",
|
|
|
|
+ dst->modifiers);
|
|
|
|
+
|
|
|
|
+ switch (dst->shift)
|
|
|
|
+ {
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 13:
|
|
|
|
+ case 14:
|
|
|
|
+ case 15:
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT, "Destination has invalid shift %#x.",
|
|
|
|
+ dst->shift);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void vsir_validate_src_param(struct validation_context *ctx,
|
|
|
|
+ const struct vkd3d_shader_src_param *src)
|
|
|
|
+{
|
|
|
|
+ vsir_validate_register(ctx, &src->reg);
|
|
|
|
+
|
|
|
|
+ if (src->swizzle & ~0x03030303u)
|
|
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source has invalid swizzle %#x.",
|
|
|
|
+ src->swizzle);
|
|
|
|
+
|
|
|
|
+ if (src->modifiers >= VKD3DSPSM_COUNT)
|
|
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.",
|
|
|
|
+ src->modifiers);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void vsir_validate_instruction(struct validation_context *ctx)
|
|
|
|
+{
|
|
|
|
+ const struct vkd3d_shader_instruction *instruction = &ctx->parser->instructions.elements[ctx->instruction_idx];
|
|
|
|
+ size_t i;
|
|
|
|
+
|
|
|
|
+ ctx->parser->location = instruction->location;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < instruction->dst_count; ++i)
|
|
|
|
+ vsir_validate_dst_param(ctx, &instruction->dst[i]);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < instruction->src_count; ++i)
|
|
|
|
+ vsir_validate_src_param(ctx, &instruction->src[i]);
|
|
|
|
+
|
|
|
|
+ if (instruction->handler_idx >= VKD3DSIH_INVALID)
|
|
|
|
+ {
|
|
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Invalid instruction handler %#x.",
|
|
|
|
+ instruction->handler_idx);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void vsir_validate(struct vkd3d_shader_parser *parser)
|
|
|
|
+{
|
|
|
|
+ struct validation_context ctx = { .parser = parser };
|
|
|
|
+
|
|
|
|
+ if (!(parser->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ for (ctx.instruction_idx = 0; ctx.instruction_idx < parser->instructions.count; ++ctx.instruction_idx)
|
|
|
|
+ vsir_validate_instruction(&ctx);
|
|
|
|
+}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.h b/libs/vkd3d/libs/vkd3d-shader/preproc.h
|
|
|
|
index 4860cf5f90e..e1cb75e177c 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/preproc.h
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.h
|
|
|
|
@@ -22,7 +22,7 @@
|
|
|
|
#define __VKD3D_SHADER_PREPROC_H
|
|
|
|
|
|
|
|
#include "vkd3d_shader_private.h"
|
|
|
|
-#include "wine/rbtree.h"
|
|
|
|
+#include "rbtree.h"
|
|
|
|
|
|
|
|
struct preproc_if_state
|
|
|
|
{
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
index 638764b81bc..8285b56a17c 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
@@ -18,7 +18,7 @@
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "vkd3d_shader_private.h"
|
|
|
|
-#include "wine/rbtree.h"
|
|
|
|
+#include "rbtree.h"
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
index 045fb6c5f64..58b7f030dac 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
@@ -2327,7 +2327,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
- ins->handler_idx = opcode_info->handler_idx;
|
|
|
|
+ vsir_instruction_init(ins, &sm4->p.location, opcode_info->handler_idx);
|
|
|
|
if (ins->handler_idx == VKD3DSIH_HS_CONTROL_POINT_PHASE || ins->handler_idx == VKD3DSIH_HS_FORK_PHASE
|
|
|
|
|| ins->handler_idx == VKD3DSIH_HS_JOIN_PHASE)
|
|
|
|
sm4->phase = ins->handler_idx;
|
|
|
|
@@ -2642,9 +2642,19 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
|
|
|
|
if (sm4->p.shader_version.type == VKD3D_SHADER_TYPE_HULL && !sm4->has_control_point_phase && !sm4->p.failed)
|
|
|
|
shader_sm4_validate_default_phase_index_ranges(sm4);
|
|
|
|
|
|
|
|
+ if (!sm4->p.failed)
|
|
|
|
+ vsir_validate(&sm4->p);
|
|
|
|
+
|
|
|
|
+ if (sm4->p.failed)
|
|
|
|
+ {
|
|
|
|
+ WARN("Failed to parse shader.\n");
|
|
|
|
+ shader_sm4_destroy(&sm4->p);
|
|
|
|
+ return VKD3D_ERROR_INVALID_SHADER;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
*parser = &sm4->p;
|
|
|
|
|
|
|
|
- return sm4->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK;
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void write_sm4_block(const struct tpf_writer *tpf, const struct hlsl_block *block);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
|
|
index f25dbb04d69..077d0144bc5 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
|
|
@@ -22,6 +22,8 @@
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
+/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */
|
|
|
|
+
|
|
|
|
static inline int char_to_int(char c)
|
|
|
|
{
|
|
|
|
if ('0' <= c && c <= '9')
|
|
|
|
@@ -452,6 +454,25 @@ static void init_scan_signature_info(const struct vkd3d_shader_compile_info *inf
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+static const struct vkd3d_debug_option vkd3d_shader_config_options[] =
|
|
|
|
+{
|
|
|
|
+ {"force_validation", VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION}, /* force validation of internal shader representations */
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static uint64_t vkd3d_shader_init_config_flags(void)
|
|
|
|
+{
|
|
|
|
+ uint64_t config_flags;
|
|
|
|
+ const char *config;
|
|
|
|
+
|
|
|
|
+ config = getenv("VKD3D_SHADER_CONFIG");
|
|
|
|
+ config_flags = vkd3d_parse_debug_options(config, vkd3d_shader_config_options, ARRAY_SIZE(vkd3d_shader_config_options));
|
|
|
|
+
|
|
|
|
+ if (config_flags)
|
|
|
|
+ TRACE("VKD3D_SHADER_CONFIG='%s'.\n", config);
|
|
|
|
+
|
|
|
|
+ return config_flags;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
|
|
|
|
struct vkd3d_shader_message_context *message_context, const char *source_name,
|
|
|
|
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
|
|
|
|
@@ -463,6 +484,7 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
|
|
|
|
parser->location.column = 0;
|
|
|
|
parser->shader_version = *version;
|
|
|
|
parser->ops = ops;
|
|
|
|
+ parser->config_flags = vkd3d_shader_init_config_flags();
|
|
|
|
return shader_instruction_array_init(&parser->instructions, instruction_reserve);
|
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
index 9443df6c232..5fd930918be 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
@@ -49,7 +49,7 @@
|
|
|
|
#include "vkd3d_common.h"
|
|
|
|
#include "vkd3d_memory.h"
|
|
|
|
#include "vkd3d_shader.h"
|
|
|
|
-#include "wine/list.h"
|
|
|
|
+#include "list.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
@@ -183,6 +183,12 @@ enum vkd3d_shader_error
|
|
|
|
VKD3D_SHADER_WARNING_DXIL_UNHANDLED_INTRINSIC = 8305,
|
|
|
|
|
|
|
|
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
|
|
|
|
+ VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001,
|
|
|
|
+ VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE = 9002,
|
|
|
|
+ VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK = 9003,
|
|
|
|
+ VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS = 9004,
|
|
|
|
+ VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT = 9005,
|
|
|
|
+ VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE = 9006,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum vkd3d_shader_opcode
|
|
|
|
@@ -585,6 +591,7 @@ enum vkd3d_shader_src_modifier
|
|
|
|
VKD3DSPSM_ABS = 11,
|
|
|
|
VKD3DSPSM_ABSNEG = 12,
|
|
|
|
VKD3DSPSM_NOT = 13,
|
|
|
|
+ VKD3DSPSM_COUNT,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define VKD3DSP_WRITEMASK_0 0x1u /* .x r */
|
|
|
|
@@ -599,6 +606,7 @@ enum vkd3d_shader_dst_modifier
|
|
|
|
VKD3DSPDM_SATURATE = 1,
|
|
|
|
VKD3DSPDM_PARTIALPRECISION = 2,
|
|
|
|
VKD3DSPDM_MSAMPCENTROID = 4,
|
|
|
|
+ VKD3DSPDM_MASK = 7,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum vkd3d_shader_interpolation_mode
|
|
|
|
@@ -968,8 +976,15 @@ struct vkd3d_shader_primitive_type
|
|
|
|
unsigned int patch_vertex_count;
|
|
|
|
};
|
|
|
|
|
|
|
|
+struct vkd3d_shader_location
|
|
|
|
+{
|
|
|
|
+ const char *source_name;
|
|
|
|
+ unsigned int line, column;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
struct vkd3d_shader_instruction
|
|
|
|
{
|
|
|
|
+ struct vkd3d_shader_location location;
|
|
|
|
enum vkd3d_shader_opcode handler_idx;
|
|
|
|
DWORD flags;
|
|
|
|
unsigned int dst_count;
|
|
|
|
@@ -1008,7 +1023,8 @@ struct vkd3d_shader_instruction
|
|
|
|
} declaration;
|
|
|
|
};
|
|
|
|
|
|
|
|
-void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx);
|
|
|
|
+void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
|
|
|
|
+ enum vkd3d_shader_opcode handler_idx);
|
|
|
|
|
|
|
|
static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins)
|
|
|
|
{
|
|
|
|
@@ -1035,12 +1051,6 @@ static inline bool register_is_constant(const struct vkd3d_shader_register *reg)
|
|
|
|
return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64);
|
|
|
|
}
|
|
|
|
|
|
|
|
-struct vkd3d_shader_location
|
|
|
|
-{
|
|
|
|
- const char *source_name;
|
|
|
|
- unsigned int line, column;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
struct vkd3d_shader_param_node
|
|
|
|
{
|
|
|
|
struct vkd3d_shader_param_node *next;
|
|
|
|
@@ -1093,6 +1103,11 @@ bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_
|
|
|
|
unsigned int dst, unsigned int src);
|
|
|
|
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions);
|
|
|
|
|
|
|
|
+enum vkd3d_shader_config_flags
|
|
|
|
+{
|
|
|
|
+ VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
struct vkd3d_shader_parser
|
|
|
|
{
|
|
|
|
struct vkd3d_shader_message_context *message_context;
|
|
|
|
@@ -1103,6 +1118,8 @@ struct vkd3d_shader_parser
|
|
|
|
struct vkd3d_shader_version shader_version;
|
|
|
|
const struct vkd3d_shader_parser_ops *ops;
|
|
|
|
struct vkd3d_shader_instruction_array instructions;
|
|
|
|
+
|
|
|
|
+ uint64_t config_flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct vkd3d_shader_parser_ops
|
|
|
|
@@ -1291,6 +1308,8 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
|
|
|
|
|
|
|
|
+void vsir_validate(struct vkd3d_shader_parser *parser);
|
|
|
|
+
|
|
|
|
static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type(
|
|
|
|
enum vkd3d_data_type data_type)
|
|
|
|
{
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
|
|
|
|
index 42a98763438..3be45120d8c 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d/command.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d/command.c
|
|
|
|
@@ -5461,6 +5461,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID
|
|
|
|
view_desc.miplevel_count = 1;
|
|
|
|
view_desc.layer_idx = view->info.texture.layer_idx;
|
|
|
|
view_desc.layer_count = view->info.texture.layer_count;
|
|
|
|
+ view_desc.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
|
|
|
|
if (!vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_UAV, resource_impl->u.vk_image, &view_desc,
|
|
|
|
&uint_view))
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
|
|
|
|
index c33061073a3..69727e09cc7 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d/device.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d/device.c
|
|
|
|
@@ -2456,17 +2456,18 @@ static void vkd3d_desc_object_cache_cleanup(struct vkd3d_desc_object_cache *cach
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ID3D12Device */
|
|
|
|
-static inline struct d3d12_device *impl_from_ID3D12Device1(ID3D12Device1 *iface)
|
|
|
|
+static inline struct d3d12_device *impl_from_ID3D12Device2(ID3D12Device2 *iface)
|
|
|
|
{
|
|
|
|
- return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device1_iface);
|
|
|
|
+ return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device2_iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device2 *iface,
|
|
|
|
REFIID riid, void **object)
|
|
|
|
{
|
|
|
|
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
|
|
|
|
|
|
|
|
- if (IsEqualGUID(riid, &IID_ID3D12Device1)
|
|
|
|
+ if (IsEqualGUID(riid, &IID_ID3D12Device2)
|
|
|
|
+ || IsEqualGUID(riid, &IID_ID3D12Device1)
|
|
|
|
|| IsEqualGUID(riid, &IID_ID3D12Device)
|
|
|
|
|| IsEqualGUID(riid, &IID_ID3D12Object)
|
|
|
|
|| IsEqualGUID(riid, &IID_IUnknown))
|
|
|
|
@@ -2482,9 +2483,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device1 *ifac
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device1 *iface)
|
|
|
|
+static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device2 *iface)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
ULONG refcount = InterlockedIncrement(&device->refcount);
|
|
|
|
|
|
|
|
TRACE("%p increasing refcount to %u.\n", device, refcount);
|
|
|
|
@@ -2492,9 +2493,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device1 *iface)
|
|
|
|
return refcount;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device1 *iface)
|
|
|
|
+static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device2 *iface)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
ULONG refcount = InterlockedDecrement(&device->refcount);
|
|
|
|
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", device, refcount);
|
|
|
|
@@ -2528,10 +2529,10 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device1 *iface)
|
|
|
|
return refcount;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device2 *iface,
|
|
|
|
REFGUID guid, UINT *data_size, void *data)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
TRACE("iface %p, guid %s, data_size %p, data %p.\n",
|
|
|
|
iface, debugstr_guid(guid), data_size, data);
|
|
|
|
@@ -2539,10 +2540,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device1 *ifac
|
|
|
|
return vkd3d_get_private_data(&device->private_store, guid, data_size, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device2 *iface,
|
|
|
|
REFGUID guid, UINT data_size, const void *data)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
TRACE("iface %p, guid %s, data_size %u, data %p.\n",
|
|
|
|
iface, debugstr_guid(guid), data_size, data);
|
|
|
|
@@ -2550,19 +2551,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device1 *ifac
|
|
|
|
return vkd3d_set_private_data(&device->private_store, guid, data_size, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device2 *iface,
|
|
|
|
REFGUID guid, const IUnknown *data)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
|
|
|
|
|
|
|
|
return vkd3d_set_private_data_interface(&device->private_store, guid, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device1 *iface, const WCHAR *name)
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device2 *iface, const WCHAR *name)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
TRACE("iface %p, name %s.\n", iface, debugstr_w(name, device->wchar_size));
|
|
|
|
|
|
|
|
@@ -2570,17 +2571,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device1 *iface, cons
|
|
|
|
VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device1 *iface)
|
|
|
|
+static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device2 *iface)
|
|
|
|
{
|
|
|
|
TRACE("iface %p.\n", iface);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device2 *iface,
|
|
|
|
const D3D12_COMMAND_QUEUE_DESC *desc, REFIID riid, void **command_queue)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_command_queue *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -2594,10 +2595,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device1 *
|
|
|
|
riid, command_queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device2 *iface,
|
|
|
|
D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **command_allocator)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_command_allocator *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -2611,10 +2612,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Devic
|
|
|
|
riid, command_allocator);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device2 *iface,
|
|
|
|
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_pipeline_state *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -2628,10 +2629,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12
|
|
|
|
&IID_ID3D12PipelineState, riid, pipeline_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device2 *iface,
|
|
|
|
const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_pipeline_state *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -2645,11 +2646,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12D
|
|
|
|
&IID_ID3D12PipelineState, riid, pipeline_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device2 *iface,
|
|
|
|
UINT node_mask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *command_allocator,
|
|
|
|
ID3D12PipelineState *initial_pipeline_state, REFIID riid, void **command_list)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_command_list *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -2772,10 +2773,10 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device2 *iface,
|
|
|
|
D3D12_FEATURE feature, void *feature_data, UINT feature_data_size)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
TRACE("iface %p, feature %#x, feature_data %p, feature_data_size %u.\n",
|
|
|
|
iface, feature, feature_data, feature_data_size);
|
|
|
|
@@ -3274,10 +3275,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device2 *iface,
|
|
|
|
const D3D12_DESCRIPTOR_HEAP_DESC *desc, REFIID riid, void **descriptor_heap)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_descriptor_heap *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -3291,7 +3292,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device1
|
|
|
|
&IID_ID3D12DescriptorHeap, riid, descriptor_heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device1 *iface,
|
|
|
|
+static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device2 *iface,
|
|
|
|
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type)
|
|
|
|
{
|
|
|
|
TRACE("iface %p, descriptor_heap_type %#x.\n", iface, descriptor_heap_type);
|
|
|
|
@@ -3314,11 +3315,11 @@ static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device2 *iface,
|
|
|
|
UINT node_mask, const void *bytecode, SIZE_T bytecode_length,
|
|
|
|
REFIID riid, void **root_signature)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_root_signature *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -3334,10 +3335,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device1
|
|
|
|
&IID_ID3D12RootSignature, riid, root_signature);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device2 *iface,
|
|
|
|
const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_desc tmp = {0};
|
|
|
|
|
|
|
|
TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr);
|
|
|
|
@@ -3346,11 +3347,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device
|
|
|
|
d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device2 *iface,
|
|
|
|
ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *desc,
|
|
|
|
D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_desc tmp = {0};
|
|
|
|
|
|
|
|
TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n",
|
|
|
|
@@ -3360,11 +3361,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device
|
|
|
|
d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device2 *iface,
|
|
|
|
ID3D12Resource *resource, ID3D12Resource *counter_resource,
|
|
|
|
const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_desc tmp = {0};
|
|
|
|
|
|
|
|
TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %#lx.\n",
|
|
|
|
@@ -3375,7 +3376,7 @@ static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Devic
|
|
|
|
d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device2 *iface,
|
|
|
|
ID3D12Resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc,
|
|
|
|
D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
|
|
|
|
{
|
|
|
|
@@ -3383,10 +3384,10 @@ static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device1
|
|
|
|
iface, resource, desc, descriptor.ptr);
|
|
|
|
|
|
|
|
d3d12_rtv_desc_create_rtv(d3d12_rtv_desc_from_cpu_handle(descriptor),
|
|
|
|
- impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc);
|
|
|
|
+ impl_from_ID3D12Device2(iface), unsafe_impl_from_ID3D12Resource(resource), desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device2 *iface,
|
|
|
|
ID3D12Resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc,
|
|
|
|
D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
|
|
|
|
{
|
|
|
|
@@ -3394,13 +3395,13 @@ static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device1
|
|
|
|
iface, resource, desc, descriptor.ptr);
|
|
|
|
|
|
|
|
d3d12_dsv_desc_create_dsv(d3d12_dsv_desc_from_cpu_handle(descriptor),
|
|
|
|
- impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc);
|
|
|
|
+ impl_from_ID3D12Device2(iface), unsafe_impl_from_ID3D12Resource(resource), desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device2 *iface,
|
|
|
|
const D3D12_SAMPLER_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_desc tmp = {0};
|
|
|
|
|
|
|
|
TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr);
|
|
|
|
@@ -3409,14 +3410,14 @@ static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device1 *iface,
|
|
|
|
d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device2 *iface,
|
|
|
|
UINT dst_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets,
|
|
|
|
const UINT *dst_descriptor_range_sizes,
|
|
|
|
UINT src_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *src_descriptor_range_offsets,
|
|
|
|
const UINT *src_descriptor_range_sizes,
|
|
|
|
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx;
|
|
|
|
unsigned int dst_range_size, src_range_size;
|
|
|
|
struct d3d12_descriptor_heap *dst_heap;
|
|
|
|
@@ -3472,7 +3473,7 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device1 *iface,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device2 *iface,
|
|
|
|
UINT descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE dst_descriptor_range_offset,
|
|
|
|
const D3D12_CPU_DESCRIPTOR_HANDLE src_descriptor_range_offset,
|
|
|
|
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type)
|
|
|
|
@@ -3487,10 +3488,10 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device1 *
|
|
|
|
}
|
|
|
|
|
|
|
|
static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo(
|
|
|
|
- ID3D12Device1 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask,
|
|
|
|
+ ID3D12Device2 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask,
|
|
|
|
UINT count, const D3D12_RESOURCE_DESC *resource_descs)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
const D3D12_RESOURCE_DESC *desc;
|
|
|
|
uint64_t requested_alignment;
|
|
|
|
|
|
|
|
@@ -3563,10 +3564,10 @@ invalid:
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device1 *iface,
|
|
|
|
+static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device2 *iface,
|
|
|
|
D3D12_HEAP_PROPERTIES *heap_properties, UINT node_mask, D3D12_HEAP_TYPE heap_type)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
bool coherent;
|
|
|
|
|
|
|
|
TRACE("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x.\n",
|
|
|
|
@@ -3606,12 +3607,12 @@ static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapPrope
|
|
|
|
return heap_properties;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device2 *iface,
|
|
|
|
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
|
|
|
|
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
|
|
|
|
const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_resource *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -3630,10 +3631,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi
|
|
|
|
return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device2 *iface,
|
|
|
|
const D3D12_HEAP_DESC *desc, REFIID iid, void **heap)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_heap *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -3649,12 +3650,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device1 *iface,
|
|
|
|
return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device2 *iface,
|
|
|
|
ID3D12Heap *heap, UINT64 heap_offset,
|
|
|
|
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
|
|
|
|
const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_heap *heap_object;
|
|
|
|
struct d3d12_resource *object;
|
|
|
|
HRESULT hr;
|
|
|
|
@@ -3673,11 +3674,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device1
|
|
|
|
return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device2 *iface,
|
|
|
|
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
|
|
|
|
const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_resource *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -3691,11 +3692,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Devic
|
|
|
|
return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device2 *iface,
|
|
|
|
ID3D12DeviceChild *object, const SECURITY_ATTRIBUTES *attributes, DWORD access,
|
|
|
|
const WCHAR *name, HANDLE *handle)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
FIXME("iface %p, object %p, attributes %p, access %#x, name %s, handle %p stub!\n",
|
|
|
|
iface, object, attributes, access, debugstr_w(name, device->wchar_size), handle);
|
|
|
|
@@ -3703,7 +3704,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device1 *
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device2 *iface,
|
|
|
|
HANDLE handle, REFIID riid, void **object)
|
|
|
|
{
|
|
|
|
FIXME("iface %p, handle %p, riid %s, object %p stub!\n",
|
|
|
|
@@ -3712,10 +3713,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device1 *if
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device2 *iface,
|
|
|
|
const WCHAR *name, DWORD access, HANDLE *handle)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
FIXME("iface %p, name %s, access %#x, handle %p stub!\n",
|
|
|
|
iface, debugstr_w(name, device->wchar_size), access, handle);
|
|
|
|
@@ -3723,7 +3724,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device2 *iface,
|
|
|
|
UINT object_count, ID3D12Pageable * const *objects)
|
|
|
|
{
|
|
|
|
FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n",
|
|
|
|
@@ -3732,7 +3733,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device1 *iface,
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device2 *iface,
|
|
|
|
UINT object_count, ID3D12Pageable * const *objects)
|
|
|
|
{
|
|
|
|
FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n",
|
|
|
|
@@ -3741,10 +3742,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device1 *iface,
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device2 *iface,
|
|
|
|
UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_fence *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -3757,21 +3758,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device1 *iface,
|
|
|
|
return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device1 *iface)
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device2 *iface)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
TRACE("iface %p.\n", iface);
|
|
|
|
|
|
|
|
return device->removed_reason;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device2 *iface,
|
|
|
|
const D3D12_RESOURCE_DESC *desc, UINT first_sub_resource, UINT sub_resource_count,
|
|
|
|
UINT64 base_offset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts,
|
|
|
|
UINT *row_counts, UINT64 *row_sizes, UINT64 *total_bytes)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
unsigned int i, sub_resource_idx, miplevel_idx, row_count, row_size, row_pitch;
|
|
|
|
unsigned int width, height, depth, plane_count, sub_resources_per_plane;
|
|
|
|
@@ -3851,10 +3852,10 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device1 *
|
|
|
|
*total_bytes = total;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device2 *iface,
|
|
|
|
const D3D12_QUERY_HEAP_DESC *desc, REFIID iid, void **heap)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_query_heap *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -3867,18 +3868,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device1 *ifa
|
|
|
|
return return_interface(&object->ID3D12QueryHeap_iface, &IID_ID3D12QueryHeap, iid, heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device1 *iface, BOOL enable)
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device2 *iface, BOOL enable)
|
|
|
|
{
|
|
|
|
FIXME("iface %p, enable %#x stub!\n", iface, enable);
|
|
|
|
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device2 *iface,
|
|
|
|
const D3D12_COMMAND_SIGNATURE_DESC *desc, ID3D12RootSignature *root_signature,
|
|
|
|
REFIID iid, void **command_signature)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
struct d3d12_command_signature *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
@@ -3892,14 +3893,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Devic
|
|
|
|
&IID_ID3D12CommandSignature, iid, command_signature);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device1 *iface,
|
|
|
|
+static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device2 *iface,
|
|
|
|
ID3D12Resource *resource, UINT *total_tile_count,
|
|
|
|
D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape,
|
|
|
|
UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling,
|
|
|
|
D3D12_SUBRESOURCE_TILING *sub_resource_tilings)
|
|
|
|
{
|
|
|
|
const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource);
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, "
|
|
|
|
"standard_title_shape %p, sub_resource_tiling_count %p, "
|
|
|
|
@@ -3912,9 +3913,9 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device1 *ifac
|
|
|
|
sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device1 *iface, LUID *luid)
|
|
|
|
+static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device2 *iface, LUID *luid)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = impl_from_ID3D12Device1(iface);
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device2(iface);
|
|
|
|
|
|
|
|
TRACE("iface %p, luid %p.\n", iface, luid);
|
|
|
|
|
|
|
|
@@ -3923,7 +3924,7 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device1 *iface
|
|
|
|
return luid;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device2 *iface,
|
|
|
|
const void *blob, SIZE_T blob_size, REFIID iid, void **lib)
|
|
|
|
{
|
|
|
|
FIXME("iface %p, blob %p, blob_size %lu, iid %s, lib %p stub!\n", iface, blob, blob_size, debugstr_guid(iid), lib);
|
|
|
|
@@ -3931,7 +3932,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device
|
|
|
|
return DXGI_ERROR_UNSUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device2 *iface,
|
|
|
|
ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count,
|
|
|
|
D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event)
|
|
|
|
{
|
|
|
|
@@ -3941,7 +3942,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device1 *iface,
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device2 *iface,
|
|
|
|
UINT object_count, ID3D12Pageable *const *objects, const D3D12_RESIDENCY_PRIORITY *priorities)
|
|
|
|
{
|
|
|
|
FIXME_ONCE("iface %p, object_count %u, objects %p, priorities %p stub!\n", iface, object_count, objects, priorities);
|
|
|
|
@@ -3949,7 +3950,15 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device1
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static const struct ID3D12Device1Vtbl d3d12_device_vtbl =
|
|
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device2 *iface,
|
|
|
|
+ const D3D12_PIPELINE_STATE_STREAM_DESC *desc, REFIID iid, void **pipeline_state)
|
|
|
|
+{
|
|
|
|
+ FIXME("iface %p, desc %p, iid %s, pipeline_state %p stub!\n", iface, desc, debugstr_guid(iid), pipeline_state);
|
|
|
|
+
|
|
|
|
+ return E_NOTIMPL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static const struct ID3D12Device2Vtbl d3d12_device_vtbl =
|
|
|
|
{
|
|
|
|
/* IUnknown methods */
|
|
|
|
d3d12_device_QueryInterface,
|
|
|
|
@@ -4002,14 +4011,16 @@ static const struct ID3D12Device1Vtbl d3d12_device_vtbl =
|
|
|
|
d3d12_device_CreatePipelineLibrary,
|
|
|
|
d3d12_device_SetEventOnMultipleFenceCompletion,
|
|
|
|
d3d12_device_SetResidencyPriority,
|
|
|
|
+ /* ID3D12Device2 methods */
|
|
|
|
+ d3d12_device_CreatePipelineState,
|
|
|
|
};
|
|
|
|
|
|
|
|
-struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface)
|
|
|
|
+struct d3d12_device *unsafe_impl_from_ID3D12Device2(ID3D12Device2 *iface)
|
|
|
|
{
|
|
|
|
if (!iface)
|
|
|
|
return NULL;
|
|
|
|
assert(iface->lpVtbl == &d3d12_device_vtbl);
|
|
|
|
- return impl_from_ID3D12Device1(iface);
|
|
|
|
+ return impl_from_ID3D12Device2(iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT d3d12_device_init(struct d3d12_device *device,
|
|
|
|
@@ -4018,7 +4029,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
|
|
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
- device->ID3D12Device1_iface.lpVtbl = &d3d12_device_vtbl;
|
|
|
|
+ device->ID3D12Device2_iface.lpVtbl = &d3d12_device_vtbl;
|
|
|
|
device->refcount = 1;
|
|
|
|
|
|
|
|
vkd3d_instance_incref(device->vkd3d_instance = instance);
|
|
|
|
@@ -4215,28 +4226,28 @@ HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_ha
|
|
|
|
|
|
|
|
IUnknown *vkd3d_get_device_parent(ID3D12Device *device)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device);
|
|
|
|
+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device2((ID3D12Device2 *)device);
|
|
|
|
|
|
|
|
return d3d12_device->parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkDevice vkd3d_get_vk_device(ID3D12Device *device)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device);
|
|
|
|
+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device2((ID3D12Device2 *)device);
|
|
|
|
|
|
|
|
return d3d12_device->vk_device;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device);
|
|
|
|
+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device2((ID3D12Device2 *)device);
|
|
|
|
|
|
|
|
return d3d12_device->vk_physical_device;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct vkd3d_instance *vkd3d_instance_from_device(ID3D12Device *device)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device);
|
|
|
|
+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device2((ID3D12Device2 *)device);
|
|
|
|
|
|
|
|
return d3d12_device->vkd3d_instance;
|
|
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
|
|
|
|
index f3842958d96..0dfb4d379ca 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d/resource.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d/resource.c
|
|
|
|
@@ -2220,7 +2220,7 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
|
|
|
|
HRESULT vkd3d_create_image_resource(ID3D12Device *device,
|
|
|
|
const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device1((ID3D12Device1 *)device);
|
|
|
|
+ struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device2((ID3D12Device2 *)device);
|
|
|
|
struct d3d12_resource *object;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
|
|
index 159560afd8e..7651acc3820 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
|
|
@@ -71,11 +71,11 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
|
|
|
|
|
|
|
|
if (!device)
|
|
|
|
{
|
|
|
|
- ID3D12Device_Release(&object->ID3D12Device1_iface);
|
|
|
|
+ ID3D12Device_Release(&object->ID3D12Device2_iface);
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
- return return_interface(&object->ID3D12Device1_iface, &IID_ID3D12Device, iid, device);
|
|
|
|
+ return return_interface(&object->ID3D12Device2_iface, &IID_ID3D12Device, iid, device);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ID3D12RootSignatureDeserializer */
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
|
|
index 363a7132c3a..fceb06fc05a 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
|
|
@@ -31,8 +31,8 @@
|
|
|
|
#include "vkd3d_blob.h"
|
|
|
|
#include "vkd3d_memory.h"
|
|
|
|
#include "vkd3d_utf8.h"
|
|
|
|
-#include "wine/list.h"
|
|
|
|
-#include "wine/rbtree.h"
|
|
|
|
+#include "list.h"
|
|
|
|
+#include "rbtree.h"
|
|
|
|
|
|
|
|
#include "vkd3d.h"
|
|
|
|
#include "vkd3d_shader.h"
|
|
|
|
@@ -1709,7 +1709,7 @@ struct vkd3d_desc_object_cache
|
|
|
|
/* ID3D12Device */
|
|
|
|
struct d3d12_device
|
|
|
|
{
|
|
|
|
- ID3D12Device1 ID3D12Device1_iface;
|
|
|
|
+ ID3D12Device2 ID3D12Device2_iface;
|
|
|
|
LONG refcount;
|
|
|
|
|
|
|
|
VkDevice vk_device;
|
|
|
|
@@ -1775,27 +1775,27 @@ struct vkd3d_queue *d3d12_device_get_vkd3d_queue(struct d3d12_device *device, D3
|
|
|
|
bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent);
|
|
|
|
void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
|
|
|
|
const char *message, ...) VKD3D_PRINTF_FUNC(3, 4);
|
|
|
|
-struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface);
|
|
|
|
+struct d3d12_device *unsafe_impl_from_ID3D12Device2(ID3D12Device2 *iface);
|
|
|
|
|
|
|
|
static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object)
|
|
|
|
{
|
|
|
|
- return ID3D12Device1_QueryInterface(&device->ID3D12Device1_iface, iid, object);
|
|
|
|
+ return ID3D12Device2_QueryInterface(&device->ID3D12Device2_iface, iid, object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline ULONG d3d12_device_add_ref(struct d3d12_device *device)
|
|
|
|
{
|
|
|
|
- return ID3D12Device1_AddRef(&device->ID3D12Device1_iface);
|
|
|
|
+ return ID3D12Device2_AddRef(&device->ID3D12Device2_iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline ULONG d3d12_device_release(struct d3d12_device *device)
|
|
|
|
{
|
|
|
|
- return ID3D12Device1_Release(&device->ID3D12Device1_iface);
|
|
|
|
+ return ID3D12Device2_Release(&device->ID3D12Device2_iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int d3d12_device_get_descriptor_handle_increment_size(struct d3d12_device *device,
|
|
|
|
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_type)
|
|
|
|
{
|
|
|
|
- return ID3D12Device1_GetDescriptorHandleIncrementSize(&device->ID3D12Device1_iface, descriptor_type);
|
|
|
|
+ return ID3D12Device2_GetDescriptorHandleIncrementSize(&device->ID3D12Device2_iface, descriptor_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* utils */
|
|
|
|
--
|
2023-09-29 01:11:42 -07:00
|
|
|
2.42.0
|
2023-09-23 15:30:07 -07:00
|
|
|
|