Commit 75ab8431 authored by Alexandre Julliard's avatar Alexandre Julliard

vkd3d: Import upstream release 1.7.

parent 3149d272
......@@ -2240,6 +2240,7 @@ interface ID3D12CommandQueue : ID3D12Pageable
void UpdateTileMappings(ID3D12Resource *resource, UINT region_count,
const D3D12_TILED_RESOURCE_COORDINATE *region_start_coordinates,
const D3D12_TILE_REGION_SIZE *region_sizes,
ID3D12Heap *heap,
UINT range_count,
const D3D12_TILE_RANGE_FLAGS *range_flags,
UINT *heap_range_offsets,
......
......@@ -186,6 +186,30 @@ static inline void list_move_tail( struct list *dst, struct list *src )
list_move_before( dst, src );
}
/* move the slice of elements from begin to end inclusive to the head of dst */
static inline void list_move_slice_head( struct list *dst, struct list *begin, struct list *end )
{
struct list *dst_next = dst->next;
begin->prev->next = end->next;
end->next->prev = begin->prev;
dst->next = begin;
dst_next->prev = end;
begin->prev = dst;
end->next = dst_next;
}
/* move the slice of elements from begin to end inclusive to the tail of dst */
static inline void list_move_slice_tail( struct list *dst, struct list *begin, struct list *end )
{
struct list *dst_prev = dst->prev;
begin->prev->next = end->next;
end->next->prev = begin->prev;
dst_prev->next = begin;
dst->prev = end;
begin->prev = dst_prev;
end->next = dst;
}
/* iterate through the list */
#define LIST_FOR_EACH(cursor,list) \
for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
......
......@@ -8,6 +8,7 @@ Chip Davis
Conor McCarthy
David Gow
Derek Lesho
Fabian Maurer
Francisco Casas
Francois Gouget
Giovanni Mascellani
......
Copyright 2016-2022 the Vkd3d project authors (see the file AUTHORS for a
Copyright 2016-2023 the Vkd3d project authors (see the file AUTHORS for a
complete list)
Vkd3d is free software; you can redistribute it and/or modify it under
......
......@@ -34,6 +34,18 @@
extern "C" {
#endif /* __cplusplus */
/**
* \file vkd3d.h
*
* This file contains definitions for the vkd3d library.
*
* The vkd3d library is a 3D graphics library built on top of
* Vulkan. It has an API very similar, but not identical, to
* Direct3D 12.
*
* \since 1.0
*/
enum vkd3d_structure_type
{
/* 1.0 */
......@@ -63,6 +75,7 @@ enum vkd3d_api_version
VKD3D_API_VERSION_1_4,
VKD3D_API_VERSION_1_5,
VKD3D_API_VERSION_1_6,
VKD3D_API_VERSION_1_7,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_API_VERSION),
};
......
......@@ -210,13 +210,6 @@ struct vkd3d_shader_sm1_parser
const uint32_t *start, *end;
bool abort;
struct vkd3d_shader_src_param src_rel_addr[4];
struct vkd3d_shader_src_param pred_rel_addr;
struct vkd3d_shader_src_param dst_rel_addr;
struct vkd3d_shader_src_param src_param[4];
struct vkd3d_shader_src_param pred_param;
struct vkd3d_shader_dst_param dst_param;
struct vkd3d_shader_parser p;
};
......@@ -556,33 +549,50 @@ static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
shader_instruction_array_destroy(&parser->instructions);
free_shader_desc(&sm1->p.shader_desc);
vkd3d_free(sm1);
}
static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
struct vkd3d_shader_src_param *src_param, struct vkd3d_shader_src_param *src_rel_addr)
struct vkd3d_shader_src_param *src_param)
{
struct vkd3d_shader_src_param *src_rel_addr = NULL;
uint32_t token, addr_token;
shader_sm1_read_param(sm1, ptr, &token, &addr_token);
if (has_relative_address(token))
{
if (!(src_rel_addr = shader_parser_get_src_params(&sm1->p, 1)))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Out of memory.");
sm1->abort = true;
return;
}
shader_sm1_parse_src_param(addr_token, NULL, src_rel_addr);
else
src_rel_addr = NULL;
}
shader_sm1_parse_src_param(token, src_rel_addr, src_param);
}
static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
struct vkd3d_shader_dst_param *dst_param, struct vkd3d_shader_src_param *dst_rel_addr)
struct vkd3d_shader_dst_param *dst_param)
{
struct vkd3d_shader_src_param *dst_rel_addr = NULL;
uint32_t token, addr_token;
shader_sm1_read_param(sm1, ptr, &token, &addr_token);
if (has_relative_address(token))
{
if (!(dst_rel_addr = shader_parser_get_src_params(&sm1->p, 1)))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Out of memory.");
sm1->abort = true;
return;
}
shader_sm1_parse_src_param(addr_token, NULL, dst_rel_addr);
else
dst_rel_addr = NULL;
}
shader_sm1_parse_dst_param(token, dst_rel_addr, dst_param);
}
......@@ -731,10 +741,13 @@ static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1,
static void shader_sm1_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins)
{
struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
struct vkd3d_shader_src_param *src_params, *predicate;
const struct vkd3d_sm1_opcode_info *opcode_info;
struct vkd3d_shader_dst_param *dst_param;
const uint32_t **ptr = &parser->ptr;
uint32_t opcode_token;
const uint32_t *p;
bool predicated;
unsigned int i;
shader_sm1_read_comment(sm1);
......@@ -761,11 +774,18 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_parser *parser, stru
ins->coissue = opcode_token & VKD3D_SM1_COISSUE;
ins->raw = false;
ins->structured = false;
ins->predicate = opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED ? &sm1->pred_param : NULL;
predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED);
ins->predicate = predicate = predicated ? shader_parser_get_src_params(parser, 1) : NULL;
ins->dst_count = opcode_info->dst_count;
ins->dst = &sm1->dst_param;
ins->dst = dst_param = shader_parser_get_dst_params(parser, ins->dst_count);
ins->src_count = opcode_info->src_count;
ins->src = sm1->src_param;
ins->src = src_params = shader_parser_get_src_params(parser, ins->src_count);
if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count))
{
vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
goto fail;
}
ins->resource_type = VKD3D_SHADER_RESOURCE_NONE;
ins->resource_stride = 0;
ins->resource_data_type[0] = VKD3D_DATA_FLOAT;
......@@ -790,32 +810,32 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_parser *parser, stru
}
else if (ins->handler_idx == VKD3DSIH_DEF)
{
shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr);
shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT);
shader_sm1_read_dst_param(sm1, &p, dst_param);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT);
}
else if (ins->handler_idx == VKD3DSIH_DEFB)
{
shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr);
shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT);
shader_sm1_read_dst_param(sm1, &p, dst_param);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT);
}
else if (ins->handler_idx == VKD3DSIH_DEFI)
{
shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr);
shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT);
shader_sm1_read_dst_param(sm1, &p, dst_param);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT);
}
else
{
/* Destination token */
if (ins->dst_count)
shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr);
shader_sm1_read_dst_param(sm1, &p, dst_param);
/* Predication token */
if (ins->predicate)
shader_sm1_read_src_param(sm1, &p, &sm1->pred_param, &sm1->pred_rel_addr);
shader_sm1_read_src_param(sm1, &p, predicate);
/* Other source tokens */
for (i = 0; i < ins->src_count; ++i)
shader_sm1_read_src_param(sm1, &p, &sm1->src_param[i], &sm1->src_rel_addr[i]);
shader_sm1_read_src_param(sm1, &p, &src_params[i]);
}
if (sm1->abort)
......@@ -851,20 +871,9 @@ static bool shader_sm1_is_end(struct vkd3d_shader_parser *parser)
return false;
}
static void shader_sm1_reset(struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
parser->ptr = sm1->start;
parser->failed = false;
}
const struct vkd3d_shader_parser_ops shader_sm1_parser_ops =
{
.parser_reset = shader_sm1_reset,
.parser_destroy = shader_sm1_destroy,
.parser_read_instruction = shader_sm1_read_instruction,
.parser_is_end = shader_sm1_is_end,
};
static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
......@@ -922,7 +931,10 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
sm1->start = &code[1];
sm1->end = &code[token_count];
vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name, &version, &shader_sm1_parser_ops);
/* Estimate instruction count to avoid reallocation in most shaders. */
if (!vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name, &version, &shader_sm1_parser_ops,
code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
return VKD3D_ERROR_OUT_OF_MEMORY;
shader_desc = &sm1->p.shader_desc;
shader_desc->byte_code = code;
shader_desc->byte_code_size = code_size;
......@@ -934,6 +946,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
{
struct vkd3d_shader_instruction_array *instructions;
struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_sm1_parser *sm1;
int ret;
......@@ -950,6 +964,28 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
return ret;
}
instructions = &sm1->p.instructions;
while (!shader_sm1_is_end(&sm1->p))
{
if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
{
ERR("Failed to allocate instructions.\n");
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
shader_sm1_destroy(&sm1->p);
return VKD3D_ERROR_OUT_OF_MEMORY;
}
ins = &instructions->elements[instructions->count];
shader_sm1_read_instruction(&sm1->p, ins);
if (ins->handler_idx == VKD3DSIH_INVALID)
{
WARN("Encountered unrecognized or invalid instruction.\n");
shader_sm1_destroy(&sm1->p);
return VKD3D_ERROR_INVALID_SHADER;
}
++instructions->count;
}
*parser = &sm1->p;
return VKD3D_OK;
......
......@@ -22,7 +22,7 @@ struct vkd3d_glsl_generator
{
struct vkd3d_shader_version version;
struct vkd3d_string_buffer buffer;
const struct vkd3d_shader_location *location;
struct vkd3d_shader_location location;
struct vkd3d_shader_message_context *message_context;
bool failed;
};
......@@ -38,7 +38,7 @@ struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shad
memset(generator, 0, sizeof(*generator));
generator->version = *version;
vkd3d_string_buffer_init(&generator->buffer);
generator->location = location;
generator->location = *location;
generator->message_context = message_context;
return generator;
}
......@@ -50,7 +50,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error(
va_list args;
va_start(args, fmt);
vkd3d_shader_verror(generator->message_context, generator->location, error, fmt, args);
vkd3d_shader_verror(generator->message_context, &generator->location, error, fmt, args);
va_end(args);
generator->failed = true;
}
......@@ -93,28 +93,20 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator
int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *out)
{
unsigned int i;
void *code;
struct vkd3d_shader_instruction ins;
vkd3d_string_buffer_printf(&generator->buffer, "#version 440\n\n");
vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n");
while (!vkd3d_shader_parser_is_end(parser))
generator->location.column = 0;
for (i = 0; i < parser->instructions.count; ++i)
{
vkd3d_shader_parser_read_instruction(parser, &ins);
if (ins.handler_idx == VKD3DSIH_INVALID)
{
vkd3d_glsl_compiler_error(generator,
VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Encountered unrecognized or invalid instruction.");
break;
}
vkd3d_glsl_handle_instruction(generator, &ins);
generator->location.line = i + 1;
vkd3d_glsl_handle_instruction(generator, &parser->instructions.elements[i]);
}
if (parser->failed || generator->failed)
if (generator->failed)
return VKD3D_ERROR_INVALID_SHADER;
vkd3d_string_buffer_printf(&generator->buffer, "}\n");
......
......@@ -181,7 +181,7 @@ row_major {return KW_ROW_MAJOR; }
yylval->name = hlsl_strdup(ctx, yytext);
if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext))
return VAR_IDENTIFIER;
else if (hlsl_get_type(ctx->cur_scope, yytext, true))
else if (hlsl_get_type(ctx->cur_scope, yytext, true, true))
return TYPE_IDENTIFIER;
else
return NEW_IDENTIFIER;
......@@ -233,14 +233,14 @@ row_major {return KW_ROW_MAJOR; }
struct hlsl_ctx *ctx = yyget_extra(yyscanner);
TRACE("#pragma setting row_major mode.\n");
ctx->matrix_majority = HLSL_ROW_MAJOR;
ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR;
BEGIN(pp_ignore);
}
<pp_pragma>pack_matrix{WS}*\({WS}*column_major{WS}*\) {
struct hlsl_ctx *ctx = yyget_extra(yyscanner);
TRACE("#pragma setting column_major mode.\n");
ctx->matrix_majority = HLSL_COLUMN_MAJOR;
ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR;
BEGIN(pp_ignore);
}
<pp_pragma>{NEWLINE} {
......
......@@ -509,6 +509,8 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
if (instr->type != HLSL_IR_EXPR)
return false;
expr = hlsl_ir_expr(instr);
if (!expr->operands[0].node)
return false;
if (instr->data_type->type > HLSL_CLASS_VECTOR)
return false;
......@@ -601,7 +603,7 @@ bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
{
struct hlsl_ir_constant *value, *res;
struct hlsl_ir_swizzle *swizzle;
unsigned int i, swizzle_bits;
unsigned int i;
if (instr->type != HLSL_IR_SWIZZLE)
return false;
......@@ -613,12 +615,8 @@ bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
if (!(res = hlsl_new_constant(ctx, instr->data_type, &instr->loc)))
return false;
swizzle_bits = swizzle->swizzle;
for (i = 0; i < swizzle->node.data_type->dimx; ++i)
{
res->value[i] = value->value[swizzle_bits & 3];
swizzle_bits >>= 2;
}
res->value[i] = value->value[hlsl_swizzle_get_component(swizzle->swizzle, i)];
list_add_before(&swizzle->node.entry, &res->node.entry);
hlsl_replace_node(&swizzle->node, &res->node);
......
......@@ -56,6 +56,9 @@
#define VKD3D_SM4_RESOURCE_TYPE_SHIFT 11
#define VKD3D_SM4_RESOURCE_TYPE_MASK (0xfu << VKD3D_SM4_RESOURCE_TYPE_SHIFT)
#define VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT 16
#define VKD3D_SM4_RESOURCE_SAMPLE_COUNT_MASK (0xfu << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT)
#define VKD3D_SM4_PRIMITIVE_TYPE_SHIFT 11
#define VKD3D_SM4_PRIMITIVE_TYPE_MASK (0x3fu << VKD3D_SM4_PRIMITIVE_TYPE_SHIFT)
......
......@@ -206,7 +206,7 @@ static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_
#define VKD3D_SPIRV_VERSION 0x00010000
#define VKD3D_SPIRV_GENERATOR_ID 18
#define VKD3D_SPIRV_GENERATOR_VERSION 6
#define VKD3D_SPIRV_GENERATOR_VERSION 7
#define VKD3D_SPIRV_GENERATOR_MAGIC vkd3d_make_u32(VKD3D_SPIRV_GENERATOR_VERSION, VKD3D_SPIRV_GENERATOR_ID)
struct vkd3d_spirv_stream
......@@ -1767,7 +1767,7 @@ static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const
rb_init(&builder->declarations, vkd3d_spirv_declaration_compare);
builder->main_function_id = vkd3d_spirv_alloc_id(builder);
vkd3d_spirv_build_op_name(builder, builder->main_function_id, entry_point);
vkd3d_spirv_build_op_name(builder, builder->main_function_id, "%s", entry_point);
}
static void vkd3d_spirv_builder_begin_main_function(struct vkd3d_spirv_builder *builder)
......@@ -2223,7 +2223,7 @@ struct spirv_compiler
struct vkd3d_spirv_builder spirv_builder;
struct vkd3d_shader_message_context *message_context;
const struct vkd3d_shader_location *location;
struct vkd3d_shader_location location;
bool failed;
bool strip_debug;
......@@ -2285,6 +2285,7 @@ struct spirv_compiler
struct vkd3d_shader_spec_constant *spec_constants;
size_t spec_constants_size;
enum vkd3d_shader_compile_option_formatting_flags formatting;
bool write_tess_geom_point_size;
struct vkd3d_string_buffer_cache string_buffers;
};
......@@ -2322,7 +2323,7 @@ struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *
memset(compiler, 0, sizeof(*compiler));
compiler->message_context = message_context;
compiler->location = location;
compiler->location = *location;
if ((target_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO)))
{
......@@ -2351,6 +2352,7 @@ struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *
compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT
| VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER;
compiler->write_tess_geom_point_size = true;
for (i = 0; i < compile_info->option_count; ++i)
{
......@@ -2389,6 +2391,10 @@ struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *
else
WARN("Ignoring unrecognised value %#x for option %#x.\n", option->value, option->name);
break;
case VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE:
compiler->write_tess_geom_point_size = option->value;
break;
}
}
......@@ -2560,7 +2566,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_error(struct spirv_compiler *
va_list args;
va_start(args, format);
vkd3d_shader_verror(compiler->message_context, compiler->location, error, format, args);
vkd3d_shader_verror(compiler->message_context, &compiler->location, error, format, args);
va_end(args);
compiler->failed = true;
}
......@@ -6348,10 +6354,18 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler)
/* Set the point size. Point sprites are not supported in d3d10+, but
* point primitives can still be used with e.g. stream output. Vulkan
* requires the point size to always be explicitly defined when outputting
* points. */
* points.
*
* If shaderTessellationAndGeometryPointSize is disabled, we must not write
* PointSize for tessellation and geometry shaders. In that case the point
* size defaults to 1.0. */
if (spirv_compiler_is_opengl_target(compiler) || compiler->shader_type == VKD3D_SHADER_TYPE_VERTEX
|| compiler->write_tess_geom_point_size)
{
vkd3d_spirv_build_op_store(&compiler->spirv_builder,
spirv_compiler_emit_builtin_variable(compiler, &point_size, SpvStorageClassOutput, 0),
spirv_compiler_get_constant_float(compiler, 1.0f), SpvMemoryAccessMaskNone);
}
}
static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compiler,
......@@ -9577,7 +9591,7 @@ static bool is_dcl_instruction(enum vkd3d_shader_opcode handler_idx)
|| handler_idx == VKD3DSIH_HS_DECLS;
}
int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
int ret = VKD3D_OK;
......@@ -9934,12 +9948,24 @@ int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
}
int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv)
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_parser *parser,
struct vkd3d_shader_code *spirv)
{
const struct vkd3d_shader_instruction_array *instructions = &parser->instructions;
const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info;
const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_phase *phase;
enum vkd3d_result result = VKD3D_OK;
unsigned int i;
compiler->location.column = 0;
for (i = 0; i < instructions->count; ++i)
{
compiler->location.line = i + 1;
if ((result = spirv_compiler_handle_instruction(compiler, &instructions->elements[i])) < 0)
return result;
}
if ((phase = spirv_compiler_get_current_shader_phase(compiler)))
spirv_compiler_leave_shader_phase(compiler, phase);
......
......@@ -663,8 +663,14 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler,
shader_addline(buffer, "_resource_");
shader_dump_resource_type(compiler, semantic->resource_type);
if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS
|| semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY)
{
shader_addline(buffer, "(%u)", semantic->sample_count);
}
if (semantic->resource.reg.reg.type == VKD3DSPR_UAV)
shader_dump_uav_flags(compiler, flags);
shader_addline(buffer, " ");
shader_dump_data_type(compiler, semantic->resource_data_type);
}
else
......@@ -1859,7 +1865,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser,
struct vkd3d_d3d_asm_compiler compiler;
enum vkd3d_result result = VKD3D_OK;
struct vkd3d_string_buffer *buffer;
unsigned int indent, i;
unsigned int indent, i, j;
const char *indent_str;
void *code;
......@@ -1920,26 +1926,17 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser,
shader_version->minor, compiler.colours.reset);
indent = 0;
vkd3d_shader_parser_reset(parser);
while (!vkd3d_shader_parser_is_end(parser))
for (i = 0; i < parser->instructions.count; ++i)
{
struct vkd3d_shader_instruction ins;
struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i];
vkd3d_shader_parser_read_instruction(parser, &ins);
if (ins.handler_idx == VKD3DSIH_INVALID)
{
WARN("Skipping unrecognized instruction.\n");
vkd3d_string_buffer_printf(buffer, "<unrecognized instruction>\n");
result = VKD3D_ERROR;
continue;
}
switch (ins.handler_idx)
switch (ins->handler_idx)
{
case VKD3DSIH_ELSE:
case VKD3DSIH_ENDIF:
case VKD3DSIH_ENDLOOP:
case VKD3DSIH_ENDSWITCH:
if (indent)
--indent;
break;
......@@ -1947,14 +1944,14 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser,
break;
}
for (i = 0; i < indent; ++i)
for (j = 0; j < indent; ++j)
{
vkd3d_string_buffer_printf(buffer, "%s", indent_str);
}
shader_dump_instruction(&compiler, &ins);
shader_dump_instruction(&compiler, ins);
switch (ins.handler_idx)
switch (ins->handler_idx)
{
case VKD3DSIH_ELSE:
case VKD3DSIH_IF:
......@@ -1968,9 +1965,6 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser,
}
}
if (parser->failed)
result = VKD3D_ERROR_INVALID_SHADER;
if ((code = vkd3d_malloc(buffer->content_size)))
{
memcpy(code, buffer->buffer, buffer->content_size);
......
......@@ -425,9 +425,10 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
shader_get_source_type_suffix(source_type), shader->code, shader->size);
}
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
struct vkd3d_shader_message_context *message_context, const char *source_name,
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops)
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
unsigned int instruction_reserve)
{
parser->message_context = message_context;
parser->location.source_name = source_name;
......@@ -435,6 +436,7 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
parser->location.column = 0;
parser->shader_version = *version;
parser->ops = ops;
return shader_instruction_array_init(&parser->instructions, instruction_reserve);
}
void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
......@@ -1053,9 +1055,10 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_instruction *instruction;
struct vkd3d_shader_scan_context context;
int ret;
int ret = VKD3D_OK;
unsigned int i;
if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO)))
{
......@@ -1068,33 +1071,19 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
if (TRACE_ON())
{
vkd3d_shader_trace(parser);
vkd3d_shader_parser_reset(parser);
}
while (!vkd3d_shader_parser_is_end(parser))
for (i = 0; i < parser->instructions.count; ++i)
{
vkd3d_shader_parser_read_instruction(parser, &instruction);
if (instruction.handler_idx == VKD3DSIH_INVALID)
instruction = &parser->instructions.elements[i];
if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0)
{
WARN("Encountered unrecognized or invalid instruction.\n");
if (scan_descriptor_info)
vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
ret = VKD3D_ERROR_INVALID_SHADER;
goto done;
}
if ((ret = vkd3d_shader_scan_instruction(&context, &instruction)) < 0)
{
if (scan_descriptor_info)
vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
goto done;
break;
}
}
ret = parser->failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK;
done:
vkd3d_shader_scan_context_cleanup(&context);
return ret;
}
......@@ -1182,7 +1171,6 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
{
struct vkd3d_shader_scan_descriptor_info scan_descriptor_info;
struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_compile_info scan_info;
struct spirv_compiler *spirv_compiler;
struct vkd3d_shader_parser *parser;
......@@ -1243,26 +1231,7 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
return VKD3D_ERROR;
}
while (!vkd3d_shader_parser_is_end(parser))
{
vkd3d_shader_parser_read_instruction(parser, &instruction);
if (instruction.handler_idx == VKD3DSIH_INVALID)
{
WARN("Encountered unrecognized or invalid instruction.\n");
ret = VKD3D_ERROR_INVALID_SHADER;
break;
}
if ((ret = spirv_compiler_handle_instruction(spirv_compiler, &instruction)) < 0)
break;
}
if (parser->failed)
ret = VKD3D_ERROR_INVALID_SHADER;
if (ret >= 0)
ret = spirv_compiler_generate_spirv(spirv_compiler, compile_info, out);
ret = spirv_compiler_generate_spirv(spirv_compiler, compile_info, parser, out);
spirv_compiler_destroy(spirv_compiler);
vkd3d_shader_parser_destroy(parser);
......@@ -1431,7 +1400,7 @@ int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
*messages = NULL;
vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO);
ret = shader_parse_input_signature(dxbc->code, dxbc->size, &message_context, signature);
ret = shader_parse_input_signature(dxbc, &message_context, signature);
vkd3d_shader_message_context_trace_messages(&message_context);
if (!vkd3d_shader_message_context_copy_messages(&message_context, messages))
ret = VKD3D_ERROR_OUT_OF_MEMORY;
......@@ -1581,3 +1550,106 @@ void vkd3d_shader_set_log_callback(PFN_vkd3d_log callback)
{
vkd3d_dbg_set_log_callback(callback);
}
static struct vkd3d_shader_param_node *shader_param_allocator_node_create(
struct vkd3d_shader_param_allocator *allocator)
{
struct vkd3d_shader_param_node *node;
if (!(node = vkd3d_malloc(offsetof(struct vkd3d_shader_param_node, param[allocator->count * allocator->stride]))))
return NULL;
node->next = NULL;
return node;
}
static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator,
unsigned int count, unsigned int stride)
{
allocator->count = max(count, 4);
allocator->stride = stride;
allocator->head = NULL;
allocator->current = NULL;
allocator->index = allocator->count;
}
static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *allocator)
{
struct vkd3d_shader_param_node *current = allocator->head;
while (current)
{
struct vkd3d_shader_param_node *next = current->next;
vkd3d_free(current);
current = next;
}
}
void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count)
{
void *params;
if (!count)
return NULL;
if (count > allocator->count - allocator->index)
{
struct vkd3d_shader_param_node *next = shader_param_allocator_node_create(allocator);
if (!next)
return NULL;
if (allocator->current)
allocator->current->next = next;
else
allocator->head = next;
allocator->current = next;
allocator->index = 0;
}
params = &allocator->current->param[allocator->index * allocator->stride];
allocator->index += count;
return params;
}
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve)
{
memset(instructions, 0, sizeof(*instructions));
/* Size the parameter initial allocations so they are large enough for most shaders. The
* code path for chained allocations will be tested if a few shaders need to use it. */
shader_param_allocator_init(&instructions->dst_params, reserve - reserve / 8u,
sizeof(*instructions->elements->dst));
shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(*instructions->elements->src));
return shader_instruction_array_reserve(instructions, reserve);
}
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve)
{
if (!vkd3d_array_reserve((void **)&instructions->elements, &instructions->capacity, reserve,
sizeof(*instructions->elements)))
{
ERR("Failed to allocate instructions.\n");
return false;
}
return true;
}
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
struct vkd3d_shader_immediate_constant_buffer *icb)
{
if (!vkd3d_array_reserve((void **)&instructions->icbs, &instructions->icb_capacity, instructions->icb_count + 1,
sizeof(*instructions->icbs)))
return false;
instructions->icbs[instructions->icb_count++] = icb;
return true;
}
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions)
{
unsigned int i;
vkd3d_free(instructions->elements);
shader_param_allocator_destroy(&instructions->dst_params);
shader_param_allocator_destroy(&instructions->src_params);
for (i = 0; i < instructions->icb_count; ++i)
vkd3d_free(instructions->icbs[i]);
vkd3d_free(instructions->icbs);
}
......@@ -68,9 +68,12 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_DXBC_INVALID_VERSION = 4,
VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET = 5,
VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6,
VKD3D_SHADER_ERROR_DXBC_OUT_OF_MEMORY = 7,
VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE = 8,
VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000,
VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_RANGE = 1001,
VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY = 1002,
VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND = 2000,
VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001,
......@@ -121,6 +124,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF = 5022,
VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT = 5023,
VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE = 5024,
VKD3D_SHADER_ERROR_HLSL_RECURSIVE_CALL = 5025,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301,
......@@ -132,6 +136,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN = 7001,
VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE = 7002,
VKD3D_SHADER_ERROR_D3DBC_INVALID_RESOURCE_TYPE = 7003,
VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY = 7004,
VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS= 7300,
};
......@@ -617,7 +622,6 @@ enum vkd3d_shader_conditional_op
VKD3D_SHADER_CONDITIONAL_OP_Z = 1
};
#define MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE 4096
#define MAX_REG_OUTPUT 32
enum vkd3d_shader_type
......@@ -647,7 +651,7 @@ struct vkd3d_shader_version
struct vkd3d_shader_immediate_constant_buffer
{
unsigned int vec4_count;
uint32_t data[MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE];
uint32_t data[];
};
struct vkd3d_shader_indexable_temp
......@@ -738,6 +742,7 @@ struct vkd3d_shader_semantic
enum vkd3d_decl_usage usage;
unsigned int usage_idx;
enum vkd3d_shader_resource_type resource_type;
unsigned int sample_count;
enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE];
struct vkd3d_shader_resource resource;
};
......@@ -928,6 +933,56 @@ struct vkd3d_shader_location
unsigned int line, column;
};
struct vkd3d_shader_param_node
{
struct vkd3d_shader_param_node *next;
uint8_t param[];
};
struct vkd3d_shader_param_allocator
{
struct vkd3d_shader_param_node *head;
struct vkd3d_shader_param_node *current;
unsigned int count;
unsigned int stride;
unsigned int index;
};
void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count);
static inline struct vkd3d_shader_src_param *shader_src_param_allocator_get(
struct vkd3d_shader_param_allocator *allocator, unsigned int count)
{
assert(allocator->stride == sizeof(struct vkd3d_shader_src_param));
return shader_param_allocator_get(allocator, count);
}
static inline struct vkd3d_shader_dst_param *shader_dst_param_allocator_get(
struct vkd3d_shader_param_allocator *allocator, unsigned int count)
{
assert(allocator->stride == sizeof(struct vkd3d_shader_dst_param));
return shader_param_allocator_get(allocator, count);
}
struct vkd3d_shader_instruction_array
{
struct vkd3d_shader_instruction *elements;
size_t capacity;
size_t count;
struct vkd3d_shader_param_allocator src_params;
struct vkd3d_shader_param_allocator dst_params;
struct vkd3d_shader_immediate_constant_buffer **icbs;
size_t icb_capacity;
size_t icb_count;
};
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
struct vkd3d_shader_immediate_constant_buffer *icb);
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions);
struct vkd3d_shader_parser
{
struct vkd3d_shader_message_context *message_context;
......@@ -938,43 +993,39 @@ struct vkd3d_shader_parser
struct vkd3d_shader_version shader_version;
const uint32_t *ptr;
const struct vkd3d_shader_parser_ops *ops;
struct vkd3d_shader_instruction_array instructions;
size_t instruction_idx;
};
struct vkd3d_shader_parser_ops
{
void (*parser_reset)(struct vkd3d_shader_parser *parser);
void (*parser_destroy)(struct vkd3d_shader_parser *parser);
void (*parser_read_instruction)(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *instruction);
bool (*parser_is_end)(struct vkd3d_shader_parser *parser);
};
void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
struct vkd3d_shader_message_context *message_context, const char *source_name,
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops);
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
unsigned int instruction_reserve);
void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
static inline struct vkd3d_shader_dst_param *shader_parser_get_dst_params(
struct vkd3d_shader_parser *parser, unsigned int count)
{
parser->ops->parser_destroy(parser);
return shader_dst_param_allocator_get(&parser->instructions.dst_params, count);
}
static inline bool vkd3d_shader_parser_is_end(struct vkd3d_shader_parser *parser)
static inline struct vkd3d_shader_src_param *shader_parser_get_src_params(
struct vkd3d_shader_parser *parser, unsigned int count)
{
return parser->ops->parser_is_end(parser);
return shader_src_param_allocator_get(&parser->instructions.src_params, count);
}
static inline void vkd3d_shader_parser_read_instruction(struct vkd3d_shader_parser *parser,
struct vkd3d_shader_instruction *instruction)
{
parser->ops->parser_read_instruction(parser, instruction);
}
static inline void vkd3d_shader_parser_reset(struct vkd3d_shader_parser *parser)
static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
{
parser->ops->parser_reset(parser);
parser->ops->parser_destroy(parser);
}
void vkd3d_shader_trace(struct vkd3d_shader_parser *parser);
......@@ -1077,7 +1128,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
void free_shader_desc(struct vkd3d_shader_desc *desc);
int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *signature);
struct vkd3d_glsl_generator;
......@@ -1096,10 +1147,9 @@ struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *
const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info,
const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info,
struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location);
int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction);
int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv);
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_parser *parser,
struct vkd3d_shader_code *spirv);
void spirv_compiler_destroy(struct spirv_compiler *compiler);
void vkd3d_compute_dxbc_checksum(const void *dxbc, size_t size, uint32_t checksum[4]);
......@@ -1261,19 +1311,12 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X')
#define TAG_TEXT VKD3D_MAKE_TAG('T', 'E', 'X', 'T')
struct dxbc_writer_section
{
uint32_t tag;
const uint8_t *data;
size_t size;
};
#define DXBC_MAX_SECTION_COUNT 5
struct dxbc_writer
{
unsigned int section_count;
struct dxbc_writer_section sections[DXBC_MAX_SECTION_COUNT];
struct vkd3d_shader_dxbc_section_desc sections[DXBC_MAX_SECTION_COUNT];
};
void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void *data, size_t size);
......
......@@ -1689,14 +1689,8 @@ HRESULT vkd3d_render_pass_cache_find(struct vkd3d_render_pass_cache *cache,
bool found = false;
HRESULT hr = S_OK;
unsigned int i;
int rc;
if ((rc = vkd3d_mutex_lock(&device->mutex)))
{
ERR("Failed to lock mutex, error %d.\n", rc);
*vk_render_pass = VK_NULL_HANDLE;
return hresult_from_errno(rc);
}
vkd3d_mutex_lock(&device->mutex);
for (i = 0; i < cache->render_pass_count; ++i)
{
......@@ -1964,8 +1958,9 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
const struct vkd3d_shader_compile_option options[] =
{
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_6},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_7},
{VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)},
{VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0},
};
stage_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
......@@ -2016,7 +2011,7 @@ static int vkd3d_scan_dxbc(const struct d3d12_device *device, const D3D12_SHADER
const struct vkd3d_shader_compile_option options[] =
{
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_6},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_7},
{VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)},
};
......@@ -3370,12 +3365,11 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12
struct d3d12_device *device = state->device;
VkPipeline vk_pipeline = VK_NULL_HANDLE;
struct vkd3d_compiled_pipeline *current;
int rc;
*vk_render_pass = VK_NULL_HANDLE;
if (!(rc = vkd3d_mutex_lock(&device->mutex)))
{
vkd3d_mutex_lock(&device->mutex);
LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry)
{
if (!memcmp(&current->key, key, sizeof(*key)))
......@@ -3385,12 +3379,8 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12
break;
}
}
vkd3d_mutex_unlock(&device->mutex);
}
else
{
ERR("Failed to lock mutex, error %d.\n", rc);
}
return vk_pipeline;
}
......@@ -3401,7 +3391,6 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
struct vkd3d_compiled_pipeline *compiled_pipeline, *current;
struct d3d12_device *device = state->device;
int rc;
if (!(compiled_pipeline = vkd3d_malloc(sizeof(*compiled_pipeline))))
return false;
......@@ -3410,12 +3399,7 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta
compiled_pipeline->vk_pipeline = vk_pipeline;
compiled_pipeline->vk_render_pass = vk_render_pass;
if ((rc = vkd3d_mutex_lock(&device->mutex)))
{
ERR("Failed to lock mutex, error %d.\n", rc);
vkd3d_free(compiled_pipeline);
return false;
}
vkd3d_mutex_lock(&device->mutex);
LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry)
{
......
......@@ -948,16 +948,11 @@ HRESULT vkd3d_get_private_data(struct vkd3d_private_store *store,
const struct vkd3d_private_data *data;
HRESULT hr = S_OK;
unsigned int size;
int rc;
if (!out_size)
return E_INVALIDARG;
if ((rc = vkd3d_mutex_lock(&store->mutex)))
{
ERR("Failed to lock mutex, error %d.\n", rc);
return hresult_from_errno(rc);
}
vkd3d_mutex_lock(&store->mutex);
if (!(data = vkd3d_private_store_get_private_data(store, tag)))
{
......@@ -990,13 +985,8 @@ HRESULT vkd3d_set_private_data(struct vkd3d_private_store *store,
const GUID *tag, unsigned int data_size, const void *data)
{
HRESULT hr;
int rc;
if ((rc = vkd3d_mutex_lock(&store->mutex)))
{
ERR("Failed to lock mutex, error %d.\n", rc);
return hresult_from_errno(rc);
}
vkd3d_mutex_lock(&store->mutex);
hr = vkd3d_private_store_set_private_data(store, tag, data, data_size, false);
......@@ -1009,13 +999,8 @@ HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store,
{
const void *data = object ? object : (void *)&object;
HRESULT hr;
int rc;
if ((rc = vkd3d_mutex_lock(&store->mutex)))
{
ERR("Failed to lock mutex, error %d.\n", rc);
return hresult_from_errno(rc);
}
vkd3d_mutex_lock(&store->mutex);
hr = vkd3d_private_store_set_private_data(store, tag, data, sizeof(object), !!object);
......
......@@ -207,56 +207,49 @@ struct vkd3d_cond
CONDITION_VARIABLE cond;
};
static inline int vkd3d_mutex_init(struct vkd3d_mutex *lock)
static inline void vkd3d_mutex_init(struct vkd3d_mutex *lock)
{
InitializeCriticalSection(&lock->lock);
return 0;
}
static inline int vkd3d_mutex_lock(struct vkd3d_mutex *lock)
static inline void vkd3d_mutex_lock(struct vkd3d_mutex *lock)
{
EnterCriticalSection(&lock->lock);
return 0;
}
static inline int vkd3d_mutex_unlock(struct vkd3d_mutex *lock)
static inline void vkd3d_mutex_unlock(struct vkd3d_mutex *lock)
{
LeaveCriticalSection(&lock->lock);
return 0;
}
static inline int vkd3d_mutex_destroy(struct vkd3d_mutex *lock)
static inline void vkd3d_mutex_destroy(struct vkd3d_mutex *lock)
{
DeleteCriticalSection(&lock->lock);
return 0;
}
static inline int vkd3d_cond_init(struct vkd3d_cond *cond)
static inline void vkd3d_cond_init(struct vkd3d_cond *cond)
{
InitializeConditionVariable(&cond->cond);
return 0;
}
static inline int vkd3d_cond_signal(struct vkd3d_cond *cond)
static inline void vkd3d_cond_signal(struct vkd3d_cond *cond)
{
WakeConditionVariable(&cond->cond);
return 0;
}
static inline int vkd3d_cond_broadcast(struct vkd3d_cond *cond)
static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond)
{
WakeAllConditionVariable(&cond->cond);
return 0;
}
static inline int vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
{
return !SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE);
if (!SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE))
ERR("Could not sleep on the condition variable, error %u.\n", GetLastError());
}
static inline int vkd3d_cond_destroy(struct vkd3d_cond *cond)
static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
{
return 0;
}
#else /* _WIN32 */
......@@ -280,49 +273,85 @@ struct vkd3d_cond
};
static inline int vkd3d_mutex_init(struct vkd3d_mutex *lock)
static inline void vkd3d_mutex_init(struct vkd3d_mutex *lock)
{
return pthread_mutex_init(&lock->lock, NULL);
int ret;
ret = pthread_mutex_init(&lock->lock, NULL);
if (ret)
ERR("Could not initialize the mutex, error %d.\n", ret);
}
static inline int vkd3d_mutex_lock(struct vkd3d_mutex *lock)
static inline void vkd3d_mutex_lock(struct vkd3d_mutex *lock)
{
return pthread_mutex_lock(&lock->lock);
int ret;
ret = pthread_mutex_lock(&lock->lock);
if (ret)
ERR("Could not lock the mutex, error %d.\n", ret);
}
static inline int vkd3d_mutex_unlock(struct vkd3d_mutex *lock)
static inline void vkd3d_mutex_unlock(struct vkd3d_mutex *lock)
{
return pthread_mutex_unlock(&lock->lock);
int ret;
ret = pthread_mutex_unlock(&lock->lock);
if (ret)
ERR("Could not unlock the mutex, error %d.\n", ret);
}
static inline int vkd3d_mutex_destroy(struct vkd3d_mutex *lock)
static inline void vkd3d_mutex_destroy(struct vkd3d_mutex *lock)
{
return pthread_mutex_destroy(&lock->lock);
int ret;
ret = pthread_mutex_destroy(&lock->lock);
if (ret)
ERR("Could not destroy the mutex, error %d.\n", ret);
}
static inline int vkd3d_cond_init(struct vkd3d_cond *cond)
static inline void vkd3d_cond_init(struct vkd3d_cond *cond)
{
return pthread_cond_init(&cond->cond, NULL);
int ret;
ret = pthread_cond_init(&cond->cond, NULL);
if (ret)
ERR("Could not initialize the condition variable, error %d.\n", ret);
}
static inline int vkd3d_cond_signal(struct vkd3d_cond *cond)
static inline void vkd3d_cond_signal(struct vkd3d_cond *cond)
{
return pthread_cond_signal(&cond->cond);
int ret;
ret = pthread_cond_signal(&cond->cond);
if (ret)
ERR("Could not signal the condition variable, error %d.\n", ret);
}
static inline int vkd3d_cond_broadcast(struct vkd3d_cond *cond)
static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond)
{
return pthread_cond_broadcast(&cond->cond);
int ret;
ret = pthread_cond_broadcast(&cond->cond);
if (ret)
ERR("Could not broadcast the condition variable, error %d.\n", ret);
}
static inline int vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
{
return pthread_cond_wait(&cond->cond, &lock->lock);
int ret;
ret = pthread_cond_wait(&cond->cond, &lock->lock);
if (ret)
ERR("Could not wait on the condition variable, error %d.\n", ret);
}
static inline int vkd3d_cond_destroy(struct vkd3d_cond *cond)
static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
{
return pthread_cond_destroy(&cond->cond);
int ret;
ret = pthread_cond_destroy(&cond->cond);
if (ret)
ERR("Could not destroy the condition variable, error %d.\n", ret);
}
#endif /* _WIN32 */
......@@ -391,30 +420,6 @@ D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_al
void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address);
void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address);
struct vkd3d_gpu_descriptor_allocation
{
const struct d3d12_desc *base;
size_t count;
};
struct vkd3d_gpu_descriptor_allocator
{
struct vkd3d_mutex mutex;
struct vkd3d_gpu_descriptor_allocation *allocations;
size_t allocations_size;
size_t allocation_count;
};
size_t vkd3d_gpu_descriptor_allocator_range_size_from_descriptor(
struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc);
bool vkd3d_gpu_descriptor_allocator_register_range(struct vkd3d_gpu_descriptor_allocator *allocator,
const struct d3d12_desc *base, size_t count);
bool vkd3d_gpu_descriptor_allocator_unregister_range(
struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *base);
struct d3d12_descriptor_heap *vkd3d_gpu_descriptor_allocator_heap_from_descriptor(
struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc);
struct vkd3d_render_pass_key
{
unsigned int attachment_count;
......@@ -471,14 +476,11 @@ static inline void vkd3d_private_data_destroy(struct vkd3d_private_data *data)
static inline HRESULT vkd3d_private_store_init(struct vkd3d_private_store *store)
{
int rc;
list_init(&store->content);
if ((rc = vkd3d_mutex_init(&store->mutex)))
ERR("Failed to initialize mutex, error %d.\n", rc);
vkd3d_mutex_init(&store->mutex);
return hresult_from_errno(rc);
return S_OK;
}
static inline void vkd3d_private_store_destroy(struct vkd3d_private_store *store)
......@@ -718,6 +720,8 @@ struct vkd3d_view_info
struct d3d12_desc
{
struct
{
uint32_t magic;
VkDescriptorType vk_descriptor_type;
union
......@@ -725,6 +729,8 @@ struct d3d12_desc
VkDescriptorBufferInfo vk_cbv_info;
struct vkd3d_view_info view_info;
} u;
} s;
unsigned int index;
};
static inline struct d3d12_desc *d3d12_desc_from_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle)
......@@ -737,6 +743,11 @@ static inline struct d3d12_desc *d3d12_desc_from_gpu_handle(D3D12_GPU_DESCRIPTOR
return (struct d3d12_desc *)(intptr_t)gpu_handle.ptr;
}
static inline void d3d12_desc_copy_raw(struct d3d12_desc *dst, const struct d3d12_desc *src)
{
dst->s = src->s;
}
void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_device *device);
void d3d12_desc_create_cbv(struct d3d12_desc *descriptor,
struct d3d12_device *device, const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc);
......@@ -857,6 +868,17 @@ struct d3d12_descriptor_heap
BYTE descriptors[];
};
static inline struct d3d12_descriptor_heap *d3d12_desc_get_descriptor_heap(const struct d3d12_desc *descriptor)
{
return CONTAINING_RECORD(descriptor - descriptor->index, struct d3d12_descriptor_heap, descriptors);
}
static inline unsigned int d3d12_desc_heap_range_size(const struct d3d12_desc *descriptor)
{
const struct d3d12_descriptor_heap *heap = d3d12_desc_get_descriptor_heap(descriptor);
return heap->desc.NumDescriptors - descriptor->index;
}
HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
const D3D12_DESCRIPTOR_HEAP_DESC *desc, struct d3d12_descriptor_heap **descriptor_heap);
......@@ -1348,6 +1370,13 @@ struct vkd3d_cs_op_data
} u;
};
struct d3d12_command_queue_op_array
{
struct vkd3d_cs_op_data *ops;
size_t count;
size_t size;
};
/* ID3D12CommandQueue */
struct d3d12_command_queue
{
......@@ -1365,11 +1394,16 @@ struct d3d12_command_queue
struct d3d12_device *device;
struct vkd3d_mutex op_mutex;
struct vkd3d_cs_op_data *ops;
size_t ops_count;
size_t ops_size;
/* These fields are protected by op_mutex. */
struct d3d12_command_queue_op_array op_queue;
bool is_flushing;
/* This field is not protected by op_mutex, but can only be used
* by the thread that set is_flushing; when is_flushing is not
* set, aux_op_queue.count must be zero. */
struct d3d12_command_queue_op_array aux_op_queue;
struct vkd3d_private_store private_store;
};
......@@ -1465,7 +1499,6 @@ struct d3d12_device
PFN_vkd3d_signal_event signal_event;
size_t wchar_size;
struct vkd3d_gpu_descriptor_allocator gpu_descriptor_allocator;
struct vkd3d_gpu_va_allocator gpu_va_allocator;
struct vkd3d_mutex mutex;
......@@ -1491,6 +1524,7 @@ struct d3d12_device
unsigned int queue_family_count;
VkTimeDomainEXT vk_host_time_domain;
struct vkd3d_mutex blocked_queues_mutex;
struct d3d12_command_queue *blocked_queues[VKD3D_MAX_DEVICE_BLOCKED_QUEUES];
unsigned int blocked_queue_count;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment