Newer
Older
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
type_id, index_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 1));
/* Validate sample index. */
bool_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_BOOL, 1);
id = vkd3d_spirv_build_op_logical_and(builder, bool_id,
vkd3d_spirv_build_op_uless_than(builder, bool_id, sample_index_id, sample_count_id),
vkd3d_spirv_build_op_uless_than_equal(builder,
bool_id, sample_index_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 16)));
index_id = vkd3d_spirv_build_op_select(builder, type_id,
id, index_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 0));
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 2);
if (!(id = compiler->sample_positions_id))
{
length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions));
array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
for (i = 0; i < ARRAY_SIZE(standard_sample_positions); ++ i)
{
constituents[i] = vkd3d_dxbc_compiler_get_constant(compiler,
VKD3D_TYPE_FLOAT, 2, (const uint32_t *)standard_sample_positions[i]);
}
id = vkd3d_spirv_build_op_constant_composite(builder, array_type_id, constituents, ARRAY_SIZE(constituents));
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, array_type_id);
id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, SpvStorageClassPrivate, id);
vkd3d_spirv_build_op_name(builder, id, "sample_pos");
compiler->sample_positions_id = id;
}
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id);
id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, id, index_id);
id = vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone);
id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
id, VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1, VKD3D_TYPE_FLOAT,
instruction->src[0].swizzle, dst->write_mask);
vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, id);
}
static void vkd3d_dxbc_compiler_emit_eval_attrib(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
const struct vkd3d_shader_register *input = &src[0].reg;
uint32_t instr_set_id, type_id, val_id, src_ids[2];
struct vkd3d_shader_register_info register_info;
unsigned int src_count = 0;
enum GLSLstd450 op;
if (!vkd3d_dxbc_compiler_get_register_info(compiler, input, ®ister_info))
return;
if (register_info.storage_class != SpvStorageClassInput)
{
FIXME("Not supported for storage class %#x.\n", register_info.storage_class);
return;
}
vkd3d_spirv_enable_capability(builder, SpvCapabilityInterpolationFunction);
src_ids[src_count++] = register_info.id;
if (instruction->handler_idx == VKD3DSIH_EVAL_CENTROID)
{
op = GLSLstd450InterpolateAtCentroid;
}
else
{
assert(instruction->handler_idx == VKD3DSIH_EVAL_SAMPLE_INDEX);
op = GLSLstd450InterpolateAtSample;
src_ids[src_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0);
}
type_id = vkd3d_spirv_get_type_id(builder,
VKD3D_TYPE_FLOAT, vkd3d_write_mask_component_count(register_info.write_mask));
instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, op, src_ids, src_count);
val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
val_id, register_info.write_mask, VKD3D_TYPE_FLOAT, src[0].swizzle, dst->write_mask);
vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id);
}
/* From the Vulkan spec:
*
* "Scope for execution must be limited to: * Workgroup * Subgroup"
*
* "Scope for memory must be limited to: * Device * Workgroup * Invocation"
*/
static void vkd3d_dxbc_compiler_emit_sync(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
unsigned int memory_semantics = SpvMemorySemanticsAcquireReleaseMask;
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
unsigned int flags = instruction->flags;
SpvScope execution_scope = SpvScopeMax;
SpvScope memory_scope = SpvScopeDevice;
if (flags & VKD3DSSF_GROUP_SHARED_MEMORY)
{
memory_scope = SpvScopeWorkgroup;
memory_semantics |= SpvMemorySemanticsWorkgroupMemoryMask;
flags &= ~VKD3DSSF_GROUP_SHARED_MEMORY;
}
if (flags & VKD3DSSF_THREAD_GROUP)
{
execution_scope = SpvScopeWorkgroup;
flags &= ~VKD3DSSF_THREAD_GROUP;
}
if (flags)
{
FIXME("Unhandled sync flags %#x.\n", flags);
memory_scope = SpvScopeDevice;
execution_scope = SpvScopeWorkgroup;
memory_semantics |= SpvMemorySemanticsUniformMemoryMask
| SpvMemorySemanticsSubgroupMemoryMask
| SpvMemorySemanticsWorkgroupMemoryMask
| SpvMemorySemanticsCrossWorkgroupMemoryMask
| SpvMemorySemanticsAtomicCounterMemoryMask
| SpvMemorySemanticsImageMemoryMask;
}
vkd3d_dxbc_compiler_emit_barrier(compiler, execution_scope, memory_scope, memory_semantics);
static void vkd3d_dxbc_compiler_emit_emit_stream(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
unsigned int stream_idx;
if (instruction->handler_idx == VKD3DSIH_EMIT_STREAM)
stream_idx = instruction->src[0].reg.idx[0].offset;
else
stream_idx = 0;
if (stream_idx)
{
FIXME("Multiple streams are not supported yet.\n");
return;
}
vkd3d_dxbc_compiler_emit_shader_epilogue_invocation(compiler);
vkd3d_spirv_build_op_emit_vertex(builder);
}
static void vkd3d_dxbc_compiler_emit_cut_stream(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
unsigned int stream_idx;
if (instruction->handler_idx == VKD3DSIH_CUT_STREAM)
stream_idx = instruction->src[0].reg.idx[0].offset;
else
stream_idx = 0;
if (stream_idx)
{
FIXME("Multiple streams are not supported yet.\n");
return;
}
vkd3d_spirv_build_op_end_primitive(builder);
}
/* This function is called after declarations are processed. */
static void vkd3d_dxbc_compiler_emit_main_prolog(struct vkd3d_dxbc_compiler *compiler)
{
Józef Kucia
committed
vkd3d_dxbc_compiler_emit_push_constant_buffers(compiler);
}
static bool is_dcl_instruction(enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx)
{
return (VKD3DSIH_DCL <= handler_idx && handler_idx <= VKD3DSIH_DCL_VERTICES_OUT)
|| handler_idx == VKD3DSIH_HS_DECLS;
Józef Kucia
committed
int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
Józef Kucia
committed
int ret = VKD3D_OK;
if (!is_dcl_instruction(instruction->handler_idx) && !compiler->after_declarations_section)
{
compiler->after_declarations_section = true;
vkd3d_dxbc_compiler_emit_main_prolog(compiler);
}
switch (instruction->handler_idx)
{
case VKD3DSIH_DCL_GLOBAL_FLAGS:
vkd3d_dxbc_compiler_emit_dcl_global_flags(compiler, instruction);
break;
case VKD3DSIH_DCL_TEMPS:
vkd3d_dxbc_compiler_emit_dcl_temps(compiler, instruction);
break;
case VKD3DSIH_DCL_INDEXABLE_TEMP:
vkd3d_dxbc_compiler_emit_dcl_indexable_temp(compiler, instruction);
break;
case VKD3DSIH_DCL_CONSTANT_BUFFER:
vkd3d_dxbc_compiler_emit_dcl_constant_buffer(compiler, instruction);
break;
case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER:
vkd3d_dxbc_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction);
break;
case VKD3DSIH_DCL_SAMPLER:
vkd3d_dxbc_compiler_emit_dcl_sampler(compiler, instruction);
break;
case VKD3DSIH_DCL:
case VKD3DSIH_DCL_UAV_TYPED:
vkd3d_dxbc_compiler_emit_dcl_resource(compiler, instruction);
break;
case VKD3DSIH_DCL_RESOURCE_RAW:
case VKD3DSIH_DCL_UAV_RAW:
vkd3d_dxbc_compiler_emit_dcl_resource_raw(compiler, instruction);
case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
case VKD3DSIH_DCL_UAV_STRUCTURED:
vkd3d_dxbc_compiler_emit_dcl_resource_structured(compiler, instruction);
case VKD3DSIH_DCL_TGSM_RAW:
vkd3d_dxbc_compiler_emit_dcl_tgsm_raw(compiler, instruction);
break;
case VKD3DSIH_DCL_TGSM_STRUCTURED:
vkd3d_dxbc_compiler_emit_dcl_tgsm_structured(compiler, instruction);
break;
case VKD3DSIH_DCL_INPUT:
vkd3d_dxbc_compiler_emit_dcl_input(compiler, instruction);
break;
case VKD3DSIH_DCL_INPUT_PS:
vkd3d_dxbc_compiler_emit_dcl_input_ps(compiler, instruction);
break;
case VKD3DSIH_DCL_INPUT_PS_SGV:
case VKD3DSIH_DCL_INPUT_PS_SIV:
vkd3d_dxbc_compiler_emit_dcl_input_ps_sysval(compiler, instruction);
case VKD3DSIH_DCL_INPUT_SGV:
case VKD3DSIH_DCL_INPUT_SIV:
vkd3d_dxbc_compiler_emit_dcl_input_sysval(compiler, instruction);
case VKD3DSIH_DCL_OUTPUT:
vkd3d_dxbc_compiler_emit_dcl_output(compiler, instruction);
break;
case VKD3DSIH_DCL_OUTPUT_SIV:
vkd3d_dxbc_compiler_emit_dcl_output_siv(compiler, instruction);
break;
case VKD3DSIH_DCL_INDEX_RANGE:
vkd3d_dxbc_compiler_emit_dcl_index_range(compiler, instruction);
break;
case VKD3DSIH_DCL_STREAM:
vkd3d_dxbc_compiler_emit_dcl_stream(compiler, instruction);
break;
case VKD3DSIH_DCL_VERTICES_OUT:
vkd3d_dxbc_compiler_emit_output_vertex_count(compiler, instruction);
case VKD3DSIH_DCL_INPUT_PRIMITIVE:
vkd3d_dxbc_compiler_emit_dcl_input_primitive(compiler, instruction);
break;
case VKD3DSIH_DCL_OUTPUT_TOPOLOGY:
vkd3d_dxbc_compiler_emit_dcl_output_topology(compiler, instruction);
break;
case VKD3DSIH_DCL_GS_INSTANCES:
vkd3d_dxbc_compiler_emit_dcl_gs_instances(compiler, instruction);
break;
case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT:
compiler->input_control_point_count = instruction->declaration.count;
break;
case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT:
compiler->output_control_point_count = instruction->declaration.count;
vkd3d_dxbc_compiler_emit_output_vertex_count(compiler, instruction);
break;
case VKD3DSIH_DCL_TESSELLATOR_DOMAIN:
vkd3d_dxbc_compiler_emit_dcl_tessellator_domain(compiler, instruction);
break;
case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
vkd3d_dxbc_compiler_emit_tessellator_output_primitive(compiler,
instruction->declaration.tessellator_output_primitive);
break;
case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING:
vkd3d_dxbc_compiler_emit_tessellator_partitioning(compiler,
instruction->declaration.tessellator_partitioning);
break;
case VKD3DSIH_DCL_THREAD_GROUP:
vkd3d_dxbc_compiler_emit_dcl_thread_group(compiler, instruction);
break;
case VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
case VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT:
ret = vkd3d_dxbc_compiler_emit_shader_phase_instance_count(compiler, instruction);
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
case VKD3DSIH_HS_FORK_PHASE:
case VKD3DSIH_HS_JOIN_PHASE:
vkd3d_dxbc_compiler_enter_shader_phase(compiler, instruction);
break;
case VKD3DSIH_MOV:
vkd3d_dxbc_compiler_emit_mov(compiler, instruction);
break;
case VKD3DSIH_MOVC:
vkd3d_dxbc_compiler_emit_movc(compiler, instruction);
break;
case VKD3DSIH_SWAPC:
vkd3d_dxbc_compiler_emit_swapc(compiler, instruction);
break;
case VKD3DSIH_ADD:
case VKD3DSIH_AND:
case VKD3DSIH_COUNTBITS:
case VKD3DSIH_FTOI:
case VKD3DSIH_FTOU:
case VKD3DSIH_ITOF:
case VKD3DSIH_NOT:
case VKD3DSIH_OR:
case VKD3DSIH_XOR:
vkd3d_dxbc_compiler_emit_alu_instruction(compiler, instruction);
break;
case VKD3DSIH_FIRSTBIT_HI:
case VKD3DSIH_FIRSTBIT_LO:
case VKD3DSIH_FIRSTBIT_SHI:
case VKD3DSIH_IMAX:
case VKD3DSIH_IMIN:
case VKD3DSIH_MAD:
case VKD3DSIH_MAX:
case VKD3DSIH_MIN:
case VKD3DSIH_ROUND_NE:
case VKD3DSIH_ROUND_NI:
case VKD3DSIH_ROUND_PI:
case VKD3DSIH_ROUND_Z:
case VKD3DSIH_RSQ:
case VKD3DSIH_UMAX:
case VKD3DSIH_UMIN:
vkd3d_dxbc_compiler_emit_ext_glsl_instruction(compiler, instruction);
break;
case VKD3DSIH_DP4:
case VKD3DSIH_DP3:
case VKD3DSIH_DP2:
vkd3d_dxbc_compiler_emit_dot(compiler, instruction);
break;
case VKD3DSIH_RCP:
vkd3d_dxbc_compiler_emit_rcp(compiler, instruction);
break;
case VKD3DSIH_SINCOS:
vkd3d_dxbc_compiler_emit_sincos(compiler, instruction);
break;
case VKD3DSIH_IMUL:
vkd3d_dxbc_compiler_emit_imul(compiler, instruction);
break;
case VKD3DSIH_IMAD:
vkd3d_dxbc_compiler_emit_imad(compiler, instruction);
break;
case VKD3DSIH_UDIV:
vkd3d_dxbc_compiler_emit_udiv(compiler, instruction);
break;
case VKD3DSIH_EQ:
case VKD3DSIH_GE:
case VKD3DSIH_IGE:
case VKD3DSIH_ILT:
case VKD3DSIH_INE:
case VKD3DSIH_LT:
case VKD3DSIH_NE:
case VKD3DSIH_UGE:
case VKD3DSIH_ULT:
vkd3d_dxbc_compiler_emit_comparison_instruction(compiler, instruction);
break;
case VKD3DSIH_IBFE:
case VKD3DSIH_UBFE:
vkd3d_dxbc_compiler_emit_bitfield_instruction(compiler, instruction);
break;
case VKD3DSIH_F16TOF32:
vkd3d_dxbc_compiler_emit_f16tof32(compiler, instruction);
break;
case VKD3DSIH_F32TOF16:
vkd3d_dxbc_compiler_emit_f32tof16(compiler, instruction);
break;
case VKD3DSIH_BREAK:
case VKD3DSIH_CASE:
case VKD3DSIH_DEFAULT:
case VKD3DSIH_ELSE:
case VKD3DSIH_ENDIF:
case VKD3DSIH_ENDSWITCH:
case VKD3DSIH_IF:
case VKD3DSIH_LOOP:
case VKD3DSIH_SWITCH:
case VKD3DSIH_TEXKILL:
Józef Kucia
committed
ret = vkd3d_dxbc_compiler_emit_control_flow_instruction(compiler, instruction);
case VKD3DSIH_DSX:
case VKD3DSIH_DSX_COARSE:
case VKD3DSIH_DSX_FINE:
case VKD3DSIH_DSY:
case VKD3DSIH_DSY_COARSE:
case VKD3DSIH_DSY_FINE:
vkd3d_dxbc_compiler_emit_deriv_instruction(compiler, instruction);
break;
case VKD3DSIH_LD:
vkd3d_dxbc_compiler_emit_ld(compiler, instruction);
break;
case VKD3DSIH_LOD:
vkd3d_dxbc_compiler_emit_lod(compiler, instruction);
break;
case VKD3DSIH_SAMPLE_GRAD:
vkd3d_dxbc_compiler_emit_sample(compiler, instruction);
break;
case VKD3DSIH_SAMPLE_C:
vkd3d_dxbc_compiler_emit_sample_c(compiler, instruction);
break;
case VKD3DSIH_GATHER4:
case VKD3DSIH_GATHER4_PO:
case VKD3DSIH_GATHER4_PO_C:
vkd3d_dxbc_compiler_emit_gather4(compiler, instruction);
break;
case VKD3DSIH_LD_STRUCTURED:
vkd3d_dxbc_compiler_emit_ld_raw_structured(compiler, instruction);
case VKD3DSIH_STORE_RAW:
case VKD3DSIH_STORE_STRUCTURED:
vkd3d_dxbc_compiler_emit_store_raw_structured(compiler, instruction);
break;
case VKD3DSIH_LD_UAV_TYPED:
vkd3d_dxbc_compiler_emit_ld_uav_typed(compiler, instruction);
case VKD3DSIH_STORE_UAV_TYPED:
vkd3d_dxbc_compiler_emit_store_uav_typed(compiler, instruction);
break;
case VKD3DSIH_IMM_ATOMIC_ALLOC:
case VKD3DSIH_IMM_ATOMIC_CONSUME:
vkd3d_dxbc_compiler_emit_uav_counter_instruction(compiler, instruction);
break;
case VKD3DSIH_ATOMIC_AND:
case VKD3DSIH_ATOMIC_CMP_STORE:
case VKD3DSIH_ATOMIC_IADD:
case VKD3DSIH_ATOMIC_IMAX:
case VKD3DSIH_ATOMIC_IMIN:
case VKD3DSIH_ATOMIC_OR:
case VKD3DSIH_ATOMIC_UMAX:
case VKD3DSIH_ATOMIC_UMIN:
case VKD3DSIH_ATOMIC_XOR:
case VKD3DSIH_IMM_ATOMIC_AND:
case VKD3DSIH_IMM_ATOMIC_CMP_EXCH:
case VKD3DSIH_IMM_ATOMIC_EXCH:
case VKD3DSIH_IMM_ATOMIC_IADD:
case VKD3DSIH_IMM_ATOMIC_IMAX:
case VKD3DSIH_IMM_ATOMIC_IMIN:
case VKD3DSIH_IMM_ATOMIC_OR:
case VKD3DSIH_IMM_ATOMIC_UMAX:
case VKD3DSIH_IMM_ATOMIC_UMIN:
case VKD3DSIH_IMM_ATOMIC_XOR:
vkd3d_dxbc_compiler_emit_atomic_instruction(compiler, instruction);
break;
case VKD3DSIH_BUFINFO:
vkd3d_dxbc_compiler_emit_bufinfo(compiler, instruction);
break;
case VKD3DSIH_RESINFO:
vkd3d_dxbc_compiler_emit_resinfo(compiler, instruction);
break;
case VKD3DSIH_SAMPLE_INFO:
vkd3d_dxbc_compiler_emit_sample_info(compiler, instruction);
break;
case VKD3DSIH_SAMPLE_POS:
vkd3d_dxbc_compiler_emit_sample_position(compiler, instruction);
break;
case VKD3DSIH_EVAL_CENTROID:
case VKD3DSIH_EVAL_SAMPLE_INDEX:
vkd3d_dxbc_compiler_emit_eval_attrib(compiler, instruction);
case VKD3DSIH_SYNC:
vkd3d_dxbc_compiler_emit_sync(compiler, instruction);
break;
case VKD3DSIH_EMIT:
case VKD3DSIH_EMIT_STREAM:
vkd3d_dxbc_compiler_emit_emit_stream(compiler, instruction);
break;
case VKD3DSIH_CUT:
case VKD3DSIH_CUT_STREAM:
vkd3d_dxbc_compiler_emit_cut_stream(compiler, instruction);
break;
case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
case VKD3DSIH_HS_DECLS:
/* nothing to do */
default:
FIXME("Unhandled instruction %#x.\n", instruction->handler_idx);
}
Józef Kucia
committed
return ret;
int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
struct vkd3d_shader_code *spirv)
{
const struct vkd3d_shader_compile_arguments *compile_args = compiler->compile_args;
const struct vkd3d_shader_domain_shader_compile_arguments *ds_args;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
Józef Kucia
committed
const struct vkd3d_shader_phase *phase;
Józef Kucia
committed
if ((phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler)))
vkd3d_dxbc_compiler_leave_shader_phase(compiler, phase);
else
vkd3d_spirv_build_op_function_end(builder);
Józef Kucia
committed
if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL)
vkd3d_dxbc_compiler_emit_hull_shader_main(compiler);
if (compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN)
{
if (compile_args && (ds_args = vkd3d_find_struct(compile_args->next, DOMAIN_SHADER_COMPILE_ARGUMENTS)))
{
vkd3d_dxbc_compiler_emit_tessellator_output_primitive(compiler, ds_args->output_primitive);
vkd3d_dxbc_compiler_emit_tessellator_partitioning(compiler, ds_args->partitioning);
}
else if (vkd3d_dxbc_compiler_is_opengl_target(compiler))
{
ERR("vkd3d_shader_domain_shader_compile_arguments are required for "
"OpenGL tessellation evaluation shader.\n");
}
}
if (compiler->epilogue_function_id)
{
vkd3d_spirv_build_op_name(builder, compiler->epilogue_function_id, "epilogue");
vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler);
Józef Kucia
committed
if (compiler->options & VKD3D_SHADER_STRIP_DEBUG)
vkd3d_spirv_stream_clear(&builder->debug_stream);
if (!vkd3d_spirv_compile_module(builder, spirv))
return VKD3D_ERROR;
if (TRACE_ON())
{
enum vkd3d_shader_target target = vkd3d_dxbc_compiler_get_target(compiler);
vkd3d_spirv_dump(spirv, target);
vkd3d_spirv_validate(spirv, target);
return VKD3D_OK;
}
void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler)
{
vkd3d_free(compiler->control_flow_info);
Józef Kucia
committed
vkd3d_free(compiler->output_info);
vkd3d_free(compiler->push_constants);
vkd3d_spirv_builder_free(&compiler->spirv_builder);
rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL);
vkd3d_free(compiler->shader_phases);
vkd3d_free(compiler->spec_constants);
vkd3d_free(compiler);
}