[Mesa-stable] [Mesa-dev] [PATCH] radv: fix multisample image copies
Samuel Pitoiset
samuel.pitoiset at gmail.com
Thu Apr 26 10:14:06 UTC 2018
On 04/25/2018 11:25 AM, Alex Smith wrote:
> Any more thoughts on this? Any objections to it going to stable as well
> (it fixes bugs, but is quite a large change)?
I will take care of this after running CTS on Polaris/Vega.
>
> Thanks,
> Alex
>
> On 19 April 2018 at 09:27, Matthew Nicholls
> <mnicholls at feralinteractive.com <mailto:mnicholls at feralinteractive.com>>
> wrote:
>
> On 18/04/18 22:56, Dave Airlie wrote:
>
> On 18 April 2018 at 00:31, Matthew Nicholls
> <mnicholls at feralinteractive.com
> <mailto:mnicholls at feralinteractive.com>> wrote:
>
> Previously before fb077b0728, the LOD parameter was being
> used in place of the
> sample index, which would only copy the first sample to all
> samples in the
> destination image. After that multisample image copies
> wouldn't copy anything
> from my observations.
>
> Fix this properly by copying each sample in a separate
> radv_CmdDraw and using a
> pipeline with the correct rasterizationSamples for the
> destination image.
>
> Have you run CTS on this?
>
> I ran the CTS tests under dEQP-VK.api.copy_and_blit.core.* and
> didn't see any
> changes. There were 6 failures both with and without this patch however:
>
> dEQP-VK.api.copy_and_blit.core.resolve_image.{whole_array_image,whole_copy_before_resolving}.{2,4,8}_bit
>
> This is on an RX 460.
>
> Matthew.
>
>
> I wrote something similiar (I'm on holidays at the moment so can't
> confirm how similiar)
> but it failed some CTS tests for me.
>
> Dave.
>
> ---
> src/amd/vulkan/radv_meta_blit2d.c | 279
> ++++++++++++++++++++++++--------------
> src/amd/vulkan/radv_private.h | 18 +--
> 2 files changed, 189 insertions(+), 108 deletions(-)
>
> diff --git a/src/amd/vulkan/radv_meta_blit2d.c
> b/src/amd/vulkan/radv_meta_blit2d.c
> index e163056257..d953241b55 100644
> --- a/src/amd/vulkan/radv_meta_blit2d.c
> +++ b/src/amd/vulkan/radv_meta_blit2d.c
> @@ -100,7 +100,8 @@ blit2d_bind_src(struct radv_cmd_buffer
> *cmd_buffer,
> struct radv_meta_blit2d_buffer *src_buf,
> struct blit2d_src_temps *tmp,
> enum blit2d_src_type src_type, VkFormat
> depth_format,
> - VkImageAspectFlagBits aspects)
> + VkImageAspectFlagBits aspects,
> + uint32_t log2_samples)
> {
> struct radv_device *device = cmd_buffer->device;
>
> @@ -108,7 +109,7 @@ blit2d_bind_src(struct radv_cmd_buffer
> *cmd_buffer,
> create_bview(cmd_buffer, src_buf,
> &tmp->bview, depth_format);
>
> radv_meta_push_descriptor_set(cmd_buffer,
> VK_PIPELINE_BIND_POINT_GRAPHICS,
> -
> device->meta_state.blit2d.p_layouts[src_type],
> +
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
> 0, /* set */
> 1, /*
> descriptorWriteCount */
>
> (VkWriteDescriptorSet[]) {
> @@ -123,7 +124,7 @@ blit2d_bind_src(struct radv_cmd_buffer
> *cmd_buffer,
> });
>
>
> radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
> -
> device->meta_state.blit2d.p_layouts[src_type],
> +
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
>
> VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4,
> &src_buf->pitch);
> } else {
> @@ -131,12 +132,12 @@ blit2d_bind_src(struct radv_cmd_buffer
> *cmd_buffer,
>
> if (src_type == BLIT2D_SRC_TYPE_IMAGE_3D)
>
> radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
> -
> device->meta_state.blit2d.p_layouts[src_type],
> +
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
>
> VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4,
>
> &src_img->layer);
>
> radv_meta_push_descriptor_set(cmd_buffer,
> VK_PIPELINE_BIND_POINT_GRAPHICS,
> -
> device->meta_state.blit2d.p_layouts[src_type],
> +
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
> 0, /* set */
> 1, /*
> descriptorWriteCount */
>
> (VkWriteDescriptorSet[]) {
> @@ -190,10 +191,11 @@ blit2d_bind_dst(struct radv_cmd_buffer
> *cmd_buffer,
>
> static void
> bind_pipeline(struct radv_cmd_buffer *cmd_buffer,
> - enum blit2d_src_type src_type, unsigned fs_key)
> + enum blit2d_src_type src_type, unsigned fs_key,
> + uint32_t log2_samples)
> {
> VkPipeline pipeline =
> -
> cmd_buffer->device->meta_state.blit2d.pipelines[src_type][fs_key];
> +
> cmd_buffer->device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key];
>
>
> radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
>
> VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
> @@ -201,10 +203,11 @@ bind_pipeline(struct radv_cmd_buffer
> *cmd_buffer,
>
> static void
> bind_depth_pipeline(struct radv_cmd_buffer *cmd_buffer,
> - enum blit2d_src_type src_type)
> + enum blit2d_src_type src_type,
> + uint32_t log2_samples)
> {
> VkPipeline pipeline =
> -
> cmd_buffer->device->meta_state.blit2d.depth_only_pipeline[src_type];
> +
> cmd_buffer->device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type];
>
>
> radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
>
> VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
> @@ -212,10 +215,11 @@ bind_depth_pipeline(struct
> radv_cmd_buffer *cmd_buffer,
>
> static void
> bind_stencil_pipeline(struct radv_cmd_buffer *cmd_buffer,
> - enum blit2d_src_type src_type)
> + enum blit2d_src_type src_type,
> + uint32_t log2_samples)
> {
> VkPipeline pipeline =
> -
> cmd_buffer->device->meta_state.blit2d.stencil_only_pipeline[src_type];
> +
> cmd_buffer->device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type];
>
>
> radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
>
> VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
> @@ -227,7 +231,8 @@ radv_meta_blit2d_normal_dst(struct
> radv_cmd_buffer *cmd_buffer,
> struct radv_meta_blit2d_buffer
> *src_buf,
> struct radv_meta_blit2d_surf *dst,
> unsigned num_rects,
> - struct radv_meta_blit2d_rect
> *rects, enum blit2d_src_type src_type)
> + struct radv_meta_blit2d_rect
> *rects, enum blit2d_src_type src_type,
> + uint32_t log2_samples)
> {
> struct radv_device *device = cmd_buffer->device;
>
> @@ -241,7 +246,7 @@ radv_meta_blit2d_normal_dst(struct
> radv_cmd_buffer *cmd_buffer,
> else if (aspect_mask ==
> VK_IMAGE_ASPECT_DEPTH_BIT)
> depth_format =
> vk_format_depth_only(dst->image->vk_format);
> struct blit2d_src_temps src_temps;
> - blit2d_bind_src(cmd_buffer, src_img,
> src_buf, &src_temps, src_type, depth_format, aspect_mask);
> + blit2d_bind_src(cmd_buffer, src_img,
> src_buf, &src_temps, src_type, depth_format, aspect_mask,
> log2_samples);
>
> struct blit2d_dst_temps dst_temps;
> blit2d_bind_dst(cmd_buffer, dst,
> rects[r].dst_x + rects[r].width,
> @@ -255,7 +260,7 @@ radv_meta_blit2d_normal_dst(struct
> radv_cmd_buffer *cmd_buffer,
> };
>
>
> radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
> -
> device->meta_state.blit2d.p_layouts[src_type],
> +
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
>
> VK_SHADER_STAGE_VERTEX_BIT, 0, 16,
>
> vertex_push_constants);
>
> @@ -266,7 +271,7 @@ radv_meta_blit2d_normal_dst(struct
> radv_cmd_buffer *cmd_buffer,
>
> radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer),
>
> &(VkRenderPassBeginInfo) {
>
> .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
> -
> .renderPass =
> device->meta_state.blit2d.render_passes[fs_key][dst_layout],
> +
> .renderPass =
> device->meta_state.blit2d_render_passes[fs_key][dst_layout],
>
> .framebuffer = dst_temps.fb,
>
> .renderArea = {
>
> .offset = { rects[r].dst_x, rects[r].dst_y, },
> @@ -277,13 +282,13 @@ radv_meta_blit2d_normal_dst(struct
> radv_cmd_buffer *cmd_buffer,
>
> }, VK_SUBPASS_CONTENTS_INLINE);
>
>
> - bind_pipeline(cmd_buffer,
> src_type, fs_key);
> + bind_pipeline(cmd_buffer,
> src_type, fs_key, log2_samples);
> } else if (aspect_mask ==
> VK_IMAGE_ASPECT_DEPTH_BIT) {
> enum radv_blit_ds_layout
> ds_layout = radv_meta_blit_ds_to_type(dst->current_layout);
>
> radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer),
>
> &(VkRenderPassBeginInfo) {
>
> .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
> -
> .renderPass =
> device->meta_state.blit2d.depth_only_rp[ds_layout],
> +
> .renderPass =
> device->meta_state.blit2d_depth_only_rp[ds_layout],
>
> .framebuffer = dst_temps.fb,
>
> .renderArea = {
>
> .offset = { rects[r].dst_x, rects[r].dst_y, },
> @@ -294,14 +299,14 @@ radv_meta_blit2d_normal_dst(struct
> radv_cmd_buffer *cmd_buffer,
>
> }, VK_SUBPASS_CONTENTS_INLINE);
>
>
> -
> bind_depth_pipeline(cmd_buffer, src_type);
> +
> bind_depth_pipeline(cmd_buffer, src_type, log2_samples);
>
> } else if (aspect_mask ==
> VK_IMAGE_ASPECT_STENCIL_BIT) {
> enum radv_blit_ds_layout
> ds_layout = radv_meta_blit_ds_to_type(dst->current_layout);
>
> radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer),
>
> &(VkRenderPassBeginInfo) {
>
> .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
> -
> .renderPass =
> device->meta_state.blit2d.stencil_only_rp[ds_layout],
> +
> .renderPass =
> device->meta_state.blit2d_stencil_only_rp[ds_layout],
>
> .framebuffer = dst_temps.fb,
>
> .renderArea = {
>
> .offset = { rects[r].dst_x, rects[r].dst_y, },
> @@ -312,7 +317,7 @@ radv_meta_blit2d_normal_dst(struct
> radv_cmd_buffer *cmd_buffer,
>
> }, VK_SUBPASS_CONTENTS_INLINE);
>
>
> -
> bind_stencil_pipeline(cmd_buffer, src_type);
> +
> bind_stencil_pipeline(cmd_buffer, src_type, log2_samples);
> } else
> unreachable("Processing
> blit2d with multiple aspects.");
>
> @@ -332,7 +337,24 @@ radv_meta_blit2d_normal_dst(struct
> radv_cmd_buffer *cmd_buffer,
>
>
>
> -
> radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1,
> 0, 0);
> + if (log2_samples > 0) {
> + for (uint32_t sample = 0;
> sample < src_img->image->info.samples; sample++) {
> + uint32_t sample_mask
> = 1 << sample;
> +
> radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
> +
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
> +
> VK_SHADER_STAGE_FRAGMENT_BIT, 20, 4,
> +
> &sample);
> +
> +
> radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
> +
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
> +
> VK_SHADER_STAGE_FRAGMENT_BIT, 24, 4,
> +
> &sample_mask);
> +
> +
> radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1,
> 0, 0);
> + }
> + }
> + else
> +
> radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1,
> 0, 0);
>
> radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer));
>
> /* At the point where we emit the
> draw call, all data from the
> @@ -358,7 +380,8 @@ radv_meta_blit2d(struct radv_cmd_buffer
> *cmd_buffer,
> enum blit2d_src_type src_type = src_buf ?
> BLIT2D_SRC_TYPE_BUFFER :
> use_3d ? BLIT2D_SRC_TYPE_IMAGE_3D :
> BLIT2D_SRC_TYPE_IMAGE;
> radv_meta_blit2d_normal_dst(cmd_buffer, src_img,
> src_buf, dst,
> - num_rects, rects, src_type);
> + num_rects, rects, src_type,
> + src_img ?
> util_logbase2(src_img->image->info.samples) : 0);
> }
>
> static nir_shader *
> @@ -421,11 +444,11 @@ build_nir_vertex_shader(void)
>
> typedef nir_ssa_def* (*texel_fetch_build_func)(struct
> nir_builder *,
> struct
> radv_device *,
> - nir_ssa_def
> *, bool);
> + nir_ssa_def
> *, bool, bool);
>
> static nir_ssa_def *
> build_nir_texel_fetch(struct nir_builder *b, struct
> radv_device *device,
> - nir_ssa_def *tex_pos, bool is_3d)
> + nir_ssa_def *tex_pos, bool is_3d,
> bool is_multisampled)
> {
> enum glsl_sampler_dim dim = is_3d ?
> GLSL_SAMPLER_DIM_3D : GLSL_SAMPLER_DIM_2D;
> const struct glsl_type *sampler_type =
> @@ -436,6 +459,7 @@ build_nir_texel_fetch(struct nir_builder
> *b, struct radv_device *device,
> sampler->data.binding = 0;
>
> nir_ssa_def *tex_pos_3d = NULL;
> + nir_intrinsic_instr *sample_idx = NULL;
> if (is_3d) {
> nir_intrinsic_instr *layer =
> nir_intrinsic_instr_create(b->shader,
> nir_intrinsic_load_push_constant);
> nir_intrinsic_set_base(layer, 16);
> @@ -451,13 +475,22 @@ build_nir_texel_fetch(struct
> nir_builder *b, struct radv_device *device,
> chans[2] = &layer->dest.ssa;
> tex_pos_3d = nir_vec(b, chans, 3);
> }
> + if (is_multisampled) {
> + sample_idx =
> nir_intrinsic_instr_create(b->shader,
> nir_intrinsic_load_push_constant);
> + nir_intrinsic_set_base(sample_idx, 20);
> + nir_intrinsic_set_range(sample_idx, 4);
> + sample_idx->src[0] =
> nir_src_for_ssa(nir_imm_int(b, 0));
> + sample_idx->num_components = 1;
> + nir_ssa_dest_init(&sample_idx->instr,
> &sample_idx->dest, 1, 32, "sample_idx");
> + nir_builder_instr_insert(b, &sample_idx->instr);
> + }
> nir_tex_instr *tex =
> nir_tex_instr_create(b->shader, 2);
> tex->sampler_dim = dim;
> - tex->op = nir_texop_txf;
> + 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(is_3d ?
> tex_pos_3d : tex_pos);
> - tex->src[1].src_type = nir_tex_src_lod;
> - tex->src[1].src = nir_src_for_ssa(nir_imm_int(b, 0));
> + tex->src[1].src_type = is_multisampled ?
> nir_tex_src_ms_index : nir_tex_src_lod;
> + tex->src[1].src = nir_src_for_ssa(is_multisampled ?
> &sample_idx->dest.ssa : nir_imm_int(b, 0));
> tex->dest_type = nir_type_uint;
> tex->is_array = false;
> tex->coord_components = is_3d ? 3 : 2;
> @@ -473,7 +506,7 @@ build_nir_texel_fetch(struct nir_builder
> *b, struct radv_device *device,
>
> static nir_ssa_def *
> build_nir_buffer_fetch(struct nir_builder *b, struct
> radv_device *device,
> - nir_ssa_def *tex_pos, bool is_3d)
> + nir_ssa_def *tex_pos, bool is_3d,
> bool is_multisampled)
> {
> const struct glsl_type *sampler_type =
> glsl_sampler_type(GLSL_SAMPLER_DIM_BUF,
> false, false, GLSL_TYPE_UINT);
> @@ -519,9 +552,31 @@ static const
> VkPipelineVertexInputStateCreateInfo normal_vi_create_info = {
> .vertexAttributeDescriptionCount = 0,
> };
>
> +static void
> +build_nir_store_sample_mask(struct nir_builder *b)
> +{
> + nir_intrinsic_instr *sample_mask =
> nir_intrinsic_instr_create(b->shader,
> nir_intrinsic_load_push_constant);
> + nir_intrinsic_set_base(sample_mask, 24);
> + nir_intrinsic_set_range(sample_mask, 4);
> + sample_mask->src[0] = nir_src_for_ssa(nir_imm_int(b,
> 0));
> + sample_mask->num_components = 1;
> + nir_ssa_dest_init(&sample_mask->instr,
> &sample_mask->dest, 1, 32, "sample_mask");
> + nir_builder_instr_insert(b, &sample_mask->instr);
> +
> + const struct glsl_type *sample_mask_out_type =
> glsl_uint_type();
> +
> + nir_variable *sample_mask_out =
> + nir_variable_create(b->shader,
> nir_var_shader_out,
> + sample_mask_out_type,
> "sample_mask_out");
> + sample_mask_out->data.location =
> FRAG_RESULT_SAMPLE_MASK;
> +
> + nir_store_var(b, sample_mask_out,
> &sample_mask->dest.ssa, 0x1);
> +}
> +
> static nir_shader *
> build_nir_copy_fragment_shader(struct radv_device *device,
> - texel_fetch_build_func
> txf_func, const char* name, bool is_3d)
> + texel_fetch_build_func
> txf_func, const char* name, bool is_3d,
> + bool is_multisampled)
> {
> const struct glsl_type *vec4 = glsl_vec4_type();
> const struct glsl_type *vec2 =
> glsl_vector_type(GLSL_TYPE_FLOAT, 2);
> @@ -538,11 +593,15 @@ build_nir_copy_fragment_shader(struct
> radv_device *device,
>
> vec4, "f_color");
> color_out->data.location = FRAG_RESULT_DATA0;
>
> + if (is_multisampled) {
> + build_nir_store_sample_mask(&b);
> + }
> +
> nir_ssa_def *pos_int = nir_f2i32(&b,
> nir_load_var(&b, tex_pos_in));
> unsigned swiz[4] = { 0, 1 };
> nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int,
> swiz, 2, false);
>
> - nir_ssa_def *color = txf_func(&b, device, tex_pos,
> is_3d);
> + nir_ssa_def *color = txf_func(&b, device, tex_pos,
> is_3d, is_multisampled);
> nir_store_var(&b, color_out, color, 0xf);
>
> return b.shader;
> @@ -550,7 +609,8 @@ build_nir_copy_fragment_shader(struct
> radv_device *device,
>
> static nir_shader *
> build_nir_copy_fragment_shader_depth(struct radv_device
> *device,
> - texel_fetch_build_func
> txf_func, const char* name, bool is_3d)
> + texel_fetch_build_func
> txf_func, const char* name, bool is_3d,
> + bool is_multisampled)
> {
> const struct glsl_type *vec4 = glsl_vec4_type();
> const struct glsl_type *vec2 =
> glsl_vector_type(GLSL_TYPE_FLOAT, 2);
> @@ -567,11 +627,15 @@
> build_nir_copy_fragment_shader_depth(struct radv_device *device,
>
> vec4, "f_color");
> color_out->data.location = FRAG_RESULT_DEPTH;
>
> + if (is_multisampled) {
> + build_nir_store_sample_mask(&b);
> + }
> +
> nir_ssa_def *pos_int = nir_f2i32(&b,
> nir_load_var(&b, tex_pos_in));
> unsigned swiz[4] = { 0, 1 };
> nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int,
> swiz, 2, false);
>
> - nir_ssa_def *color = txf_func(&b, device, tex_pos,
> is_3d);
> + nir_ssa_def *color = txf_func(&b, device, tex_pos,
> is_3d, is_multisampled);
> nir_store_var(&b, color_out, color, 0x1);
>
> return b.shader;
> @@ -579,7 +643,8 @@
> build_nir_copy_fragment_shader_depth(struct radv_device *device,
>
> static nir_shader *
> build_nir_copy_fragment_shader_stencil(struct radv_device
> *device,
> -
> texel_fetch_build_func txf_func, const char* name, bool is_3d)
> +
> texel_fetch_build_func txf_func, const char* name, bool is_3d,
> + bool is_multisampled)
> {
> const struct glsl_type *vec4 = glsl_vec4_type();
> const struct glsl_type *vec2 =
> glsl_vector_type(GLSL_TYPE_FLOAT, 2);
> @@ -596,11 +661,15 @@
> build_nir_copy_fragment_shader_stencil(struct radv_device
> *device,
>
> vec4, "f_color");
> color_out->data.location = FRAG_RESULT_STENCIL;
>
> + if (is_multisampled) {
> + build_nir_store_sample_mask(&b);
> + }
> +
> nir_ssa_def *pos_int = nir_f2i32(&b,
> nir_load_var(&b, tex_pos_in));
> unsigned swiz[4] = { 0, 1 };
> nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int,
> swiz, 2, false);
>
> - nir_ssa_def *color = txf_func(&b, device, tex_pos,
> is_3d);
> + nir_ssa_def *color = txf_func(&b, device, tex_pos,
> is_3d, is_multisampled);
> nir_store_var(&b, color_out, color, 0x1);
>
> return b.shader;
> @@ -614,45 +683,48 @@
> radv_device_finish_meta_blit2d_state(struct radv_device *device)
> for(unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
> for (unsigned k = 0; k <
> RADV_META_DST_LAYOUT_COUNT; ++k) {
>
> radv_DestroyRenderPass(radv_device_to_handle(device),
> -
> state->blit2d.render_passes[j][k],
> - &state->alloc);
> +
> state->blit2d_render_passes[j][k],
> + &state->alloc);
> }
> }
>
> for (enum radv_blit_ds_layout j =
> RADV_BLIT_DS_LAYOUT_TILE_ENABLE; j <
> RADV_BLIT_DS_LAYOUT_COUNT; j++) {
>
> radv_DestroyRenderPass(radv_device_to_handle(device),
> -
> state->blit2d.depth_only_rp[j], &state->alloc);
> +
> state->blit2d_depth_only_rp[j], &state->alloc);
>
> radv_DestroyRenderPass(radv_device_to_handle(device),
> -
> state->blit2d.stencil_only_rp[j], &state->alloc);
> +
> state->blit2d_stencil_only_rp[j], &state->alloc);
> }
>
> - for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES;
> src++) {
> -
> radv_DestroyPipelineLayout(radv_device_to_handle(device),
> -
> state->blit2d.p_layouts[src],
> - &state->alloc);
> -
> radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
> -
> state->blit2d.ds_layouts[src],
> - &state->alloc);
> + for (unsigned log2_samples = 0; log2_samples < 1 +
> MAX_SAMPLES_LOG2; ++log2_samples) {
> + for (unsigned src = 0; src <
> BLIT2D_NUM_SRC_TYPES; src++) {
> +
> radv_DestroyPipelineLayout(radv_device_to_handle(device),
> +
> state->blit2d[log2_samples].p_layouts[src],
> +
> &state->alloc);
> +
> radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
> +
> state->blit2d[log2_samples].ds_layouts[src],
> +
> &state->alloc);
> +
> + for (unsigned j = 0; j <
> NUM_META_FS_KEYS; ++j) {
> +
> radv_DestroyPipeline(radv_device_to_handle(device),
> +
> state->blit2d[log2_samples].pipelines[src][j],
> +
> &state->alloc);
> + }
>
> - for (unsigned j = 0; j < NUM_META_FS_KEYS;
> ++j) {
>
> radv_DestroyPipeline(radv_device_to_handle(device),
> -
> state->blit2d.pipelines[src][j],
> +
> state->blit2d[log2_samples].depth_only_pipeline[src],
> + &state->alloc);
> +
> radv_DestroyPipeline(radv_device_to_handle(device),
> +
> state->blit2d[log2_samples].stencil_only_pipeline[src],
> &state->alloc);
> }
> -
> -
> radv_DestroyPipeline(radv_device_to_handle(device),
> -
> state->blit2d.depth_only_pipeline[src],
> - &state->alloc);
> -
> radv_DestroyPipeline(radv_device_to_handle(device),
> -
> state->blit2d.stencil_only_pipeline[src],
> - &state->alloc);
> }
> }
>
> static VkResult
> blit2d_init_color_pipeline(struct radv_device *device,
> enum blit2d_src_type src_type,
> - VkFormat format)
> + VkFormat format,
> + uint32_t log2_samples)
> {
> VkResult result;
> unsigned fs_key = radv_format_meta_fs_key(format);
> @@ -681,7 +753,7 @@ blit2d_init_color_pipeline(struct
> radv_device *device,
> struct radv_shader_module fs = { .nir = NULL };
>
>
> - fs.nir = build_nir_copy_fragment_shader(device,
> src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D);
> + fs.nir = build_nir_copy_fragment_shader(device,
> src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D,
> log2_samples > 0);
> vi_create_info = &normal_vi_create_info;
>
> struct radv_shader_module vs = {
> @@ -705,7 +777,7 @@ blit2d_init_color_pipeline(struct
> radv_device *device,
> };
>
> for (unsigned dst_layout = 0; dst_layout <
> RADV_META_DST_LAYOUT_COUNT; ++dst_layout) {
> - if (!device->meta_state.blit2d.re
> <http://meta_state.blit2d.re>nder_passes[fs_key][dst_layout]) {
> + if
> (!device->meta_state.blit2d_render_passes[fs_key][dst_layout]) {
> VkImageLayout layout =
> radv_meta_dst_layout_to_layout(dst_layout);
>
> result =
> radv_CreateRenderPass(radv_device_to_handle(device),
> @@ -737,7 +809,7 @@ blit2d_init_color_pipeline(struct
> radv_device *device,
>
> .pPreserveAttachments = (uint32_t[]) { 0 },
> },
>
> .dependencyCount = 0,
> - },
> &device->meta_state.alloc,
> &device->meta_state.blit2d.render_passes[fs_key][dst_layout]);
> + },
> &device->meta_state.alloc,
> &device->meta_state.blit2d_render_passes[fs_key][dst_layout]);
> }
> }
>
> @@ -765,7 +837,7 @@ blit2d_init_color_pipeline(struct
> radv_device *device,
> },
> .pMultisampleState =
> &(VkPipelineMultisampleStateCreateInfo) {
> .sType =
> VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
> - .rasterizationSamples = 1,
> + .rasterizationSamples = 1 <<
> log2_samples,
> .sampleShadingEnable = false,
> .pSampleMask = (VkSampleMask[]) {
> UINT32_MAX },
> },
> @@ -796,8 +868,8 @@ blit2d_init_color_pipeline(struct
> radv_device *device,
> },
> },
> .flags = 0,
> - .layout =
> device->meta_state.blit2d.p_layouts[src_type],
> - .renderPass =
> device->meta_state.blit2d.render_passes[fs_key][0],
> + .layout =
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
> + .renderPass =
> device->meta_state.blit2d_render_passes[fs_key][0],
> .subpass = 0,
> };
>
> @@ -809,7 +881,7 @@ blit2d_init_color_pipeline(struct
> radv_device *device,
>
> radv_pipeline_cache_to_handle(&device->meta_state.cache),
>
> &vk_pipeline_info, &radv_pipeline_info,
>
> &device->meta_state.alloc,
> -
> &device->meta_state.blit2d.pipelines[src_type][fs_key]);
> +
> &device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]);
>
>
> ralloc_free(vs.nir);
> @@ -820,7 +892,8 @@ blit2d_init_color_pipeline(struct
> radv_device *device,
>
> static VkResult
> blit2d_init_depth_only_pipeline(struct radv_device *device,
> - enum blit2d_src_type src_type)
> + enum blit2d_src_type src_type,
> + uint32_t log2_samples)
> {
> VkResult result;
> const char *name;
> @@ -847,7 +920,7 @@ blit2d_init_depth_only_pipeline(struct
> radv_device *device,
> const VkPipelineVertexInputStateCreateInfo
> *vi_create_info;
> struct radv_shader_module fs = { .nir = NULL };
>
> - fs.nir =
> build_nir_copy_fragment_shader_depth(device, src_func, name,
> src_type == BLIT2D_SRC_TYPE_IMAGE_3D);
> + fs.nir =
> build_nir_copy_fragment_shader_depth(device, src_func, name,
> src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
> vi_create_info = &normal_vi_create_info;
>
> struct radv_shader_module vs = {
> @@ -871,7 +944,7 @@ blit2d_init_depth_only_pipeline(struct
> radv_device *device,
> };
>
> for (enum radv_blit_ds_layout ds_layout =
> RADV_BLIT_DS_LAYOUT_TILE_ENABLE; ds_layout <
> RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
> - if (!device->meta_state.blit2d.de
> <http://meta_state.blit2d.de>pth_only_rp[ds_layout]) {
> + if
> (!device->meta_state.blit2d_depth_only_rp[ds_layout]) {
> VkImageLayout layout =
> radv_meta_blit_ds_to_layout(ds_layout);
> result =
> radv_CreateRenderPass(radv_device_to_handle(device),
>
> &(VkRenderPassCreateInfo) {
> @@ -899,7 +972,7 @@ blit2d_init_depth_only_pipeline(struct
> radv_device *device,
>
> .pPreserveAttachments = (uint32_t[]) { 0 },
>
> },
>
> .dependencyCount = 0,
> - },
> &device->meta_state.alloc,
> &device->meta_state.blit2d.depth_only_rp[ds_layout]);
> + },
> &device->meta_state.alloc,
> &device->meta_state.blit2d_depth_only_rp[ds_layout]);
> }
> }
>
> @@ -927,7 +1000,7 @@ blit2d_init_depth_only_pipeline(struct
> radv_device *device,
> },
> .pMultisampleState =
> &(VkPipelineMultisampleStateCreateInfo) {
> .sType =
> VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
> - .rasterizationSamples = 1,
> + .rasterizationSamples = 1 <<
> log2_samples,
> .sampleShadingEnable = false,
> .pSampleMask = (VkSampleMask[]) {
> UINT32_MAX },
> },
> @@ -958,8 +1031,8 @@ blit2d_init_depth_only_pipeline(struct
> radv_device *device,
> },
> },
> .flags = 0,
> - .layout =
> device->meta_state.blit2d.p_layouts[src_type],
> - .renderPass =
> device->meta_state.blit2d.depth_only_rp[0],
> + .layout =
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
> + .renderPass =
> device->meta_state.blit2d_depth_only_rp[0],
> .subpass = 0,
> };
>
> @@ -971,7 +1044,7 @@ blit2d_init_depth_only_pipeline(struct
> radv_device *device,
>
> radv_pipeline_cache_to_handle(&device->meta_state.cache),
>
> &vk_pipeline_info, &radv_pipeline_info,
>
> &device->meta_state.alloc,
> -
> &device->meta_state.blit2d.depth_only_pipeline[src_type]);
> +
> &device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]);
>
>
> ralloc_free(vs.nir);
> @@ -982,7 +1055,8 @@ blit2d_init_depth_only_pipeline(struct
> radv_device *device,
>
> static VkResult
> blit2d_init_stencil_only_pipeline(struct radv_device *device,
> - enum blit2d_src_type src_type)
> + enum blit2d_src_type src_type,
> + uint32_t log2_samples)
> {
> VkResult result;
> const char *name;
> @@ -1009,7 +1083,7 @@
> blit2d_init_stencil_only_pipeline(struct radv_device *device,
> const VkPipelineVertexInputStateCreateInfo
> *vi_create_info;
> struct radv_shader_module fs = { .nir = NULL };
>
> - fs.nir =
> build_nir_copy_fragment_shader_stencil(device, src_func,
> name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D);
> + fs.nir =
> build_nir_copy_fragment_shader_stencil(device, src_func,
> name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
> vi_create_info = &normal_vi_create_info;
>
> struct radv_shader_module vs = {
> @@ -1033,7 +1107,7 @@
> blit2d_init_stencil_only_pipeline(struct radv_device *device,
> };
>
> for (enum radv_blit_ds_layout ds_layout =
> RADV_BLIT_DS_LAYOUT_TILE_ENABLE; ds_layout <
> RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
> - if (!device->meta_state.blit2d.st
> <http://meta_state.blit2d.st>encil_only_rp[ds_layout]) {
> + if
> (!device->meta_state.blit2d_stencil_only_rp[ds_layout]) {
> VkImageLayout layout =
> radv_meta_blit_ds_to_layout(ds_layout);
> result =
> radv_CreateRenderPass(radv_device_to_handle(device),
>
> &(VkRenderPassCreateInfo) {
> @@ -1061,7 +1135,7 @@
> blit2d_init_stencil_only_pipeline(struct radv_device *device,
>
> .pPreserveAttachments = (uint32_t[]) { 0 },
>
> },
>
> .dependencyCount = 0,
> - },
> &device->meta_state.alloc,
> &device->meta_state.blit2d.stencil_only_rp[ds_layout]);
> + },
> &device->meta_state.alloc,
> &device->meta_state.blit2d_stencil_only_rp[ds_layout]);
> }
> }
>
> @@ -1089,7 +1163,7 @@
> blit2d_init_stencil_only_pipeline(struct radv_device *device,
> },
> .pMultisampleState =
> &(VkPipelineMultisampleStateCreateInfo) {
> .sType =
> VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
> - .rasterizationSamples = 1,
> + .rasterizationSamples = 1 <<
> log2_samples,
> .sampleShadingEnable = false,
> .pSampleMask = (VkSampleMask[]) {
> UINT32_MAX },
> },
> @@ -1136,8 +1210,8 @@
> blit2d_init_stencil_only_pipeline(struct radv_device *device,
> },
> },
> .flags = 0,
> - .layout =
> device->meta_state.blit2d.p_layouts[src_type],
> - .renderPass =
> device->meta_state.blit2d.stencil_only_rp[0],
> + .layout =
> device->meta_state.blit2d[log2_samples].p_layouts[src_type],
> + .renderPass =
> device->meta_state.blit2d_stencil_only_rp[0],
> .subpass = 0,
> };
>
> @@ -1149,7 +1223,7 @@
> blit2d_init_stencil_only_pipeline(struct radv_device *device,
>
> radv_pipeline_cache_to_handle(&device->meta_state.cache),
>
> &vk_pipeline_info, &radv_pipeline_info,
>
> &device->meta_state.alloc,
> -
> &device->meta_state.blit2d.stencil_only_pipeline[src_type]);
> +
> &device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]);
>
>
> ralloc_free(vs.nir);
> @@ -1175,15 +1249,16 @@ static VkFormat pipeline_formats[] = {
>
> static VkResult
> meta_blit2d_create_pipe_layout(struct radv_device *device,
> - int idx)
> + int idx,
> + uint32_t log2_samples)
> {
> VkResult result;
> VkDescriptorType desc_type = (idx ==
> BLIT2D_SRC_TYPE_BUFFER) ?
> VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER :
> VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
> const VkPushConstantRange push_constant_ranges[] = {
> {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
> - {VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4},
> + {VK_SHADER_STAGE_FRAGMENT_BIT, 16, 12},
> };
> - int num_push_constant_range = (idx !=
> BLIT2D_SRC_TYPE_IMAGE) ? 2 : 1;
> + int num_push_constant_range = (idx !=
> BLIT2D_SRC_TYPE_IMAGE || log2_samples > 0) ? 2 : 1;
>
> result =
> radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
>
> &(VkDescriptorSetLayoutCreateInfo) {
> @@ -1199,7 +1274,7 @@ meta_blit2d_create_pipe_layout(struct
> radv_device *device,
>
> .pImmutableSamplers = NULL
> },
> }
> - },
> &device->meta_state.alloc,
> &device->meta_state.blit2d.ds_layouts[idx]);
> + },
> &device->meta_state.alloc,
> &device->meta_state.blit2d[log2_samples].ds_layouts[idx]);
> if (result != VK_SUCCESS)
> goto fail;
>
> @@ -1207,11 +1282,11 @@
> meta_blit2d_create_pipe_layout(struct radv_device *device,
>
> &(VkPipelineLayoutCreateInfo) {
> .sType
> = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
>
> .setLayoutCount = 1,
> -
> .pSetLayouts = &device->meta_state.blit2d.ds_layouts[idx],
> +
> .pSetLayouts =
> &device->meta_state.blit2d[log2_samples].ds_layouts[idx],
>
> .pushConstantRangeCount = num_push_constant_range,
>
> .pPushConstantRanges = push_constant_ranges,
> },
> -
> &device->meta_state.alloc,
> &device->meta_state.blit2d.p_layouts[idx]);
> +
> &device->meta_state.alloc,
> &device->meta_state.blit2d[log2_samples].p_layouts[idx]);
> if (result != VK_SUCCESS)
> goto fail;
> return VK_SUCCESS;
> @@ -1225,27 +1300,33 @@
> radv_device_init_meta_blit2d_state(struct radv_device *device)
> VkResult result;
> bool create_3d =
> device->physical_device->rad_info.chip_class >= GFX9;
>
> - for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES;
> src++) {
> - if (src == BLIT2D_SRC_TYPE_IMAGE_3D &&
> !create_3d)
> - continue;
> + for (unsigned log2_samples = 0; log2_samples < 1 +
> MAX_SAMPLES_LOG2; log2_samples++) {
> + for (unsigned src = 0; src <
> BLIT2D_NUM_SRC_TYPES; src++) {
> + if (src == BLIT2D_SRC_TYPE_IMAGE_3D
> && !create_3d)
> + continue;
>
> - result =
> meta_blit2d_create_pipe_layout(device, src);
> - if (result != VK_SUCCESS)
> - goto fail;
> + /* Don't need to handle copies
> between buffers and multisample images. */
> + if (src == BLIT2D_SRC_TYPE_BUFFER &&
> log2_samples > 0)
> + continue;
>
> - for (unsigned j = 0; j <
> ARRAY_SIZE(pipeline_formats); ++j) {
> - result =
> blit2d_init_color_pipeline(device, src, pipeline_formats[j]);
> + result =
> meta_blit2d_create_pipe_layout(device, src, log2_samples);
> if (result != VK_SUCCESS)
> goto fail;
> - }
>
> - result =
> blit2d_init_depth_only_pipeline(device, src);
> - if (result != VK_SUCCESS)
> - goto fail;
> + for (unsigned j = 0; j <
> ARRAY_SIZE(pipeline_formats); ++j) {
> + result =
> blit2d_init_color_pipeline(device, src, pipeline_formats[j],
> log2_samples);
> + if (result != VK_SUCCESS)
> + goto fail;
> + }
> +
> + result =
> blit2d_init_depth_only_pipeline(device, src, log2_samples);
> + if (result != VK_SUCCESS)
> + goto fail;
>
> - result =
> blit2d_init_stencil_only_pipeline(device, src);
> - if (result != VK_SUCCESS)
> - goto fail;
> + result =
> blit2d_init_stencil_only_pipeline(device, src, log2_samples);
> + if (result != VK_SUCCESS)
> + goto fail;
> + }
> }
>
> return VK_SUCCESS;
> diff --git a/src/amd/vulkan/radv_private.h
> b/src/amd/vulkan/radv_private.h
> index 1869604e9e..3c548fe059 100644
> --- a/src/amd/vulkan/radv_private.h
> +++ b/src/amd/vulkan/radv_private.h
> @@ -462,18 +462,18 @@ struct radv_meta_state {
> } blit;
>
> struct {
> - VkRenderPass
> render_passes[NUM_META_FS_KEYS][RADV_META_DST_LAYOUT_COUNT];
> + VkPipelineLayout p_layouts[5];
> + VkDescriptorSetLayout ds_layouts[5];
> + VkPipeline pipelines[5][NUM_META_FS_KEYS];
>
> - VkPipelineLayout p_layouts[3];
> - VkDescriptorSetLayout ds_layouts[3];
> - VkPipeline pipelines[3][NUM_META_FS_KEYS];
> + VkPipeline depth_only_pipeline[5];
>
> - VkRenderPass
> depth_only_rp[RADV_BLIT_DS_LAYOUT_COUNT];
> - VkPipeline depth_only_pipeline[3];
> + VkPipeline stencil_only_pipeline[5];
> + } blit2d[1 + MAX_SAMPLES_LOG2];
>
> - VkRenderPass
> stencil_only_rp[RADV_BLIT_DS_LAYOUT_COUNT];
> - VkPipeline stencil_only_pipeline[3];
> - } blit2d;
> + VkRenderPass
> blit2d_render_passes[NUM_META_FS_KEYS][RADV_META_DST_LAYOUT_COUNT];
> + VkRenderPass
> blit2d_depth_only_rp[RADV_BLIT_DS_LAYOUT_COUNT];
> + VkRenderPass
> blit2d_stencil_only_rp[RADV_BLIT_DS_LAYOUT_COUNT];
>
> struct {
> VkPipelineLayout
> img_p_layout;
> --
> 2.14.3
>
>
>
>
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
More information about the mesa-stable
mailing list