mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
2992 lines
109 KiB
Diff
2992 lines
109 KiB
Diff
From d0677b700d8fc3f569a3353b788343b3267bd4ed Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Sat, 27 Jan 2024 12:22:22 +1100
|
|
Subject: [PATCH] Updated vkd3d to fd7d23f64bc8c33fe3b59431219e14c0865be37a.
|
|
|
|
---
|
|
libs/vkd3d/include/private/list.h | 270 +++++++++++
|
|
libs/vkd3d/include/private/rbtree.h | 378 +++++++++++++++
|
|
libs/vkd3d/include/private/vkd3d_test.h | 432 ++++++++++++++++++
|
|
libs/vkd3d/include/vkd3d_d3d9types.h | 237 ++++++++++
|
|
libs/vkd3d/include/vkd3d_d3dcompiler.h | 93 ++++
|
|
libs/vkd3d/include/vkd3d_d3dcompiler_types.h | 45 ++
|
|
libs/vkd3d/include/vkd3d_shader.h | 1 +
|
|
libs/vkd3d/include/vkd3d_utils.h | 126 +++++
|
|
libs/vkd3d/include/vkd3d_windows.h | 289 ++++++++++++
|
|
libs/vkd3d/libs/vkd3d-common/blob.c | 1 +
|
|
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 9 +
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 20 +-
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 45 ++
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 138 +++++-
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 83 +++-
|
|
.../libs/vkd3d-shader/vkd3d_shader_main.c | 28 +-
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 9 +
|
|
libs/vkd3d/libs/vkd3d/command.c | 48 +-
|
|
libs/vkd3d/libs/vkd3d/state.c | 14 +-
|
|
libs/vkd3d/libs/vkd3d/vkd3d_main.c | 10 +-
|
|
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 12 +-
|
|
21 files changed, 2217 insertions(+), 71 deletions(-)
|
|
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_d3dcompiler_types.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/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_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..1975f4f980a
|
|
--- /dev/null
|
|
+++ b/libs/vkd3d/include/vkd3d_d3dcompiler.h
|
|
@@ -0,0 +1,93 @@
|
|
+/*
|
|
+ * 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__
|
|
+
|
|
+#include <vkd3d_d3dcompiler_types.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
|
|
+
|
|
+typedef enum D3DCOMPILER_STRIP_FLAGS
|
|
+{
|
|
+ D3DCOMPILER_STRIP_REFLECTION_DATA = 0x00000001,
|
|
+ D3DCOMPILER_STRIP_DEBUG_INFO = 0x00000002,
|
|
+ D3DCOMPILER_STRIP_TEST_BLOBS = 0x00000004,
|
|
+ D3DCOMPILER_STRIP_PRIVATE_DATA = 0x00000008,
|
|
+ D3DCOMPILER_STRIP_ROOT_SIGNATURE = 0x00000010,
|
|
+ D3DCOMPILER_STRIP_FORCE_DWORD = 0x7fffffff,
|
|
+} D3DCOMPILER_STRIP_FLAGS;
|
|
+
|
|
+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 D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob);
|
|
+HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
|
+HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
|
+HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
|
+HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_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);
|
|
+HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection);
|
|
+HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
|
|
+
|
|
+#endif /* __D3DCOMPILER_H__ */
|
|
+#endif /* __VKD3D_D3DCOMPILER_H */
|
|
diff --git a/libs/vkd3d/include/vkd3d_d3dcompiler_types.h b/libs/vkd3d/include/vkd3d_d3dcompiler_types.h
|
|
new file mode 100644
|
|
index 00000000000..b3a47cdd912
|
|
--- /dev/null
|
|
+++ b/libs/vkd3d/include/vkd3d_d3dcompiler_types.h
|
|
@@ -0,0 +1,45 @@
|
|
+/*
|
|
+ * 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_TYPES_H
|
|
+#define __VKD3D_D3DCOMPILER_TYPES_H
|
|
+#ifndef __D3DCOMPILER_H__
|
|
+
|
|
+typedef enum D3D_BLOB_PART
|
|
+{
|
|
+ D3D_BLOB_INPUT_SIGNATURE_BLOB,
|
|
+ D3D_BLOB_OUTPUT_SIGNATURE_BLOB,
|
|
+ D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB,
|
|
+ D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB,
|
|
+ D3D_BLOB_ALL_SIGNATURE_BLOB,
|
|
+ D3D_BLOB_DEBUG_INFO,
|
|
+ D3D_BLOB_LEGACY_SHADER,
|
|
+ D3D_BLOB_XNA_PREPASS_SHADER,
|
|
+ D3D_BLOB_XNA_SHADER,
|
|
+ D3D_BLOB_PDB,
|
|
+ D3D_BLOB_PRIVATE_DATA,
|
|
+ D3D_BLOB_ROOT_SIGNATURE,
|
|
+ D3D_BLOB_DEBUG_NAME,
|
|
+ D3D_BLOB_TEST_ALTERNATE_SHADER = 0x8000,
|
|
+ D3D_BLOB_TEST_COMPILE_DETAILS,
|
|
+ D3D_BLOB_TEST_COMPILE_PERF,
|
|
+ D3D_BLOB_TEST_COMPILE_REPORT
|
|
+} D3D_BLOB_PART;
|
|
+
|
|
+#endif /* __D3DCOMPILER_H__ */
|
|
+#endif /* __VKD3D_D3DCOMPILER_TYPES_H */
|
|
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
|
|
index 449b3684a10..a8cc3a336a3 100644
|
|
--- a/libs/vkd3d/include/vkd3d_shader.h
|
|
+++ b/libs/vkd3d/include/vkd3d_shader.h
|
|
@@ -200,6 +200,7 @@ enum vkd3d_shader_compile_option_fragment_coordinate_origin
|
|
enum vkd3d_shader_compile_option_feature_flags
|
|
{
|
|
VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64 = 0x00000001,
|
|
+ VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64 = 0x00000002,
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS),
|
|
};
|
|
diff --git a/libs/vkd3d/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h
|
|
new file mode 100644
|
|
index 00000000000..adcac5fcf64
|
|
--- /dev/null
|
|
+++ b/libs/vkd3d/include/vkd3d_utils.h
|
|
@@ -0,0 +1,126 @@
|
|
+/*
|
|
+ * 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>
|
|
+#include <vkd3d_d3dcompiler_types.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);
|
|
+
|
|
+/** \since 1.10 */
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DGetBlobPart(const void *data,
|
|
+ SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob);
|
|
+/** \since 1.10 */
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
|
+/** \since 1.10 */
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
|
+/** \since 1.10 */
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
|
+/** \since 1.10 */
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
|
|
+/** \since 1.10 */
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
|
|
+
|
|
+/** \since 1.11 */
|
|
+VKD3D_UTILS_API HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection);
|
|
+
|
|
+#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 4d347acef05..dbb26de7d73 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
@@ -23,6 +23,7 @@
|
|
#include "vkd3d_blob.h"
|
|
#include "vkd3d_debug.h"
|
|
#include "vkd3d_memory.h"
|
|
+#include "d3d12shader.h"
|
|
|
|
struct vkd3d_blob
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
index d9751945d8a..af939396a08 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
@@ -198,8 +198,11 @@ static const char * const shader_opcode_names[] =
|
|
[VKD3DSIH_IMUL ] = "imul",
|
|
[VKD3DSIH_INE ] = "ine",
|
|
[VKD3DSIH_INEG ] = "ineg",
|
|
+ [VKD3DSIH_ISFINITE ] = "isfinite",
|
|
[VKD3DSIH_ISHL ] = "ishl",
|
|
[VKD3DSIH_ISHR ] = "ishr",
|
|
+ [VKD3DSIH_ISINF ] = "isinf",
|
|
+ [VKD3DSIH_ISNAN ] = "isnan",
|
|
[VKD3DSIH_ITOD ] = "itod",
|
|
[VKD3DSIH_ITOF ] = "itof",
|
|
[VKD3DSIH_ITOI ] = "itoi",
|
|
@@ -282,6 +285,7 @@ static const char * const shader_opcode_names[] =
|
|
[VKD3DSIH_SWITCH ] = "switch",
|
|
[VKD3DSIH_SWITCH_MONOLITHIC ] = "switch",
|
|
[VKD3DSIH_SYNC ] = "sync",
|
|
+ [VKD3DSIH_TAN ] = "tan",
|
|
[VKD3DSIH_TEX ] = "texld",
|
|
[VKD3DSIH_TEXBEM ] = "texbem",
|
|
[VKD3DSIH_TEXBEML ] = "texbeml",
|
|
@@ -442,6 +446,11 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint
|
|
vkd3d_string_buffer_printf(&compiler->buffer, "_uglobal");
|
|
sync_flags &= ~VKD3DSSF_GLOBAL_UAV;
|
|
}
|
|
+ if (sync_flags & VKD3DSSF_THREAD_GROUP_UAV)
|
|
+ {
|
|
+ vkd3d_string_buffer_printf(&compiler->buffer, "_ugroup");
|
|
+ sync_flags &= ~VKD3DSSF_THREAD_GROUP_UAV;
|
|
+ }
|
|
if (sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY)
|
|
{
|
|
vkd3d_string_buffer_printf(&compiler->buffer, "_g");
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
index 035095d5b48..4ba001ea4cd 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
@@ -2345,8 +2345,6 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
|
|
|
|
sm1_instr = (struct sm1_instruction)
|
|
{
|
|
- .opcode = D3DSIO_TEX,
|
|
-
|
|
.dst.type = D3DSPR_TEMP,
|
|
.dst.reg = instr->reg.id,
|
|
.dst.writemask = instr->reg.writemask,
|
|
@@ -2362,8 +2360,22 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
|
|
|
|
.src_count = 2,
|
|
};
|
|
- if (load->load_type == HLSL_RESOURCE_SAMPLE_PROJ)
|
|
- sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
|
|
+
|
|
+ switch (load->load_type)
|
|
+ {
|
|
+ case HLSL_RESOURCE_SAMPLE:
|
|
+ sm1_instr.opcode = D3DSIO_TEX;
|
|
+ break;
|
|
+
|
|
+ case HLSL_RESOURCE_SAMPLE_PROJ:
|
|
+ sm1_instr.opcode = D3DSIO_TEX;
|
|
+ sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ hlsl_fixme(ctx, &instr->loc, "Resource load type %u\n", load->load_type);
|
|
+ return;
|
|
+ }
|
|
|
|
assert(instr->reg.allocated);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
index 2a0ff61cfeb..8a31d03c531 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
@@ -328,6 +328,12 @@ enum dx_intrinsic_opcode
|
|
{
|
|
DX_LOAD_INPUT = 4,
|
|
DX_STORE_OUTPUT = 5,
|
|
+ DX_ISNAN = 8,
|
|
+ DX_ISINF = 9,
|
|
+ DX_ISFINITE = 10,
|
|
+ DX_COS = 12,
|
|
+ DX_SIN = 13,
|
|
+ DX_TAN = 14,
|
|
DX_EXP = 21,
|
|
DX_FRC = 22,
|
|
DX_LOG = 23,
|
|
@@ -3494,6 +3500,14 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op)
|
|
{
|
|
switch (op)
|
|
{
|
|
+ case DX_ISNAN:
|
|
+ return VKD3DSIH_ISNAN;
|
|
+ case DX_ISINF:
|
|
+ return VKD3DSIH_ISINF;
|
|
+ case DX_ISFINITE:
|
|
+ return VKD3DSIH_ISFINITE;
|
|
+ case DX_TAN:
|
|
+ return VKD3DSIH_TAN;
|
|
case DX_EXP:
|
|
return VKD3DSIH_EXP;
|
|
case DX_FRC:
|
|
@@ -3743,6 +3757,28 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri
|
|
instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6);
|
|
}
|
|
|
|
+static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
+ const struct sm6_value **operands, struct function_emission_state *state)
|
|
+{
|
|
+ struct sm6_value *dst = sm6_parser_get_current_value(sm6);
|
|
+ struct vkd3d_shader_instruction *ins = state->ins;
|
|
+ struct vkd3d_shader_dst_param *dst_params;
|
|
+ struct vkd3d_shader_src_param *src_param;
|
|
+ unsigned int index;
|
|
+
|
|
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SINCOS);
|
|
+ src_param = instruction_src_params_alloc(ins, 1, sm6);
|
|
+ src_param_init_from_value(src_param, operands[0]);
|
|
+
|
|
+ index = op == DX_COS;
|
|
+ dst_params = instruction_dst_params_alloc(ins, 2, sm6);
|
|
+ dst_param_init(&dst_params[0]);
|
|
+ dst_param_init(&dst_params[1]);
|
|
+ register_init_ssa_scalar(&dst_params[index].reg, dst->type, sm6);
|
|
+ vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0);
|
|
+ dst->u.reg = dst_params[index].reg;
|
|
+}
|
|
+
|
|
static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
const struct sm6_value **operands, struct function_emission_state *state)
|
|
{
|
|
@@ -3806,6 +3842,7 @@ struct sm6_dx_opcode_info
|
|
};
|
|
|
|
/*
|
|
+ 1 -> int1
|
|
8 -> int8
|
|
b -> constant int1
|
|
c -> constant int8/16/32
|
|
@@ -3824,6 +3861,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
|
[DX_BFREV ] = {"m", "R", sm6_parser_emit_dx_unary},
|
|
[DX_BUFFER_LOAD ] = {"o", "Hii", sm6_parser_emit_dx_buffer_load},
|
|
[DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load},
|
|
+ [DX_COS ] = {"g", "R", sm6_parser_emit_dx_sincos},
|
|
[DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
[DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle},
|
|
[DX_DERIV_COARSEX ] = {"e", "R", sm6_parser_emit_dx_unary},
|
|
@@ -3839,6 +3877,9 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
|
[DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
|
|
[DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary},
|
|
+ [DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_ISINF ] = {"1", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_ISNAN ] = {"1", "g", sm6_parser_emit_dx_unary},
|
|
[DX_LEGACY_F16TOF32 ] = {"f", "i", sm6_parser_emit_dx_unary},
|
|
[DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary},
|
|
[DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input},
|
|
@@ -3848,8 +3889,10 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
|
[DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
+ [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos},
|
|
[DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output},
|
|
+ [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
|
|
[DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary},
|
|
};
|
|
@@ -3867,6 +3910,8 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc
|
|
case 0:
|
|
FIXME("Invalid operand count.\n");
|
|
return false;
|
|
+ case '1':
|
|
+ return sm6_type_is_bool(type);
|
|
case '8':
|
|
return sm6_type_is_i8(type);
|
|
case 'b':
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index 865a292cd62..9079be48b4f 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -39,10 +39,11 @@ static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shade
|
|
return reg->type == VKD3DSPR_FORKINSTID || reg->type == VKD3DSPR_JOININSTID;
|
|
}
|
|
|
|
-static bool shader_instruction_is_dcl(const struct vkd3d_shader_instruction *ins)
|
|
+static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
- return (VKD3DSIH_DCL <= ins->handler_idx && ins->handler_idx <= VKD3DSIH_DCL_VERTICES_OUT)
|
|
- || ins->handler_idx == VKD3DSIH_HS_DECLS;
|
|
+ enum vkd3d_shader_opcode handler_idx = instruction->handler_idx;
|
|
+ return (VKD3DSIH_DCL <= handler_idx && handler_idx <= VKD3DSIH_DCL_VERTICES_OUT)
|
|
+ || handler_idx == VKD3DSIH_HS_DECLS;
|
|
}
|
|
|
|
static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins)
|
|
@@ -65,6 +66,116 @@ static void remove_dcl_temps(struct vsir_program *program)
|
|
}
|
|
}
|
|
|
|
+static bool vsir_instruction_init_with_params(struct vkd3d_shader_parser *parser,
|
|
+ struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
|
|
+ enum vkd3d_shader_opcode handler_idx, unsigned int dst_count, unsigned int src_count)
|
|
+{
|
|
+ vsir_instruction_init(ins, location, handler_idx);
|
|
+ ins->dst_count = dst_count;
|
|
+ ins->src_count = src_count;
|
|
+
|
|
+ if (!(ins->dst = shader_parser_get_dst_params(parser, ins->dst_count)))
|
|
+ {
|
|
+ ERR("Failed to allocate %u destination parameters.\n", dst_count);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (!(ins->src = shader_parser_get_src_params(parser, ins->src_count)))
|
|
+ {
|
|
+ ERR("Failed to allocate %u source parameters.\n", src_count);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ memset(ins->dst, 0, sizeof(*ins->dst) * ins->dst_count);
|
|
+ memset(ins->src, 0, sizeof(*ins->src) * ins->src_count);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static enum vkd3d_result instruction_array_lower_texkills(struct vkd3d_shader_parser *parser)
|
|
+{
|
|
+ struct vsir_program *program = &parser->program;
|
|
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
+ struct vkd3d_shader_instruction *texkill_ins, *ins;
|
|
+ unsigned int components_read = 3 + (program->shader_version.major >= 2);
|
|
+ unsigned int tmp_idx = ~0u;
|
|
+ unsigned int i, k;
|
|
+
|
|
+ for (i = 0; i < instructions->count; ++i)
|
|
+ {
|
|
+ texkill_ins = &instructions->elements[i];
|
|
+
|
|
+ if (texkill_ins->handler_idx != VKD3DSIH_TEXKILL)
|
|
+ continue;
|
|
+
|
|
+ if (!shader_instruction_array_insert_at(instructions, i + 1, components_read + 1))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ if (tmp_idx == ~0u)
|
|
+ tmp_idx = program->temp_count++;
|
|
+
|
|
+ /* tmp = ins->dst[0] < 0 */
|
|
+
|
|
+ ins = &instructions->elements[i + 1];
|
|
+ if (!vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
|
+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->dst[0].reg.idx[0].offset = tmp_idx;
|
|
+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
|
|
+
|
|
+ ins->src[0].reg = texkill_ins->dst[0].reg;
|
|
+ vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
|
|
+ ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->src[1].reg.u.immconst_f32[0] = 0.0f;
|
|
+ ins->src[1].reg.u.immconst_f32[1] = 0.0f;
|
|
+ ins->src[1].reg.u.immconst_f32[2] = 0.0f;
|
|
+ ins->src[1].reg.u.immconst_f32[3] = 0.0f;
|
|
+
|
|
+ /* tmp.x = tmp.x || tmp.y */
|
|
+ /* tmp.x = tmp.x || tmp.z */
|
|
+ /* tmp.x = tmp.x || tmp.w, if sm >= 2.0 */
|
|
+
|
|
+ for (k = 1; k < components_read; ++k)
|
|
+ {
|
|
+ ins = &instructions->elements[i + 1 + k];
|
|
+ if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2)))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
|
+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->dst[0].reg.idx[0].offset = tmp_idx;
|
|
+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
|
|
+
|
|
+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
|
+ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->src[0].reg.idx[0].offset = tmp_idx;
|
|
+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
|
+ vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
|
+ ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->src[1].reg.idx[0].offset = tmp_idx;
|
|
+ ins->src[1].swizzle = vkd3d_shader_create_swizzle(k, k, k, k);
|
|
+ }
|
|
+
|
|
+ /* discard_nz tmp.x */
|
|
+
|
|
+ ins = &instructions->elements[i + 1 + components_read];
|
|
+ if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1)))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
|
|
+
|
|
+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
|
+ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->src[0].reg.idx[0].offset = tmp_idx;
|
|
+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
|
+
|
|
+ /* Make the original instruction no-op */
|
|
+ vkd3d_shader_instruction_make_nop(texkill_ins);
|
|
+ }
|
|
+
|
|
+ return VKD3D_OK;
|
|
+}
|
|
+
|
|
static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg,
|
|
unsigned int instance_id)
|
|
{
|
|
@@ -230,7 +341,7 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal
|
|
return;
|
|
}
|
|
|
|
- if (normaliser->phase == VKD3DSIH_INVALID || shader_instruction_is_dcl(ins))
|
|
+ if (normaliser->phase == VKD3DSIH_INVALID || vsir_instruction_is_dcl(ins))
|
|
return;
|
|
|
|
if (normaliser->phase_body_idx == ~0u)
|
|
@@ -529,7 +640,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
|
|
normaliser.phase = ins->handler_idx;
|
|
break;
|
|
default:
|
|
- if (shader_instruction_is_dcl(ins))
|
|
+ if (vsir_instruction_is_dcl(ins))
|
|
break;
|
|
for (j = 0; j < ins->dst_count; ++j)
|
|
shader_dst_param_normalise_outpointid(&ins->dst[j], &normaliser);
|
|
@@ -1222,7 +1333,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
|
|
memset(normaliser->pc_dcl_params, 0, sizeof(normaliser->pc_dcl_params));
|
|
break;
|
|
default:
|
|
- if (shader_instruction_is_dcl(ins))
|
|
+ if (vsir_instruction_is_dcl(ins))
|
|
break;
|
|
for (i = 0; i < ins->dst_count; ++i)
|
|
shader_dst_param_io_normalise(&ins->dst[i], false, normaliser);
|
|
@@ -1862,13 +1973,6 @@ static void VKD3D_PRINTF_FUNC(3, 4) cf_flattener_create_block_name(struct cf_fla
|
|
flattener->block_names[block_id] = buffer.buffer;
|
|
}
|
|
|
|
-static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction)
|
|
-{
|
|
- enum vkd3d_shader_opcode handler_idx = instruction->handler_idx;
|
|
- return (VKD3DSIH_DCL <= handler_idx && handler_idx <= VKD3DSIH_DCL_VERTICES_OUT)
|
|
- || handler_idx == VKD3DSIH_HS_DECLS;
|
|
-}
|
|
-
|
|
static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flattener *flattener)
|
|
{
|
|
bool main_block_open, is_hull_shader, after_declarations_section;
|
|
@@ -2239,7 +2343,7 @@ static enum vkd3d_result flatten_control_flow_constructs(struct vkd3d_shader_par
|
|
}
|
|
|
|
vkd3d_free(flattener.control_flow_info);
|
|
- /* Simpler to always free these in free_shader_desc(). */
|
|
+ /* Simpler to always free these in vsir_program_cleanup(). */
|
|
program->block_names = flattener.block_names;
|
|
program->block_name_count = flattener.block_name_count;
|
|
|
|
@@ -2254,6 +2358,9 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
|
|
|
|
remove_dcl_temps(&parser->program);
|
|
|
|
+ if ((result = instruction_array_lower_texkills(parser)) < 0)
|
|
+ return result;
|
|
+
|
|
if (!parser->shader_desc.is_dxil)
|
|
{
|
|
if (parser->program.shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
|
|
@@ -2791,8 +2898,7 @@ static void vsir_validate_instruction(struct validation_context *ctx)
|
|
* purely structured. In principle we could allow structured
|
|
* constructs in a block, provided they are confined in a single
|
|
* block, but need for that hasn't arisen yet, so we don't. */
|
|
- if (ctx->cf_type == CF_TYPE_UNKNOWN && !(instruction->handler_idx >= VKD3DSIH_DCL
|
|
- && instruction->handler_idx <= VKD3DSIH_DCL_VERTICES_OUT))
|
|
+ if (ctx->cf_type == CF_TYPE_UNKNOWN && !vsir_instruction_is_dcl(instruction))
|
|
{
|
|
if (instruction->handler_idx == VKD3DSIH_LABEL)
|
|
ctx->cf_type = CF_TYPE_BLOCKS;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index 3b2e45829fd..a86ca583e63 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -1515,6 +1515,25 @@ static uint32_t vkd3d_spirv_build_op_uless_than_equal(struct vkd3d_spirv_builder
|
|
SpvOpULessThanEqual, result_type, operand0, operand1);
|
|
}
|
|
|
|
+static uint32_t vkd3d_spirv_build_op_is_inf(struct vkd3d_spirv_builder *builder,
|
|
+ uint32_t result_type, uint32_t operand)
|
|
+{
|
|
+ return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsInf, result_type, operand);
|
|
+}
|
|
+
|
|
+static uint32_t vkd3d_spirv_build_op_is_nan(struct vkd3d_spirv_builder *builder,
|
|
+ uint32_t result_type, uint32_t operand)
|
|
+{
|
|
+ return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsNan, result_type, operand);
|
|
+}
|
|
+
|
|
+static uint32_t vkd3d_spirv_build_op_logical_equal(struct vkd3d_spirv_builder *builder,
|
|
+ uint32_t result_type, uint32_t operand0, uint32_t operand1)
|
|
+{
|
|
+ return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
|
|
+ SpvOpLogicalEqual, result_type, operand0, operand1);
|
|
+}
|
|
+
|
|
static uint32_t vkd3d_spirv_build_op_convert_utof(struct vkd3d_spirv_builder *builder,
|
|
uint32_t result_type, uint32_t unsigned_value)
|
|
{
|
|
@@ -2350,6 +2369,7 @@ struct spirv_compiler
|
|
size_t spec_constants_size;
|
|
enum vkd3d_shader_compile_option_formatting_flags formatting;
|
|
enum vkd3d_shader_compile_option_feature_flags features;
|
|
+ enum vkd3d_shader_api_version api_version;
|
|
bool write_tess_geom_point_size;
|
|
|
|
struct vkd3d_string_buffer_cache string_buffers;
|
|
@@ -2494,6 +2514,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve
|
|
break;
|
|
|
|
case VKD3D_SHADER_COMPILE_OPTION_API_VERSION:
|
|
+ compiler->api_version = option->value;
|
|
break;
|
|
|
|
case VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV:
|
|
@@ -2528,6 +2549,10 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve
|
|
}
|
|
}
|
|
|
|
+ /* Explicit enabling of float64 was not required for API versions <= 1.10. */
|
|
+ if (compiler->api_version <= VKD3D_SHADER_API_VERSION_1_10)
|
|
+ compiler->features |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64;
|
|
+
|
|
rb_init(&compiler->symbol_table, vkd3d_symbol_compare);
|
|
|
|
compiler->shader_type = shader_version->type;
|
|
@@ -5582,7 +5607,16 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler
|
|
|
|
if (flags & (VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS))
|
|
{
|
|
- vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityFloat64);
|
|
+ if (compiler->features & VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64)
|
|
+ {
|
|
+ vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityFloat64);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ WARN("Unsupported 64-bit float ops.\n");
|
|
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE,
|
|
+ "The target environment does not support 64-bit floating point.");
|
|
+ }
|
|
flags &= ~(VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS);
|
|
}
|
|
|
|
@@ -6203,6 +6237,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
|
|
if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ))
|
|
vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0);
|
|
|
|
+ if (d->uav_flags & VKD3DSUF_GLOBALLY_COHERENT)
|
|
+ vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationCoherent, NULL, 0);
|
|
+
|
|
if (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER)
|
|
{
|
|
assert(structure_stride); /* counters are valid only for structured buffers */
|
|
@@ -6749,6 +6786,8 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru
|
|
{VKD3DSIH_INEG, SpvOpSNegate},
|
|
{VKD3DSIH_ISHL, SpvOpShiftLeftLogical},
|
|
{VKD3DSIH_ISHR, SpvOpShiftRightArithmetic},
|
|
+ {VKD3DSIH_ISINF, SpvOpIsInf},
|
|
+ {VKD3DSIH_ISNAN, SpvOpIsNan},
|
|
{VKD3DSIH_ITOD, SpvOpConvertSToF},
|
|
{VKD3DSIH_ITOF, SpvOpConvertSToF},
|
|
{VKD3DSIH_ITOI, SpvOpSConvert},
|
|
@@ -6896,6 +6935,23 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
+static void spirv_compiler_emit_isfinite(struct spirv_compiler *compiler,
|
|
+ const struct vkd3d_shader_instruction *instruction)
|
|
+{
|
|
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
|
+ const struct vkd3d_shader_src_param *src = instruction->src;
|
|
+ uint32_t type_id, src_id, isinf_id, isnan_id, val_id;
|
|
+
|
|
+ type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
|
|
+ src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
|
|
+ /* OpIsFinite is only available in Kernel mode. */
|
|
+ isinf_id = vkd3d_spirv_build_op_is_inf(builder, type_id, src_id);
|
|
+ isnan_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src_id);
|
|
+ val_id = vkd3d_spirv_build_op_logical_equal(builder, type_id, isinf_id, isnan_id);
|
|
+ spirv_compiler_emit_store_dst(compiler, dst, val_id);
|
|
+}
|
|
+
|
|
static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction(
|
|
const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
@@ -6926,6 +6982,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction(
|
|
{VKD3DSIH_ROUND_Z, GLSLstd450Trunc},
|
|
{VKD3DSIH_RSQ, GLSLstd450InverseSqrt},
|
|
{VKD3DSIH_SQRT, GLSLstd450Sqrt},
|
|
+ {VKD3DSIH_TAN, GLSLstd450Tan},
|
|
{VKD3DSIH_UMAX, GLSLstd450UMax},
|
|
{VKD3DSIH_UMIN, GLSLstd450UMin},
|
|
};
|
|
@@ -9287,11 +9344,20 @@ static void spirv_compiler_emit_sync(struct spirv_compiler *compiler,
|
|
flags &= ~VKD3DSSF_THREAD_GROUP;
|
|
}
|
|
|
|
- if (flags & VKD3DSSF_GLOBAL_UAV)
|
|
+ if (flags & (VKD3DSSF_THREAD_GROUP_UAV | VKD3DSSF_GLOBAL_UAV))
|
|
{
|
|
- memory_scope = SpvScopeDevice;
|
|
- memory_semantics |= SpvMemorySemanticsImageMemoryMask;
|
|
- flags &= ~VKD3DSSF_GLOBAL_UAV;
|
|
+ bool group_uav = flags & VKD3DSSF_THREAD_GROUP_UAV;
|
|
+ bool global_uav = flags & VKD3DSSF_GLOBAL_UAV;
|
|
+
|
|
+ if (group_uav && global_uav)
|
|
+ {
|
|
+ WARN("Invalid UAV sync flag combination; assuming global.\n");
|
|
+ spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_UAV_FLAGS,
|
|
+ "The flags for a UAV sync instruction are contradictory; assuming global sync.");
|
|
+ }
|
|
+ memory_scope = global_uav ? SpvScopeDevice : SpvScopeWorkgroup;
|
|
+ memory_semantics |= SpvMemorySemanticsUniformMemoryMask | SpvMemorySemanticsImageMemoryMask;
|
|
+ flags &= ~(VKD3DSSF_THREAD_GROUP_UAV | VKD3DSSF_GLOBAL_UAV);
|
|
}
|
|
|
|
if (flags)
|
|
@@ -9452,6 +9518,8 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
case VKD3DSIH_INEG:
|
|
case VKD3DSIH_ISHL:
|
|
case VKD3DSIH_ISHR:
|
|
+ case VKD3DSIH_ISINF:
|
|
+ case VKD3DSIH_ISNAN:
|
|
case VKD3DSIH_ITOD:
|
|
case VKD3DSIH_ITOF:
|
|
case VKD3DSIH_ITOI:
|
|
@@ -9465,6 +9533,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
case VKD3DSIH_XOR:
|
|
ret = spirv_compiler_emit_alu_instruction(compiler, instruction);
|
|
break;
|
|
+ case VKD3DSIH_ISFINITE:
|
|
+ spirv_compiler_emit_isfinite(compiler, instruction);
|
|
+ break;
|
|
case VKD3DSIH_DFMA:
|
|
case VKD3DSIH_DMAX:
|
|
case VKD3DSIH_DMIN:
|
|
@@ -9485,6 +9556,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
case VKD3DSIH_ROUND_Z:
|
|
case VKD3DSIH_RSQ:
|
|
case VKD3DSIH_SQRT:
|
|
+ case VKD3DSIH_TAN:
|
|
case VKD3DSIH_UMAX:
|
|
case VKD3DSIH_UMIN:
|
|
spirv_compiler_emit_ext_glsl_instruction(compiler, instruction);
|
|
@@ -9558,7 +9630,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
spirv_compiler_emit_retc(compiler, instruction);
|
|
break;
|
|
case VKD3DSIH_DISCARD:
|
|
- case VKD3DSIH_TEXKILL:
|
|
spirv_compiler_emit_discard(compiler, instruction);
|
|
break;
|
|
case VKD3DSIH_LABEL:
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
index 14d885fb666..1b7ea8dde9a 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
@@ -1016,7 +1016,7 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
|
|
static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context,
|
|
const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type,
|
|
enum vkd3d_shader_resource_data_type resource_data_type,
|
|
- unsigned int sample_count, unsigned int structure_stride, bool raw)
|
|
+ unsigned int sample_count, unsigned int structure_stride, bool raw, uint32_t flags)
|
|
{
|
|
struct vkd3d_shader_descriptor_info1 *d;
|
|
enum vkd3d_shader_descriptor_type type;
|
|
@@ -1032,6 +1032,8 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
|
|
d->structure_stride = structure_stride;
|
|
if (raw)
|
|
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER;
|
|
+ if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
|
|
+ d->uav_flags = flags;
|
|
}
|
|
|
|
static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context,
|
|
@@ -1090,7 +1092,7 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca
|
|
}
|
|
|
|
vkd3d_shader_scan_resource_declaration(context, &semantic->resource,
|
|
- semantic->resource_type, resource_data_type, semantic->sample_count, 0, false);
|
|
+ semantic->resource_type, resource_data_type, semantic->sample_count, 0, false, instruction->flags);
|
|
}
|
|
|
|
static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context,
|
|
@@ -1126,15 +1128,16 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
|
|
case VKD3DSIH_DCL_RESOURCE_RAW:
|
|
case VKD3DSIH_DCL_UAV_RAW:
|
|
vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource,
|
|
- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true);
|
|
+ VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true, instruction->flags);
|
|
break;
|
|
case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
|
|
case VKD3DSIH_DCL_UAV_STRUCTURED:
|
|
vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource,
|
|
VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0,
|
|
- instruction->declaration.structured_resource.byte_stride, false);
|
|
+ instruction->declaration.structured_resource.byte_stride, false, instruction->flags);
|
|
break;
|
|
case VKD3DSIH_IF:
|
|
+ case VKD3DSIH_IFC:
|
|
cf_info = vkd3d_shader_scan_push_cf_info(context);
|
|
cf_info->type = VKD3D_SHADER_BLOCK_IF;
|
|
cf_info->inside_block = true;
|
|
@@ -2084,6 +2087,23 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins
|
|
return true;
|
|
}
|
|
|
|
+bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions,
|
|
+ unsigned int idx, unsigned int count)
|
|
+{
|
|
+ assert(idx <= instructions->count);
|
|
+
|
|
+ if (!shader_instruction_array_reserve(instructions, instructions->count + count))
|
|
+ return false;
|
|
+
|
|
+ memmove(&instructions->elements[idx + count], &instructions->elements[idx],
|
|
+ (instructions->count - idx) * sizeof(*instructions->elements));
|
|
+ memset(&instructions->elements[idx], 0, count * sizeof(*instructions->elements));
|
|
+
|
|
+ instructions->count += count;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
|
|
struct vkd3d_shader_immediate_constant_buffer *icb)
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index 115a7d8c83b..fd0f2f0f34a 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -99,6 +99,7 @@ enum vkd3d_shader_error
|
|
VKD3D_SHADER_ERROR_SPV_INVALID_SHADER = 2009,
|
|
|
|
VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300,
|
|
+ VKD3D_SHADER_WARNING_SPV_INVALID_UAV_FLAGS = 2301,
|
|
|
|
VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY = 3000,
|
|
VKD3D_SHADER_ERROR_RS_INVALID_VERSION = 3001,
|
|
@@ -392,8 +393,11 @@ enum vkd3d_shader_opcode
|
|
VKD3DSIH_IMUL,
|
|
VKD3DSIH_INE,
|
|
VKD3DSIH_INEG,
|
|
+ VKD3DSIH_ISFINITE,
|
|
VKD3DSIH_ISHL,
|
|
VKD3DSIH_ISHR,
|
|
+ VKD3DSIH_ISINF,
|
|
+ VKD3DSIH_ISNAN,
|
|
VKD3DSIH_ITOD,
|
|
VKD3DSIH_ITOF,
|
|
VKD3DSIH_ITOI,
|
|
@@ -476,6 +480,7 @@ enum vkd3d_shader_opcode
|
|
VKD3DSIH_SWITCH,
|
|
VKD3DSIH_SWITCH_MONOLITHIC,
|
|
VKD3DSIH_SYNC,
|
|
+ VKD3DSIH_TAN,
|
|
VKD3DSIH_TEX,
|
|
VKD3DSIH_TEXBEM,
|
|
VKD3DSIH_TEXBEML,
|
|
@@ -727,6 +732,7 @@ enum vkd3d_shader_sync_flags
|
|
{
|
|
VKD3DSSF_THREAD_GROUP = 0x1,
|
|
VKD3DSSF_GROUP_SHARED_MEMORY = 0x2,
|
|
+ VKD3DSSF_THREAD_GROUP_UAV = 0x4,
|
|
VKD3DSSF_GLOBAL_UAV = 0x8,
|
|
};
|
|
|
|
@@ -1248,6 +1254,8 @@ struct vkd3d_shader_instruction_array
|
|
|
|
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
|
|
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
|
|
+bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions,
|
|
+ unsigned int idx, unsigned int count);
|
|
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
|
|
struct vkd3d_shader_immediate_constant_buffer *icb);
|
|
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
|
|
@@ -1334,6 +1342,7 @@ struct vkd3d_shader_descriptor_info1
|
|
unsigned int buffer_size;
|
|
unsigned int structure_stride;
|
|
unsigned int count;
|
|
+ uint32_t uav_flags;
|
|
};
|
|
|
|
struct vkd3d_shader_scan_descriptor_info1
|
|
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
|
|
index d146e322d25..3cf58e06d40 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/command.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/command.c
|
|
@@ -926,7 +926,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence1 *iface,
|
|
static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence1 *iface)
|
|
{
|
|
struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
- ULONG refcount = InterlockedIncrement(&fence->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_increment_u32(&fence->refcount);
|
|
|
|
TRACE("%p increasing refcount to %u.\n", fence, refcount);
|
|
|
|
@@ -935,13 +935,13 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence1 *iface)
|
|
|
|
static void d3d12_fence_incref(struct d3d12_fence *fence)
|
|
{
|
|
- InterlockedIncrement(&fence->internal_refcount);
|
|
+ vkd3d_atomic_increment_u32(&fence->internal_refcount);
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence1 *iface)
|
|
{
|
|
struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
- ULONG refcount = InterlockedDecrement(&fence->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&fence->refcount);
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", fence, refcount);
|
|
|
|
@@ -953,24 +953,24 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence1 *iface)
|
|
|
|
static void d3d12_fence_decref(struct d3d12_fence *fence)
|
|
{
|
|
- ULONG internal_refcount = InterlockedDecrement(&fence->internal_refcount);
|
|
+ struct d3d12_device *device;
|
|
|
|
- if (!internal_refcount)
|
|
- {
|
|
- struct d3d12_device *device = fence->device;
|
|
+ if (vkd3d_atomic_decrement_u32(&fence->internal_refcount))
|
|
+ return;
|
|
|
|
- vkd3d_private_store_destroy(&fence->private_store);
|
|
+ device = fence->device;
|
|
|
|
- d3d12_fence_destroy_vk_objects(fence);
|
|
+ vkd3d_private_store_destroy(&fence->private_store);
|
|
|
|
- vkd3d_free(fence->events);
|
|
- vkd3d_free(fence->semaphores);
|
|
- vkd3d_mutex_destroy(&fence->mutex);
|
|
- vkd3d_cond_destroy(&fence->null_event_cond);
|
|
- vkd3d_free(fence);
|
|
+ d3d12_fence_destroy_vk_objects(fence);
|
|
|
|
- d3d12_device_release(device);
|
|
- }
|
|
+ vkd3d_free(fence->events);
|
|
+ vkd3d_free(fence->semaphores);
|
|
+ vkd3d_mutex_destroy(&fence->mutex);
|
|
+ vkd3d_cond_destroy(&fence->null_event_cond);
|
|
+ vkd3d_free(fence);
|
|
+
|
|
+ d3d12_device_release(device);
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence1 *iface,
|
|
@@ -1635,7 +1635,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_allocator_QueryInterface(ID3D12Co
|
|
static ULONG STDMETHODCALLTYPE d3d12_command_allocator_AddRef(ID3D12CommandAllocator *iface)
|
|
{
|
|
struct d3d12_command_allocator *allocator = impl_from_ID3D12CommandAllocator(iface);
|
|
- ULONG refcount = InterlockedIncrement(&allocator->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_increment_u32(&allocator->refcount);
|
|
|
|
TRACE("%p increasing refcount to %u.\n", allocator, refcount);
|
|
|
|
@@ -1645,7 +1645,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_AddRef(ID3D12CommandAlloc
|
|
static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllocator *iface)
|
|
{
|
|
struct d3d12_command_allocator *allocator = impl_from_ID3D12CommandAllocator(iface);
|
|
- ULONG refcount = InterlockedDecrement(&allocator->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&allocator->refcount);
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", allocator, refcount);
|
|
|
|
@@ -2320,7 +2320,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic
|
|
static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList5 *iface)
|
|
{
|
|
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
|
|
- ULONG refcount = InterlockedIncrement(&list->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_increment_u32(&list->refcount);
|
|
|
|
TRACE("%p increasing refcount to %u.\n", list, refcount);
|
|
|
|
@@ -2335,7 +2335,7 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind
|
|
static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList5 *iface)
|
|
{
|
|
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
|
|
- ULONG refcount = InterlockedDecrement(&list->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&list->refcount);
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", list, refcount);
|
|
|
|
@@ -6230,7 +6230,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_QueryInterface(ID3D12Comman
|
|
static ULONG STDMETHODCALLTYPE d3d12_command_queue_AddRef(ID3D12CommandQueue *iface)
|
|
{
|
|
struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
|
|
- ULONG refcount = InterlockedIncrement(&command_queue->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_increment_u32(&command_queue->refcount);
|
|
|
|
TRACE("%p increasing refcount to %u.\n", command_queue, refcount);
|
|
|
|
@@ -6272,7 +6272,7 @@ static void d3d12_command_queue_op_array_destroy(struct d3d12_command_queue_op_a
|
|
static ULONG STDMETHODCALLTYPE d3d12_command_queue_Release(ID3D12CommandQueue *iface)
|
|
{
|
|
struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
|
|
- ULONG refcount = InterlockedDecrement(&command_queue->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&command_queue->refcount);
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", command_queue, refcount);
|
|
|
|
@@ -7442,7 +7442,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_signature_QueryInterface(ID3D12Co
|
|
static ULONG STDMETHODCALLTYPE d3d12_command_signature_AddRef(ID3D12CommandSignature *iface)
|
|
{
|
|
struct d3d12_command_signature *signature = impl_from_ID3D12CommandSignature(iface);
|
|
- ULONG refcount = InterlockedIncrement(&signature->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_increment_u32(&signature->refcount);
|
|
|
|
TRACE("%p increasing refcount to %u.\n", signature, refcount);
|
|
|
|
@@ -7452,7 +7452,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_signature_AddRef(ID3D12CommandSigna
|
|
static ULONG STDMETHODCALLTYPE d3d12_command_signature_Release(ID3D12CommandSignature *iface)
|
|
{
|
|
struct d3d12_command_signature *signature = impl_from_ID3D12CommandSignature(iface);
|
|
- ULONG refcount = InterlockedDecrement(&signature->refcount);
|
|
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&signature->refcount);
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", signature, refcount);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
|
|
index 82782e7d5fc..5f383d256cc 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/state.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/state.c
|
|
@@ -2154,6 +2154,8 @@ static unsigned int feature_flags_compile_option(const struct d3d12_device *devi
|
|
|
|
if (device->feature_options1.Int64ShaderOps)
|
|
flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64;
|
|
+ if (device->feature_options.DoublePrecisionFloatShaderOps)
|
|
+ flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64;
|
|
|
|
return flags;
|
|
}
|
|
@@ -2270,7 +2272,7 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
|
|
VK_CALL(vkDestroyShaderModule(device->vk_device, pipeline_info.stage.module, NULL));
|
|
if (vr < 0)
|
|
{
|
|
- WARN("Failed to create Vulkan compute pipeline, hr %#x.\n", hr);
|
|
+ WARN("Failed to create Vulkan compute pipeline, hr %s.\n", debugstr_hresult(hr));
|
|
return hresult_from_vk_result(vr);
|
|
}
|
|
|
|
@@ -2398,7 +2400,7 @@ static HRESULT d3d12_pipeline_state_find_and_init_uav_counters(struct d3d12_pipe
|
|
}
|
|
|
|
if (FAILED(hr = d3d12_pipeline_state_init_uav_counters(state, device, root_signature, &shader_info, stage_flags)))
|
|
- WARN("Failed to create descriptor set layout for UAV counters, hr %#x.\n", hr);
|
|
+ WARN("Failed to create descriptor set layout for UAV counters, hr %s.\n", debugstr_hresult(hr));
|
|
|
|
vkd3d_shader_free_scan_descriptor_info(&shader_info);
|
|
|
|
@@ -2472,7 +2474,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
|
|
if (FAILED(hr = vkd3d_create_compute_pipeline(device, &desc->cs, &shader_interface,
|
|
vk_pipeline_layout, &state->u.compute.vk_pipeline)))
|
|
{
|
|
- WARN("Failed to create Vulkan compute pipeline, hr %#x.\n", hr);
|
|
+ WARN("Failed to create Vulkan compute pipeline, hr %s.\n", debugstr_hresult(hr));
|
|
d3d12_pipeline_uav_counter_state_cleanup(&state->uav_counters, device);
|
|
return hr;
|
|
}
|
|
@@ -4026,14 +4028,14 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
|
|
if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, 0,
|
|
1, false, &set_binding, set_layouts[i].set_layout)))
|
|
{
|
|
- ERR("Failed to create descriptor set layout %u, hr %#x.\n", i, hr);
|
|
+ ERR("Failed to create descriptor set layout %u, hr %s.\n", i, debugstr_hresult(hr));
|
|
goto fail;
|
|
}
|
|
|
|
if (FAILED(hr = vkd3d_create_pipeline_layout(device, 1, set_layouts[i].set_layout,
|
|
1, &push_constant_range, set_layouts[i].pipeline_layout)))
|
|
{
|
|
- ERR("Failed to create pipeline layout %u, hr %#x.\n", i, hr);
|
|
+ ERR("Failed to create pipeline layout %u, hr %s.\n", i, debugstr_hresult(hr));
|
|
goto fail;
|
|
}
|
|
}
|
|
@@ -4071,7 +4073,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
|
|
vkd3d_shader_free_shader_code(&dxbc);
|
|
if (FAILED(hr))
|
|
{
|
|
- ERR("Failed to create compute pipeline %u, hr %#x.\n", i, hr);
|
|
+ ERR("Failed to create compute pipeline %u, hr %s.\n", i, debugstr_hresult(hr));
|
|
goto fail;
|
|
}
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
index 245edb5aeac..0139de5dd23 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
@@ -60,7 +60,7 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
|
|
}
|
|
else if (FAILED(hr = vkd3d_create_instance(create_info->instance_create_info, &instance)))
|
|
{
|
|
- WARN("Failed to create instance, hr %#x.\n", hr);
|
|
+ WARN("Failed to create instance, hr %s.\n", debugstr_hresult(hr));
|
|
return E_FAIL;
|
|
}
|
|
|
|
@@ -456,7 +456,7 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc,
|
|
if (error_blob && messages)
|
|
{
|
|
if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), error_blob)))
|
|
- ERR("Failed to create error blob, hr %#x.\n", hr);
|
|
+ ERR("Failed to create error blob, hr %s.\n", debugstr_hresult(hr));
|
|
}
|
|
return hresult_from_vkd3d_result(ret);
|
|
}
|
|
@@ -464,7 +464,7 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc,
|
|
|
|
if (FAILED(hr = vkd3d_blob_create((void *)dxbc.code, dxbc.size, blob)))
|
|
{
|
|
- WARN("Failed to create blob object, hr %#x.\n", hr);
|
|
+ WARN("Failed to create blob object, hr %s.\n", debugstr_hresult(hr));
|
|
vkd3d_shader_free_shader_code(&dxbc);
|
|
}
|
|
return hr;
|
|
@@ -497,7 +497,7 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN
|
|
if (error_blob && messages)
|
|
{
|
|
if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), error_blob)))
|
|
- ERR("Failed to create error blob, hr %#x.\n", hr);
|
|
+ ERR("Failed to create error blob, hr %s.\n", debugstr_hresult(hr));
|
|
}
|
|
return hresult_from_vkd3d_result(ret);
|
|
}
|
|
@@ -505,7 +505,7 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN
|
|
|
|
if (FAILED(hr = vkd3d_blob_create((void *)dxbc.code, dxbc.size, blob)))
|
|
{
|
|
- WARN("Failed to create blob object, hr %#x.\n", hr);
|
|
+ WARN("Failed to create blob object, hr %s.\n", debugstr_hresult(hr));
|
|
vkd3d_shader_free_shader_code(&dxbc);
|
|
}
|
|
return hr;
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
index 13802c97773..a6d5b94b778 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
@@ -621,8 +621,8 @@ struct vkd3d_signaled_semaphore
|
|
struct d3d12_fence
|
|
{
|
|
ID3D12Fence1 ID3D12Fence1_iface;
|
|
- LONG internal_refcount;
|
|
- LONG refcount;
|
|
+ unsigned int internal_refcount;
|
|
+ unsigned int refcount;
|
|
|
|
D3D12_FENCE_FLAGS flags;
|
|
|
|
@@ -1365,7 +1365,7 @@ struct vkd3d_buffer
|
|
struct d3d12_command_allocator
|
|
{
|
|
ID3D12CommandAllocator ID3D12CommandAllocator_iface;
|
|
- LONG refcount;
|
|
+ unsigned int refcount;
|
|
|
|
D3D12_COMMAND_LIST_TYPE type;
|
|
VkQueueFlags vk_queue_flags;
|
|
@@ -1466,7 +1466,7 @@ enum vkd3d_pipeline_bind_point
|
|
struct d3d12_command_list
|
|
{
|
|
ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5_iface;
|
|
- LONG refcount;
|
|
+ unsigned int refcount;
|
|
|
|
D3D12_COMMAND_LIST_TYPE type;
|
|
VkQueueFlags vk_queue_flags;
|
|
@@ -1622,7 +1622,7 @@ struct d3d12_command_queue_op_array
|
|
struct d3d12_command_queue
|
|
{
|
|
ID3D12CommandQueue ID3D12CommandQueue_iface;
|
|
- LONG refcount;
|
|
+ unsigned int refcount;
|
|
|
|
D3D12_COMMAND_QUEUE_DESC desc;
|
|
|
|
@@ -1657,7 +1657,7 @@ HRESULT d3d12_command_queue_create(struct d3d12_device *device,
|
|
struct d3d12_command_signature
|
|
{
|
|
ID3D12CommandSignature ID3D12CommandSignature_iface;
|
|
- LONG refcount;
|
|
+ unsigned int refcount;
|
|
unsigned int internal_refcount;
|
|
|
|
D3D12_COMMAND_SIGNATURE_DESC desc;
|
|
--
|
|
2.43.0
|
|
|