Newer
Older
return vkd3d_spirv_build_op_r2(builder, &builder->global_stream, SpvOpTypeInt, width, signedness);
}
static uint32_t vkd3d_spirv_get_op_type_int(struct vkd3d_spirv_builder *builder,
uint32_t width, uint32_t signedness)
{
return vkd3d_spirv_build_once2(builder, SpvOpTypeInt, width, signedness,
vkd3d_spirv_build_op_type_int);
}
static uint32_t vkd3d_spirv_build_op_type_vector(struct vkd3d_spirv_builder *builder,
uint32_t component_type, uint32_t component_count)
{
return vkd3d_spirv_build_op_r2(builder, &builder->global_stream,
SpvOpTypeVector, component_type, component_count);
}
static uint32_t vkd3d_spirv_get_op_type_vector(struct vkd3d_spirv_builder *builder,
uint32_t component_type, uint32_t component_count)
{
return vkd3d_spirv_build_once2(builder, SpvOpTypeVector, component_type, component_count,
vkd3d_spirv_build_op_type_vector);
}
static uint32_t vkd3d_spirv_build_op_type_array(struct vkd3d_spirv_builder *builder,
uint32_t element_type, uint32_t length_id)
{
return vkd3d_spirv_build_op_r2(builder, &builder->global_stream,
SpvOpTypeArray, element_type, length_id);
}
static uint32_t vkd3d_spirv_get_op_type_array(struct vkd3d_spirv_builder *builder,
uint32_t element_type, uint32_t length_id)
{
return vkd3d_spirv_build_once2(builder, SpvOpTypeArray, element_type, length_id,
vkd3d_spirv_build_op_type_array);
}
static uint32_t vkd3d_spirv_build_op_type_runtime_array(struct vkd3d_spirv_builder *builder, uint32_t element_type)
{
return vkd3d_spirv_build_op_r1(builder, &builder->global_stream, SpvOpTypeRuntimeArray, element_type);
}
static uint32_t vkd3d_spirv_get_op_type_runtime_array(struct vkd3d_spirv_builder *builder, uint32_t element_type)
{
return vkd3d_spirv_build_once1(builder, SpvOpTypeRuntimeArray,
element_type, vkd3d_spirv_build_op_type_runtime_array);
}
static uint32_t vkd3d_spirv_build_op_type_struct(struct vkd3d_spirv_builder *builder,
uint32_t *members, unsigned int member_count)
{
return vkd3d_spirv_build_op_rv(builder, &builder->global_stream,
SpvOpTypeStruct, members, member_count);
}
static uint32_t vkd3d_spirv_build_op_type_sampler(struct vkd3d_spirv_builder *builder)
{
return vkd3d_spirv_build_op_r(builder, &builder->global_stream, SpvOpTypeSampler);
}
Józef Kucia
committed
static uint32_t vkd3d_spirv_get_op_type_sampler(struct vkd3d_spirv_builder *builder)
{
return vkd3d_spirv_build_once(builder, &builder->type_sampler_id, vkd3d_spirv_build_op_type_sampler);
}
/* Access qualifiers are not supported. */
static uint32_t vkd3d_spirv_build_op_type_image(struct vkd3d_spirv_builder *builder,
uint32_t sampled_type_id, SpvDim dim, uint32_t depth, uint32_t arrayed,
uint32_t ms, uint32_t sampled, SpvImageFormat format)
{
uint32_t operands[] = {sampled_type_id, dim, depth, arrayed, ms, sampled, format};
return vkd3d_spirv_build_op_rv(builder, &builder->global_stream,
SpvOpTypeImage, operands, ARRAY_SIZE(operands));
}
static uint32_t vkd3d_spirv_get_op_type_image(struct vkd3d_spirv_builder *builder,
uint32_t sampled_type_id, SpvDim dim, uint32_t depth, uint32_t arrayed,
uint32_t ms, uint32_t sampled, SpvImageFormat format)
{
uint32_t operands[] = {sampled_type_id, dim, depth, arrayed, ms, sampled, format};
return vkd3d_spirv_build_once7(builder, SpvOpTypeImage, operands,
vkd3d_spirv_build_op_type_image);
}
static uint32_t vkd3d_spirv_build_op_type_sampled_image(struct vkd3d_spirv_builder *builder,
uint32_t image_type_id)
{
return vkd3d_spirv_build_op_r1(builder, &builder->global_stream,
SpvOpTypeSampledImage, image_type_id);
}
static uint32_t vkd3d_spirv_get_op_type_sampled_image(struct vkd3d_spirv_builder *builder,
uint32_t image_type_id)
{
return vkd3d_spirv_build_once1(builder, SpvOpTypeSampledImage, image_type_id,
vkd3d_spirv_build_op_type_sampled_image);
}
static uint32_t vkd3d_spirv_build_op_type_function(struct vkd3d_spirv_builder *builder,
uint32_t return_type, const uint32_t *param_types, unsigned int param_count)
{
return vkd3d_spirv_build_op_r1v(builder, &builder->global_stream,
SpvOpTypeFunction, return_type, param_types, param_count);
}
static uint32_t vkd3d_spirv_get_op_type_function(struct vkd3d_spirv_builder *builder,
uint32_t return_type, const uint32_t *param_types, unsigned int param_count)
{
return vkd3d_spirv_build_once1v(builder, SpvOpTypeFunction, return_type,
param_types, param_count, vkd3d_spirv_build_op_type_function);
}
static uint32_t vkd3d_spirv_build_op_type_pointer(struct vkd3d_spirv_builder *builder,
uint32_t storage_class, uint32_t type_id)
{
return vkd3d_spirv_build_op_r2(builder, &builder->global_stream,
SpvOpTypePointer, storage_class, type_id);
}
static uint32_t vkd3d_spirv_get_op_type_pointer(struct vkd3d_spirv_builder *builder,
uint32_t storage_class, uint32_t type_id)
{
return vkd3d_spirv_build_once2(builder, SpvOpTypePointer, storage_class, type_id,
vkd3d_spirv_build_op_type_pointer);
}
/* Types larger than 32-bits are not supported. */
static uint32_t vkd3d_spirv_build_op_constant(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t value)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->global_stream,
SpvOpConstant, result_type, value);
}
static uint32_t vkd3d_spirv_get_op_constant(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t value)
{
return vkd3d_spirv_build_once2(builder, SpvOpConstant, result_type, value,
vkd3d_spirv_build_op_constant);
}
static uint32_t vkd3d_spirv_build_op_constant64(struct vkd3d_spirv_builder *builder,
uint32_t result_type, const uint32_t *values, unsigned int value_count)
{
assert(value_count == 2);
return vkd3d_spirv_build_op_trv(builder, &builder->global_stream,
SpvOpConstant, result_type, values, value_count);
}
static uint32_t vkd3d_spirv_get_op_constant64(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint64_t value)
{
return vkd3d_spirv_build_once1v(builder, SpvOpConstant, result_type,
(const uint32_t *)&value, 2, vkd3d_spirv_build_op_constant64);
}
static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder,
uint32_t result_type, const uint32_t *constituents, unsigned int constituent_count)
{
return vkd3d_spirv_build_op_trv(builder, &builder->global_stream,
SpvOpConstantComposite, result_type, constituents, constituent_count);
}
static uint32_t vkd3d_spirv_get_op_constant_composite(struct vkd3d_spirv_builder *builder,
uint32_t result_type, const uint32_t *constituents, unsigned int constituent_count)
{
return vkd3d_spirv_build_once1v(builder, SpvOpConstantComposite, result_type,
constituents, constituent_count, vkd3d_spirv_build_op_constant_composite);
}
static uint32_t vkd3d_spirv_build_op_spec_constant(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t value)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->global_stream,
SpvOpSpecConstant, result_type, value);
}
static uint32_t vkd3d_spirv_build_op_variable(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, uint32_t type_id, uint32_t storage_class, uint32_t initializer)
return vkd3d_spirv_build_op_tr1v(builder, stream,
SpvOpVariable, type_id, storage_class, &initializer, !!initializer);
static uint32_t vkd3d_spirv_build_op_function(struct vkd3d_spirv_builder *builder,
Józef Kucia
committed
uint32_t result_type, uint32_t result_id, uint32_t function_control, uint32_t function_type)
Józef Kucia
committed
vkd3d_spirv_build_op3v(&builder->function_stream,
SpvOpFunction, result_type, result_id, function_control, &function_type, 1);
return result_id;
}
static uint32_t vkd3d_spirv_build_op_function_parameter(struct vkd3d_spirv_builder *builder,
uint32_t result_type)
{
return vkd3d_spirv_build_op_tr(builder, &builder->function_stream,
SpvOpFunctionParameter, result_type);
}
static void vkd3d_spirv_build_op_function_end(struct vkd3d_spirv_builder *builder)
{
vkd3d_spirv_build_op(&builder->function_stream, SpvOpFunctionEnd);
}
Józef Kucia
committed
static uint32_t vkd3d_spirv_build_op_function_call(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t function_id, const uint32_t *arguments, unsigned int argument_count)
{
return vkd3d_spirv_build_op_tr1v(builder, &builder->function_stream,
SpvOpFunctionCall, result_type, function_id, arguments, argument_count);
}
static uint32_t vkd3d_spirv_build_op_undef(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, uint32_t type_id)
{
return vkd3d_spirv_build_op_tr(builder, stream, SpvOpUndef, type_id);
}
static uint32_t vkd3d_spirv_build_op_access_chain(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t base_id, uint32_t *indexes, uint32_t index_count)
{
return vkd3d_spirv_build_op_tr1v(builder, &builder->function_stream,
SpvOpAccessChain, result_type, base_id, indexes, index_count);
}
static uint32_t vkd3d_spirv_build_op_access_chain1(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t base_id, uint32_t index)
{
return vkd3d_spirv_build_op_access_chain(builder, result_type, base_id, &index, 1);
}
static uint32_t vkd3d_spirv_build_op_in_bounds_access_chain(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t base_id, uint32_t *indexes, uint32_t index_count)
{
return vkd3d_spirv_build_op_tr1v(builder, &builder->function_stream,
SpvOpInBoundsAccessChain, result_type, base_id, indexes, index_count);
}
static uint32_t vkd3d_spirv_build_op_in_bounds_access_chain1(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t base_id, uint32_t index)
{
return vkd3d_spirv_build_op_in_bounds_access_chain(builder, result_type, base_id, &index, 1);
}
static uint32_t vkd3d_spirv_build_op_vector_shuffle(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t vector1_id, uint32_t vector2_id,
const uint32_t *components, uint32_t component_count)
{
return vkd3d_spirv_build_op_tr2v(builder, &builder->function_stream, SpvOpVectorShuffle,
result_type, vector1_id, vector2_id, components, component_count);
}
static uint32_t vkd3d_spirv_build_op_composite_construct(struct vkd3d_spirv_builder *builder,
uint32_t result_type, const uint32_t *constituents, unsigned int constituent_count)
{
return vkd3d_spirv_build_op_trv(builder, &builder->function_stream, SpvOpCompositeConstruct,
result_type, constituents, constituent_count);
}
static uint32_t vkd3d_spirv_build_op_composite_extract(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t composite_id, const uint32_t *indexes, unsigned int index_count)
{
return vkd3d_spirv_build_op_tr1v(builder, &builder->function_stream, SpvOpCompositeExtract,
result_type, composite_id, indexes, index_count);
}
static uint32_t vkd3d_spirv_build_op_composite_extract1(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t composite_id, uint32_t index)
{
return vkd3d_spirv_build_op_composite_extract(builder, result_type, composite_id, &index, 1);
}
static uint32_t vkd3d_spirv_build_op_composite_insert(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t object_id, uint32_t composite_id,
const uint32_t *indexes, unsigned int index_count)
{
return vkd3d_spirv_build_op_tr2v(builder, &builder->function_stream, SpvOpCompositeInsert,
result_type, object_id, composite_id, indexes, index_count);
}
static uint32_t vkd3d_spirv_build_op_composite_insert1(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t object_id, uint32_t composite_id, uint32_t index)
{
return vkd3d_spirv_build_op_composite_insert(builder, result_type, object_id, composite_id, &index, 1);
}
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
static uint32_t vkd3d_spirv_build_op_load(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t pointer_id, uint32_t memory_access)
{
if (!memory_access)
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpLoad,
result_type, pointer_id);
else
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpLoad,
result_type, pointer_id, memory_access);
}
static void vkd3d_spirv_build_op_store(struct vkd3d_spirv_builder *builder,
uint32_t pointer_id, uint32_t object_id, uint32_t memory_access)
{
if (!memory_access)
return vkd3d_spirv_build_op2(&builder->function_stream, SpvOpStore,
pointer_id, object_id);
else
return vkd3d_spirv_build_op3(&builder->function_stream, SpvOpStore,
pointer_id, object_id, memory_access);
}
static void vkd3d_spirv_build_op_copy_memory(struct vkd3d_spirv_builder *builder,
uint32_t target_id, uint32_t source_id, uint32_t memory_access)
{
if (!memory_access)
return vkd3d_spirv_build_op2(&builder->function_stream, SpvOpCopyMemory,
target_id, source_id);
else
return vkd3d_spirv_build_op3(&builder->function_stream, SpvOpCopyMemory,
target_id, source_id, memory_access);
}
static uint32_t vkd3d_spirv_build_op_select(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t condition_id, uint32_t object0_id, uint32_t object1_id)
{
return vkd3d_spirv_build_op_tr3(builder, &builder->function_stream,
SpvOpSelect, result_type, condition_id, object0_id, object1_id);
}
static void vkd3d_spirv_build_op_kill(struct vkd3d_spirv_builder *builder)
{
vkd3d_spirv_build_op(&builder->function_stream, SpvOpKill);
}
static void vkd3d_spirv_build_op_demote_to_helper_invocation(struct vkd3d_spirv_builder *builder)
{
vkd3d_spirv_build_op(&builder->function_stream, SpvOpDemoteToHelperInvocationEXT);
}
static void vkd3d_spirv_build_op_return(struct vkd3d_spirv_builder *builder)
{
vkd3d_spirv_build_op(&builder->function_stream, SpvOpReturn);
}
static uint32_t vkd3d_spirv_build_op_label(struct vkd3d_spirv_builder *builder,
uint32_t label_id)
{
vkd3d_spirv_build_op1(&builder->function_stream, SpvOpLabel, label_id);
return label_id;
}
/* Loop control parameters are not supported. */
static void vkd3d_spirv_build_op_loop_merge(struct vkd3d_spirv_builder *builder,
uint32_t merge_block, uint32_t continue_target, SpvLoopControlMask loop_control)
{
vkd3d_spirv_build_op3(&builder->function_stream, SpvOpLoopMerge,
merge_block, continue_target, loop_control);
}
static void vkd3d_spirv_build_op_selection_merge(struct vkd3d_spirv_builder *builder,
uint32_t merge_block, uint32_t selection_control)
{
vkd3d_spirv_build_op2(&builder->function_stream, SpvOpSelectionMerge,
merge_block, selection_control);
}
static void vkd3d_spirv_build_op_branch(struct vkd3d_spirv_builder *builder, uint32_t label)
{
vkd3d_spirv_build_op1(&builder->function_stream, SpvOpBranch, label);
}
/* Branch weights are not supported. */
static void vkd3d_spirv_build_op_branch_conditional(struct vkd3d_spirv_builder *builder,
uint32_t condition, uint32_t true_label, uint32_t false_label)
{
vkd3d_spirv_build_op3(&builder->function_stream, SpvOpBranchConditional,
condition, true_label, false_label);
}
static void vkd3d_spirv_build_op_switch(struct vkd3d_spirv_builder *builder,
uint32_t selector, uint32_t default_label, uint32_t *targets, unsigned int target_count)
{
vkd3d_spirv_build_op2v(&builder->function_stream, SpvOpSwitch,
selector, default_label, targets, 2 * target_count);
}
Józef Kucia
committed
static uint32_t vkd3d_spirv_build_op_iadd(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpIAdd, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_imul(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpIMul, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_udiv(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpUDiv, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_umod(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpUMod, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_isub(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpISub, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_fdiv(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpFDiv, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_fnegate(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpFNegate, result_type, operand);
}
static uint32_t vkd3d_spirv_build_op_snegate(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpSNegate, result_type, operand);
}
static uint32_t vkd3d_spirv_build_op_and(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpBitwiseAnd, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_shift_left_logical(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t base, uint32_t shift)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpShiftLeftLogical, result_type, base, shift);
}
static uint32_t vkd3d_spirv_build_op_shift_right_logical(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t base, uint32_t shift)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpShiftRightLogical, result_type, base, shift);
}
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
static uint32_t vkd3d_spirv_build_op_logical_and(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpLogicalAnd, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_uless_than(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpULessThan, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_uless_than_equal(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpULessThanEqual, result_type, operand0, operand1);
}
static uint32_t vkd3d_spirv_build_op_convert_utof(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t unsigned_value)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpConvertUToF, result_type, unsigned_value);
}
static uint32_t vkd3d_spirv_build_op_bitcast(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpBitcast, result_type, operand);
}
static uint32_t vkd3d_spirv_build_op_image_texel_pointer(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id, uint32_t coordinate_id, uint32_t sample_id)
{
return vkd3d_spirv_build_op_tr3(builder, &builder->function_stream,
SpvOpImageTexelPointer, result_type, image_id, coordinate_id, sample_id);
}
static uint32_t vkd3d_spirv_build_op_sampled_image(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id, uint32_t sampler_id)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpSampledImage, result_type, image_id, sampler_id);
}
static uint32_t vkd3d_spirv_build_op_image(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t sampled_image_id)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpImage, result_type, sampled_image_id);
}
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
static uint32_t vkd3d_spirv_build_image_instruction(struct vkd3d_spirv_builder *builder,
SpvOp op, uint32_t result_type, const uint32_t *operands, unsigned int operand_count,
uint32_t image_operands_mask, const uint32_t *image_operands, unsigned int image_operand_count)
{
unsigned int index = 0, i;
uint32_t w[10];
assert(operand_count <= ARRAY_SIZE(w));
for (i = 0; i < operand_count; ++i)
w[index++] = operands[i];
if (image_operands_mask)
{
assert(index + 1 + image_operand_count <= ARRAY_SIZE(w));
w[index++] = image_operands_mask;
for (i = 0; i < image_operand_count; ++i)
w[index++] = image_operands[i];
}
return vkd3d_spirv_build_op_trv(builder, &builder->function_stream,
op, result_type, w, index);
}
static uint32_t vkd3d_spirv_build_op_image_sample(struct vkd3d_spirv_builder *builder,
SpvOp op, uint32_t result_type, uint32_t sampled_image_id, uint32_t coordinate_id,
uint32_t image_operands_mask, const uint32_t *image_operands, unsigned int image_operand_count)
const uint32_t operands[] = {sampled_image_id, coordinate_id};
if (op == SpvOpImageSampleExplicitLod)
assert(image_operands_mask & (SpvImageOperandsLodMask | SpvImageOperandsGradMask));
else
assert(op == SpvOpImageSampleImplicitLod);
return vkd3d_spirv_build_image_instruction(builder, op, result_type,
operands, ARRAY_SIZE(operands), image_operands_mask, image_operands, image_operand_count);
static uint32_t vkd3d_spirv_build_op_image_sample_dref(struct vkd3d_spirv_builder *builder,
SpvOp op, uint32_t result_type, uint32_t sampled_image_id, uint32_t coordinate_id, uint32_t dref_id,
uint32_t image_operands_mask, const uint32_t *image_operands, unsigned int image_operand_count)
const uint32_t operands[] = {sampled_image_id, coordinate_id, dref_id};
if (op == SpvOpImageSampleDrefExplicitLod)
assert(image_operands_mask & (SpvImageOperandsLodMask | SpvImageOperandsGradMask));
else
assert(op == SpvOpImageSampleDrefImplicitLod);
return vkd3d_spirv_build_image_instruction(builder, op, result_type,
operands, ARRAY_SIZE(operands), image_operands_mask, image_operands, image_operand_count);
static uint32_t vkd3d_spirv_build_op_image_gather(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t sampled_image_id, uint32_t coordinate_id, uint32_t component_id,
uint32_t image_operands_mask, const uint32_t *image_operands, unsigned int image_operand_count)
{
const uint32_t operands[] = {sampled_image_id, coordinate_id, component_id};
return vkd3d_spirv_build_image_instruction(builder, SpvOpImageGather, result_type,
operands, ARRAY_SIZE(operands), image_operands_mask, image_operands, image_operand_count);
}
static uint32_t vkd3d_spirv_build_op_image_dref_gather(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t sampled_image_id, uint32_t coordinate_id, uint32_t dref_id,
uint32_t image_operands_mask, const uint32_t *image_operands, unsigned int image_operand_count)
{
const uint32_t operands[] = {sampled_image_id, coordinate_id, dref_id};
return vkd3d_spirv_build_image_instruction(builder, SpvOpImageDrefGather, result_type,
operands, ARRAY_SIZE(operands), image_operands_mask, image_operands, image_operand_count);
}
static uint32_t vkd3d_spirv_build_op_image_fetch(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id, uint32_t coordinate_id,
uint32_t image_operands_mask, const uint32_t *image_operands, unsigned int image_operand_count)
const uint32_t operands[] = {image_id, coordinate_id};
return vkd3d_spirv_build_image_instruction(builder, SpvOpImageFetch, result_type,
operands, ARRAY_SIZE(operands), image_operands_mask, image_operands, image_operand_count);
static uint32_t vkd3d_spirv_build_op_image_read(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id, uint32_t coordinate_id,
uint32_t image_operands_mask, const uint32_t *image_operands, unsigned int image_operand_count)
const uint32_t operands[] = {image_id, coordinate_id};
return vkd3d_spirv_build_image_instruction(builder, SpvOpImageRead, result_type,
operands, ARRAY_SIZE(operands), image_operands_mask, image_operands, image_operand_count);
static void vkd3d_spirv_build_op_image_write(struct vkd3d_spirv_builder *builder,
uint32_t image_id, uint32_t coordinate_id, uint32_t texel_id,
uint32_t image_operands, const uint32_t *operands, unsigned int operand_count)
{
if (image_operands)
FIXME("Image operands not supported.\n");
vkd3d_spirv_build_op3(&builder->function_stream, SpvOpImageWrite,
image_id, coordinate_id, texel_id);
}
static uint32_t vkd3d_spirv_build_op_array_length(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t struct_id, uint32_t member_id)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpArrayLength, result_type, struct_id, member_id);
}
static uint32_t vkd3d_spirv_build_op_image_query_size_lod(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id, uint32_t lod_id)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpImageQuerySizeLod, result_type, image_id, lod_id);
}
static uint32_t vkd3d_spirv_build_op_image_query_size(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpImageQuerySize, result_type, image_id);
}
static uint32_t vkd3d_spirv_build_op_image_query_levels(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpImageQueryLevels, result_type, image_id);
}
static uint32_t vkd3d_spirv_build_op_image_query_samples(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpImageQuerySamples, result_type, image_id);
}
static uint32_t vkd3d_spirv_build_op_image_query_lod(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t image_id, uint32_t coordinate_id)
{
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpImageQueryLod, result_type, image_id, coordinate_id);
}
static void vkd3d_spirv_build_op_emit_vertex(struct vkd3d_spirv_builder *builder)
{
return vkd3d_spirv_build_op(&builder->function_stream, SpvOpEmitVertex);
}
static void vkd3d_spirv_build_op_end_primitive(struct vkd3d_spirv_builder *builder)
{
return vkd3d_spirv_build_op(&builder->function_stream, SpvOpEndPrimitive);
}
static void vkd3d_spirv_build_op_control_barrier(struct vkd3d_spirv_builder *builder,
uint32_t execution_id, uint32_t memory_id, uint32_t memory_semantics_id)
{
vkd3d_spirv_build_op3(&builder->function_stream,
SpvOpControlBarrier, execution_id, memory_id, memory_semantics_id);
}
static void vkd3d_spirv_build_op_memory_barrier(struct vkd3d_spirv_builder *builder,
uint32_t memory_id, uint32_t memory_semantics_id)
{
vkd3d_spirv_build_op2(&builder->function_stream,
SpvOpMemoryBarrier, memory_id, memory_semantics_id);
}
static uint32_t vkd3d_spirv_build_op_glsl_std450_tr1(struct vkd3d_spirv_builder *builder,
enum GLSLstd450 op, uint32_t result_type, uint32_t operand)
{
uint32_t id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
return vkd3d_spirv_build_op_ext_inst(builder, result_type, id, op, &operand, 1);
}
static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand)
{
return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450FAbs, result_type, operand);
}
static uint32_t vkd3d_spirv_build_op_glsl_std450_sin(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand)
{
return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Sin, result_type, operand);
}
static uint32_t vkd3d_spirv_build_op_glsl_std450_cos(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand)
{
return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Cos, result_type, operand);
static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t x, uint32_t min, uint32_t max)
{
uint32_t glsl_std450_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
uint32_t operands[] = {x, min, max};
return vkd3d_spirv_build_op_ext_inst(builder, result_type, glsl_std450_id,
GLSLstd450NClamp, operands, ARRAY_SIZE(operands));
static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
Henri Verbeet
committed
enum vkd3d_shader_component_type component_type, unsigned int component_count)
uint32_t scalar_id;
if (component_count == 1)
switch (component_type)
Henri Verbeet
committed
case VKD3D_SHADER_COMPONENT_VOID:
return vkd3d_spirv_get_op_type_void(builder);
break;
Henri Verbeet
committed
case VKD3D_SHADER_COMPONENT_FLOAT:
return vkd3d_spirv_get_op_type_float(builder, 32);
break;
Henri Verbeet
committed
case VKD3D_SHADER_COMPONENT_INT:
case VKD3D_SHADER_COMPONENT_UINT:
return vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT);
break;
Henri Verbeet
committed
case VKD3D_SHADER_COMPONENT_BOOL:
return vkd3d_spirv_get_op_type_bool(builder);
break;
case VKD3D_SHADER_COMPONENT_DOUBLE:
return vkd3d_spirv_get_op_type_float(builder, 64);
default:
FIXME("Unhandled component type %#x.\n", component_type);
return 0;
else
{
Henri Verbeet
committed
assert(component_type != VKD3D_SHADER_COMPONENT_VOID);
scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
return vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count);
}
static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point)
vkd3d_spirv_stream_init(&builder->debug_stream);
vkd3d_spirv_stream_init(&builder->annotation_stream);
vkd3d_spirv_stream_init(&builder->global_stream);
vkd3d_spirv_stream_init(&builder->function_stream);
vkd3d_spirv_stream_init(&builder->execution_mode_stream);
vkd3d_spirv_stream_init(&builder->insertion_stream);
builder->insertion_location = ~(size_t)0;
builder->current_id = 1;
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);
}
static void vkd3d_spirv_builder_begin_main_function(struct vkd3d_spirv_builder *builder)
{
uint32_t void_id, function_type_id;
Józef Kucia
committed
void_id = vkd3d_spirv_get_op_type_void(builder);
function_type_id = vkd3d_spirv_get_op_type_function(builder, void_id, NULL, 0);
vkd3d_spirv_build_op_function(builder, void_id,
builder->main_function_id, SpvFunctionControlMaskNone, function_type_id);
vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
Józef Kucia
committed
builder->main_function_location = vkd3d_spirv_stream_current_location(&builder->function_stream);
}
static void vkd3d_spirv_builder_free(struct vkd3d_spirv_builder *builder)
{
vkd3d_spirv_stream_free(&builder->debug_stream);
vkd3d_spirv_stream_free(&builder->annotation_stream);
vkd3d_spirv_stream_free(&builder->global_stream);
vkd3d_spirv_stream_free(&builder->function_stream);
vkd3d_spirv_stream_free(&builder->execution_mode_stream);
vkd3d_spirv_stream_free(&builder->insertion_stream);
vkd3d_free(builder->capabilities);
rb_destroy(&builder->declarations, vkd3d_spirv_declaration_free, NULL);
vkd3d_free(builder->iface);
static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder,
struct vkd3d_shader_code *spirv, const char *entry_point)
uint64_t capability_mask = builder->capability_mask;
struct vkd3d_spirv_stream stream;
uint32_t *code;
unsigned int i;
size_t size;
vkd3d_spirv_stream_init(&stream);
vkd3d_spirv_build_word(&stream, SpvMagicNumber);
vkd3d_spirv_build_word(&stream, VKD3D_SPIRV_VERSION);
vkd3d_spirv_build_word(&stream, VKD3D_SPIRV_GENERATOR_MAGIC);
vkd3d_spirv_build_word(&stream, builder->current_id); /* bound */
vkd3d_spirv_build_word(&stream, 0); /* schema, reserved */
/* capabilities */
for (i = 0; capability_mask; ++i)
{
if (capability_mask & 1)
vkd3d_spirv_build_op_capability(&stream, i);
capability_mask >>= 1;
}
for (i = 0; i < builder->capabilities_count; ++i)
vkd3d_spirv_build_op_capability(&stream, builder->capabilities[i]);
/* extensions */
if (vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityDrawParameters))
vkd3d_spirv_build_op_extension(&stream, "SPV_KHR_shader_draw_parameters");
if (vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityDemoteToHelperInvocationEXT))
vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_demote_to_helper_invocation");
if (vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityRuntimeDescriptorArrayEXT)
|| vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityUniformBufferArrayDynamicIndexing)
|| vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT)
|| vkd3d_spirv_capability_is_enabled(builder, SpvCapabilitySampledImageArrayDynamicIndexing)
|| vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageBufferArrayDynamicIndexing)
|| vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT)
|| vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageImageArrayDynamicIndexing)
|| vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityShaderNonUniformEXT))
vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_descriptor_indexing");
if (vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStencilExportEXT))
vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_shader_stencil_export");
if (builder->ext_instr_set_glsl_450)
vkd3d_spirv_build_op_ext_inst_import(&stream, builder->ext_instr_set_glsl_450, "GLSL.std.450");
/* entry point declarations */
vkd3d_spirv_build_op_memory_model(&stream, SpvAddressingModelLogical, SpvMemoryModelGLSL450);
vkd3d_spirv_build_op_entry_point(&stream, builder->execution_model, builder->main_function_id,
entry_point, builder->iface, builder->iface_element_count);
/* execution mode declarations */
if (builder->invocation_count)
vkd3d_spirv_build_op_execution_mode(&builder->execution_mode_stream,
builder->main_function_id, SpvExecutionModeInvocations, &builder->invocation_count, 1);
vkd3d_spirv_stream_append(&stream, &builder->execution_mode_stream);
vkd3d_spirv_stream_append(&stream, &builder->debug_stream);
vkd3d_spirv_stream_append(&stream, &builder->annotation_stream);
vkd3d_spirv_stream_append(&stream, &builder->global_stream);
vkd3d_spirv_stream_append(&stream, &builder->function_stream);
if (!(code = vkd3d_calloc(stream.word_count, sizeof(*code))))
{
vkd3d_spirv_stream_free(&stream);
return false;
}
size = stream.word_count * sizeof(*code);
memcpy(code, stream.words, size);
vkd3d_spirv_stream_free(&stream);
spirv->code = code;
spirv->size = size;
Józef Kucia
committed
static const struct vkd3d_spirv_resource_type
{
enum vkd3d_shader_resource_type resource_type;
SpvDim dim;
uint32_t arrayed;
uint32_t ms;
unsigned int coordinate_component_count;
unsigned int offset_component_count;
Józef Kucia
committed
SpvCapability capability;
SpvCapability uav_capability;
}
vkd3d_spirv_resource_type_table[] =
{
{VKD3D_SHADER_RESOURCE_BUFFER, SpvDimBuffer, 0, 0, 1, 0,
Józef Kucia
committed
SpvCapabilitySampledBuffer, SpvCapabilityImageBuffer},
{VKD3D_SHADER_RESOURCE_TEXTURE_1D, SpvDim1D, 0, 0, 1, 1,
Józef Kucia
committed
SpvCapabilitySampled1D, SpvCapabilityImage1D},
{VKD3D_SHADER_RESOURCE_TEXTURE_2DMS, SpvDim2D, 0, 1, 2, 2},
{VKD3D_SHADER_RESOURCE_TEXTURE_2D, SpvDim2D, 0, 0, 2, 2},
{VKD3D_SHADER_RESOURCE_TEXTURE_3D, SpvDim3D, 0, 0, 3, 3},
{VKD3D_SHADER_RESOURCE_TEXTURE_CUBE, SpvDimCube, 0, 0, 3, 0},
{VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY, SpvDim1D, 1, 0, 2, 1,
Józef Kucia
committed
SpvCapabilitySampled1D, SpvCapabilityImage1D},
{VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY, SpvDim2D, 1, 0, 3, 2},
{VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY, SpvDim2D, 1, 1, 3, 2},
{VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY, SpvDimCube, 1, 0, 4, 0,
Józef Kucia
committed
SpvCapabilitySampledCubeArray, SpvCapabilityImageCubeArray},
};
static const struct vkd3d_spirv_resource_type *vkd3d_get_spirv_resource_type(
enum vkd3d_shader_resource_type resource_type)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(vkd3d_spirv_resource_type_table); ++i)
{
const struct vkd3d_spirv_resource_type* current = &vkd3d_spirv_resource_type_table[i];
if (current->resource_type == resource_type)
return current;
}
FIXME("Unhandled resource type %#x.\n", resource_type);
return NULL;
}
struct vkd3d_symbol_register
{
enum vkd3d_shader_register_type type;
unsigned int idx;
};
struct vkd3d_symbol_resource
{
enum vkd3d_shader_register_type type;
unsigned int idx;
};
struct vkd3d_symbol_sampler
{
unsigned int id;
};
struct vkd3d_symbol_combined_sampler
{
enum vkd3d_shader_register_type resource_type;
unsigned int resource_id;
unsigned int sampler_space;
unsigned int sampler_index;
Conor McCarthy
committed
struct vkd3d_symbol_descriptor_array
{
uint32_t ptr_type_id;
unsigned int set;
unsigned int binding;
Conor McCarthy
committed
unsigned int push_constant_index;
Conor McCarthy
committed
};
struct vkd3d_symbol_register_data
{
SpvStorageClass storage_class;
uint32_t member_idx;
Henri Verbeet
committed
enum vkd3d_shader_component_type component_type;
unsigned int write_mask;
uint32_t dcl_mask;
unsigned int structure_stride;
unsigned int binding_base_idx;
bool is_aggregate; /* An aggregate, i.e. a structure or an array. */
bool is_dynamically_indexed; /* If member_idx is a variable ID instead of a constant. */
struct vkd3d_symbol_resource_data
{
Conor McCarthy
committed
struct vkd3d_shader_register_range range;
Henri Verbeet
committed
enum vkd3d_shader_component_type sampled_type;
Józef Kucia
committed
const struct vkd3d_spirv_resource_type *resource_type_info;
unsigned int structure_stride;
bool raw;
unsigned int binding_base_idx;
uint32_t uav_counter_id;
const struct vkd3d_symbol *uav_counter_array;
unsigned int uav_counter_base_idx;
struct vkd3d_symbol_sampler_data
{
Conor McCarthy
committed
struct vkd3d_shader_register_range range;
Conor McCarthy
committed
struct vkd3d_descriptor_binding_address
{
unsigned int binding_base_idx;
unsigned int push_constant_index;
};