Compare commits

...

8 Commits

Author SHA1 Message Date
Hans-Kristian Arntzen b45e51fb5a vkd3d-shader: Add path for debug dumping SPIR-V as well.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
2020-01-15 13:23:20 +01:00
Hans-Kristian Arntzen f4d874725c vkd3d: Add test case for SM 5.1 register spaces.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
2020-01-15 13:23:20 +01:00
Hans-Kristian Arntzen 6f986940c9 vkd3d: Deal correctly with SM 5.1 register spaces.
Resource index is found in idx[0] in SM 5.0, but idx[1] when using SM
5.1, and register space is encoded reparately. An rb_tree keeps track of
the internal resource index idx[0] and can map that to space/binding as
required when emitting SPIR-V.

For this to work, we must also make UAV counters register space aware.
In earlier implementation, UAV counter mask was assumed to correlate 1:1
with register_index, which breaks on SM 5.1.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
2020-01-15 13:23:17 +01:00
Hans-Kristian Arntzen 0184aac9d4 vkd3d: Load d3d12 dynamically in d3d12 tests.
MinGW does not ship d3d12 properly, so link against d3d12.dll
dynamically instead.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
2020-01-15 10:11:19 +01:00
Hans-Kristian Arntzen c22cc17611 vkd3d: Load Vulkan dynamically in d3d12 test app.
On Windows, it is not ideal to rely on Vulkan being available as a
linkable library as a full install of the Vulkan SDK must be present and
set up, be friendly and load Vulkan dynamically instead.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
2020-01-15 10:11:19 +01:00
Hans-Kristian Arntzen d3c1147923 vkd3d: Support using vkd3d-utils path when testing on Windows.
When testing vkd3d on Windows, we were only able to use the native D3D12
path. Add an ifdef to configure this.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
2020-01-15 10:11:19 +01:00
Hans-Kristian Arntzen bf2b437346 vkd3d-utils: Make vkd3d-utils compilable on MSVC.
Useful to be able to run unit tests on Windows.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
2020-01-15 10:11:19 +01:00
Hans-Kristian Arntzen 1fbba4a947 vkd3d: Add simple pthread wrapper for MSVC.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
2020-01-15 10:11:19 +01:00
15 changed files with 981 additions and 83 deletions

View File

@ -0,0 +1,167 @@
/*
* Copyright 2019 Hans-Kristian Arntzen for Valve
*
* 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_THREADS_H
#define __VKD3D_THREADS_H
#include "config.h"
#include "vkd3d_memory.h"
#if defined(HAVE_PTHREAD_H)
#include <pthread.h>
#elif defined(_WIN32) /* HAVE_PTHREAD_H */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/* pthread_t is passed by value in some functions,
* which implies we need pthread_t to be a pointer type here. */
struct pthread
{
HANDLE thread;
DWORD id;
void * (*routine)(void *);
void *arg;
};
typedef struct pthread *pthread_t;
/* pthread_mutex_t is not copyable, so embed CS inline. */
typedef struct pthread_mutex
{
CRITICAL_SECTION lock;
} pthread_mutex_t;
/* pthread_cond_t is not copyable, so embed CV inline. */
typedef struct pthread_cond
{
CONDITION_VARIABLE cond;
} pthread_cond_t;
static DWORD WINAPI win32_thread_wrapper_routine(void *arg)
{
pthread_t thread = arg;
thread->routine(thread->arg);
return 0;
}
static inline int pthread_create(pthread_t *out_thread, void *attr, void * (*thread_fun)(void *), void *arg)
{
pthread_t thread = vkd3d_calloc(1, sizeof(*thread));
if (!thread)
return -1;
(void)attr;
thread->routine = thread_fun;
thread->arg = arg;
thread->thread = CreateThread(NULL, 0, win32_thread_wrapper_routine, thread, 0, &thread->id);
if (!thread->thread)
{
vkd3d_free(thread);
return -1;
}
*out_thread = thread;
return 0;
}
static inline int pthread_join(pthread_t thread, void **ret)
{
(void)ret;
int success = WaitForSingleObject(thread->thread, INFINITE) == WAIT_OBJECT_0;
if (success)
{
CloseHandle(thread->thread);
vkd3d_free(thread);
}
return success ? 0 : -1;
}
static inline int pthread_mutex_init(pthread_mutex_t *lock, void *attr)
{
(void)attr;
InitializeCriticalSection(&lock->lock);
return 0;
}
static inline int pthread_mutex_lock(pthread_mutex_t *lock)
{
EnterCriticalSection(&lock->lock);
return 0;
}
static inline int pthread_mutex_unlock(pthread_mutex_t *lock)
{
LeaveCriticalSection(&lock->lock);
return 0;
}
static inline int pthread_mutex_destroy(pthread_mutex_t *lock)
{
DeleteCriticalSection(&lock->lock);
return 0;
}
static inline int pthread_cond_init(pthread_cond_t *cond, void *attr)
{
(void)attr;
InitializeConditionVariable(&cond->cond);
return 0;
}
static inline int pthread_cond_destroy(pthread_cond_t *cond)
{
(void)cond;
return 0;
}
static inline int pthread_cond_signal(pthread_cond_t *cond)
{
WakeConditionVariable(&cond->cond);
return 0;
}
static inline int pthread_cond_broadcast(pthread_cond_t *cond)
{
WakeAllConditionVariable(&cond->cond);
return 0;
}
static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *lock)
{
BOOL ret = SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE);
return ret ? 0 : -1;
}
#else /* HAVE_PTHREAD_H */
#error "Threads are not supported. Cannot build."
#endif /* HAVE_PTHREAD_H */
static inline void vkd3d_set_thread_name(const char *name)
{
#if defined(_MSC_VER)
(void)name;
#elif defined(HAVE_PTHREAD_SETNAME_NP_2)
pthread_setname_np(pthread_self(), name);
#elif defined(HAVE_PTHREAD_SETNAME_NP_1)
pthread_setname_np(name);
#else
(void)name;
#endif
}
#endif /* __VKD3D_THREADS_H */

View File

