Newer
Older
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);
Henri Verbeet
committed
id = vkd3d_dxbc_compiler_emit_swizzle(compiler, id, VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1,
VKD3D_SHADER_COMPONENT_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);
}
Henri Verbeet
committed
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_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);
Henri Verbeet
committed
val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id, register_info.write_mask,
VKD3D_SHADER_COMPONENT_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;
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 & VKD3DSSF_GLOBAL_UAV)
{
memory_scope = SpvScopeDevice;
memory_semantics |= SpvMemorySemanticsImageMemoryMask;
flags &= ~VKD3DSSF_GLOBAL_UAV;
}
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);
}
Henri Verbeet
committed
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
static void vkd3d_dxbc_compiler_emit_hull_shader_inputs(struct vkd3d_dxbc_compiler *compiler)
{
const struct vkd3d_shader_signature *signature = compiler->input_signature;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id, length_id, vicp_id, vicp_type_id;
unsigned int register_count, register_idx, i;
struct vkd3d_shader_register r;
struct vkd3d_symbol symbol;
struct rb_entry *entry;
for (i = 0, register_count = 0; i < signature->element_count; ++i)
{
register_count = max(register_count, signature->elements[i].register_index + 1);
}
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4);
length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, compiler->input_control_point_count);
type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_count);
type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
vicp_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id);
vicp_id = vkd3d_spirv_build_op_variable(builder,
&builder->global_stream, vicp_type_id, SpvStorageClassPrivate, 0);
vkd3d_spirv_build_op_name(builder, vicp_id, "vicp");
memset(&r, 0, sizeof(r));
r.type = VKD3DSPR_INPUT;
r.idx[0].offset = 0;
r.idx[1].offset = ~0u;
vkd3d_symbol_make_register(&symbol, &r);
for (i = 0; i < signature->element_count; ++i)
{
register_idx = signature->elements[i].register_index;
symbol.key.reg.idx = register_idx;
if ((entry = rb_get(&compiler->symbol_table, &symbol)))
Henri Verbeet
committed
{
struct vkd3d_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
s->info.reg.dcl_mask |= signature->elements[i].mask;
Henri Verbeet
committed
continue;
Henri Verbeet
committed
}
Henri Verbeet
committed
vkd3d_symbol_set_register_info(&symbol, vicp_id, SpvStorageClassPrivate,
VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL);
Henri Verbeet
committed
symbol.info.reg.dcl_mask = signature->elements[i].mask;
Henri Verbeet
committed
symbol.info.reg.is_aggregate = true;
vkd3d_dxbc_compiler_put_symbol(compiler, &symbol);
}
}
/* 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);
if (compiler->xfb_info && compiler->xfb_info->element_count
&& compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY)
vkd3d_dxbc_compiler_emit_point_size(compiler);
Henri Verbeet
committed
if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL)
vkd3d_dxbc_compiler_emit_hull_shader_inputs(compiler);
Henri Verbeet
committed
static bool is_dcl_instruction(enum vkd3d_shader_opcode 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
Elizabeth Figura
committed
++compiler->location.line;
Józef Kucia
committed
return ret;
int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv)
const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info;
Henri Verbeet
committed
const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info;
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 (info && (ds_info = vkd3d_find_struct(compile_info->next, SPIRV_DOMAIN_SHADER_TARGET_INFO)))
Henri Verbeet
committed
vkd3d_dxbc_compiler_emit_tessellator_output_primitive(compiler, ds_info->output_primitive);
vkd3d_dxbc_compiler_emit_tessellator_partitioning(compiler, ds_info->partitioning);
}
else if (vkd3d_dxbc_compiler_is_opengl_target(compiler))
{
Henri Verbeet
committed
ERR("vkd3d_shader_spirv_domain_shader_target_info is 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->strip_debug)
vkd3d_spirv_stream_clear(&builder->debug_stream);
if (!vkd3d_spirv_compile_module(builder, spirv, vkd3d_dxbc_compiler_get_entry_point_name(compiler)))
return VKD3D_ERROR;
if (TRACE_ON())
{
Henri Verbeet
committed
enum vkd3d_shader_spirv_environment environment = vkd3d_dxbc_compiler_get_target_environment(compiler);
vkd3d_spirv_dump(spirv, environment);
vkd3d_spirv_validate(spirv, environment);
Henri Verbeet
committed
if (compiler->failed)
return VKD3D_ERROR_INVALID_SHADER;
if (compile_info->target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT)
{
struct vkd3d_shader_code text;
enum vkd3d_shader_spirv_environment environment = vkd3d_dxbc_compiler_get_target_environment(compiler);
if (vkd3d_spirv_binary_to_text(spirv, environment,
get_binary_to_text_options(compiler->formatting), &text) != VKD3D_OK)
return VKD3D_ERROR;
*spirv = text;
}
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);
Conor McCarthy
committed
vkd3d_string_buffer_cache_cleanup(&compiler->string_buffers);
vkd3d_free(compiler);
}