mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader: Allow plain storage buffers to be used for buffer UAVs.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1496dc054e
commit
ffe0dca779
@ -40,9 +40,22 @@ enum vkd3d_shader_structure_type
|
|||||||
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This also affects UAV counters in Vulkan environments. In OpenGL
|
||||||
|
* environments, atomic counter buffers are always used for UAV counters. */
|
||||||
|
enum vkd3d_shader_compile_option_buffer_uav
|
||||||
|
{
|
||||||
|
/* Use buffer textures for buffer UAVs, this is the default. */
|
||||||
|
VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV_STORAGE_TEXEL_BUFFER = 0x00000000,
|
||||||
|
/* Use storage buffers for buffer UAVs. */
|
||||||
|
VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV_STORAGE_BUFFER = 0x00000001,
|
||||||
|
|
||||||
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV),
|
||||||
|
};
|
||||||
|
|
||||||
enum vkd3d_shader_compile_option_name
|
enum vkd3d_shader_compile_option_name
|
||||||
{
|
{
|
||||||
VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG = 0x00000001,
|
VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG = 0x00000001,
|
||||||
|
VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV = 0x00000002, /* vkd3d_shader_compile_option_buffer_uav */
|
||||||
|
|
||||||
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
|
||||||
};
|
};
|
||||||
|
@ -965,6 +965,17 @@ static uint32_t vkd3d_spirv_get_op_type_array(struct vkd3d_spirv_builder *builde
|
|||||||
vkd3d_spirv_build_op_type_array);
|
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,
|
static uint32_t vkd3d_spirv_build_op_type_struct(struct vkd3d_spirv_builder *builder,
|
||||||
uint32_t *members, unsigned int member_count)
|
uint32_t *members, unsigned int member_count)
|
||||||
{
|
{
|
||||||
@ -1517,6 +1528,13 @@ static void vkd3d_spirv_build_op_image_write(struct vkd3d_spirv_builder *builder
|
|||||||
image_id, coordinate_id, texel_id);
|
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,
|
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)
|
uint32_t result_type, uint32_t image_id, uint32_t lod_id)
|
||||||
{
|
{
|
||||||
@ -2047,6 +2065,7 @@ struct vkd3d_dxbc_compiler
|
|||||||
bool failed;
|
bool failed;
|
||||||
|
|
||||||
bool strip_debug;
|
bool strip_debug;
|
||||||
|
bool ssbo_uavs;
|
||||||
|
|
||||||
struct rb_tree symbol_table;
|
struct rb_tree symbol_table;
|
||||||
uint32_t temp_id;
|
uint32_t temp_id;
|
||||||
@ -2168,6 +2187,15 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
|
|||||||
compiler->strip_debug = !!option->value;
|
compiler->strip_debug = !!option->value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV:
|
||||||
|
if (option->value == VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV_STORAGE_TEXEL_BUFFER)
|
||||||
|
compiler->ssbo_uavs = false;
|
||||||
|
else if (option->value == VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV_STORAGE_BUFFER)
|
||||||
|
compiler->ssbo_uavs = true;
|
||||||
|
else
|
||||||
|
WARN("Ignoring unrecognised value %#x for option %#x.\n", option->value, option->name);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value);
|
WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value);
|
||||||
break;
|
break;
|
||||||
@ -2207,6 +2235,12 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
|
|||||||
return compiler;
|
return compiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool vkd3d_dxbc_compiler_use_storage_buffer(const struct vkd3d_dxbc_compiler *compiler,
|
||||||
|
const struct vkd3d_symbol_resource_data *resource)
|
||||||
|
{
|
||||||
|
return compiler->ssbo_uavs && resource->resource_type_info->resource_type == VKD3D_SHADER_RESOURCE_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
static enum vkd3d_shader_spirv_environment vkd3d_dxbc_compiler_get_target_environment(
|
static enum vkd3d_shader_spirv_environment vkd3d_dxbc_compiler_get_target_environment(
|
||||||
const struct vkd3d_dxbc_compiler *compiler)
|
const struct vkd3d_dxbc_compiler *compiler)
|
||||||
{
|
{
|
||||||
@ -5322,8 +5356,28 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (compiler->ssbo_uavs && is_uav && resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
|
||||||
|
{
|
||||||
|
uint32_t array_type_id, struct_id;
|
||||||
|
|
||||||
|
type_id = vkd3d_spirv_get_type_id(builder, sampled_type, 1);
|
||||||
|
|
||||||
|
array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id);
|
||||||
|
vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4);
|
||||||
|
|
||||||
|
struct_id = vkd3d_spirv_build_op_type_struct(builder, &array_type_id, 1);
|
||||||
|
vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBufferBlock, NULL, 0);
|
||||||
|
vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0);
|
||||||
|
|
||||||
|
type_id = struct_id;
|
||||||
|
storage_class = SpvStorageClassUniform;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
type_id = vkd3d_dxbc_compiler_get_image_type_id(compiler, reg, register_space,
|
type_id = vkd3d_dxbc_compiler_get_image_type_id(compiler, reg, register_space,
|
||||||
register_index, resource_type_info, sampled_type, structure_stride || raw, 0);
|
register_index, resource_type_info, sampled_type, structure_stride || raw, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
|
||||||
var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
|
var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
|
||||||
ptr_type_id, storage_class, 0);
|
ptr_type_id, storage_class, 0);
|
||||||
@ -5347,13 +5401,28 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
|
|||||||
{
|
{
|
||||||
assert(structure_stride); /* counters are valid only for structured buffers */
|
assert(structure_stride); /* counters are valid only for structured buffers */
|
||||||
|
|
||||||
|
counter_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
||||||
if (vkd3d_dxbc_compiler_is_opengl_target(compiler))
|
if (vkd3d_dxbc_compiler_is_opengl_target(compiler))
|
||||||
{
|
{
|
||||||
vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage);
|
vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage);
|
||||||
storage_class = SpvStorageClassAtomicCounter;
|
storage_class = SpvStorageClassAtomicCounter;
|
||||||
counter_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
||||||
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, counter_type_id);
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, counter_type_id);
|
||||||
}
|
}
|
||||||
|
else if (compiler->ssbo_uavs)
|
||||||
|
{
|
||||||
|
uint32_t length_id, array_type_id, struct_id;
|
||||||
|
|
||||||
|
length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 1);
|
||||||
|
array_type_id = vkd3d_spirv_build_op_type_array(builder, counter_type_id, length_id);
|
||||||
|
vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4);
|
||||||
|
|
||||||
|
struct_id = vkd3d_spirv_build_op_type_struct(builder, &array_type_id, 1);
|
||||||
|
vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBufferBlock, NULL, 0);
|
||||||
|
vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0);
|
||||||
|
|
||||||
|
storage_class = SpvStorageClassUniform;
|
||||||
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, struct_id);
|
||||||
|
}
|
||||||
|
|
||||||
counter_var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
|
counter_var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
|
||||||
ptr_type_id, storage_class, 0);
|
ptr_type_id, storage_class, 0);
|
||||||
@ -7602,19 +7671,53 @@ static uint32_t vkd3d_dxbc_compiler_emit_raw_structured_addressing(
|
|||||||
static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc_compiler *compiler,
|
static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc_compiler *compiler,
|
||||||
const struct vkd3d_shader_instruction *instruction)
|
const struct vkd3d_shader_instruction *instruction)
|
||||||
{
|
{
|
||||||
|
uint32_t coordinate_id, type_id, val_id, texel_type_id, ptr_type_id, ptr_id;
|
||||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||||
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
||||||
const struct vkd3d_shader_src_param *src = instruction->src;
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
||||||
uint32_t coordinate_id, type_id, val_id, texel_type_id;
|
|
||||||
const struct vkd3d_shader_src_param *resource;
|
const struct vkd3d_shader_src_param *resource;
|
||||||
|
const struct vkd3d_symbol *resource_symbol;
|
||||||
uint32_t base_coordinate_id, component_idx;
|
uint32_t base_coordinate_id, component_idx;
|
||||||
uint32_t constituents[VKD3D_VEC4_SIZE];
|
uint32_t constituents[VKD3D_VEC4_SIZE];
|
||||||
struct vkd3d_shader_image image;
|
struct vkd3d_shader_image image;
|
||||||
|
uint32_t indices[2];
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
SpvOp op;
|
SpvOp op;
|
||||||
|
|
||||||
resource = &src[instruction->src_count - 1];
|
resource = &src[instruction->src_count - 1];
|
||||||
|
resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &resource->reg);
|
||||||
|
|
||||||
|
if (resource->reg.type == VKD3DSPR_UAV
|
||||||
|
&& vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource))
|
||||||
|
{
|
||||||
|
texel_type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1);
|
||||||
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id);
|
||||||
|
|
||||||
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
||||||
|
base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler,
|
||||||
|
type_id, resource_symbol->info.resource.structure_stride,
|
||||||
|
&src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
|
||||||
|
|
||||||
|
assert(dst->write_mask & VKD3DSP_WRITEMASK_ALL);
|
||||||
|
for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i)
|
||||||
|
{
|
||||||
|
if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
component_idx = vkd3d_swizzle_get_component(resource->swizzle, i);
|
||||||
|
coordinate_id = base_coordinate_id;
|
||||||
|
if (component_idx)
|
||||||
|
coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id,
|
||||||
|
coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx));
|
||||||
|
indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||||
|
indices[1] = coordinate_id;
|
||||||
|
|
||||||
|
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2);
|
||||||
|
constituents[j++] = vkd3d_spirv_build_op_load(builder, texel_type_id, ptr_id, SpvMemoryAccessMaskNone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (resource->reg.type == VKD3DSPR_RESOURCE)
|
if (resource->reg.type == VKD3DSPR_RESOURCE)
|
||||||
op = SpvOpImageFetch;
|
op = SpvOpImageFetch;
|
||||||
else
|
else
|
||||||
@ -7644,6 +7747,7 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc
|
|||||||
constituents[j++] = vkd3d_spirv_build_op_composite_extract1(builder,
|
constituents[j++] = vkd3d_spirv_build_op_composite_extract1(builder,
|
||||||
type_id, val_id, 0);
|
type_id, val_id, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
assert(dst->reg.data_type == VKD3D_DATA_UINT);
|
assert(dst->reg.data_type == VKD3D_DATA_UINT);
|
||||||
vkd3d_dxbc_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents);
|
vkd3d_dxbc_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents);
|
||||||
}
|
}
|
||||||
@ -7710,30 +7814,67 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured(struct vkd3d_dxbc_compile
|
|||||||
static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_compiler *compiler,
|
static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_compiler *compiler,
|
||||||
const struct vkd3d_shader_instruction *instruction)
|
const struct vkd3d_shader_instruction *instruction)
|
||||||
{
|
{
|
||||||
|
uint32_t coordinate_id, type_id, val_id, data_id, ptr_type_id, ptr_id;
|
||||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||||
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
||||||
const struct vkd3d_shader_src_param *src = instruction->src;
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
||||||
uint32_t coordinate_id, type_id, val_id, texel_id;
|
const struct vkd3d_symbol *resource_symbol;
|
||||||
const struct vkd3d_shader_src_param *texel;
|
|
||||||
uint32_t base_coordinate_id, component_idx;
|
uint32_t base_coordinate_id, component_idx;
|
||||||
|
const struct vkd3d_shader_src_param *data;
|
||||||
struct vkd3d_shader_image image;
|
struct vkd3d_shader_image image;
|
||||||
unsigned int component_count;
|
unsigned int component_count;
|
||||||
|
uint32_t indices[2];
|
||||||
|
|
||||||
|
resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &dst->reg);
|
||||||
|
|
||||||
|
if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource))
|
||||||
|
{
|
||||||
|
type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1);
|
||||||
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id);
|
||||||
|
|
||||||
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
||||||
|
base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler,
|
||||||
|
type_id, resource_symbol->info.resource.structure_stride,
|
||||||
|
&src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
|
||||||
|
|
||||||
|
data = &src[instruction->src_count - 1];
|
||||||
|
assert(data->reg.data_type == VKD3D_DATA_UINT);
|
||||||
|
val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, data, dst->write_mask);
|
||||||
|
|
||||||
|
component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
||||||
|
for (component_idx = 0; component_idx < component_count; ++component_idx)
|
||||||
|
{
|
||||||
|
data_id = component_count > 1 ?
|
||||||
|
vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx) : val_id;
|
||||||
|
|
||||||
|
coordinate_id = base_coordinate_id;
|
||||||
|
if (component_idx)
|
||||||
|
coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id,
|
||||||
|
coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx));
|
||||||
|
indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||||
|
indices[1] = coordinate_id;
|
||||||
|
|
||||||
|
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2);
|
||||||
|
vkd3d_spirv_build_op_store(builder, ptr_id, data_id, SpvMemoryAccessMaskNone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
||||||
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
||||||
assert((instruction->handler_idx == VKD3DSIH_STORE_STRUCTURED) != !image.structure_stride);
|
assert((instruction->handler_idx == VKD3DSIH_STORE_STRUCTURED) != !image.structure_stride);
|
||||||
base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler,
|
base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler,
|
||||||
type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
|
type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
|
||||||
|
|
||||||
texel = &src[instruction->src_count - 1];
|
data = &src[instruction->src_count - 1];
|
||||||
assert(texel->reg.data_type == VKD3D_DATA_UINT);
|
assert(data->reg.data_type == VKD3D_DATA_UINT);
|
||||||
val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, texel, dst->write_mask);
|
val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, data, dst->write_mask);
|
||||||
|
|
||||||
component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
||||||
for (component_idx = 0; component_idx < component_count; ++component_idx)
|
for (component_idx = 0; component_idx < component_count; ++component_idx)
|
||||||
{
|
{
|
||||||
/* Mesa Vulkan drivers require the texel parameter to be a vector. */
|
/* Mesa Vulkan drivers require the texel parameter to be a vector. */
|
||||||
texel_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler, VKD3D_SHADER_COMPONENT_UINT,
|
data_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler, VKD3D_SHADER_COMPONENT_UINT,
|
||||||
VKD3D_VEC4_SIZE, val_id, component_idx, component_count);
|
VKD3D_VEC4_SIZE, val_id, component_idx, component_count);
|
||||||
|
|
||||||
coordinate_id = base_coordinate_id;
|
coordinate_id = base_coordinate_id;
|
||||||
@ -7742,10 +7883,12 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_
|
|||||||
coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx));
|
coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx));
|
||||||
|
|
||||||
vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id,
|
vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id,
|
||||||
texel_id, SpvImageOperandsMaskNone, NULL, 0);
|
data_id, SpvImageOperandsMaskNone, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void vkd3d_dxbc_compiler_emit_store_tgsm(struct vkd3d_dxbc_compiler *compiler,
|
static void vkd3d_dxbc_compiler_emit_store_tgsm(struct vkd3d_dxbc_compiler *compiler,
|
||||||
const struct vkd3d_shader_instruction *instruction)
|
const struct vkd3d_shader_instruction *instruction)
|
||||||
{
|
{
|
||||||
@ -7808,12 +7951,32 @@ static void vkd3d_dxbc_compiler_emit_ld_uav_typed(struct vkd3d_dxbc_compiler *co
|
|||||||
const struct vkd3d_shader_instruction *instruction)
|
const struct vkd3d_shader_instruction *instruction)
|
||||||
{
|
{
|
||||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||||
|
uint32_t coordinate_id, type_id, val_id, ptr_type_id, ptr_id;
|
||||||
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
||||||
const struct vkd3d_shader_src_param *src = instruction->src;
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
||||||
uint32_t coordinate_id, type_id, val_id;
|
const struct vkd3d_symbol *resource_symbol;
|
||||||
struct vkd3d_shader_image image;
|
struct vkd3d_shader_image image;
|
||||||
DWORD coordinate_mask;
|
DWORD coordinate_mask;
|
||||||
|
uint32_t indices[2];
|
||||||
|
|
||||||
|
resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &src[1].reg);
|
||||||
|
|
||||||
|
if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource))
|
||||||
|
{
|
||||||
|
type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1);
|
||||||
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id);
|
||||||
|
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0);
|
||||||
|
indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||||
|
indices[1] = coordinate_id;
|
||||||
|
|
||||||
|
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2);
|
||||||
|
val_id = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone);
|
||||||
|
|
||||||
|
vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler, dst, val_id,
|
||||||
|
resource_symbol->info.resource.sampled_type, src[1].swizzle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
||||||
type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE);
|
type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE);
|
||||||
coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1;
|
coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1;
|
||||||
@ -7825,17 +7988,37 @@ static void vkd3d_dxbc_compiler_emit_ld_uav_typed(struct vkd3d_dxbc_compiler *co
|
|||||||
vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler,
|
vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler,
|
||||||
dst, val_id, image.sampled_type, src[1].swizzle);
|
dst, val_id, image.sampled_type, src[1].swizzle);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler *compiler,
|
static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler *compiler,
|
||||||
const struct vkd3d_shader_instruction *instruction)
|
const struct vkd3d_shader_instruction *instruction)
|
||||||
{
|
{
|
||||||
|
uint32_t coordinate_id, texel_id, type_id, val_id, ptr_type_id, ptr_id;
|
||||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||||
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
||||||
const struct vkd3d_shader_src_param *src = instruction->src;
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
||||||
uint32_t coordinate_id, texel_id;
|
const struct vkd3d_symbol *resource_symbol;
|
||||||
struct vkd3d_shader_image image;
|
struct vkd3d_shader_image image;
|
||||||
DWORD coordinate_mask;
|
DWORD coordinate_mask;
|
||||||
|
uint32_t indices[2];
|
||||||
|
|
||||||
|
resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &dst->reg);
|
||||||
|
|
||||||
|
if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource))
|
||||||
|
{
|
||||||
|
type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1);
|
||||||
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id);
|
||||||
|
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0);
|
||||||
|
indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||||
|
indices[1] = coordinate_id;
|
||||||
|
|
||||||
|
val_id = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[1],
|
||||||
|
VKD3DSP_WRITEMASK_0, resource_symbol->info.resource.sampled_type);
|
||||||
|
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2);
|
||||||
|
vkd3d_spirv_build_op_store(builder, ptr_id, val_id, SpvMemoryAccessMaskNone);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageWriteWithoutFormat);
|
vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageWriteWithoutFormat);
|
||||||
|
|
||||||
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
||||||
@ -7846,6 +8029,7 @@ static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler
|
|||||||
vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, texel_id,
|
vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, texel_id,
|
||||||
SpvImageOperandsMaskNone, NULL, 0);
|
SpvImageOperandsMaskNone, NULL, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_compiler *compiler,
|
static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_compiler *compiler,
|
||||||
const struct vkd3d_shader_instruction *instruction)
|
const struct vkd3d_shader_instruction *instruction)
|
||||||
@ -7873,6 +8057,15 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c
|
|||||||
pointer_id = counter_id;
|
pointer_id = counter_id;
|
||||||
memory_semantics |= SpvMemorySemanticsAtomicCounterMemoryMask;
|
memory_semantics |= SpvMemorySemanticsAtomicCounterMemoryMask;
|
||||||
}
|
}
|
||||||
|
else if (compiler->ssbo_uavs)
|
||||||
|
{
|
||||||
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id);
|
||||||
|
coordinate_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||||
|
operands[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||||
|
operands[1] = coordinate_id;
|
||||||
|
pointer_id = vkd3d_spirv_build_op_access_chain(builder,
|
||||||
|
ptr_type_id, counter_id, operands, 2);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id);
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id);
|
||||||
@ -7946,6 +8139,7 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil
|
|||||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||||
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
||||||
const struct vkd3d_shader_src_param *src = instruction->src;
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
||||||
|
const struct vkd3d_symbol *resource_symbol = NULL;
|
||||||
uint32_t ptr_type_id, type_id, val_id, result_id;
|
uint32_t ptr_type_id, type_id, val_id, result_id;
|
||||||
enum vkd3d_shader_component_type component_type;
|
enum vkd3d_shader_component_type component_type;
|
||||||
const struct vkd3d_shader_dst_param *resource;
|
const struct vkd3d_shader_dst_param *resource;
|
||||||
@ -7981,11 +8175,22 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
scope = SpvScopeDevice;
|
scope = SpvScopeDevice;
|
||||||
|
resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &resource->reg);
|
||||||
|
|
||||||
|
if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource))
|
||||||
|
{
|
||||||
|
coordinate_mask = VKD3DSP_WRITEMASK_0;
|
||||||
|
structure_stride = resource_symbol->info.resource.structure_stride;
|
||||||
|
raw = resource_symbol->info.resource.raw;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NO_LOAD);
|
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NO_LOAD);
|
||||||
coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1;
|
coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1;
|
||||||
structure_stride = image.structure_stride;
|
structure_stride = image.structure_stride;
|
||||||
raw = image.raw;
|
raw = image.raw;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
||||||
if (structure_stride || raw)
|
if (structure_stride || raw)
|
||||||
@ -8008,6 +8213,17 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil
|
|||||||
pointer_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id);
|
pointer_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource))
|
||||||
|
{
|
||||||
|
component_type = resource_symbol->info.resource.sampled_type;
|
||||||
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
|
||||||
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id);
|
||||||
|
operands[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||||
|
operands[1] = coordinate_id;
|
||||||
|
pointer_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, operands, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
component_type = image.sampled_type;
|
component_type = image.sampled_type;
|
||||||
type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1);
|
type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1);
|
||||||
@ -8016,6 +8232,7 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil
|
|||||||
pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder,
|
pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder,
|
||||||
ptr_type_id, image.id, coordinate_id, sample_id);
|
ptr_type_id, image.id, coordinate_id, sample_id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val_id = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type);
|
val_id = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type);
|
||||||
|
|
||||||
@ -8041,11 +8258,22 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile
|
|||||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||||
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
||||||
const struct vkd3d_shader_src_param *src = instruction->src;
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
||||||
|
const struct vkd3d_symbol *resource_symbol;
|
||||||
uint32_t type_id, val_id, stride_id;
|
uint32_t type_id, val_id, stride_id;
|
||||||
struct vkd3d_shader_image image;
|
struct vkd3d_shader_image image;
|
||||||
uint32_t constituents[2];
|
uint32_t constituents[2];
|
||||||
unsigned int write_mask;
|
unsigned int write_mask;
|
||||||
|
|
||||||
|
if (compiler->ssbo_uavs && src->reg.type == VKD3DSPR_UAV)
|
||||||
|
{
|
||||||
|
resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &src->reg);
|
||||||
|
|
||||||
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
||||||
|
val_id = vkd3d_spirv_build_op_array_length(builder, type_id, resource_symbol->id, 0);
|
||||||
|
write_mask = VKD3DSP_WRITEMASK_0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery);
|
vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery);
|
||||||
|
|
||||||
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
||||||
@ -8053,6 +8281,7 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile
|
|||||||
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
||||||
val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id);
|
val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id);
|
||||||
write_mask = VKD3DSP_WRITEMASK_0;
|
write_mask = VKD3DSP_WRITEMASK_0;
|
||||||
|
}
|
||||||
|
|
||||||
if (image.structure_stride)
|
if (image.structure_stride)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user