wine-staging/patches/vkd3d-latest/0006-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch

2992 lines
109 KiB
Diff
Raw Normal View History

2024-01-26 17:33:52 -08:00
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