mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 15:38:09 +02:00
radv: add MSAA support to CopyImage() on compute queue
CopyImage supports copying MSAA images if the number of samples match. Found by inspection because this is untested by CTS for some reasons. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10055>
This commit is contained in:
parent
4caf19eb7d
commit
b4a66b29cd
2 changed files with 84 additions and 55 deletions
|
|
@ -617,9 +617,10 @@ radv_device_finish_meta_btoi_r32g32b32_state(struct radv_device *device)
|
|||
}
|
||||
|
||||
static nir_shader *
|
||||
build_nir_itoi_compute_shader(struct radv_device *dev, bool is_3d)
|
||||
build_nir_itoi_compute_shader(struct radv_device *dev, bool is_3d, int samples)
|
||||
{
|
||||
enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D : GLSL_SAMPLER_DIM_2D;
|
||||
bool is_multisampled = samples > 1;
|
||||
enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D : is_multisampled ? GLSL_SAMPLER_DIM_MS : GLSL_SAMPLER_DIM_2D;
|
||||
const struct glsl_type *buf_type = glsl_sampler_type(dim,
|
||||
false,
|
||||
false,
|
||||
|
|
@ -627,7 +628,7 @@ build_nir_itoi_compute_shader(struct radv_device *dev, bool is_3d)
|
|||
const struct glsl_type *img_type = glsl_image_type(dim,
|
||||
false,
|
||||
GLSL_TYPE_FLOAT);
|
||||
nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, NULL, is_3d ? "meta_itoi_cs_3d" : "meta_itoi_cs");
|
||||
nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, NULL, is_3d ? "meta_itoi_cs_3d-%d" : "meta_itoi_cs-%d", samples);
|
||||
b.shader->info.cs.local_size[0] = 8;
|
||||
b.shader->info.cs.local_size[1] = 8;
|
||||
b.shader->info.cs.local_size[2] = 1;
|
||||
|
|
@ -658,38 +659,78 @@ build_nir_itoi_compute_shader(struct radv_device *dev, bool is_3d)
|
|||
|
||||
nir_ssa_def *dst_coord = nir_iadd(&b, global_id, dst_offset);
|
||||
|
||||
nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
|
||||
tex->sampler_dim = dim;
|
||||
tex->op = nir_texop_txf;
|
||||
tex->src[0].src_type = nir_tex_src_coord;
|
||||
tex->src[0].src = nir_src_for_ssa(nir_channels(&b, src_coord, is_3d ? 0x7 : 0x3));
|
||||
tex->src[1].src_type = nir_tex_src_lod;
|
||||
tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
|
||||
tex->src[2].src_type = nir_tex_src_texture_deref;
|
||||
tex->src[2].src = nir_src_for_ssa(input_img_deref);
|
||||
tex->dest_type = nir_type_float32;
|
||||
tex->is_array = false;
|
||||
tex->coord_components = is_3d ? 3 : 2;
|
||||
nir_tex_instr *tex_instr[8];
|
||||
for (uint32_t i = 0; i < samples; i++) {
|
||||
tex_instr[i] = nir_tex_instr_create(b.shader, is_multisampled ? 4 : 3);
|
||||
|
||||
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
|
||||
nir_builder_instr_insert(&b, &tex->instr);
|
||||
nir_tex_instr *tex = tex_instr[i];
|
||||
tex->sampler_dim = dim;
|
||||
tex->op = is_multisampled ? nir_texop_txf_ms : nir_texop_txf;
|
||||
tex->src[0].src_type = nir_tex_src_coord;
|
||||
tex->src[0].src = nir_src_for_ssa(nir_channels(&b, src_coord, is_3d ? 0x7 : 0x3));
|
||||
tex->src[1].src_type = nir_tex_src_lod;
|
||||
tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
|
||||
tex->src[2].src_type = nir_tex_src_texture_deref;
|
||||
tex->src[2].src = nir_src_for_ssa(input_img_deref);
|
||||
if (is_multisampled) {
|
||||
tex->src[3].src_type = nir_tex_src_ms_index;
|
||||
tex->src[3].src = nir_src_for_ssa(nir_imm_int(&b, i));
|
||||
}
|
||||
tex->dest_type = nir_type_float32;
|
||||
tex->is_array = false;
|
||||
tex->coord_components = is_3d ? 3 : 2;
|
||||
|
||||
nir_ssa_def *outval = &tex->dest.ssa;
|
||||
nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa,
|
||||
dst_coord, nir_ssa_undef(&b, 1, 32), outval, nir_imm_int(&b, 0));
|
||||
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
|
||||
nir_builder_instr_insert(&b, &tex->instr);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < samples; i++) {
|
||||
nir_ssa_def *outval = &tex_instr[i]->dest.ssa;
|
||||
nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa,
|
||||
dst_coord, nir_imm_int(&b, i), outval, nir_imm_int(&b, 0));
|
||||
}
|
||||
|
||||
return b.shader;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
create_itoi_pipeline(struct radv_device *device,
|
||||
int samples,
|
||||
VkPipeline *pipeline)
|
||||
{
|
||||
struct radv_meta_state *state = &device->meta_state;
|
||||
nir_shader *cs = build_nir_itoi_compute_shader(device, false, samples);
|
||||
VkResult result;
|
||||
|
||||
VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.module = vk_shader_module_handle_from_nir(cs),
|
||||
.pName = "main",
|
||||
.pSpecializationInfo = NULL,
|
||||
};
|
||||
|
||||
VkComputePipelineCreateInfo vk_pipeline_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||
.stage = pipeline_shader_stage,
|
||||
.flags = 0,
|
||||
.layout = state->itoi.img_p_layout,
|
||||
};
|
||||
|
||||
result = radv_CreateComputePipelines(radv_device_to_handle(device),
|
||||
radv_pipeline_cache_to_handle(&state->cache),
|
||||
1, &vk_pipeline_info, NULL,
|
||||
pipeline);
|
||||
ralloc_free(cs);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* image to image - don't write use image accessors */
|
||||
static VkResult
|
||||
radv_device_init_meta_itoi_state(struct radv_device *device)
|
||||
{
|
||||
VkResult result;
|
||||
nir_shader *cs = build_nir_itoi_compute_shader(device, false);
|
||||
nir_shader *cs_3d = NULL;
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9)
|
||||
cs_3d = build_nir_itoi_compute_shader(device, true);
|
||||
|
||||
/*
|
||||
* two descriptors one for the image being sampled
|
||||
* one for the buffer being written.
|
||||
|
|
@ -739,31 +780,17 @@ radv_device_init_meta_itoi_state(struct radv_device *device)
|
|||
if (result != VK_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
/* compute shader */
|
||||
|
||||
VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.module = vk_shader_module_handle_from_nir(cs),
|
||||
.pName = "main",
|
||||
.pSpecializationInfo = NULL,
|
||||
};
|
||||
|
||||
VkComputePipelineCreateInfo vk_pipeline_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||
.stage = pipeline_shader_stage,
|
||||
.flags = 0,
|
||||
.layout = device->meta_state.itoi.img_p_layout,
|
||||
};
|
||||
|
||||
result = radv_CreateComputePipelines(radv_device_to_handle(device),
|
||||
radv_pipeline_cache_to_handle(&device->meta_state.cache),
|
||||
1, &vk_pipeline_info, NULL,
|
||||
&device->meta_state.itoi.pipeline);
|
||||
if (result != VK_SUCCESS)
|
||||
goto fail;
|
||||
for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; i++) {
|
||||
uint32_t samples = 1 << i;
|
||||
result = create_itoi_pipeline(device, samples,
|
||||
&device->meta_state.itoi.pipeline[i]);
|
||||
if (result != VK_SUCCESS)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
||||
nir_shader *cs_3d = build_nir_itoi_compute_shader(device, true, 1);
|
||||
|
||||
VkPipelineShaderStageCreateInfo pipeline_shader_stage_3d = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
|
|
@ -783,15 +810,11 @@ radv_device_init_meta_itoi_state(struct radv_device *device)
|
|||
radv_pipeline_cache_to_handle(&device->meta_state.cache),
|
||||
1, &vk_pipeline_info_3d, NULL,
|
||||
&device->meta_state.itoi.pipeline_3d);
|
||||
|
||||
ralloc_free(cs_3d);
|
||||
}
|
||||
ralloc_free(cs);
|
||||
|
||||
return VK_SUCCESS;
|
||||
fail:
|
||||
ralloc_free(cs);
|
||||
ralloc_free(cs_3d);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -805,8 +828,12 @@ radv_device_finish_meta_itoi_state(struct radv_device *device)
|
|||
radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
|
||||
state->itoi.img_ds_layout,
|
||||
&state->alloc);
|
||||
radv_DestroyPipeline(radv_device_to_handle(device),
|
||||
state->itoi.pipeline, &state->alloc);
|
||||
|
||||
for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
|
||||
radv_DestroyPipeline(radv_device_to_handle(device),
|
||||
state->itoi.pipeline[i], &state->alloc);
|
||||
}
|
||||
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9)
|
||||
radv_DestroyPipeline(radv_device_to_handle(device),
|
||||
state->itoi.pipeline_3d, &state->alloc);
|
||||
|
|
@ -1899,9 +1926,10 @@ radv_meta_image_to_image_cs(struct radv_cmd_buffer *cmd_buffer,
|
|||
unsigned num_rects,
|
||||
struct radv_meta_blit2d_rect *rects)
|
||||
{
|
||||
VkPipeline pipeline = cmd_buffer->device->meta_state.itoi.pipeline;
|
||||
struct radv_device *device = cmd_buffer->device;
|
||||
struct radv_image_view src_view, dst_view;
|
||||
uint32_t samples = src->image->info.samples;
|
||||
uint32_t samples_log2 = ffs(samples) - 1;
|
||||
|
||||
if (src->format == VK_FORMAT_R32G32B32_UINT ||
|
||||
src->format == VK_FORMAT_R32G32B32_SINT ||
|
||||
|
|
@ -1916,6 +1944,7 @@ radv_meta_image_to_image_cs(struct radv_cmd_buffer *cmd_buffer,
|
|||
|
||||
itoi_bind_descriptors(cmd_buffer, &src_view, &dst_view);
|
||||
|
||||
VkPipeline pipeline = cmd_buffer->device->meta_state.itoi.pipeline[samples_log2];
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9 &&
|
||||
(src->image->type == VK_IMAGE_TYPE_3D || dst->image->type == VK_IMAGE_TYPE_3D))
|
||||
pipeline = cmd_buffer->device->meta_state.itoi.pipeline_3d;
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ struct radv_meta_state {
|
|||
struct {
|
||||
VkPipelineLayout img_p_layout;
|
||||
VkDescriptorSetLayout img_ds_layout;
|
||||
VkPipeline pipeline;
|
||||
VkPipeline pipeline[MAX_SAMPLES_LOG2];
|
||||
VkPipeline pipeline_3d;
|
||||
} itoi;
|
||||
struct {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue