<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 3 August 2017 at 23:44, Bas Nieuwenhuizen <span dir="ltr"><<a href="mailto:bas@basnieuwenhuizen.nl" target="_blank">bas@basnieuwenhuizen.nl</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">On Fri, Aug 4, 2017 at 12:26 AM, Marek Olšák <<a href="mailto:maraeo@gmail.com">maraeo@gmail.com</a>> wrote:<br>
> Hi Alex,<br>
><br>
> Which game uses texturing from MSAA depth buffers?<br>
<br>
</span>They don't necessarily have to do that, radv could also be doing some<br>
superfluous layout transitions that might mess the texture up due to<br>
not taking the samples into account.<br></blockquote><div><br></div><div>This is for an unreleased game, and yes, it is sampling from an MSAA depth buffer. Even better, sometimes it samples it at the same time it's bound as the current (read-only) depth target.</div><div><br></div><div>Alex</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class="gmail-HOEnZb"><font color="#888888"><br>
- Bas<br>
</font></span><div class="gmail-HOEnZb"><div class="gmail-h5"><br>
><br>
> Thanks,<br>
> Marek<br>
><br>
> On Thu, Aug 3, 2017 at 4:32 PM, Alex Smith <<a href="mailto:asmith@feralinteractive.com">asmith@feralinteractive.com</a>> wrote:<br>
>> Need to take the sample count into account in the depth decompress and<br>
>> resummarize pipelines and render pass.<br>
>><br>
>> Fixes: f4e499ec791 ("radv: add initial non-conformant radv vulkan driver")<br>
>> Signed-off-by: Alex Smith <<a href="mailto:asmith@feralinteractive.com">asmith@feralinteractive.com</a>><br>
>> Cc: "17.2" <<a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.<wbr>freedesktop.org</a>><br>
>> ---<br>
>> Possibly a little late, but I'd really like to get this into 17.2 if<br>
>> possible - fixes a bunch of corruption we're seeing when using MSAA.<br>
>> ---<br>
>>  src/amd/vulkan/radv_meta_<wbr>decompress.c | 102 ++++++++++++++++++++++--------<wbr>----<br>
>>  src/amd/vulkan/radv_private.h         |   2 +-<br>
>>  2 files changed, 69 insertions(+), 35 deletions(-)<br>
>><br>
>> diff --git a/src/amd/vulkan/radv_meta_<wbr>decompress.c b/src/amd/vulkan/radv_meta_<wbr>decompress.c<br>
>> index 7afe08fbdb..f68ce8d2b0 100644<br>
>> --- a/src/amd/vulkan/radv_meta_<wbr>decompress.c<br>
>> +++ b/src/amd/vulkan/radv_meta_<wbr>decompress.c<br>
>> @@ -29,7 +29,9 @@<br>
>>  #include "sid.h"<br>
>><br>
>>  static VkResult<br>
>> -create_pass(struct radv_device *device)<br>
>> +create_pass(struct radv_device *device,<br>
>> +           uint32_t samples,<br>
>> +           VkRenderPass *pass)<br>
>>  {<br>
>>         VkResult result;<br>
>>         VkDevice device_h = radv_device_to_handle(device);<br>
>> @@ -37,7 +39,7 @@ create_pass(struct radv_device *device)<br>
>>         VkAttachmentDescription attachment;<br>
>><br>
>>         attachment.format = VK_FORMAT_D32_SFLOAT_S8_UINT;<br>
>> -       attachment.samples = 1;<br>
>> +       attachment.samples = samples;<br>
>>         attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;<br>
>>         attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;<br>
>>         attachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_<wbr>ATTACHMENT_OPTIMAL;<br>
>> @@ -65,14 +67,18 @@ create_pass(struct radv_device *device)<br>
>>                                                                 .dependencyCount = 0,<br>
>>                                                                    },<br>
>>                                        alloc,<br>
>> -                                      &device->meta_state.depth_<wbr>decomp.pass);<br>
>> +                                      pass);<br>
>><br>
>>         return result;<br>
>>  }<br>
>><br>
>>  static VkResult<br>
>>  create_pipeline(struct radv_device *device,<br>
>> -                VkShaderModule vs_module_h)<br>
>> +                VkShaderModule vs_module_h,<br>
>> +               uint32_t samples,<br>
>> +               VkRenderPass pass,<br>
>> +               VkPipeline *decompress_pipeline,<br>
>> +               VkPipeline *resummarize_pipeline)<br>
>>  {<br>
>>         VkResult result;<br>
>>         VkDevice device_h = radv_device_to_handle(device);<br>
>> @@ -129,7 +135,7 @@ create_pipeline(struct radv_device *device,<br>
>>                 },<br>
>>                 .pMultisampleState = &(<wbr>VkPipelineMultisampleStateCrea<wbr>teInfo) {<br>
>>                         .sType = VK_STRUCTURE_TYPE_PIPELINE_<wbr>MULTISAMPLE_STATE_CREATE_INFO,<br>
>> -                       .rasterizationSamples = 1,<br>
>> +                       .rasterizationSamples = samples,<br>
>>                         .sampleShadingEnable = false,<br>
>>                         .pSampleMask = NULL,<br>
>>                         .alphaToCoverageEnable = false,<br>
>> @@ -156,7 +162,7 @@ create_pipeline(struct radv_device *device,<br>
>>                                 VK_DYNAMIC_STATE_SCISSOR,<br>
>>                         },<br>
>>                 },<br>
>> -               .renderPass = device->meta_state.depth_<wbr>decomp.pass,<br>
>> +               .renderPass = pass,<br>
>>                 .subpass = 0,<br>
>>         };<br>
>><br>
>> @@ -169,7 +175,7 @@ create_pipeline(struct radv_device *device,<br>
>>                                                         .db_flush_stencil_inplace = true,<br>
>>                                                },<br>
>>                                                &device->meta_state.alloc,<br>
>> -                                              &device->meta_state.depth_<wbr>decomp.decompress_pipeline);<br>
>> +                                              decompress_pipeline);<br>
>>         if (result != VK_SUCCESS)<br>
>>                 goto cleanup;<br>
>><br>
>> @@ -183,7 +189,7 @@ create_pipeline(struct radv_device *device,<br>
>>                                                         .db_resummarize = true,<br>
>>                                                },<br>
>>                                                &device->meta_state.alloc,<br>
>> -                                              &device->meta_state.depth_<wbr>decomp.resummarize_pipeline);<br>
>> +                                              resummarize_pipeline);<br>
>>         if (result != VK_SUCCESS)<br>
>>                 goto cleanup;<br>
>><br>
>> @@ -199,29 +205,31 @@ radv_device_finish_meta_depth_<wbr>decomp_state(struct radv_device *device)<br>
>>  {<br>
>>         struct radv_meta_state *state = &device->meta_state;<br>
>>         VkDevice device_h = radv_device_to_handle(device);<br>
>> -       VkRenderPass pass_h = device->meta_state.depth_<wbr>decomp.pass;<br>
>>         const VkAllocationCallbacks *alloc = &device->meta_state.alloc;<br>
>><br>
>> -       if (pass_h)<br>
>> -               radv_DestroyRenderPass(device_<wbr>h, pass_h,<br>
>> -                                            &device->meta_state.alloc);<br>
>> -<br>
>> -       VkPipeline pipeline_h = state->depth_decomp.<wbr>decompress_pipeline;<br>
>> -       if (pipeline_h) {<br>
>> -               radv_DestroyPipeline(device_h, pipeline_h, alloc);<br>
>> -       }<br>
>> -       pipeline_h = state->depth_decomp.<wbr>resummarize_pipeline;<br>
>> -       if (pipeline_h) {<br>
>> -               radv_DestroyPipeline(device_h, pipeline_h, alloc);<br>
>> +       for (uint32_t i = 0; i < ARRAY_SIZE(state->depth_<wbr>decomp); ++i) {<br>
>> +               VkRenderPass pass_h = state->depth_decomp[i].pass;<br>
>> +               if (pass_h) {<br>
>> +                       radv_DestroyRenderPass(device_<wbr>h, pass_h, alloc);<br>
>> +               }<br>
>> +               VkPipeline pipeline_h = state->depth_decomp[i].<wbr>decompress_pipeline;<br>
>> +               if (pipeline_h) {<br>
>> +                       radv_DestroyPipeline(device_h, pipeline_h, alloc);<br>
>> +               }<br>
>> +               pipeline_h = state->depth_decomp[i].<wbr>resummarize_pipeline;<br>
>> +               if (pipeline_h) {<br>
>> +                       radv_DestroyPipeline(device_h, pipeline_h, alloc);<br>
>> +               }<br>
>>         }<br>
>>  }<br>
>><br>
>>  VkResult<br>
>>  radv_device_init_meta_depth_<wbr>decomp_state(struct radv_device *device)<br>
>>  {<br>
>> +       struct radv_meta_state *state = &device->meta_state;<br>
>>         VkResult res = VK_SUCCESS;<br>
>><br>
>> -       zero(device->meta_state.depth_<wbr>decomp);<br>
>> +       zero(state->depth_decomp);<br>
>><br>
>>         struct radv_shader_module vs_module = { .nir = radv_meta_build_nir_vs_<wbr>generate_vertices() };<br>
>>         if (!vs_module.nir) {<br>
>> @@ -230,14 +238,22 @@ radv_device_init_meta_depth_<wbr>decomp_state(struct radv_device *device)<br>
>>                 goto fail;<br>
>>         }<br>
>><br>
>> -       res = create_pass(device);<br>
>> -       if (res != VK_SUCCESS)<br>
>> -               goto fail;<br>
>> -<br>
>>         VkShaderModule vs_module_h = radv_shader_module_to_handle(&<wbr>vs_module);<br>
>> -       res = create_pipeline(device, vs_module_h);<br>
>> -       if (res != VK_SUCCESS)<br>
>> -               goto fail;<br>
>> +<br>
>> +       for (uint32_t i = 0; i < ARRAY_SIZE(state->depth_<wbr>decomp); ++i) {<br>
>> +               uint32_t samples = 1 << i;<br>
>> +<br>
>> +               res = create_pass(device, samples, &state->depth_decomp[i].pass);<br>
>> +               if (res != VK_SUCCESS)<br>
>> +                       goto fail;<br>
>> +<br>
>> +               res = create_pipeline(device, vs_module_h, samples,<br>
>> +                                     state->depth_decomp[i].pass,<br>
>> +                                     &state->depth_decomp[i].<wbr>decompress_pipeline,<br>
>> +                                     &state->depth_decomp[i].<wbr>resummarize_pipeline);<br>
>> +               if (res != VK_SUCCESS)<br>
>> +                       goto fail;<br>
>> +       }<br>
>><br>
>>         goto cleanup;<br>
>><br>
>> @@ -283,10 +299,15 @@ emit_depth_decomp(struct radv_cmd_buffer *cmd_buffer,<br>
>>  }<br>
>><br>
>><br>
>> +enum radv_depth_op {<br>
>> +       DEPTH_DECOMPRESS,<br>
>> +       DEPTH_RESUMMARIZE,<br>
>> +};<br>
>> +<br>
>>  static void radv_process_depth_image_<wbr>inplace(struct radv_cmd_buffer *cmd_buffer,<br>
>>                                              struct radv_image *image,<br>
>>                                              VkImageSubresourceRange *subresourceRange,<br>
>> -                                            VkPipeline pipeline_h)<br>
>> +                                            enum radv_depth_op op)<br>
>>  {<br>
>>         struct radv_meta_saved_state saved_state;<br>
>>         struct radv_meta_saved_pass_state saved_pass_state;<br>
>> @@ -296,6 +317,9 @@ static void radv_process_depth_image_<wbr>inplace(struct radv_cmd_buffer *cmd_buffer,<br>
>>                                      subresourceRange-><wbr>baseMipLevel);<br>
>>         uint32_t height = radv_minify(image->info.<wbr>height,<br>
>>                                      subresourceRange-><wbr>baseMipLevel);<br>
>> +       uint32_t samples = image->info.samples;<br>
>> +       uint32_t samples_log2 = ffs(samples) - 1;<br>
>> +       struct radv_meta_state *meta_state = &cmd_buffer->device->meta_<wbr>state;<br>
>><br>
>>         if (!image->surface.htile_size)<br>
>>                 return;<br>
>> @@ -339,7 +363,7 @@ static void radv_process_depth_image_<wbr>inplace(struct radv_cmd_buffer *cmd_buffer,<br>
>>                 radv_CmdBeginRenderPass(cmd_<wbr>buffer_h,<br>
>>                                               &(VkRenderPassBeginInfo) {<br>
>>                                                       .sType = VK_STRUCTURE_TYPE_RENDER_PASS_<wbr>BEGIN_INFO,<br>
>> -                                                             .renderPass = cmd_buffer->device->meta_<wbr>state.depth_decomp.pass,<br>
>> +                                                             .renderPass = meta_state->depth_decomp[<wbr>samples_log2].pass,<br>
>>                                                               .framebuffer = fb_h,<br>
>>                                                               .renderArea = {<br>
>>                                                               .offset = {<br>
>> @@ -356,6 +380,18 @@ static void radv_process_depth_image_<wbr>inplace(struct radv_cmd_buffer *cmd_buffer,<br>
>>                                            },<br>
>>                                            VK_SUBPASS_CONTENTS_INLINE);<br>
>><br>
>> +               VkPipeline pipeline_h;<br>
>> +               switch (op) {<br>
>> +               case DEPTH_DECOMPRESS:<br>
>> +                       pipeline_h = meta_state->depth_decomp[<wbr>samples_log2].decompress_<wbr>pipeline;<br>
>> +                       break;<br>
>> +               case DEPTH_RESUMMARIZE:<br>
>> +                       pipeline_h = meta_state->depth_decomp[<wbr>samples_log2].resummarize_<wbr>pipeline;<br>
>> +                       break;<br>
>> +               default:<br>
>> +                       unreachable("unknown operation");<br>
>> +               }<br>
>> +<br>
>>                 emit_depth_decomp(cmd_buffer, &(VkOffset2D){0, 0 }, &(VkExtent2D){width, height}, pipeline_h);<br>
>>                 radv_CmdEndRenderPass(cmd_<wbr>buffer_h);<br>
>><br>
>> @@ -371,8 +407,7 @@ void radv_decompress_depth_image_<wbr>inplace(struct radv_cmd_buffer *cmd_buffer,<br>
>>                                          VkImageSubresourceRange *subresourceRange)<br>
>>  {<br>
>>         assert(cmd_buffer->queue_<wbr>family_index == RADV_QUEUE_GENERAL);<br>
>> -       radv_process_depth_image_<wbr>inplace(cmd_buffer, image, subresourceRange,<br>
>> -                                        cmd_buffer->device->meta_<wbr>state.depth_decomp.decompress_<wbr>pipeline);<br>
>> +       radv_process_depth_image_<wbr>inplace(cmd_buffer, image, subresourceRange, DEPTH_DECOMPRESS);<br>
>>  }<br>
>><br>
>>  void radv_resummarize_depth_image_<wbr>inplace(struct radv_cmd_buffer *cmd_buffer,<br>
>> @@ -380,6 +415,5 @@ void radv_resummarize_depth_image_<wbr>inplace(struct radv_cmd_buffer *cmd_buffer,<br>
>>                                          VkImageSubresourceRange *subresourceRange)<br>
>>  {<br>
>>         assert(cmd_buffer->queue_<wbr>family_index == RADV_QUEUE_GENERAL);<br>
>> -       radv_process_depth_image_<wbr>inplace(cmd_buffer, image, subresourceRange,<br>
>> -                                        cmd_buffer->device->meta_<wbr>state.depth_decomp.<wbr>resummarize_pipeline);<br>
>> +       radv_process_depth_image_<wbr>inplace(cmd_buffer, image, subresourceRange, DEPTH_RESUMMARIZE);<br>
>>  }<br>
>> diff --git a/src/amd/vulkan/radv_private.<wbr>h b/src/amd/vulkan/radv_private.<wbr>h<br>
>> index 8e86f5c1d5..45ab7692b4 100644<br>
>> --- a/src/amd/vulkan/radv_private.<wbr>h<br>
>> +++ b/src/amd/vulkan/radv_private.<wbr>h<br>
>> @@ -444,7 +444,7 @@ struct radv_meta_state {<br>
>>                 VkPipeline                                decompress_pipeline;<br>
>>                 VkPipeline                                resummarize_pipeline;<br>
>>                 VkRenderPass                              pass;<br>
>> -       } depth_decomp;<br>
>> +       } depth_decomp[1 + MAX_SAMPLES_LOG2];<br>
>><br>
>>         struct {<br>
>>                 VkPipeline                                cmask_eliminate_pipeline;<br>
>> --<br>
>> 2.13.3<br>
>><br>
>> ______________________________<wbr>_________________<br>
>> mesa-stable mailing list<br>
>> <a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.<wbr>org</a><br>
>> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-stable" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-stable</a><br>
</div></div></blockquote></div><br></div></div>