mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
954 lines
33 KiB
Diff
954 lines
33 KiB
Diff
From 669446d32104b9a4b879f5cb2ad46a964606fa70 Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Sun, 28 Apr 2024 09:46:44 +1000
|
|
Subject: [PATCH] Updated vkd3d to 13e1491941a1af32ddfc1019fa304231fd121c4d.
|
|
|
|
---
|
|
libs/vkd3d/include/private/vkd3d_common.h | 63 +++++++
|
|
libs/vkd3d/include/vkd3d_types.h | 6 +
|
|
libs/vkd3d/libs/vkd3d-common/blob.c | 3 +
|
|
libs/vkd3d/libs/vkd3d-common/error.c | 6 +
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 61 ++++++-
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 122 +++++++++++++-
|
|
libs/vkd3d/libs/vkd3d/cache.c | 195 ++++++++++++++++++++++
|
|
libs/vkd3d/libs/vkd3d/device.c | 36 +++-
|
|
libs/vkd3d/libs/vkd3d/resource.c | 24 +--
|
|
libs/vkd3d/libs/vkd3d/vkd3d_main.c | 2 +-
|
|
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 92 ++--------
|
|
11 files changed, 497 insertions(+), 113 deletions(-)
|
|
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
|
|
index b0e9230dab6..2d950b4f7aa 100644
|
|
--- a/libs/vkd3d/include/private/vkd3d_common.h
|
|
+++ b/libs/vkd3d/include/private/vkd3d_common.h
|
|
@@ -340,6 +340,11 @@ static inline int vkd3d_u32_compare(uint32_t x, uint32_t y)
|
|
return (x > y) - (x < y);
|
|
}
|
|
|
|
+static inline int vkd3d_u64_compare(uint64_t x, uint64_t y)
|
|
+{
|
|
+ return (x > y) - (x < y);
|
|
+}
|
|
+
|
|
#define VKD3D_BITMAP_SIZE(x) (((x) + 0x1f) >> 5)
|
|
|
|
static inline bool bitmap_clear(uint32_t *map, unsigned int idx)
|
|
@@ -431,6 +436,64 @@ static inline uint32_t vkd3d_atomic_increment_u32(uint32_t volatile *x)
|
|
return vkd3d_atomic_add_fetch_u32(x, 1);
|
|
}
|
|
|
|
+static inline bool vkd3d_atomic_compare_exchange_u32(uint32_t volatile *x, uint32_t expected, uint32_t val)
|
|
+{
|
|
+#if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
|
|
+ return __sync_bool_compare_and_swap(x, expected, val);
|
|
+#elif defined(_WIN32)
|
|
+ return InterlockedCompareExchange((LONG *)x, val, expected) == expected;
|
|
+#else
|
|
+# error "vkd3d_atomic_compare_exchange_u32() not implemented for this platform"
|
|
+#endif
|
|
+}
|
|
+
|
|
+static inline bool vkd3d_atomic_compare_exchange_ptr(void * volatile *x, void *expected, void *val)
|
|
+{
|
|
+#if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
|
|
+ return __sync_bool_compare_and_swap(x, expected, val);
|
|
+#elif defined(_WIN32)
|
|
+ return InterlockedCompareExchangePointer(x, val, expected) == expected;
|
|
+#else
|
|
+# error "vkd3d_atomic_compare_exchange_ptr() not implemented for this platform"
|
|
+#endif
|
|
+}
|
|
+
|
|
+static inline uint32_t vkd3d_atomic_exchange_u32(uint32_t volatile *x, uint32_t val)
|
|
+{
|
|
+#if HAVE_ATOMIC_EXCHANGE_N
|
|
+ return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST);
|
|
+#elif defined(_WIN32)
|
|
+ return InterlockedExchange((LONG *)x, val);
|
|
+#else
|
|
+ uint32_t expected;
|
|
+
|
|
+ do
|
|
+ {
|
|
+ expected = *x;
|
|
+ } while (!vkd3d_atomic_compare_exchange_u32(x, expected, val));
|
|
+
|
|
+ return expected;
|
|
+#endif
|
|
+}
|
|
+
|
|
+static inline void *vkd3d_atomic_exchange_ptr(void * volatile *x, void *val)
|
|
+{
|
|
+#if HAVE_ATOMIC_EXCHANGE_N
|
|
+ return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST);
|
|
+#elif defined(_WIN32)
|
|
+ return InterlockedExchangePointer(x, val);
|
|
+#else
|
|
+ void *expected;
|
|
+
|
|
+ do
|
|
+ {
|
|
+ expected = *x;
|
|
+ } while (!vkd3d_atomic_compare_exchange_ptr(x, expected, val));
|
|
+
|
|
+ return expected;
|
|
+#endif
|
|
+}
|
|
+
|
|
struct vkd3d_mutex
|
|
{
|
|
#ifdef _WIN32
|
|
diff --git a/libs/vkd3d/include/vkd3d_types.h b/libs/vkd3d/include/vkd3d_types.h
|
|
index 017eaf11806..dc5a7c064ae 100644
|
|
--- a/libs/vkd3d/include/vkd3d_types.h
|
|
+++ b/libs/vkd3d/include/vkd3d_types.h
|
|
@@ -53,6 +53,12 @@ enum vkd3d_result
|
|
VKD3D_ERROR_INVALID_SHADER = -4,
|
|
/** The operation is not implemented in this version of vkd3d. */
|
|
VKD3D_ERROR_NOT_IMPLEMENTED = -5,
|
|
+ /** The object or entry already exists. \since 1.12 */
|
|
+ VKD3D_ERROR_KEY_ALREADY_EXISTS = -6,
|
|
+ /** The requested object was not found. \since 1.12 */
|
|
+ VKD3D_ERROR_NOT_FOUND = -7,
|
|
+ /** The output buffer is larger than the requested object \since 1.12. */
|
|
+ VKD3D_ERROR_MORE_DATA = -8,
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_RESULT),
|
|
};
|
|
diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
index 6bc95dc55c4..c2c6ad67804 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
@@ -16,6 +16,9 @@
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
+#ifndef __MINGW32__
|
|
+#define WIDL_C_INLINE_WRAPPERS
|
|
+#endif
|
|
#define COBJMACROS
|
|
|
|
#define CONST_VTABLE
|
|
diff --git a/libs/vkd3d/libs/vkd3d-common/error.c b/libs/vkd3d/libs/vkd3d-common/error.c
|
|
index b8350a5404c..2f978c4977d 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-common/error.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-common/error.c
|
|
@@ -35,6 +35,12 @@ HRESULT hresult_from_vkd3d_result(int vkd3d_result)
|
|
return E_INVALIDARG;
|
|
case VKD3D_ERROR_NOT_IMPLEMENTED:
|
|
return E_NOTIMPL;
|
|
+ case VKD3D_ERROR_KEY_ALREADY_EXISTS:
|
|
+ return DXGI_ERROR_ALREADY_EXISTS;
|
|
+ case VKD3D_ERROR_NOT_FOUND:
|
|
+ return DXGI_ERROR_NOT_FOUND;
|
|
+ case VKD3D_ERROR_MORE_DATA:
|
|
+ return DXGI_ERROR_MORE_DATA;
|
|
default:
|
|
FIXME("Unhandled vkd3d result %d.\n", vkd3d_result);
|
|
return E_FAIL;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
index 55d9ecf707d..09e4f596241 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
@@ -1813,6 +1813,7 @@ static uint32_t sm1_encode_register_type(D3DSHADER_PARAM_REGISTER_TYPE type)
|
|
struct sm1_instruction
|
|
{
|
|
D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode;
|
|
+ unsigned int flags;
|
|
|
|
struct sm1_dst_register
|
|
{
|
|
@@ -1852,6 +1853,8 @@ static void write_sm1_instruction(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu
|
|
uint32_t token = instr->opcode;
|
|
unsigned int i;
|
|
|
|
+ token |= VKD3D_SM1_INSTRUCTION_FLAGS_MASK & (instr->flags << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT);
|
|
+
|
|
if (ctx->profile->major_version > 1)
|
|
token |= (instr->has_dst + instr->src_count) << D3DSI_INSTLENGTH_SHIFT;
|
|
put_u32(buffer, token);
|
|
@@ -2414,6 +2417,49 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
|
|
}
|
|
}
|
|
|
|
+static void write_sm1_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
|
|
+ const struct hlsl_block *block);
|
|
+
|
|
+static void write_sm1_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
|
|
+{
|
|
+ const struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
|
+ const struct hlsl_ir_node *condition;
|
|
+ struct sm1_instruction sm1_ifc, sm1_else, sm1_endif;
|
|
+
|
|
+ condition = iff->condition.node;
|
|
+ assert(condition->data_type->dimx == 1 && condition->data_type->dimy == 1);
|
|
+
|
|
+ sm1_ifc = (struct sm1_instruction)
|
|
+ {
|
|
+ .opcode = D3DSIO_IFC,
|
|
+ .flags = VKD3D_SHADER_REL_OP_NE, /* Make it a "if_ne" instruction. */
|
|
+
|
|
+ .srcs[0].type = D3DSPR_TEMP,
|
|
+ .srcs[0].swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask),
|
|
+ .srcs[0].reg = condition->reg.id,
|
|
+ .srcs[0].mod = 0,
|
|
+
|
|
+ .srcs[1].type = D3DSPR_TEMP,
|
|
+ .srcs[1].swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask),
|
|
+ .srcs[1].reg = condition->reg.id,
|
|
+ .srcs[1].mod = D3DSPSM_NEG,
|
|
+
|
|
+ .src_count = 2,
|
|
+ };
|
|
+ write_sm1_instruction(ctx, buffer, &sm1_ifc);
|
|
+ write_sm1_block(ctx, buffer, &iff->then_block);
|
|
+
|
|
+ if (!list_empty(&iff->else_block.instrs))
|
|
+ {
|
|
+ sm1_else = (struct sm1_instruction){.opcode = D3DSIO_ELSE};
|
|
+ write_sm1_instruction(ctx, buffer, &sm1_else);
|
|
+ write_sm1_block(ctx, buffer, &iff->else_block);
|
|
+ }
|
|
+
|
|
+ sm1_endif = (struct sm1_instruction){.opcode = D3DSIO_ENDIF};
|
|
+ write_sm1_instruction(ctx, buffer, &sm1_endif);
|
|
+}
|
|
+
|
|
static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
|
|
{
|
|
const struct hlsl_ir_jump *jump = hlsl_ir_jump(instr);
|
|
@@ -2614,12 +2660,12 @@ static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer
|
|
write_sm1_instruction(ctx, buffer, &sm1_instr);
|
|
}
|
|
|
|
-static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
|
|
- const struct hlsl_ir_function_decl *entry_func)
|
|
+static void write_sm1_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
|
|
+ const struct hlsl_block *block)
|
|
{
|
|
const struct hlsl_ir_node *instr;
|
|
|
|
- LIST_FOR_EACH_ENTRY(instr, &entry_func->body.instrs, struct hlsl_ir_node, entry)
|
|
+ LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry)
|
|
{
|
|
if (instr->data_type)
|
|
{
|
|
@@ -2643,6 +2689,13 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
|
|
write_sm1_expr(ctx, buffer, instr);
|
|
break;
|
|
|
|
+ case HLSL_IR_IF:
|
|
+ if (hlsl_version_ge(ctx, 2, 1))
|
|
+ write_sm1_if(ctx, buffer, instr);
|
|
+ else
|
|
+ hlsl_fixme(ctx, &instr->loc, "Flatten \"if\" conditionals branches.");
|
|
+ break;
|
|
+
|
|
case HLSL_IR_JUMP:
|
|
write_sm1_jump(ctx, buffer, instr);
|
|
break;
|
|
@@ -2680,7 +2733,7 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
|
|
write_sm1_constant_defs(ctx, &buffer);
|
|
write_sm1_semantic_dcls(ctx, &buffer);
|
|
write_sm1_sampler_dcls(ctx, &buffer);
|
|
- write_sm1_instructions(ctx, &buffer, entry_func);
|
|
+ write_sm1_block(ctx, &buffer, &entry_func->body);
|
|
|
|
put_u32(&buffer, D3DSIO_END);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index 59b74c065d8..121b0fe3a6c 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -82,6 +82,106 @@ static bool vsir_instruction_init_with_params(struct vsir_program *program,
|
|
return true;
|
|
}
|
|
|
|
+static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type,
|
|
+ enum vkd3d_shader_opcode *opcode, bool *requires_swap)
|
|
+{
|
|
+ switch (rel_op)
|
|
+ {
|
|
+ case VKD3D_SHADER_REL_OP_LT:
|
|
+ case VKD3D_SHADER_REL_OP_GT:
|
|
+ *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_GT);
|
|
+ if (data_type == VKD3D_DATA_FLOAT)
|
|
+ {
|
|
+ *opcode = VKD3DSIH_LTO;
|
|
+ return true;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case VKD3D_SHADER_REL_OP_GE:
|
|
+ case VKD3D_SHADER_REL_OP_LE:
|
|
+ *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_LE);
|
|
+ if (data_type == VKD3D_DATA_FLOAT)
|
|
+ {
|
|
+ *opcode = VKD3DSIH_GEO;
|
|
+ return true;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case VKD3D_SHADER_REL_OP_EQ:
|
|
+ *requires_swap = false;
|
|
+ if (data_type == VKD3D_DATA_FLOAT)
|
|
+ {
|
|
+ *opcode = VKD3DSIH_EQO;
|
|
+ return true;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case VKD3D_SHADER_REL_OP_NE:
|
|
+ *requires_swap = false;
|
|
+ if (data_type == VKD3D_DATA_FLOAT)
|
|
+ {
|
|
+ *opcode = VKD3DSIH_NEO;
|
|
+ return true;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
+static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program,
|
|
+ struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx,
|
|
+ struct vkd3d_shader_message_context *message_context)
|
|
+{
|
|
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
+ size_t pos = ifc - instructions->elements;
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
+ enum vkd3d_shader_opcode opcode;
|
|
+ bool swap;
|
|
+
|
|
+ if (!shader_instruction_array_insert_at(instructions, pos + 1, 2))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ if (*tmp_idx == ~0u)
|
|
+ *tmp_idx = program->temp_count++;
|
|
+
|
|
+ /* Replace ifc comparison with actual comparison, saving the result in the tmp register. */
|
|
+ if (!(get_opcode_from_rel_op(ifc->flags, ifc->src[0].reg.data_type, &opcode, &swap)))
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, &ifc->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
|
+ "Aborting due to not yet implemented feature: opcode for rel_op %u and data type %u.",
|
|
+ ifc->flags, ifc->src[0].reg.data_type);
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
+ }
|
|
+
|
|
+ ins = &instructions->elements[pos + 1];
|
|
+ if (!vsir_instruction_init_with_params(program, ins, &ifc->location, opcode, 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;
|
|
+
|
|
+ ins->src[0] = ifc->src[swap];
|
|
+ ins->src[1] = ifc->src[!swap];
|
|
+
|
|
+ /* Create new if instruction using the previous result. */
|
|
+ ins = &instructions->elements[pos + 2];
|
|
+ if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VKD3DSIH_IF, 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(ifc);
|
|
+
|
|
+ return VKD3D_OK;
|
|
+}
|
|
+
|
|
static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program,
|
|
struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx)
|
|
{
|
|
@@ -210,7 +310,8 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
-static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program)
|
|
+static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program,
|
|
+ struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
unsigned int tmp_idx = ~0u, i;
|
|
@@ -222,6 +323,11 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
|
|
|
|
switch (ins->handler_idx)
|
|
{
|
|
+ case VKD3DSIH_IFC:
|
|
+ if ((ret = vsir_program_lower_ifc(program, ins, &tmp_idx, message_context)) < 0)
|
|
+ return ret;
|
|
+ break;
|
|
+
|
|
case VKD3DSIH_TEXKILL:
|
|
if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0)
|
|
return ret;
|
|
@@ -4992,12 +5098,12 @@ static void register_map_undominated_use(struct vkd3d_shader_register *reg, stru
|
|
{
|
|
unsigned int i;
|
|
|
|
- if (!register_is_ssa(reg))
|
|
- return;
|
|
-
|
|
- i = reg->idx[0].offset;
|
|
- if (alloc->table[i] == UINT_MAX && !vsir_block_dominates(origin_blocks[i], block))
|
|
- alloc->table[i] = alloc->next_temp_idx++;
|
|
+ if (register_is_ssa(reg))
|
|
+ {
|
|
+ i = reg->idx[0].offset;
|
|
+ if (alloc->table[i] == UINT_MAX && !vsir_block_dominates(origin_blocks[i], block))
|
|
+ alloc->table[i] = alloc->next_temp_idx++;
|
|
+ }
|
|
|
|
for (i = 0; i < reg->idx_count; ++i)
|
|
if (reg->idx[i].rel_addr)
|
|
@@ -6056,7 +6162,7 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t
|
|
{
|
|
enum vkd3d_result result = VKD3D_OK;
|
|
|
|
- if ((result = vsir_program_lower_instructions(program)) < 0)
|
|
+ if ((result = vsir_program_lower_instructions(program, message_context)) < 0)
|
|
return result;
|
|
|
|
if (program->shader_version.major >= 6)
|
|
diff --git a/libs/vkd3d/libs/vkd3d/cache.c b/libs/vkd3d/libs/vkd3d/cache.c
|
|
index 56ba6990420..a0a29ed30cb 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/cache.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/cache.c
|
|
@@ -18,11 +18,60 @@
|
|
|
|
#include "vkd3d_private.h"
|
|
|
|
+struct vkd3d_cache_entry_header
|
|
+{
|
|
+ uint64_t hash;
|
|
+ uint64_t key_size;
|
|
+ uint64_t value_size;
|
|
+};
|
|
+
|
|
struct vkd3d_shader_cache
|
|
{
|
|
unsigned int refcount;
|
|
+ struct vkd3d_mutex lock;
|
|
+
|
|
+ struct rb_tree tree;
|
|
};
|
|
|
|
+struct shader_cache_entry
|
|
+{
|
|
+ struct vkd3d_cache_entry_header h;
|
|
+ struct rb_entry entry;
|
|
+ uint8_t *payload;
|
|
+};
|
|
+
|
|
+struct shader_cache_key
|
|
+{
|
|
+ uint64_t hash;
|
|
+ const void *key;
|
|
+ uint64_t key_size;
|
|
+};
|
|
+
|
|
+static int vkd3d_shader_cache_compare_key(const void *key, const struct rb_entry *entry)
|
|
+{
|
|
+ const struct shader_cache_entry *e = RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry);
|
|
+ const struct shader_cache_key *k = key;
|
|
+ int ret;
|
|
+
|
|
+ if ((ret = vkd3d_u64_compare(k->hash, e->h.hash)))
|
|
+ return ret;
|
|
+ if ((ret = vkd3d_u64_compare(k->key_size, e->h.key_size)))
|
|
+ return ret;
|
|
+
|
|
+ /* Until now we have not seen an actual hash collision. If the key didn't match it was always
|
|
+ * due to a bug in the serialization code or memory corruption. If you see this FIXME please
|
|
+ * investigate. */
|
|
+ if ((ret = memcmp(k->key, e->payload, k->key_size)))
|
|
+ FIXME("Actual case of a hash collision found.\n");
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void vkd3d_shader_cache_add_entry(struct vkd3d_shader_cache *cache,
|
|
+ struct shader_cache_entry *e)
|
|
+{
|
|
+ rb_put(&cache->tree, &e->h.hash, &e->entry);
|
|
+}
|
|
+
|
|
int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache)
|
|
{
|
|
struct vkd3d_shader_cache *object;
|
|
@@ -34,6 +83,9 @@ int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache)
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
object->refcount = 1;
|
|
+ rb_init(&object->tree, vkd3d_shader_cache_compare_key);
|
|
+ vkd3d_mutex_init(&object->lock);
|
|
+
|
|
*cache = object;
|
|
|
|
return VKD3D_OK;
|
|
@@ -46,6 +98,13 @@ unsigned int vkd3d_shader_cache_incref(struct vkd3d_shader_cache *cache)
|
|
return refcount;
|
|
}
|
|
|
|
+static void vkd3d_shader_cache_destroy_entry(struct rb_entry *entry, void *context)
|
|
+{
|
|
+ struct shader_cache_entry *e = RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry);
|
|
+ vkd3d_free(e->payload);
|
|
+ vkd3d_free(e);
|
|
+}
|
|
+
|
|
unsigned int vkd3d_shader_cache_decref(struct vkd3d_shader_cache *cache)
|
|
{
|
|
unsigned int refcount = vkd3d_atomic_decrement_u32(&cache->refcount);
|
|
@@ -54,6 +113,142 @@ unsigned int vkd3d_shader_cache_decref(struct vkd3d_shader_cache *cache)
|
|
if (refcount)
|
|
return refcount;
|
|
|
|
+ rb_destroy(&cache->tree, vkd3d_shader_cache_destroy_entry, NULL);
|
|
+ vkd3d_mutex_destroy(&cache->lock);
|
|
+
|
|
vkd3d_free(cache);
|
|
return 0;
|
|
}
|
|
+
|
|
+static uint64_t vkd3d_shader_cache_hash_key(const void *key, size_t size)
|
|
+{
|
|
+ static const uint64_t fnv_prime = 0x00000100000001b3;
|
|
+ uint64_t hash = 0xcbf29ce484222325;
|
|
+ const uint8_t *k = key;
|
|
+ size_t i;
|
|
+
|
|
+ for (i = 0; i < size; ++i)
|
|
+ hash = (hash ^ k[i]) * fnv_prime;
|
|
+
|
|
+ return hash;
|
|
+}
|
|
+
|
|
+static void vkd3d_shader_cache_lock(struct vkd3d_shader_cache *cache)
|
|
+{
|
|
+ vkd3d_mutex_lock(&cache->lock);
|
|
+}
|
|
+
|
|
+static void vkd3d_shader_cache_unlock(struct vkd3d_shader_cache *cache)
|
|
+{
|
|
+ vkd3d_mutex_unlock(&cache->lock);
|
|
+}
|
|
+
|
|
+int vkd3d_shader_cache_put(struct vkd3d_shader_cache *cache,
|
|
+ const void *key, size_t key_size, const void *value, size_t value_size)
|
|
+{
|
|
+ struct shader_cache_entry *e;
|
|
+ struct shader_cache_key k;
|
|
+ struct rb_entry *entry;
|
|
+ enum vkd3d_result ret;
|
|
+
|
|
+ TRACE("%p, %p, %#zx, %p, %#zx.\n", cache, key, key_size, value, value_size);
|
|
+
|
|
+ k.hash = vkd3d_shader_cache_hash_key(key, key_size);
|
|
+ k.key = key;
|
|
+ k.key_size = key_size;
|
|
+
|
|
+ vkd3d_shader_cache_lock(cache);
|
|
+
|
|
+ entry = rb_get(&cache->tree, &k);
|
|
+ e = entry ? RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry) : NULL;
|
|
+
|
|
+ if (e)
|
|
+ {
|
|
+ WARN("Key already exists, returning VKD3D_ERROR_KEY_ALREADY_EXISTS.\n");
|
|
+ ret = VKD3D_ERROR_KEY_ALREADY_EXISTS;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ e = vkd3d_malloc(sizeof(*e));
|
|
+ if (!e)
|
|
+ {
|
|
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ goto done;
|
|
+ }
|
|
+ e->payload = vkd3d_malloc(key_size + value_size);
|
|
+ if (!e->payload)
|
|
+ {
|
|
+ vkd3d_free(e);
|
|
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ e->h.key_size = key_size;
|
|
+ e->h.value_size = value_size;
|
|
+ e->h.hash = k.hash;
|
|
+ memcpy(e->payload, key, key_size);
|
|
+ memcpy(e->payload + key_size, value, value_size);
|
|
+
|
|
+ vkd3d_shader_cache_add_entry(cache, e);
|
|
+ TRACE("Cache entry %#"PRIx64" stored.\n", k.hash);
|
|
+ ret = VKD3D_OK;
|
|
+
|
|
+done:
|
|
+ vkd3d_shader_cache_unlock(cache);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int vkd3d_shader_cache_get(struct vkd3d_shader_cache *cache,
|
|
+ const void *key, size_t key_size, void *value, size_t *value_size)
|
|
+{
|
|
+ struct shader_cache_entry *e;
|
|
+ struct shader_cache_key k;
|
|
+ struct rb_entry *entry;
|
|
+ enum vkd3d_result ret;
|
|
+ size_t size_in;
|
|
+
|
|
+ TRACE("%p, %p, %#zx, %p, %p.\n", cache, key, key_size, value, value_size);
|
|
+
|
|
+ size_in = *value_size;
|
|
+
|
|
+ k.hash = vkd3d_shader_cache_hash_key(key, key_size);
|
|
+ k.key = key;
|
|
+ k.key_size = key_size;
|
|
+
|
|
+ vkd3d_shader_cache_lock(cache);
|
|
+
|
|
+ entry = rb_get(&cache->tree, &k);
|
|
+ if (!entry)
|
|
+ {
|
|
+ WARN("Entry not found.\n");
|
|
+ ret = VKD3D_ERROR_NOT_FOUND;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ e = RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry);
|
|
+
|
|
+ *value_size = e->h.value_size;
|
|
+ if (!value)
|
|
+ {
|
|
+ TRACE("Found item %#"PRIx64", returning needed size %#"PRIx64".\n",
|
|
+ e->h.hash, e->h.value_size);
|
|
+ ret = VKD3D_OK;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (size_in < e->h.value_size)
|
|
+ {
|
|
+ WARN("Output buffer is too small for item %#"PRIx64", got %#zx want %#"PRIx64".\n",
|
|
+ e->h.hash, size_in, e->h.value_size);
|
|
+ ret = VKD3D_ERROR_MORE_DATA;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ memcpy(value, e->payload + e->h.key_size, e->h.value_size);
|
|
+ ret = VKD3D_OK;
|
|
+ TRACE("Returning cached item %#"PRIx64".\n", e->h.hash);
|
|
+
|
|
+done:
|
|
+ vkd3d_shader_cache_unlock(cache);
|
|
+ return ret;
|
|
+}
|
|
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
|
|
index a394e3f7592..cb2b6ad0364 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/device.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/device.c
|
|
@@ -2685,19 +2685,43 @@ static HRESULT STDMETHODCALLTYPE d3d12_cache_session_GetDevice(ID3D12ShaderCache
|
|
static HRESULT STDMETHODCALLTYPE d3d12_cache_session_FindValue(ID3D12ShaderCacheSession *iface,
|
|
const void *key, UINT key_size, void *value, UINT *value_size)
|
|
{
|
|
- FIXME("iface %p, key %p, key_size %#x, value %p, value_size %p stub!\n",
|
|
+ struct d3d12_cache_session *session = impl_from_ID3D12ShaderCacheSession(iface);
|
|
+ enum vkd3d_result ret;
|
|
+ size_t size;
|
|
+
|
|
+ TRACE("iface %p, key %p, key_size %#x, value %p, value_size %p.\n",
|
|
iface, key, key_size, value, value_size);
|
|
|
|
- return DXGI_ERROR_NOT_FOUND;
|
|
+ if (!value_size)
|
|
+ {
|
|
+ WARN("value_size is NULL, returning E_INVALIDARG.\n");
|
|
+ return E_INVALIDARG;
|
|
+ }
|
|
+
|
|
+ size = *value_size;
|
|
+ ret = vkd3d_shader_cache_get(session->cache, key, key_size, value, &size);
|
|
+ *value_size = size;
|
|
+
|
|
+ return hresult_from_vkd3d_result(ret);
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE d3d12_cache_session_StoreValue(ID3D12ShaderCacheSession *iface,
|
|
const void *key, UINT key_size, const void *value, UINT value_size)
|
|
{
|
|
- FIXME("iface %p, key %p, key_size %#x, value %p, value_size %u stub!\n", iface, key, key_size,
|
|
- value, value_size);
|
|
+ struct d3d12_cache_session *session = impl_from_ID3D12ShaderCacheSession(iface);
|
|
+ enum vkd3d_result ret;
|
|
|
|
- return E_NOTIMPL;
|
|
+ TRACE("iface %p, key %p, key_size %#x, value %p, value_size %u.\n",
|
|
+ iface, key, key_size, value, value_size);
|
|
+
|
|
+ if (!key || !key_size || !value || !value_size)
|
|
+ {
|
|
+ WARN("Invalid input parameters, returning E_INVALIDARG.\n");
|
|
+ return E_INVALIDARG;
|
|
+ }
|
|
+
|
|
+ ret = vkd3d_shader_cache_put(session->cache, key, key_size, value, value_size);
|
|
+ return hresult_from_vkd3d_result(ret);
|
|
}
|
|
|
|
static void STDMETHODCALLTYPE d3d12_cache_session_SetDeleteOnDestroy(ID3D12ShaderCacheSession *iface)
|
|
@@ -2833,7 +2857,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device9 *ifac
|
|
|| IsEqualGUID(riid, &IID_ID3D12Object)
|
|
|| IsEqualGUID(riid, &IID_IUnknown))
|
|
{
|
|
- ID3D12Device_AddRef(iface);
|
|
+ ID3D12Device9_AddRef(iface);
|
|
*object = iface;
|
|
return S_OK;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
|
|
index 179999148bc..7a2f464c98e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/resource.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/resource.c
|
|
@@ -1271,7 +1271,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource2 *
|
|
|| IsEqualGUID(riid, &IID_ID3D12Object)
|
|
|| IsEqualGUID(riid, &IID_IUnknown))
|
|
{
|
|
- ID3D12Resource_AddRef(iface);
|
|
+ ID3D12Resource2_AddRef(iface);
|
|
*object = iface;
|
|
return S_OK;
|
|
}
|
|
@@ -2350,16 +2350,16 @@ static void *vkd3d_desc_object_cache_get(struct vkd3d_desc_object_cache *cache)
|
|
i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK;
|
|
for (;;)
|
|
{
|
|
- if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1))
|
|
+ if (vkd3d_atomic_compare_exchange_u32(&cache->heads[i].spinlock, 0, 1))
|
|
{
|
|
if ((u.object = cache->heads[i].head))
|
|
{
|
|
vkd3d_atomic_decrement_u32(&cache->free_count);
|
|
cache->heads[i].head = u.header->next;
|
|
- vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0);
|
|
+ vkd3d_atomic_exchange_u32(&cache->heads[i].spinlock, 0);
|
|
return u.object;
|
|
}
|
|
- vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0);
|
|
+ vkd3d_atomic_exchange_u32(&cache->heads[i].spinlock, 0);
|
|
}
|
|
/* Keeping a free count avoids uncertainty over when this loop should terminate,
|
|
* which could result in excess allocations gradually increasing without limit. */
|
|
@@ -2381,7 +2381,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache,
|
|
i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK;
|
|
for (;;)
|
|
{
|
|
- if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1))
|
|
+ if (vkd3d_atomic_compare_exchange_u32(&cache->heads[i].spinlock, 0, 1))
|
|
break;
|
|
i = (i + 1) & HEAD_INDEX_MASK;
|
|
}
|
|
@@ -2389,7 +2389,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache,
|
|
head = cache->heads[i].head;
|
|
u.header->next = head;
|
|
cache->heads[i].head = u.object;
|
|
- vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0);
|
|
+ vkd3d_atomic_exchange_u32(&cache->heads[i].spinlock, 0);
|
|
vkd3d_atomic_increment_u32(&cache->free_count);
|
|
}
|
|
|
|
@@ -2473,7 +2473,7 @@ void vkd3d_view_decref(void *view, struct d3d12_device *device)
|
|
|
|
static inline void d3d12_desc_replace(struct d3d12_desc *dst, void *view, struct d3d12_device *device)
|
|
{
|
|
- if ((view = vkd3d_atomic_exchange_pointer(&dst->s.u.object, view)))
|
|
+ if ((view = vkd3d_atomic_exchange_ptr(&dst->s.u.object, view)))
|
|
vkd3d_view_decref(view, device);
|
|
}
|
|
|
|
@@ -2652,7 +2652,7 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
|
|
union d3d12_desc_object u;
|
|
unsigned int i, next;
|
|
|
|
- if ((i = vkd3d_atomic_exchange(&descriptor_heap->dirty_list_head, UINT_MAX)) == UINT_MAX)
|
|
+ if ((i = vkd3d_atomic_exchange_u32(&descriptor_heap->dirty_list_head, UINT_MAX)) == UINT_MAX)
|
|
return;
|
|
|
|
writes.null_vk_cbv_info.buffer = VK_NULL_HANDLE;
|
|
@@ -2667,7 +2667,7 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
|
|
for (; i != UINT_MAX; i = next)
|
|
{
|
|
src = &descriptors[i];
|
|
- next = vkd3d_atomic_exchange(&src->next, 0);
|
|
+ next = vkd3d_atomic_exchange_u32(&src->next, 0);
|
|
next = (int)next >> 1;
|
|
|
|
/* A race exists here between updating src->next and getting the current object. The best
|
|
@@ -2695,13 +2695,13 @@ static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst, struct d3d12_des
|
|
head = descriptor_heap->dirty_list_head;
|
|
|
|
/* Only one thread can swap the value away from zero. */
|
|
- if (!vkd3d_atomic_compare_exchange(&dst->next, 0, (head << 1) | 1))
|
|
+ if (!vkd3d_atomic_compare_exchange_u32(&dst->next, 0, (head << 1) | 1))
|
|
return;
|
|
/* Now it is safe to modify 'next' to another nonzero value if necessary. */
|
|
- while (!vkd3d_atomic_compare_exchange(&descriptor_heap->dirty_list_head, head, i))
|
|
+ while (!vkd3d_atomic_compare_exchange_u32(&descriptor_heap->dirty_list_head, head, i))
|
|
{
|
|
head = descriptor_heap->dirty_list_head;
|
|
- vkd3d_atomic_exchange(&dst->next, (head << 1) | 1);
|
|
+ vkd3d_atomic_exchange_u32(&dst->next, (head << 1) | 1);
|
|
}
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
index 29305fbdc63..c7431bd821b 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c
|
|
@@ -71,7 +71,7 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
|
|
|
|
if (!device)
|
|
{
|
|
- ID3D12Device_Release(&object->ID3D12Device9_iface);
|
|
+ ID3D12Device9_Release(&object->ID3D12Device9_iface);
|
|
return S_FALSE;
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
index 5f60c8d90ad..d1fa866d9e3 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
@@ -19,6 +19,9 @@
|
|
#ifndef __VKD3D_PRIVATE_H
|
|
#define __VKD3D_PRIVATE_H
|
|
|
|
+#ifndef __MINGW32__
|
|
+#define WIDL_C_INLINE_WRAPPERS
|
|
+#endif
|
|
#define COBJMACROS
|
|
#define NONAMELESSUNION
|
|
#define VK_NO_PROTOTYPES
|
|
@@ -194,93 +197,14 @@ struct vkd3d_instance
|
|
unsigned int refcount;
|
|
};
|
|
|
|
-#ifdef _WIN32
|
|
-
|
|
-union vkd3d_thread_handle
|
|
-{
|
|
- void *handle;
|
|
-};
|
|
-
|
|
-static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg)
|
|
-{
|
|
- return InterlockedCompareExchange((LONG volatile *)x, xchg, cmp) == cmp;
|
|
-}
|
|
-
|
|
-static inline unsigned int vkd3d_atomic_exchange(unsigned int volatile *x, unsigned int val)
|
|
-{
|
|
- return InterlockedExchange((LONG volatile *)x, val);
|
|
-}
|
|
-
|
|
-static inline bool vkd3d_atomic_compare_exchange_pointer(void * volatile *x, void *cmp, void *xchg)
|
|
-{
|
|
- return InterlockedCompareExchangePointer(x, xchg, cmp) == cmp;
|
|
-}
|
|
-
|
|
-static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val)
|
|
-{
|
|
- return InterlockedExchangePointer(x, val);
|
|
-}
|
|
-
|
|
-#else /* _WIN32 */
|
|
-
|
|
-#include <pthread.h>
|
|
-
|
|
union vkd3d_thread_handle
|
|
{
|
|
+#ifndef _WIN32
|
|
pthread_t pthread;
|
|
+#endif
|
|
void *handle;
|
|
};
|
|
|
|
-# if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
|
|
-static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg)
|
|
-{
|
|
- return __sync_bool_compare_and_swap(x, cmp, xchg);
|
|
-}
|
|
-
|
|
-static inline bool vkd3d_atomic_compare_exchange_pointer(void * volatile *x, void *cmp, void *xchg)
|
|
-{
|
|
- return __sync_bool_compare_and_swap(x, cmp, xchg);
|
|
-}
|
|
-# else
|
|
-# error "vkd3d_atomic_compare_exchange() not implemented for this platform"
|
|
-# endif
|
|
-
|
|
-# if HAVE_ATOMIC_EXCHANGE_N
|
|
-static inline unsigned int vkd3d_atomic_exchange(unsigned int volatile *x, unsigned int val)
|
|
-{
|
|
- return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST);
|
|
-}
|
|
-
|
|
-static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val)
|
|
-{
|
|
- return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST);
|
|
-}
|
|
-# elif HAVE_SYNC_BOOL_COMPARE_AND_SWAP
|
|
-static inline unsigned int vkd3d_atomic_exchange(unsigned int volatile *x, unsigned int val)
|
|
-{
|
|
- unsigned int i;
|
|
- do
|
|
- {
|
|
- i = *x;
|
|
- } while (!__sync_bool_compare_and_swap(x, i, val));
|
|
- return i;
|
|
-}
|
|
-
|
|
-static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val)
|
|
-{
|
|
- void *p;
|
|
- do
|
|
- {
|
|
- p = *x;
|
|
- } while (!__sync_bool_compare_and_swap(x, p, val));
|
|
- return p;
|
|
-}
|
|
-# else
|
|
-# error "vkd3d_atomic_exchange() not implemented for this platform"
|
|
-# endif
|
|
-
|
|
-#endif /* _WIN32 */
|
|
-
|
|
HRESULT vkd3d_create_thread(struct vkd3d_instance *instance,
|
|
PFN_vkd3d_thread thread_main, void *data, union vkd3d_thread_handle *thread);
|
|
HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_handle *thread);
|
|
@@ -742,7 +666,7 @@ static inline bool vkd3d_view_incref(void *desc)
|
|
if (refcount <= 0)
|
|
return false;
|
|
}
|
|
- while (!vkd3d_atomic_compare_exchange(&h->refcount, refcount, refcount + 1));
|
|
+ while (!vkd3d_atomic_compare_exchange_u32(&h->refcount, refcount, refcount + 1));
|
|
|
|
return true;
|
|
}
|
|
@@ -1852,5 +1776,9 @@ struct vkd3d_shader_cache;
|
|
int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache);
|
|
unsigned int vkd3d_shader_cache_incref(struct vkd3d_shader_cache *cache);
|
|
unsigned int vkd3d_shader_cache_decref(struct vkd3d_shader_cache *cache);
|
|
+int vkd3d_shader_cache_put(struct vkd3d_shader_cache *cache,
|
|
+ const void *key, size_t key_size, const void *value, size_t value_size);
|
|
+int vkd3d_shader_cache_get(struct vkd3d_shader_cache *cache,
|
|
+ const void *key, size_t key_size, void *value, size_t *value_size);
|
|
|
|
#endif /* __VKD3D_PRIVATE_H */
|
|
--
|
|
2.43.0
|
|
|