@ -35,6 +35,7 @@ enum vkd3d_shader_structure_type
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_DOMAIN_SHADER_COMPILE_ARGUMENTS,
VKD3D_SHADER_STRUCTURE_TYPE_EFFECTIVE_UAV_COUNTER_BINDING_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
};
@ -138,6 +139,7 @@ struct vkd3d_shader_parameter
struct vkd3d_shader_resource_binding
{
enum vkd3d_shader_descriptor_type type;
unsigned int register_space;
unsigned int register_index;
enum vkd3d_shader_visibility shader_visibility;
unsigned int flags; /* vkd3d_shader_binding_flags */
@ -159,8 +161,10 @@ struct vkd3d_shader_combined_resource_sampler
struct vkd3d_shader_uav_counter_binding
{
unsigned int register_space;
unsigned int register_index; /* u# */
enum vkd3d_shader_visibility shader_visibility;
unsigned int counter_index;
struct vkd3d_shader_descriptor_binding binding;
unsigned int offset;
@ -168,6 +172,7 @@ struct vkd3d_shader_uav_counter_binding
struct vkd3d_shader_push_constant_buffer
{
unsigned int register_space;
unsigned int register_index;
enum vkd3d_shader_visibility shader_visibility;
@ -215,6 +220,17 @@ struct vkd3d_shader_transform_feedback_info
unsigned int buffer_stride_count;
};
/* Extends vkd3d_shader_interface_info. */
struct vkd3d_shader_effective_uav_counter_binding_info
{
enum vkd3d_shader_structure_type type;
const void *next;
unsigned int *uav_register_spaces;
unsigned int *uav_register_bindings;
unsigned int uav_counter_count;
};
enum vkd3d_shader_target
{
VKD3D_SHADER_TARGET_NONE,

View File

@ -624,6 +624,10 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins,
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.semantic.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.semantic.register_index = ins->declaration.semantic.reg.reg.idx[1].offset;
else
ins->declaration.semantic.register_index = ins->declaration.semantic.reg.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction *ins,
@ -647,9 +651,12 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction
return;
}
ins->declaration.cb.register_index = ins->declaration.cb.src.reg.idx[1].offset;
ins->declaration.cb.size = *tokens++;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.cb.register_space);
}
else
ins->declaration.cb.register_index = ins->declaration.cb.src.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins,
@ -663,6 +670,10 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins,
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_SAMPLER, &ins->declaration.sampler.src);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.sampler.register_index = ins->declaration.sampler.src.reg.idx[1].offset;
else
ins->declaration.sampler.register_index = ins->declaration.sampler.src.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins,
@ -863,6 +874,10 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins,
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &ins->declaration.raw_resource.dst);
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.raw_resource.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.raw_resource.register_index = ins->declaration.raw_resource.dst.reg.idx[1].offset;
else
ins->declaration.raw_resource.register_index = ins->declaration.raw_resource.dst.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *ins,
@ -874,9 +889,14 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &ins->declaration.structured_resource.reg);
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
ins->declaration.structured_resource.byte_stride = *tokens;
tokens++;
if (ins->declaration.structured_resource.byte_stride % 4)
FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.structured_resource.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[1].offset;
else
ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins,
@ -909,9 +929,14 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &ins->declaration.structured_resource.reg);
ins->declaration.structured_resource.byte_stride = *tokens;
tokens++;
if (ins->declaration.structured_resource.byte_stride % 4)
FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.structured_resource.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[1].offset;
else
ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *ins,
@ -922,6 +947,10 @@ static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *in
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &ins->declaration.dst);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.raw_resource.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.raw_resource.register_index = ins->declaration.dst.reg.idx[1].offset;
else
ins->declaration.raw_resource.register_index = ins->declaration.dst.reg.idx[0].offset;
}
static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins,

View File

