Any more thoughts on this? Any objections to it going to stable as well (it fixes bugs, but is quite a large change)?
Thanks, Alex On 19 April 2018 at 09:27, Matthew Nicholls <mnicho...@feralinteractive.com> wrote: > On 18/04/18 22:56, Dave Airlie wrote: > > On 18 April 2018 at 00:31, Matthew Nicholls >> <mnicho...@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_cm >>> d_buffer_to_handle(cmd_buffer), >>> - device->meta_state.blit2d.p_l >>> ayouts[src_type], >>> + device->meta_state.blit2d[log >>> 2_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_cm >>> d_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_stat >>> e.blit2d.pipelines[src_type][fs_key]; >>> + cmd_buffer->device->meta_stat >>> e.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_stat >>> e.blit2d.depth_only_pipeline[src_type]; >>> + cmd_buffer->device->meta_stat >>> e.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_stat >>> e.blit2d.stencil_only_pipeline[src_type]; >>> + cmd_buffer->device->meta_stat >>> e.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_cm >>> d_buffer_to_handle(cmd_buffer), >>> - device->meta_state.blit2d.p_l >>> ayouts[src_type], >>> + device->meta_state.blit2d[log >>> 2_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.rend >>> er_passes[fs_key][dst_layout], >>> + >>> .renderPass = device->meta_state.blit2d_rend >>> er_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_cm >>> d_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_cm >>> d_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_cm >>> d_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_d >>> evice_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(ra >>> dv_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(ra >>> dv_device_to_handle(device), >>> + >>> state->blit2d[log2_samples].p_layouts[src], >>> + &state->alloc); >>> + radv_DestroyDescriptorSetLayo >>> ut(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_dev >>> ice_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_dev >>> ice_to_handle(device), >>> - >>> state->blit2d.pipelines[src][j], >>> + >>> state->blit2d[log2_samples].depth_only_pipeline[src], >>> + &state->alloc); >>> + radv_DestroyPipeline(radv_dev >>> ice_to_handle(device), >>> + >>> state->blit2d[log2_samples].stencil_only_pipeline[src], >>> &state->alloc); >>> } >>> - >>> - radv_DestroyPipeline(radv_device_to_handle(device), >>> - state->blit2d.depth_only_pipel >>> ine[src], >>> - &state->alloc); >>> - radv_DestroyPipeline(radv_device_to_handle(device), >>> - state->blit2d.stencil_only_pip >>> eline[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 >>> nder_passes[fs_key][dst_layout]) { >>> + if (!device->meta_state.blit2d_re >>> nder_passes[fs_key][dst_layout]) { >>> VkImageLayout layout = >>> radv_meta_dst_layout_to_layout(dst_layout); >>> >>> result = radv_CreateRenderPass(radv_dev >>> ice_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_MUL >>> TISAMPLE_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.rend >>> er_passes[fs_key][0], >>> + .layout = device->meta_state.blit2d[log2 >>> _samples].p_layouts[src_type], >>> + .renderPass = device->meta_state.blit2d_rend >>> er_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.depth_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_dev >>> ice_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.dep >>> th_only_rp[ds_layout]); >>> + }, >>> &device->meta_state.alloc, &device->meta_state.blit2d_dep >>> th_only_rp[ds_layout]); >>> } >>> } >>> >>> @@ -927,7 +1000,7 @@ blit2d_init_depth_only_pipeline(struct radv_device >>> *device, >>> }, >>> .pMultisampleState = >>> &(VkPipelineMultisampleStateCreateInfo) >>> { >>> .sType = VK_STRUCTURE_TYPE_PIPELINE_MUL >>> TISAMPLE_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.dept >>> h_only_rp[0], >>> + .layout = device->meta_state.blit2d[log2 >>> _samples].p_layouts[src_type], >>> + .renderPass = device->meta_state.blit2d_dept >>> h_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.stencil_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_dev >>> ice_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.ste >>> ncil_only_rp[ds_layout]); >>> + }, >>> &device->meta_state.alloc, &device->meta_state.blit2d_ste >>> ncil_only_rp[ds_layout]); >>> } >>> } >>> >>> @@ -1089,7 +1163,7 @@ blit2d_init_stencil_only_pipeline(struct >>> radv_device *device, >>> }, >>> .pMultisampleState = >>> &(VkPipelineMultisampleStateCreateInfo) >>> { >>> .sType = VK_STRUCTURE_TYPE_PIPELINE_MUL >>> TISAMPLE_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.sten >>> cil_only_rp[0], >>> + .layout = device->meta_state.blit2d[log2 >>> _samples].p_layouts[src_type], >>> + .renderPass = device->meta_state.blit2d_sten >>> cil_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_pipeli >>> ne[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_IMA >>> GE; >>> 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[log >>> 2_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@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev