libs/vkd3d-shader: Translate atomic_iadd instructions.

This commit is contained in:
Józef Kucia 2017-08-21 12:41:07 +02:00
parent d287591889
commit 03e189386a

View File

@ -629,6 +629,15 @@ static uint32_t vkd3d_spirv_build_op_tr2(struct vkd3d_spirv_builder *builder,
operands, ARRAY_SIZE(operands));
}
static uint32_t vkd3d_spirv_build_op_tr3(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, SpvOp op, uint32_t result_type,
uint32_t operand0, uint32_t operand1, uint32_t operand2)
{
uint32_t operands[] = {operand0, operand1, operand2};
return vkd3d_spirv_build_op_trv(builder, stream, op, result_type,
operands, ARRAY_SIZE(operands));
}
static uint32_t vkd3d_spirv_build_op_tr1v(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, SpvOp op, uint32_t result_type,
uint32_t operand0, const uint32_t *operands, unsigned int operand_count)
@ -1068,9 +1077,8 @@ static void vkd3d_spirv_build_op_store(struct vkd3d_spirv_builder *builder,
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)
{
uint32_t operands[] = {condition_id, object0_id, object1_id};
return vkd3d_spirv_build_op_trv(builder, &builder->function_stream, SpvOpSelect,
result_type, operands, ARRAY_SIZE(operands));
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_return(struct vkd3d_spirv_builder *builder)
@ -1204,6 +1212,13 @@ static uint32_t vkd3d_spirv_build_op_bitcast(struct vkd3d_spirv_builder *builder
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)
{
@ -4105,6 +4120,7 @@ static void vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_
struct vkd3d_shader_image
{
uint32_t id;
uint32_t image_id;
uint32_t sampler_id;
uint32_t sampled_image_id;
@ -4114,15 +4130,23 @@ struct vkd3d_shader_image
const struct vkd3d_spirv_resource_type *resource_type_info;
};
#define VKD3D_IMAGE_FLAG_NONE 0x0
#define VKD3D_IMAGE_FLAG_DEPTH 0x1
#define VKD3D_IMAGE_FLAG_NO_LOAD 0x2
static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compiler,
struct vkd3d_shader_image *image, const struct vkd3d_shader_register *resource_reg,
bool depth_comparison)
unsigned int flags)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_symbol *resource_symbol;
struct vkd3d_symbol resource_key;
bool load, depth_comparison;
struct rb_entry *entry;
load = !(flags & VKD3D_IMAGE_FLAG_NO_LOAD);
depth_comparison = flags & VKD3D_IMAGE_FLAG_DEPTH;
vkd3d_symbol_make_resource(&resource_key, resource_reg);
entry = rb_get(&compiler->symbol_table, &resource_key);
assert(entry);
@ -4132,8 +4156,9 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil
image->image_type_id = resource_symbol->info.resource.type_id;
image->resource_type_info = resource_symbol->info.resource.resource_type_info;
image->image_id = vkd3d_spirv_build_op_load(builder,
image->image_type_id, resource_symbol->id, SpvMemoryAccessMaskNone);
image->id = resource_symbol->id;
image->image_id = load ? vkd3d_spirv_build_op_load(builder,
image->image_type_id, image->id, SpvMemoryAccessMaskNone) : 0;
image->image_type_id = vkd3d_dxbc_compiler_get_image_type_id(compiler,
resource_reg, image->resource_type_info, image->sampled_type, depth_comparison);
@ -4144,12 +4169,12 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil
static void vkd3d_dxbc_compiler_prepare_sampled_image_for_sampler(struct vkd3d_dxbc_compiler *compiler,
struct vkd3d_shader_image *image, const struct vkd3d_shader_register *resource_reg,
uint32_t sampler_var_id, bool depth_comparison)
uint32_t sampler_var_id, unsigned int flags)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t sampled_image_type_id;
vkd3d_dxbc_compiler_prepare_image(compiler, image, resource_reg, depth_comparison);
vkd3d_dxbc_compiler_prepare_image(compiler, image, resource_reg, flags);
image->sampler_id = vkd3d_spirv_build_op_load(builder,
vkd3d_spirv_get_op_type_sampler(builder), sampler_var_id, SpvMemoryAccessMaskNone);
sampled_image_type_id = vkd3d_spirv_get_op_type_sampled_image(builder, image->image_type_id);
@ -4223,7 +4248,8 @@ static void vkd3d_dxbc_compiler_emit_sample(struct vkd3d_dxbc_compiler *compiler
if (vkd3d_shader_instruction_has_texel_offset(instruction))
FIXME("Texel offset not supported.\n");
vkd3d_dxbc_compiler_prepare_sampled_image(compiler, &image, &src[1].reg, &src[2].reg, false);
vkd3d_dxbc_compiler_prepare_sampled_image(compiler, &image,
&src[1].reg, &src[2].reg, VKD3D_IMAGE_FLAG_NONE);
sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE);
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL);
val_id = vkd3d_spirv_build_op_image_sample_implicit_lod(builder, sampled_type_id,
@ -4248,7 +4274,8 @@ static void vkd3d_dxbc_compiler_emit_sample_c(struct vkd3d_dxbc_compiler *compil
if (vkd3d_shader_instruction_has_texel_offset(instruction))
FIXME("Texel offset not supported.\n");
vkd3d_dxbc_compiler_prepare_sampled_image(compiler, &image, &src[1].reg, &src[2].reg, true);
vkd3d_dxbc_compiler_prepare_sampled_image(compiler,
&image, &src[1].reg, &src[2].reg, VKD3D_IMAGE_FLAG_DEPTH);
sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE);
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL);
ref_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0);
@ -4286,7 +4313,7 @@ static void vkd3d_dxbc_compiler_emit_store_raw(struct vkd3d_dxbc_compiler *compi
assert(src[1].reg.data_type == VKD3D_DATA_UINT);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 1);
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, false);
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, VKD3D_IMAGE_FLAG_NONE);
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0);
coordinate_id = vkd3d_spirv_build_op_shift_right_logical(builder, type_id,
coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 2));
@ -4327,7 +4354,7 @@ static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler
vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageWriteWithoutFormat);
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, false);
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, VKD3D_IMAGE_FLAG_NONE);
coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1;
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask);
/* XXX: Fix the data type. */
@ -4338,6 +4365,44 @@ static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler
SpvImageOperandsMaskNone, NULL, 0);
}
static void vkd3d_dxbc_compiler_emit_atomic_instruction(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;
uint32_t coordinate_id, sample_id, texel_pointer_id;
uint32_t ptr_type_id, type_id, val_id;
struct vkd3d_shader_image image;
DWORD coordinate_mask;
uint32_t operands[4];
unsigned int i = 0;
if (dst->reg.type == VKD3DSPR_GROUPSHAREDMEM)
{
FIXME("Compute shared memory not supported.\n");
return;
}
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, VKD3D_IMAGE_FLAG_NO_LOAD);
coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1;
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask);
sample_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id);
texel_pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder,
ptr_type_id, image.id, coordinate_id, sample_id);
val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0);
operands[i++] = texel_pointer_id;
operands[i++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvScopeDevice);
operands[i++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone);
operands[i++] = val_id;
vkd3d_spirv_build_op_trv(builder, &builder->function_stream,
SpvOpAtomicIAdd, type_id, operands, i);
}
static void vkd3d_dxbc_compiler_emit_resinfo(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
@ -4351,7 +4416,7 @@ static void vkd3d_dxbc_compiler_emit_resinfo(struct vkd3d_dxbc_compiler *compile
vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery);
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src[1].reg, false);
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src[1].reg, VKD3D_IMAGE_FLAG_NONE);
size_component_count = image.resource_type_info->coordinate_component_count;
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, size_component_count);
@ -4585,6 +4650,9 @@ void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler
case VKD3DSIH_STORE_UAV_TYPED:
vkd3d_dxbc_compiler_emit_store_uav_typed(compiler, instruction);
break;
case VKD3DSIH_ATOMIC_IADD:
vkd3d_dxbc_compiler_emit_atomic_instruction(compiler, instruction);
break;
case VKD3DSIH_RESINFO:
vkd3d_dxbc_compiler_emit_resinfo(compiler, instruction);
break;