@ -1890,6 +1890,20 @@ struct vkd3d_symbol
} info;
};
struct vkd3d_sm51_symbol_key
{
enum vkd3d_shader_descriptor_type descriptor_type;
unsigned int idx;
};
struct vkd3d_sm51_symbol
{
struct rb_entry entry;
struct vkd3d_sm51_symbol_key key;
unsigned int register_space;
unsigned int resource_idx;
};
static int vkd3d_symbol_compare(const void *key, const struct rb_entry *entry)
{
const struct vkd3d_symbol *a = key;
@ -1900,6 +1914,13 @@ static int vkd3d_symbol_compare(const void *key, const struct rb_entry *entry)
return memcmp(&a->key, &b->key, sizeof(a->key));
}
static int vkd3d_sm51_symbol_compare(const void *key, const struct rb_entry *entry)
{
const struct vkd3d_sm51_symbol_key *a = key;
const struct vkd3d_sm51_symbol *b = RB_ENTRY_VALUE(entry, const struct vkd3d_sm51_symbol, entry);
return memcmp(a, &b->key, sizeof(*a));
}
static void vkd3d_symbol_free(struct rb_entry *entry, void *context)
{
struct vkd3d_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
@ -1907,6 +1928,13 @@ static void vkd3d_symbol_free(struct rb_entry *entry, void *context)
vkd3d_free(s);
}
static void vkd3d_sm51_symbol_free(struct rb_entry *entry, void *context)
{
struct vkd3d_sm51_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_sm51_symbol, entry);
vkd3d_free(s);
}
static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol,
const struct vkd3d_shader_register *reg)
{
@ -2052,6 +2080,7 @@ struct vkd3d_hull_shader_variables
struct vkd3d_dxbc_compiler
{
struct vkd3d_shader_version shader_version;
struct vkd3d_spirv_builder spirv_builder;
uint32_t options;
@ -2062,6 +2091,8 @@ struct vkd3d_dxbc_compiler
struct vkd3d_hull_shader_variables hs;
uint32_t sample_positions_id;
struct rb_tree sm51_resource_table;
enum vkd3d_shader_type shader_type;
unsigned int branch_id;
@ -2107,6 +2138,11 @@ struct vkd3d_dxbc_compiler
size_t spec_constants_size;
};
static bool shader_is_sm_5_1(const struct vkd3d_dxbc_compiler *compiler)
{
return (compiler->shader_version.major * 100 + compiler->shader_version.minor) >= 501;
}
static bool is_control_point_phase(const struct vkd3d_shader_phase *phase)
{
return phase && phase->type == VKD3DSIH_HS_CONTROL_POINT_PHASE;
@ -2131,6 +2167,8 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
memset(compiler, 0, sizeof(*compiler));
compiler->shader_version = *shader_version;
max_element_count = max(output_signature->element_count, patch_constant_signature->element_count);
if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info))))
{
@ -2142,6 +2180,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
compiler->options = compiler_options;
rb_init(&compiler->symbol_table, vkd3d_symbol_compare);
rb_init(&compiler->sm51_resource_table, vkd3d_sm51_symbol_compare);
compiler->shader_type = shader_version->type;
@ -2227,9 +2266,10 @@ static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_
}
static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_constant_buffer(
const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg)
const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb)
{
unsigned int reg_idx = reg->idx[0].offset;
unsigned int reg_idx = cb->register_index;
unsigned int reg_space = cb->register_space;
unsigned int i;
for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i)
@ -2239,7 +2279,7 @@ static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_
if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->pc.shader_visibility))
continue;
if (current->pc.register_index == reg_idx)
if (current->pc.register_index == reg_idx && current->pc.register_space == reg_space)
return current;
}
@ -2274,6 +2314,49 @@ static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_com
return false;
}
static bool vkd3d_get_binding_info_for_register(
struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg,
unsigned int *reg_space, unsigned int *reg_binding)
{
const struct vkd3d_sm51_symbol *symbol;
struct vkd3d_sm51_symbol_key key;
const struct rb_entry *entry;
if (shader_is_sm_5_1(compiler))
{
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN;
if (reg->type == VKD3DSPR_CONSTBUFFER)
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
else if (reg->type == VKD3DSPR_RESOURCE)
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
else if (reg->type == VKD3DSPR_UAV)
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
else if (reg->type == VKD3DSPR_SAMPLER)
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
else
FIXME("Unhandled register type %#x.\n", reg->type);
key.idx = reg->idx[0].offset;
entry = rb_get(&compiler->sm51_resource_table, &key);
if (entry)
{
symbol = RB_ENTRY_VALUE(entry, const struct vkd3d_sm51_symbol, entry);
*reg_space = symbol->register_space;
*reg_binding = symbol->resource_idx;
return true;
}
else
return false;
}
else
{
*reg_space = 0;
*reg_binding = reg->idx[0].offset;
return true;
}
}
static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding(
struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg,
enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
@ -2282,8 +2365,9 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
enum vkd3d_shader_descriptor_type descriptor_type;
enum vkd3d_shader_binding_flag resource_type_flag;
struct vkd3d_shader_descriptor_binding binding;
unsigned int reg_idx = reg->idx[0].offset;
unsigned int i;
unsigned int reg_space;
unsigned int reg_idx;
descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN;
if (reg->type == VKD3DSPR_CONSTBUFFER)
@ -2300,6 +2384,11 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER
? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
if (!vkd3d_get_binding_info_for_register(compiler, reg, &reg_space, &reg_idx))
{
ERR("Failed to find binding for resource type %#x.\n", reg->type);
}
if (is_uav_counter)
{
assert(descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV);
@ -2313,8 +2402,19 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (current->offset)
FIXME("Atomic counter offsets are not supported yet.\n");
if (current->register_index == reg_idx)
/* Do not use space/binding, but just the plain index here, since that's how the UAV counter mask is exposed. */
if (current->register_index == reg->idx[0].offset)
{
/* Let pipeline know what the actual space/bindings for the counter are. */
const struct vkd3d_shader_effective_uav_counter_binding_info *binding_info =
vkd3d_find_struct(shader_interface->next, EFFECTIVE_UAV_COUNTER_BINDING_INFO);
if (binding_info && current->register_index < binding_info->uav_counter_count)
{
binding_info->uav_register_spaces[current->register_index] = reg_space;
binding_info->uav_register_bindings[current->register_index] = reg_idx;
}
return current->binding;
}
}
if (shader_interface->uav_counter_count)
FIXME("Could not find descriptor binding for UAV counter %u.\n", reg_idx);
@ -2331,7 +2431,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility))
continue;
if (current->type == descriptor_type && current->register_index == reg_idx)
if (current->type == descriptor_type && current->register_index == reg_idx && current->register_space == reg_space)
return current->binding;
}
if (shader_interface->binding_count)
@ -2828,7 +2928,8 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp
{
assert(!reg->idx[0].rel_addr);
indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx);
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, &reg->idx[1]);
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler,
&reg->idx[shader_is_sm_5_1(compiler) ? 2 : 1]);
}
else if (reg->type == VKD3DSPR_IMMCONSTBUFFER)
{
@ -2838,6 +2939,11 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp
{
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, &reg->idx[1]);
}
else if (reg->type == VKD3DSPR_SAMPLER)
{
/* SM 5.1 will have an index here referring to something which we throw away. */
index_count = 0;
}
else if (register_info->is_aggregate)
{
struct vkd3d_shader_register_index reg_idx = reg->idx[0];
@ -4965,10 +5071,19 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC));
if (cb->register_space)
FIXME("Unhandled register space %u.\n", cb->register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = reg->idx[0].offset;
sym->key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
sym->register_space = instruction->declaration.sampler.register_space;
sym->resource_idx = instruction->declaration.sampler.register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, reg)))
if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, cb)))
{
/* Push constant buffers are handled in
* vkd3d_dxbc_compiler_emit_push_constant_buffers().
@ -5050,8 +5165,17 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com
uint32_t type_id, ptr_type_id, var_id;
struct vkd3d_symbol reg_symbol;
if (instruction->declaration.sampler.register_space)
FIXME("Unhandled register space %u.\n", instruction->declaration.sampler.register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = reg->idx[0].offset;
sym->key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
sym->register_space = instruction->declaration.sampler.register_space;
sym->resource_idx = instruction->declaration.sampler.register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if (vkd3d_dxbc_compiler_has_combined_sampler(compiler, NULL, reg))
return;
@ -5062,7 +5186,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com
ptr_type_id, storage_class, 0);
vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler,
var_id, reg, VKD3D_SHADER_RESOURCE_NONE, false);
var_id, reg,VKD3D_SHADER_RESOURCE_NONE, false);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@ -5272,8 +5396,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource(struct vkd3d_dxbc_compiler *co
{
const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic;
if (semantic->register_space)
FIXME("Unhandled register space %u.\n", semantic->register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = semantic->reg.reg.idx[0].offset;
sym->key.descriptor_type = semantic->reg.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
sym->register_space = semantic->register_space;
sym->resource_idx = semantic->register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@ -5286,8 +5420,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_raw(struct vkd3d_dxbc_compiler
{
const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource;
if (resource->register_space)
FIXME("Unhandled register space %u.\n", resource->register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = resource->dst.reg.idx[0].offset;
sym->key.descriptor_type = resource->dst.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
sym->register_space = resource->register_space;
sym->resource_idx = resource->register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@ -5302,8 +5446,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_structured(struct vkd3d_dxbc_c
const struct vkd3d_shader_register *reg = &resource->reg.reg;
unsigned int stride = resource->byte_stride;
if (resource->register_space)
FIXME("Unhandled register space %u.\n", resource->register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = resource->reg.reg.idx[0].offset;
sym->key.descriptor_type = resource->reg.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
sym->register_space = resource->register_space;
sym->resource_idx = resource->register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@ -8717,6 +8871,7 @@ void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler)
vkd3d_spirv_builder_free(&compiler->spirv_builder);
rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL);
rb_destroy(&compiler->sm51_resource_table, vkd3d_sm51_symbol_free, NULL);
vkd3d_free(compiler->shader_phases);
vkd3d_free(compiler->spec_constants);

View File

@ -25,16 +25,13 @@ VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG");
STATIC_ASSERT(MEMBER_SIZE(struct vkd3d_shader_scan_info, uav_counter_mask) * CHAR_BIT >= VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS);
STATIC_ASSERT(MEMBER_SIZE(struct vkd3d_shader_scan_info, uav_read_mask) * CHAR_BIT >= VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS);
static void vkd3d_shader_dump_blob(const char *path, const char *prefix, const void *data, size_t size)
static void vkd3d_shader_dump_blob(const char *path, const char *prefix, const void *data, size_t size,
unsigned int id, const char *ext)
{
static int shader_id = 0;
char filename[1024];
unsigned int id;
FILE *f;
id = InterlockedIncrement(&shader_id) - 1;
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%s-%u.dxbc", path, prefix, id);
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%s-%u.%s", path, prefix, id, ext);
if ((f = fopen(filename, "wb")))
{
if (fwrite(data, 1, size, f) != size)
@ -50,6 +47,7 @@ static void vkd3d_shader_dump_blob(const char *path, const char *prefix, const v
static void vkd3d_shader_dump_shader(enum vkd3d_shader_type type, const struct vkd3d_shader_code *shader)
{
static int shader_id = 0;
static bool enabled = true;
const char *path;
@ -62,7 +60,27 @@ static void vkd3d_shader_dump_shader(enum vkd3d_shader_type type, const struct v
return;
}
vkd3d_shader_dump_blob(path, shader_get_type_prefix(type), shader->code, shader->size);
vkd3d_shader_dump_blob(path, shader_get_type_prefix(type), shader->code, shader->size,
InterlockedIncrement(&shader_id) - 1, "dxbc");
}
static void vkd3d_shader_dump_spirv_shader(enum vkd3d_shader_type type, const struct vkd3d_shader_code *shader)
{
static int shader_id = 0;
static bool enabled = true;
const char *path;
if (!enabled)
return;
if (!(path = getenv("VKD3D_SHADER_DUMP_PATH")))
{
enabled = false;
return;
}
vkd3d_shader_dump_blob(path, shader_get_type_prefix(type), shader->code, shader->size,
InterlockedIncrement(&shader_id) - 1, "spv");
}
struct vkd3d_shader_parser
@ -190,6 +208,9 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
if (ret >= 0)
ret = vkd3d_dxbc_compiler_generate_spirv(spirv_compiler, spirv);
if (ret == 0)
vkd3d_shader_dump_spirv_shader(parser.shader_version.type, spirv);
vkd3d_dxbc_compiler_destroy(spirv_compiler);
vkd3d_shader_parser_destroy(&parser);
return ret;

View File

@ -615,6 +615,7 @@ struct vkd3d_shader_semantic
enum vkd3d_data_type resource_data_type;
struct vkd3d_shader_dst_param reg;
unsigned int register_space;
unsigned int register_index;
};
enum vkd3d_shader_input_sysval_semantic
@ -662,6 +663,7 @@ struct vkd3d_shader_register_semantic
struct vkd3d_shader_sampler
{
struct vkd3d_shader_src_param src;
unsigned int register_index;
unsigned int register_space;
};
@ -669,6 +671,7 @@ struct vkd3d_shader_constant_buffer
{
struct vkd3d_shader_src_param src;
unsigned int size;
unsigned int register_index;
unsigned int register_space;
};
@ -676,12 +679,14 @@ struct vkd3d_shader_structured_resource
{
struct vkd3d_shader_dst_param reg;
unsigned int byte_stride;
unsigned int register_index;
unsigned int register_space;
};
struct vkd3d_shader_raw_resource
{
struct vkd3d_shader_dst_param dst;
unsigned int register_index;
unsigned int register_space;
};

View File

@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "vkd3d_common.h"
#include "vkd3d_utils_private.h"
VKD3D_DEBUG_ENV_NAME("VKD3D_DEBUG");

View File

@ -23,7 +23,7 @@
#define NONAMELESSUNION
#define VK_NO_PROTOTYPES
#include <pthread.h>
#include "vkd3d_threads.h"
#include <vkd3d.h>
#include "vkd3d_memory.h"

View File

@ -2655,7 +2655,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
const struct d3d12_root_descriptor_table *descriptor_table;
const struct d3d12_root_descriptor_table_range *range;
VkDevice vk_device = list->device->vk_device;
unsigned int i, j, descriptor_count;
unsigned int i, j, k, descriptor_count;
struct d3d12_desc *descriptor;
descriptor_table = root_signature_get_descriptor_table(root_signature, index);
@ -2678,14 +2678,26 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
unsigned int register_idx = range->base_register_idx + j;
/* Track UAV counters. */
if (range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_UAV
&& register_idx < ARRAY_SIZE(bindings->vk_uav_counter_views))
if (list->state->uav_counter_mask != 0 && range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_UAV)
{
VkBufferView vk_counter_view = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV
? descriptor->u.view->vk_counter_view : VK_NULL_HANDLE;
if (bindings->vk_uav_counter_views[register_idx] != vk_counter_view)
bindings->uav_counter_dirty_mask |= 1u << register_idx;
bindings->vk_uav_counter_views[register_idx] = vk_counter_view;
const struct vkd3d_shader_uav_counter_binding *counter_bindings = list->state->uav_counters;
for (k = 0; k < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; k++)
{
if ((list->state->uav_counter_mask & (1u << k)))
{
if (counter_bindings->register_space == range->register_space &&
counter_bindings->register_index == register_idx)
{
VkBufferView vk_counter_view = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV
? descriptor->u.view->vk_counter_view : VK_NULL_HANDLE;
if (bindings->vk_uav_counter_views[k] != vk_counter_view)
bindings->uav_counter_dirty_mask |= 1u << k;
bindings->vk_uav_counter_views[k] = vk_counter_view;
break;
}
counter_bindings++;
}
}
}
if (!vk_write_descriptor_set_from_d3d12_desc(current_descriptor_write,
@ -2841,7 +2853,7 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
const struct vkd3d_shader_uav_counter_binding *uav_counter = &state->uav_counters[i];
const VkBufferView *vk_uav_counter_views = bindings->vk_uav_counter_views;
assert(vk_uav_counter_views[uav_counter->register_index]);
assert(vk_uav_counter_views[uav_counter->counter_index]);
vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
vk_descriptor_writes[i].pNext = NULL;
@ -2852,7 +2864,7 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
vk_descriptor_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
vk_descriptor_writes[i].pImageInfo = NULL;
vk_descriptor_writes[i].pBufferInfo = NULL;
vk_descriptor_writes[i].pTexelBufferView = &vk_uav_counter_views[uav_counter->register_index];
vk_descriptor_writes[i].pTexelBufferView = &vk_uav_counter_views[uav_counter->counter_index];
}
VK_CALL(vkUpdateDescriptorSets(vk_device, uav_counter_count, vk_descriptor_writes, 0, NULL));

View File

@ -40,6 +40,28 @@ static const char *vkd3d_dlerror(void)
{
return dlerror();
}
#elif defined(_WIN32)
#include <windows.h>
static void *vkd3d_dlopen(const char *name)
{
return LoadLibraryA(name);
}
static void *vkd3d_dlsym(void *handle, const char *symbol)
{
return GetProcAddress(handle, symbol);
}
static int vkd3d_dlclose(void *handle)
{
FreeLibrary(handle);
return 0;
}
static const char *vkd3d_dlerror(void)
{
return "Not implemented for this platform.\n";
}
#else
static void *vkd3d_dlopen(const char *name)
{
@ -453,7 +475,7 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
bool *user_extension_supported = NULL;
VkApplicationInfo application_info;
VkInstanceCreateInfo instance_info;
char application_name[PATH_MAX];
char application_name[VKD3D_PATH_MAX];
uint32_t extension_count;
const char **extensions;
VkInstance vk_instance;

View File

@ -309,12 +309,6 @@ static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutB
= vk_descriptor_type_from_d3d12_range_type(descriptor_range->RangeType, is_buffer);
binding_desc->descriptorCount = 1;
if (descriptor_range->RegisterSpace)
{
FIXME("Unhandled register space %u.\n", descriptor_range->RegisterSpace);
return false;
}
binding_desc->stageFlags = stage_flags_from_visibility(shader_visibility);
binding_desc->pImmutableSamplers = NULL;
@ -510,6 +504,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
? push_constants[0].stageFlags : stage_flags_from_visibility(p->ShaderVisibility);
root_constant->offset = offset;
root_signature->root_constants[j].register_space = p->u.Constants.RegisterSpace;
root_signature->root_constants[j].register_index = p->u.Constants.ShaderRegister;
root_signature->root_constants[j].shader_visibility
= vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility);
@ -533,7 +528,7 @@ struct vkd3d_descriptor_set_context
};
static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_idx,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int register_idx,
bool buffer_descriptor, enum vkd3d_shader_visibility shader_visibility,
struct vkd3d_descriptor_set_context *context)
{
@ -541,6 +536,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
= &root_signature->descriptor_mapping[context->descriptor_index++];
mapping->type = descriptor_type;
mapping->register_space = register_space;
mapping->register_index = register_idx;
mapping->shader_visibility = shader_visibility;
mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
@ -549,7 +545,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
}
static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int base_register_idx,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int base_register_idx,
unsigned int binding_count, bool is_buffer_descriptor, bool duplicate_descriptors,
enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context)
{
@ -566,10 +562,10 @@ static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signat
{
if (duplicate_descriptors)
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
base_register_idx + i, true, shader_visibility, context);
register_space, base_register_idx + i, true, shader_visibility, context);
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
base_register_idx + i, is_buffer_descriptor, shader_visibility, context);
register_space, base_register_idx + i, is_buffer_descriptor, shader_visibility, context);
}
return first_binding;
}
@ -625,7 +621,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature,
vkd3d_descriptor_type_from_d3d12_range_type(range->RangeType),
range->BaseShaderRegister, range->NumDescriptors, false, true,
range->RegisterSpace, range->BaseShaderRegister, range->NumDescriptors, false, true,
vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context);
/* Unroll descriptor range. */
@ -658,6 +654,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
table->ranges[j].binding = vk_binding;
table->ranges[j].descriptor_magic = vkd3d_descriptor_magic_from_d3d12(range->RangeType);
table->ranges[j].base_register_idx = range->BaseShaderRegister;
table->ranges[j].register_space = range->RegisterSpace;
}
}
@ -691,7 +688,7 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType),
p->u.Descriptor.ShaderRegister, 1, true, false,
p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1, true, false,
vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context);
cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType);
cur_binding->descriptorCount = 1;
@ -728,7 +725,7 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa
return hr;
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->ShaderRegister, 1, false, false,
VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, 1, false, false,
vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context);
cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
cur_binding->descriptorCount = 1;
@ -1451,7 +1448,14 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel
if (!(shader_info->uav_counter_mask & (1u << i)))
continue;
/* UAV counters will lookup Vulkan bindings based on the mask index directly.
* We currently don't know the actual space/binding for this UAV,
* but register_space/register_index are fixed up later after compilation is finished. */
state->uav_counters[j].register_space = 0;
state->uav_counters[j].register_index = i;
state->uav_counters[j].counter_index = i;
state->uav_counters[j].shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
state->uav_counters[j].binding.set = context.set_index;
state->uav_counters[j].binding.binding = context.descriptor_binding;
@ -1507,6 +1511,10 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
struct vkd3d_shader_code dxbc;
HRESULT hr;
int ret;
unsigned int i, j;
unsigned int uav_counter_spaces[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS] = { 0 };
unsigned int uav_counter_bindings[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS] = { 0 };
struct vkd3d_shader_effective_uav_counter_binding_info uav_binding_info = { VKD3D_SHADER_STRUCTURE_TYPE_EFFECTIVE_UAV_COUNTER_BINDING_INFO };
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
state->refcount = 1;
@ -1550,8 +1558,14 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
shader_interface.uav_counters = state->uav_counters;
shader_interface.uav_counter_count = vkd3d_popcount(state->uav_counter_mask);
shader_interface.next = &uav_binding_info;
uav_binding_info.uav_register_spaces = uav_counter_spaces;
uav_binding_info.uav_register_bindings = uav_counter_bindings;
uav_binding_info.uav_counter_count = VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS;
vk_pipeline_layout = state->vk_pipeline_layout
? state->vk_pipeline_layout : root_signature->vk_pipeline_layout;
if (FAILED(hr = vkd3d_create_compute_pipeline(device, &desc->CS, &shader_interface,
vk_pipeline_layout, &state->u.compute.vk_pipeline)))
{
@ -1575,6 +1589,17 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
return hr;
}
/* Map back to actual space/bindings for the UAV counter now that we know. */
for (i = 0, j = 0; i < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; i++)
{
if (state->uav_counter_mask & (1u << i))
{
state->uav_counters[j].register_space = uav_counter_spaces[i];
state->uav_counters[j].register_index = uav_counter_bindings[i];
j++;
}
}
state->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
d3d12_device_add_ref(state->device = device);
@ -2911,6 +2936,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
binding.type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
binding.register_index = 0;
binding.register_space = 0;
binding.shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
binding.binding.set = 0;
binding.binding.binding = 0;
@ -2919,6 +2945,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
push_constant_range.offset = 0;
push_constant_range.size = sizeof(struct vkd3d_uav_clear_args);
push_constant.register_space = 0;
push_constant.register_index = 0;
push_constant.shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
push_constant.offset = 0;

View File

@ -861,7 +861,7 @@ HRESULT vkd3d_load_vk_device_procs(struct vkd3d_vk_device_procs *procs,
#if HAVE_DECL_PROGRAM_INVOCATION_NAME
bool vkd3d_get_program_name(char program_name[PATH_MAX])
bool vkd3d_get_program_name(char program_name[VKD3D_PATH_MAX])
{
char *name, *p, *real_path = NULL;
@ -887,15 +887,15 @@ bool vkd3d_get_program_name(char program_name[PATH_MAX])
name = program_invocation_name;
}
strncpy(program_name, name, PATH_MAX);
program_name[PATH_MAX - 1] = '\0';
strncpy(program_name, name, VKD3D_PATH_MAX);
program_name[VKD3D_PATH_MAX - 1] = '\0';
free(real_path);
return true;
}
#else
bool vkd3d_get_program_name(char program_name[PATH_MAX])
bool vkd3d_get_program_name(char program_name[VKD3D_PATH_MAX])
{
*program_name = '\0';
return false;

View File

@ -31,11 +31,11 @@
#include "vkd3d.h"
#include "vkd3d_shader.h"
#include "vkd3d_threads.h"
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <pthread.h>
#include <stdbool.h>
#define VK_CALL(f) (vk_procs->f)
@ -659,6 +659,7 @@ struct d3d12_root_descriptor_table_range
uint32_t descriptor_magic;
unsigned int base_register_idx;
unsigned int register_space;
};
struct d3d12_root_descriptor_table
@ -1328,16 +1329,13 @@ HRESULT vkd3d_load_vk_device_procs(struct vkd3d_vk_device_procs *procs,
extern const char vkd3d_build[];
bool vkd3d_get_program_name(char program_name[PATH_MAX]) DECLSPEC_HIDDEN;
static inline void vkd3d_set_thread_name(const char *name)
{
#if defined(HAVE_PTHREAD_SETNAME_NP_2)
pthread_setname_np(pthread_self(), name);
#elif defined(HAVE_PTHREAD_SETNAME_NP_1)
pthread_setname_np(name);
#ifdef _WIN32
/* This value isn't really used for anything useful on Windows, just need some kind of value. */
#define VKD3D_PATH_MAX _MAX_PATH
#else
#define VKD3D_PATH_MAX PATH_MAX
#endif
}
bool vkd3d_get_program_name(char program_name[VKD3D_PATH_MAX]) DECLSPEC_HIDDEN;
VkResult vkd3d_set_vk_object_name_utf8(struct d3d12_device *device, uint64_t vk_object,
VkDebugReportObjectTypeEXT vk_object_type, const char *name) DECLSPEC_HIDDEN;

View File

@ -25,6 +25,8 @@
static PFN_D3D12_CREATE_VERSIONED_ROOT_SIGNATURE_DESERIALIZER pfn_D3D12CreateVersionedRootSignatureDeserializer;
static PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE pfn_D3D12SerializeVersionedRootSignature;
PFN_D3D12_CREATE_DEVICE pfn_D3D12CreateDevice;
PFN_D3D12_GET_DEBUG_INTERFACE pfn_D3D12GetDebugInterface;
struct vec2
{
@ -32811,8 +32813,392 @@ static void test_write_buffer_immediate(void)
destroy_test_context(&context);
}
static void test_register_space_sm51(void)
{
ID3D12DescriptorHeap *heap, *sampler_heap, *heaps[2];
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
D3D12_ROOT_PARAMETER root_parameters[2];
ID3D12Resource *input_buffers[8];
ID3D12Resource* input_buffer_counter;
ID3D12Resource *textures[2];
struct resource_readback rb;
D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc;
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
ID3D12GraphicsCommandList *command_list;
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
unsigned int i, descriptor_size;
D3D12_SAMPLER_DESC sampler_desc;
D3D12_SUBRESOURCE_DATA data;
struct test_context context;
ID3D12CommandQueue *queue;
HRESULT hr;
unsigned int counter_value;
static const DWORD cs_code[] =
{
#if 0
cbuffer CBuf : register(b1, space1)
{
float4 cbuffer_data;
};
Buffer<float4> Buf : register(t1, space2);
ByteAddressBuffer AddrBuf : register(t1, space3);
StructuredBuffer<float4> StructuredBuf : register(t1, space4);
RWBuffer<float4> RWBuf : register(u1, space5);
RWByteAddressBuffer RWAddrBuf : register(u1, space6);
RWStructuredBuffer<float4> RWStructuredBuf : register(u1, space7);
RWStructuredBuffer<float4> RWStructuredBufResult : register(u1, space8);
Texture2D<float4> Tex : register(t1, space9);
RWTexture2D<float> RWTex : register(u1, space10);
SamplerState Samp : register(s1, space11);
[numthreads(1, 1, 1)]
void main()
{
float4 res = 1.0.xxxx;
res *= cbuffer_data;
res *= Buf[0];
res *= asfloat(AddrBuf.Load4(0));
res *= StructuredBuf[0];
res *= RWBuf[0];
res *= asfloat(RWAddrBuf.Load4(0));
res *= RWStructuredBuf[0];
res *= Tex.SampleLevel(Samp, float2(0.5, 0.5), 0.0).xxxx;
res *= RWTex[int2(0, 0)].xxxx;
RWStructuredBuf.IncrementCounter();
RWStructuredBufResult[0] = res;
}
#endif
0x43425844, 0x70f33bd3, 0x11527a3b, 0x08c5298b, 0x28a1f88e, 0x00000001, 0x00000434, 0x00000004,
0x00000030, 0x00000040, 0x00000050, 0x00000424, 0x4e475349, 0x00000008, 0x00000000, 0x00000008,
0x4e47534f, 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000003cc, 0x00050051, 0x000000f3,
0x0100086a, 0x07000059, 0x00308e46, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x0600005a, 0x00306e46, 0x00000000, 0x00000001, 0x00000001, 0x0000000b, 0x07000858, 0x00307e46,
0x00000000, 0x00000001, 0x00000001, 0x00005555, 0x00000002, 0x060000a1, 0x00307e46, 0x00000001,
0x00000001, 0x00000001, 0x00000003, 0x070000a2, 0x00307e46, 0x00000002, 0x00000001, 0x00000001,
0x00000010, 0x00000004, 0x07001858, 0x00307e46, 0x00000003, 0x00000001, 0x00000001, 0x00005555,
0x00000009, 0x0700089c, 0x0031ee46, 0x00000000, 0x00000001, 0x00000001, 0x00005555, 0x00000005,
0x0600009d, 0x0031ee46, 0x00000001, 0x00000001, 0x00000001, 0x00000006, 0x0780009e, 0x0031ee46,
0x00000002, 0x00000001, 0x00000001, 0x00000010, 0x00000007, 0x0700009e, 0x0031ee46, 0x00000003,
0x00000001, 0x00000001, 0x00000010, 0x00000008, 0x0700189c, 0x0031ee46, 0x00000004, 0x00000001,
0x00000001, 0x00005555, 0x0000000a, 0x02000068, 0x00000002, 0x0400009b, 0x00000001, 0x00000001,
0x00000001, 0x0b00002d, 0x001000f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00207e46, 0x00000000, 0x00000001, 0x09000038, 0x001000f2, 0x00000000, 0x00100e46,
0x00000000, 0x00308e46, 0x00000000, 0x00000001, 0x00000000, 0x080000a5, 0x001000f2, 0x00000001,
0x00004001, 0x00000000, 0x00207e46, 0x00000001, 0x00000001, 0x07000038, 0x001000f2, 0x00000000,
0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0a0000a7, 0x001000f2, 0x00000001, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x00207e46, 0x00000002, 0x00000001, 0x07000038, 0x001000f2,
0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0b0000a3, 0x001000f2, 0x00000001,
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0021ee46, 0x00000000, 0x00000001,
0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x080000a5,
0x001000f2, 0x00000001, 0x00004001, 0x00000000, 0x0021ee46, 0x00000001, 0x00000001, 0x07000038,
0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0a0000a7, 0x001000f2,
0x00000001, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x0021ee46, 0x00000002, 0x00000001,
0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x10000048,
0x00100012, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00207e46,
0x00000003, 0x00000001, 0x00206000, 0x00000000, 0x00000001, 0x00004001, 0x00000000, 0x07000038,
0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x0b0000a3, 0x00100012,
0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0021ee46, 0x00000004,
0x00000001, 0x07000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001,
0x060000b2, 0x00100012, 0x00000001, 0x0021e000, 0x00000002, 0x00000001, 0x0a0000a8, 0x0021e0f2,
0x00000003, 0x00000001, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x00100e46, 0x00000000,
0x0100003e, 0x30494653, 0x00000008, 0x00000800, 0x00000000,
};
static const D3D12_DESCRIPTOR_RANGE_TYPE range_types[] = {
/* CBV<> */
D3D12_DESCRIPTOR_RANGE_TYPE_CBV,
/* Buffer<> */
D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
/* ByteAddressBuffer<> */
D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
/* StructuredBuffer<> */
D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
/* RWBuffer<> */
D3D12_DESCRIPTOR_RANGE_TYPE_UAV,
/* RWByteAddressBuffer<> */
D3D12_DESCRIPTOR_RANGE_TYPE_UAV,
/* RWStructuredBuffer<> with atomic counter */
D3D12_DESCRIPTOR_RANGE_TYPE_UAV,
/* RWStructuredBuffer<> */
D3D12_DESCRIPTOR_RANGE_TYPE_UAV,
/* Texture<> */
D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
/* RWTexture<> */
D3D12_DESCRIPTOR_RANGE_TYPE_UAV,
/* SamplerState */
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
};
static const float buffer_data[ARRAY_SIZE(range_types) - 1][D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT / sizeof(float)] = {
{ 2.0f, 2.0f, 2.0f, 2.0f },
{ 3.0f, 3.0f, 3.0f, 3.0f },
{ 4.0f, 4.0f, 4.0f, 4.0f },
{ 5.0f, 5.0f, 5.0f, 5.0f },
{ 6.0f, 6.0f, 6.0f, 6.0f },
{ 7.0f, 7.0f, 7.0f, 7.0f },
{ 8.0f, 8.0f, 8.0f, 8.0f },
{ 9.0f, 9.0f, 9.0f, 9.0f },
{ 10.0f, 10.0f, 10.0f, 10.0f },
{ 11.0f, 11.0f, 11.0f, 11.0f },
};
static const uint8_t zero_data[D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT] = { 0 };
D3D12_DESCRIPTOR_RANGE descriptor_range[ARRAY_SIZE(range_types)];
if (!init_compute_test_context(&context))
return;
command_list = context.list;
queue = context.queue;
root_signature_desc.NumParameters = 2;
root_signature_desc.Flags = 0;
root_signature_desc.NumStaticSamplers = 0;
root_signature_desc.pStaticSamplers = NULL;
root_signature_desc.pParameters = root_parameters;
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[0].DescriptorTable.NumDescriptorRanges = ARRAY_SIZE(range_types) - 1;
root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range[0];
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_range[ARRAY_SIZE(range_types) - 1];
memset(descriptor_range, 0, sizeof(descriptor_range));
for (i = 0; i < ARRAY_SIZE(range_types); i++)
{
descriptor_range[i].NumDescriptors = 1;
descriptor_range[i].BaseShaderRegister = 1;
descriptor_range[i].RegisterSpace = i + 1;
descriptor_range[i].OffsetInDescriptorsFromTableStart = (i != ARRAY_SIZE(range_types) - 1) ? i : 0;
descriptor_range[i].RangeType = range_types[i];
}
hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
context.pipeline_state = create_compute_pipeline_state(context.device,
context.root_signature, shader_bytecode(cs_code, sizeof(cs_code)));
heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, ARRAY_SIZE(range_types) - 1);
sampler_heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1);
memset(&sampler_desc, 0, sizeof(sampler_desc));
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(sampler_heap);
ID3D12Device_CreateSampler(context.device, &sampler_desc, cpu_handle);
descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
/* CBV<> */
input_buffers[0] = create_default_buffer(context.device, sizeof(buffer_data[0]),
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
/* Buffer<> */
input_buffers[1] = create_default_buffer(context.device, sizeof(buffer_data[1]),
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
/* ByteAddressBuffer<> */
input_buffers[2] = create_default_buffer(context.device, sizeof(buffer_data[2]),
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
/* StructuredBuffer<> */
input_buffers[3] = create_default_buffer(context.device, sizeof(buffer_data[3]),
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
/* RWBuffer<> */
input_buffers[4] = create_default_buffer(context.device, sizeof(buffer_data[4]),
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
/* RWByteAddressBuffer<> */
input_buffers[5] = create_default_buffer(context.device, sizeof(buffer_data[5]),
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
/* RWStructuredBuffer<> with counter */
input_buffers[6] = create_default_buffer(context.device, sizeof(buffer_data[6]),
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
input_buffer_counter = create_default_buffer(context.device, sizeof(buffer_data[6]),
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
/* RWStructuredBuffer<> without counter */
input_buffers[7] = create_default_buffer(context.device, sizeof(buffer_data[7]),
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
textures[0] = create_default_texture2d(context.device, 1, 1, 1, 1, DXGI_FORMAT_R32_FLOAT, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
textures[1] = create_default_texture2d(context.device, 1, 1, 1, 1, DXGI_FORMAT_R32_FLOAT, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
/* CBV<> */
cbv_desc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(input_buffers[0]);
cbv_desc.SizeInBytes = sizeof(buffer_data[0]);
ID3D12Device_CreateConstantBufferView(context.device, &cbv_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* Buffer<> */
srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
srv_desc.Buffer.FirstElement = 0;
srv_desc.Buffer.NumElements = 1;
srv_desc.Buffer.StructureByteStride = 0;
ID3D12Device_CreateShaderResourceView(context.device, input_buffers[1], &srv_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* ByteAddressBuffer<> */
srv_desc.Format = DXGI_FORMAT_R32_TYPELESS;
srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
srv_desc.Buffer.FirstElement = 0;
srv_desc.Buffer.NumElements = 4;
srv_desc.Buffer.StructureByteStride = 0;
ID3D12Device_CreateShaderResourceView(context.device, input_buffers[2], &srv_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* StructuredBuffer<> */
srv_desc.Format = DXGI_FORMAT_UNKNOWN;
srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
srv_desc.Buffer.FirstElement = 0;
srv_desc.Buffer.NumElements = 1;
srv_desc.Buffer.StructureByteStride = 16;
ID3D12Device_CreateShaderResourceView(context.device, input_buffers[3], &srv_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* RWBuffer<> */
uav_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
uav_desc.Buffer.FirstElement = 0;
uav_desc.Buffer.NumElements = 1;
uav_desc.Buffer.StructureByteStride = 0;
uav_desc.Buffer.CounterOffsetInBytes = 0;
ID3D12Device_CreateUnorderedAccessView(context.device, input_buffers[4], NULL, &uav_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* RWByteAddressBuffer<> */
uav_desc.Format = DXGI_FORMAT_R32_TYPELESS;
uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
uav_desc.Buffer.StructureByteStride = 0;
uav_desc.Buffer.NumElements = 4;
ID3D12Device_CreateUnorderedAccessView(context.device, input_buffers[5], NULL, &uav_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* RWStructuredBuffer<> with counter */
uav_desc.Format = DXGI_FORMAT_UNKNOWN;
uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
uav_desc.Buffer.StructureByteStride = 16;
uav_desc.Buffer.NumElements = 1;
uav_desc.Buffer.CounterOffsetInBytes = 0;
ID3D12Device_CreateUnorderedAccessView(context.device, input_buffers[6], input_buffer_counter, &uav_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* RWStructuredBuffer<> without counter */
uav_desc.Format = DXGI_FORMAT_UNKNOWN;
uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
uav_desc.Buffer.StructureByteStride = 16;
uav_desc.Buffer.NumElements = 1;
uav_desc.Buffer.CounterOffsetInBytes = 0;
ID3D12Device_CreateUnorderedAccessView(context.device, input_buffers[7], NULL, &uav_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* Texture */
srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MipLevels = 1;
srv_desc.Texture2D.MostDetailedMip = 0;
srv_desc.Texture2D.PlaneSlice = 0;
srv_desc.Texture2D.ResourceMinLODClamp = 0;
ID3D12Device_CreateShaderResourceView(context.device, textures[0], &srv_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
/* RWTexture */
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
uav_desc.Format = DXGI_FORMAT_R32_FLOAT;
uav_desc.Texture2D.MipSlice = 0;
uav_desc.Texture2D.PlaneSlice = 0;
ID3D12Device_CreateUnorderedAccessView(context.device, textures[1], NULL, &uav_desc, cpu_handle);
for (i = 0; i < 8; i++)
{
upload_buffer_data(input_buffers[i], 0, sizeof(buffer_data[i]), buffer_data[i], queue, command_list);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, input_buffers[i], D3D12_RESOURCE_STATE_COPY_DEST,
i < 4 ? D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
for (i = 0; i < 2; i++)
{
D3D12_SUBRESOURCE_DATA sub;
sub.pData = buffer_data[8 + i];
sub.RowPitch = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT / 4;
sub.SlicePitch = 0;
upload_texture_data(textures[i], &sub, 1, queue, command_list);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, textures[i], D3D12_RESOURCE_STATE_COPY_DEST,
i == 0 ? D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
upload_buffer_data(input_buffer_counter, 0, sizeof(zero_data), zero_data, queue, command_list);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, input_buffer_counter, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_COPY_DEST);
ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
heaps[0] = heap; heaps[1] = sampler_heap;
ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps);
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 1,
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(sampler_heap));
ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
transition_resource_state(command_list, input_buffers[7], D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_COPY_DEST);
get_buffer_readback_with_command_list(input_buffers[7], DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
for (i = 0; i < 4; i++)
{
/* Start value of 9 is for the StructuredBuffer we write to. */
float reference = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 10 * 11;
ok(get_readback_float(&rb, i, 0) == reference, "Readback value is: %f\n", get_readback_float(&rb, i, 0));
}
release_resource_readback(&rb);
reset_command_list(command_list, context.allocator);
counter_value = read_uav_counter(&context, input_buffer_counter, 0);
ok(counter_value == 1, "Atomic counter is %u.\n", counter_value);
for (i = 0; i < 8; i++)
ID3D12Resource_Release(input_buffers[i]);
for (i = 0; i < 2; i++)
ID3D12Resource_Release(textures[i]);
ID3D12Resource_Release(input_buffer_counter);
ID3D12DescriptorHeap_Release(heap);
ID3D12DescriptorHeap_Release(sampler_heap);
destroy_test_context(&context);
}
START_TEST(d3d12)
{
pfn_D3D12CreateDevice = get_d3d12_pfn(D3D12CreateDevice);
pfn_D3D12GetDebugInterface = get_d3d12_pfn(D3D12GetDebugInterface);
parse_args(argc, argv);
enable_d3d12_debug_layer(argc, argv);
init_adapter_info();
@ -32975,4 +33361,5 @@ START_TEST(d3d12)
run_test(test_conditional_rendering);
run_test(test_bufinfo_instruction);
run_test(test_write_buffer_immediate);
run_test(test_register_space_sm51);
}

View File

@ -52,17 +52,24 @@ typedef int HRESULT;
#include <math.h>
#include <time.h>
#ifdef _WIN32
#if defined(_WIN32) && !defined(VKD3D_FORCE_UTILS_WRAPPER)
# include "vkd3d_dxgi1_4.h"
#else
# include <pthread.h>
# include "vkd3d_threads.h"
# include "vkd3d.h"
# include "vkd3d_utils.h"
#endif
#if !defined(_WIN32)
#include <dlfcn.h>
#endif
#include "d3d12_test_utils.h"
#ifdef _WIN32
extern PFN_D3D12_CREATE_DEVICE pfn_D3D12CreateDevice;
extern PFN_D3D12_GET_DEBUG_INTERFACE pfn_D3D12GetDebugInterface;
#if defined(_WIN32) && !defined(VKD3D_FORCE_UTILS_WRAPPER)
static inline HANDLE create_event(void)
{
return CreateEventA(NULL, FALSE, FALSE, NULL);
@ -86,7 +93,10 @@ static inline void destroy_event(HANDLE event)
#define get_d3d12_pfn(name) get_d3d12_pfn_(#name)
static inline void *get_d3d12_pfn_(const char *name)
{
return GetProcAddress(GetModuleHandleA("d3d12.dll"), name);
static HMODULE d3d12_module;
if (!d3d12_module)
d3d12_module = LoadLibraryA("d3d12.dll");
return GetProcAddress(d3d12_module, name);
}
#else
#define INFINITE VKD3D_INFINITE
@ -124,7 +134,7 @@ struct test_thread_data
void *user_data;
};
#ifdef _WIN32
#if defined(_WIN32) && !defined(VKD3D_FORCE_UTILS_WRAPPER)
static inline DWORD WINAPI test_thread_main(void *untyped_data)
{
struct test_thread_data *data = untyped_data;
@ -242,7 +252,7 @@ static void wait_queue_idle_(unsigned int line, ID3D12Device *device, ID3D12Comm
static bool use_warp_device;
static unsigned int use_adapter_idx;
#ifdef _WIN32
#if defined(_WIN32) && !defined(VKD3D_FORCE_UTILS_WRAPPER)
static IUnknown *create_warp_adapter(IDXGIFactory4 *factory)
{
IUnknown *adapter;
@ -289,7 +299,7 @@ static ID3D12Device *create_device(void)
return NULL;
}
hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
hr = pfn_D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
if (adapter)
IUnknown_Release(adapter);
@ -401,7 +411,39 @@ static inline bool is_depth_clip_enable_supported(ID3D12Device *device)
#else
static bool check_device_extension(VkPhysicalDevice vk_physical_device, const char *name)
static PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr;
static bool init_vulkan_loader(void)
{
if (pfn_vkGetInstanceProcAddr)
return true;
#ifdef _WIN32
HMODULE mod = LoadLibrary(SONAME_LIBVULKAN);
if (!mod)
return false;
pfn_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetProcAddress(mod, "vkGetInstanceProcAddr");
#else
void *mod = dlopen(SONAME_LIBVULKAN, RTLD_LAZY);
if (!mod)
return false;
pfn_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(mod, "vkGetInstanceProcAddr");
#endif
return pfn_vkGetInstanceProcAddr != NULL;
}
#define get_vk_instance_proc(instance, sym) (PFN_##sym)get_vk_instance_proc_(instance, #sym)
static PFN_vkVoidFunction get_vk_instance_proc_(VkInstance instance, const char *sym)
{
if (!init_vulkan_loader())
return NULL;
return pfn_vkGetInstanceProcAddr(instance, sym);
}
static bool check_device_extension(VkInstance instance, VkPhysicalDevice vk_physical_device, const char *name)
{
VkExtensionProperties *properties;
bool ret = false;
@ -409,7 +451,12 @@ static bool check_device_extension(VkPhysicalDevice vk_physical_device, const ch
uint32_t count;
VkResult vr;
vr = vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, NULL);
PFN_vkEnumerateDeviceExtensionProperties pfn_vkEnumerateDeviceExtensionProperties;
pfn_vkEnumerateDeviceExtensionProperties = get_vk_instance_proc(instance, vkEnumerateDeviceExtensionProperties);
if (!pfn_vkEnumerateDeviceExtensionProperties)
return false;
vr = pfn_vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, NULL);
ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
if (!count)
return false;
@ -417,7 +464,7 @@ static bool check_device_extension(VkPhysicalDevice vk_physical_device, const ch
properties = calloc(count, sizeof(*properties));
ok(properties, "Failed to allocate memory.\n");
vr = vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, properties);
vr = pfn_vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, properties);
ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
for (i = 0; i < count; ++i)
{
@ -463,10 +510,14 @@ static VkPhysicalDevice select_physical_device(struct vkd3d_instance *instance)
VkInstance vk_instance;
uint32_t count;
VkResult vr;
PFN_vkEnumeratePhysicalDevices pfn_vkEnumeratePhysicalDevices;
vk_instance = vkd3d_instance_get_vk_instance(instance);
vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
pfn_vkEnumeratePhysicalDevices = get_vk_instance_proc(vk_instance, vkEnumeratePhysicalDevices);
if (!pfn_vkEnumeratePhysicalDevices)
return VK_NULL_HANDLE;
vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
if (use_adapter_idx >= count)
@ -477,7 +528,7 @@ static VkPhysicalDevice select_physical_device(struct vkd3d_instance *instance)
vk_physical_devices = calloc(count, sizeof(*vk_physical_devices));
ok(vk_physical_devices, "Failed to allocate memory.\n");
vr = vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
vk_physical_device = vk_physical_devices[use_adapter_idx];
@ -537,19 +588,24 @@ static bool get_driver_properties(ID3D12Device *device, VkPhysicalDeviceDriverPr
PFN_vkGetPhysicalDeviceProperties2KHR pfn_vkGetPhysicalDeviceProperties2KHR;
VkPhysicalDeviceProperties2 device_properties2;
VkPhysicalDevice vk_physical_device;
VkInstance vk_instance;
memset(driver_properties, 0, sizeof(*driver_properties));
driver_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
vk_physical_device = vkd3d_get_vk_physical_device(device);
vk_instance = vkd3d_instance_get_vk_instance(vkd3d_instance_from_device(device));
if (check_device_extension(vk_physical_device, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME))
if (!init_vulkan_loader())
return false;
if (check_device_extension(vk_instance, vk_physical_device, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME))
{
struct vkd3d_instance *instance = vkd3d_instance_from_device(device);
VkInstance vk_instance = vkd3d_instance_get_vk_instance(instance);
pfn_vkGetPhysicalDeviceProperties2KHR
= (void *)vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2KHR");
= (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2KHR");
ok(pfn_vkGetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2KHR is NULL.\n");
memset(&device_properties2, 0, sizeof(device_properties2));
@ -628,8 +684,10 @@ static inline bool is_radv_device(ID3D12Device *device)
static inline bool is_depth_clip_enable_supported(ID3D12Device *device)
{
struct vkd3d_instance *instance = vkd3d_instance_from_device(device);
VkInstance vk_instance = vkd3d_instance_get_vk_instance(instance);
VkPhysicalDevice vk_physical_device = vkd3d_get_vk_physical_device(device);
return check_device_extension(vk_physical_device, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
return check_device_extension(vk_instance, vk_physical_device, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
}
#endif
@ -663,7 +721,7 @@ static void enable_d3d12_debug_layer(int argc, char **argv)
if (enable_gpu_based_validation)
{
if (SUCCEEDED(D3D12GetDebugInterface(&IID_ID3D12Debug1, (void **)&debug1)))
if (SUCCEEDED(pfn_D3D12GetDebugInterface(&IID_ID3D12Debug1, (void **)&debug1)))
{
ID3D12Debug1_SetEnableGPUBasedValidation(debug1, true);
ID3D12Debug1_Release(debug1);
@ -675,7 +733,7 @@ static void enable_d3d12_debug_layer(int argc, char **argv)
}
}
if (enable_debug_layer && SUCCEEDED(D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug)))
if (enable_debug_layer && SUCCEEDED(pfn_D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug)))
{
ID3D12Debug_EnableDebugLayer(debug);
ID3D12Debug_Release(debug);