<div dir="ltr">Tested-by: Alex Smith <<a href="mailto:asmith@feralinteractive.com">asmith@feralinteractive.com</a>><div><br></div><div>Fixes 3D texture contents being captured incorrectly in RenderDoc for me.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 19 December 2017 at 07:36, Dave Airlie <span dir="ltr"><<a href="mailto:airlied@gmail.com" target="_blank">airlied@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
<br>
On GFX9 we must access 3D textures with 3D samplers AFAICS.<br>
<br>
This fixes:<br>
dEQP-VK.api.image_clearing.<wbr>core.clear_color_image.3d.<wbr>single_layer<br>
<br>
on GFX9 for me.<br>
<br>
v2: fixes a bunch of other tests as well.<br>
<br>
v1.1: fix tex->sampler_dim to dim<br>
v2: send layer in from outside<br>
<br>
Fixes: e38685cc62e 'Revert "radv: disable support for VEGA for now."'<br>
Signed-off-by: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
---<br>
 src/amd/vulkan/radv_meta_<wbr>bufimage.c | 87 ++++++++++++++++++++++++++++++<wbr>-------<br>
 src/amd/vulkan/radv_private.h       |  1 +<br>
 2 files changed, 72 insertions(+), 16 deletions(-)<br>
<br>
diff --git a/src/amd/vulkan/radv_meta_<wbr>bufimage.c b/src/amd/vulkan/radv_meta_<wbr>bufimage.c<br>
index dfd99aa75f..4a61beef18 100644<br>
--- a/src/amd/vulkan/radv_meta_<wbr>bufimage.c<br>
+++ b/src/amd/vulkan/radv_meta_<wbr>bufimage.c<br>
@@ -29,11 +29,15 @@<br>
  * Compute queue: implementation also of buffer->image, image->image, and image clear.<br>
  */<br>
<br>
+/* GFX9 needs to use a 3D sampler to access 3D resources, so the shader has the options<br>
+ * for that.<br>
+ */<br>
 static nir_shader *<br>
-build_nir_itob_compute_<wbr>shader(struct radv_device *dev)<br>
+build_nir_itob_compute_<wbr>shader(struct radv_device *dev, bool is_3d)<br>
 {<br>
        nir_builder b;<br>
-       const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_<wbr>SAMPLER_DIM_2D,<br>
+       enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D : GLSL_SAMPLER_DIM_2D;<br>
+       const struct glsl_type *sampler_type = glsl_sampler_type(dim,<br>
                                                                 false,<br>
                                                                 false,<br>
                                                                 GLSL_TYPE_FLOAT);<br>
@@ -42,7 +46,7 @@ build_nir_itob_compute_shader(<wbr>struct radv_device *dev)<br>
                                                             false,<br>
                                                             GLSL_TYPE_FLOAT);<br>
        nir_builder_init_simple_<wbr>shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);<br>
-       b.shader-><a href="http://info.name" rel="noreferrer" target="_blank">info.name</a> = ralloc_strdup(b.shader, "meta_itob_cs");<br>
+       b.shader-><a href="http://info.name" rel="noreferrer" target="_blank">info.name</a> = ralloc_strdup(b.shader, is_3d ? "meta_itob_cs_3d" : "meta_itob_cs");<br>
        b.shader->info.cs.local_size[<wbr>0] = 16;<br>
        b.shader->info.cs.local_size[<wbr>1] = 16;<br>
        b.shader->info.cs.local_size[<wbr>2] = 1;<br>
@@ -69,32 +73,46 @@ build_nir_itob_compute_shader(<wbr>struct radv_device *dev)<br>
<br>
        nir_intrinsic_instr *offset = nir_intrinsic_instr_create(b.<wbr>shader, nir_intrinsic_load_push_<wbr>constant);<br>
        nir_intrinsic_set_base(offset, 0);<br>
-       nir_intrinsic_set_range(<wbr>offset, 12);<br>
+       nir_intrinsic_set_range(<wbr>offset, 16);<br>
        offset->src[0] = nir_src_for_ssa(nir_imm_int(&<wbr>b, 0));<br>
-       offset->num_components = 2;<br>
-       nir_ssa_dest_init(&offset-><wbr>instr, &offset->dest, 2, 32, "offset");<br>
+       offset->num_components = 3;<br>
+       nir_ssa_dest_init(&offset-><wbr>instr, &offset->dest, 3, 32, "offset");<br>
        nir_builder_instr_insert(&b, &offset->instr);<br>
<br>
        nir_intrinsic_instr *stride = nir_intrinsic_instr_create(b.<wbr>shader, nir_intrinsic_load_push_<wbr>constant);<br>
        nir_intrinsic_set_base(stride, 0);<br>
-       nir_intrinsic_set_range(<wbr>stride, 12);<br>
-       stride->src[0] = nir_src_for_ssa(nir_imm_int(&<wbr>b, 8));<br>
+       nir_intrinsic_set_range(<wbr>stride, 16);<br>
+       stride->src[0] = nir_src_for_ssa(nir_imm_int(&<wbr>b, 12));<br>
        stride->num_components = 1;<br>
        nir_ssa_dest_init(&stride-><wbr>instr, &stride->dest, 1, 32, "stride");<br>
        nir_builder_instr_insert(&b, &stride->instr);<br>
<br>
        nir_ssa_def *img_coord = nir_iadd(&b, global_id, &offset->dest.ssa);<br>
<br>
+       nir_ssa_def *img_coord_3d = NULL;<br>
+<br>
+       if (is_3d) {<br>
+               nir_ssa_def *chans[3];<br>
+<br>
+               chans[0] = nir_channel(&b, img_coord, 0);<br>
+               chans[1] = nir_channel(&b, img_coord, 1);<br>
+               chans[2] = nir_channel(&b, img_coord, 2);<br>
+               img_coord_3d = nir_vec(&b, chans, 3);<br>
+       }<br>
+<br>
        nir_tex_instr *tex = nir_tex_instr_create(b.shader, 2);<br>
-       tex->sampler_dim = GLSL_SAMPLER_DIM_2D;<br>
+       tex->sampler_dim = dim;<br>
        tex->op = nir_texop_txf;<br>
        tex->src[0].src_type = nir_tex_src_coord;<br>
-       tex->src[0].src = nir_src_for_ssa(nir_channels(&<wbr>b, img_coord, 0x3));<br>
+       if (is_3d)<br>
+               tex->src[0].src = nir_src_for_ssa(nir_channels(&<wbr>b, img_coord_3d, 0x7));<br>
+       else<br>
+               tex->src[0].src = nir_src_for_ssa(nir_channels(&<wbr>b, img_coord, 0x3));<br>
        tex->src[1].src_type = nir_tex_src_lod;<br>
        tex->src[1].src = nir_src_for_ssa(nir_imm_int(&<wbr>b, 0));<br>
        tex->dest_type = nir_type_float;<br>
        tex->is_array = false;<br>
-       tex->coord_components = 2;<br>
+       tex->coord_components = is_3d ? 3 : 2;<br>
        tex->texture = nir_deref_var_create(tex, input_img);<br>
        tex->sampler = NULL;<br>
<br>
@@ -126,8 +144,11 @@ radv_device_init_meta_itob_<wbr>state(struct radv_device *device)<br>
 {<br>
        VkResult result;<br>
        struct radv_shader_module cs = { .nir = NULL };<br>
+       struct radv_shader_module cs_3d = { .nir = NULL };<br>
<br>
-       cs.nir = build_nir_itob_compute_shader(<wbr>device);<br>
+       cs.nir = build_nir_itob_compute_shader(<wbr>device, false);<br>
+       if (device->physical_device->rad_<wbr>info.chip_class >= GFX9)<br>
+               cs_3d.nir = build_nir_itob_compute_shader(<wbr>device, true);<br>
<br>
        /*<br>
         * two descriptors one for the image being sampled<br>
@@ -168,7 +189,7 @@ radv_device_init_meta_itob_<wbr>state(struct radv_device *device)<br>
                .setLayoutCount = 1,<br>
                .pSetLayouts = &device->meta_state.itob.img_<wbr>ds_layout,<br>
                .pushConstantRangeCount = 1,<br>
-               .pPushConstantRanges = &(VkPushConstantRange){VK_<wbr>SHADER_STAGE_COMPUTE_BIT, 0, 12},<br>
+               .pPushConstantRanges = &(VkPushConstantRange){VK_<wbr>SHADER_STAGE_COMPUTE_BIT, 0, 16},<br>
        };<br>
<br>
        result = radv_CreatePipelineLayout(<wbr>radv_device_to_handle(device),<br>
@@ -202,10 +223,36 @@ radv_device_init_meta_itob_<wbr>state(struct radv_device *device)<br>
        if (result != VK_SUCCESS)<br>
                goto fail;<br>
<br>
+       if (device->physical_device->rad_<wbr>info.chip_class >= GFX9) {<br>
+               VkPipelineShaderStageCreateInf<wbr>o pipeline_shader_stage_3d = {<br>
+                       .sType = VK_STRUCTURE_TYPE_PIPELINE_<wbr>SHADER_STAGE_CREATE_INFO,<br>
+                       .stage = VK_SHADER_STAGE_COMPUTE_BIT,<br>
+                       .module = radv_shader_module_to_handle(&<wbr>cs_3d),<br>
+                       .pName = "main",<br>
+                       .pSpecializationInfo = NULL,<br>
+               };<br>
+<br>
+               VkComputePipelineCreateInfo vk_pipeline_info_3d = {<br>
+                       .sType = VK_STRUCTURE_TYPE_COMPUTE_<wbr>PIPELINE_CREATE_INFO,<br>
+                       .stage = pipeline_shader_stage_3d,<br>
+                       .flags = 0,<br>
+                       .layout = device->meta_state.itob.img_p_<wbr>layout,<br>
+               };<br>
+<br>
+               result = radv_CreateComputePipelines(<wbr>radv_device_to_handle(device),<br>
+                                                    radv_pipeline_cache_to_handle(<wbr>&device->meta_state.cache),<br>
+                                                    1, &vk_pipeline_info_3d, NULL,<br>
+                                                    &device->meta_state.itob.<wbr>pipeline_3d);<br>
+               if (result != VK_SUCCESS)<br>
+                       goto fail;<br>
+               ralloc_free(cs_3d.nir);<br>
+       }<br>
        ralloc_free(cs.nir);<br>
+<br>
        return VK_SUCCESS;<br>
 fail:<br>
        ralloc_free(cs.nir);<br>
+       ralloc_free(cs_3d.nir);<br>
        return result;<br>
 }<br>
<br>
@@ -221,6 +268,9 @@ radv_device_finish_meta_itob_<wbr>state(struct radv_device *device)<br>
                                        &state->alloc);<br>
        radv_DestroyPipeline(radv_<wbr>device_to_handle(device),<br>
                             state->itob.pipeline, &state->alloc);<br>
+       if (device->physical_device->rad_<wbr>info.chip_class >= GFX9)<br>
+               radv_DestroyPipeline(radv_<wbr>device_to_handle(device),<br>
+                                    state->itob.pipeline_3d, &state->alloc);<br>
 }<br>
<br>
 static nir_shader *<br>
@@ -792,7 +842,7 @@ create_iview(struct radv_cmd_buffer *cmd_buffer,<br>
                             &(VkImageViewCreateInfo) {<br>
                                     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_<wbr>CREATE_INFO,<br>
                                             .image = radv_image_to_handle(surf-><wbr>image),<br>
-                                            .viewType = VK_IMAGE_VIEW_TYPE_2D,<br>
+                                            .viewType = radv_meta_get_view_type(surf-><wbr>image),<br>
                                             .format = surf->format,<br>
                                             .subresourceRange = {<br>
                                             .aspectMask = surf->aspect_mask,<br>
@@ -878,18 +928,23 @@ radv_meta_image_to_buffer(<wbr>struct radv_cmd_buffer *cmd_buffer,<br>
        itob_bind_descriptors(cmd_<wbr>buffer, &src_view, &dst_view);<br>
<br>
<br>
+       if (device->physical_device->rad_<wbr>info.chip_class >= GFX9 &&<br>
+           src->image->type == VK_IMAGE_TYPE_3D)<br>
+               pipeline = cmd_buffer->device->meta_<wbr>state.itob.pipeline_3d;<br>
+<br>
        radv_CmdBindPipeline(radv_cmd_<wbr>buffer_to_handle(cmd_buffer),<br>
                             VK_PIPELINE_BIND_POINT_<wbr>COMPUTE, pipeline);<br>
<br>
        for (unsigned r = 0; r < num_rects; ++r) {<br>
-               unsigned push_constants[3] = {<br>
+               unsigned push_constants[4] = {<br>
                        rects[r].src_x,<br>
                        rects[r].src_y,<br>
+                       src->layer,<br>
                        dst->pitch<br>
                };<br>
                radv_CmdPushConstants(radv_<wbr>cmd_buffer_to_handle(cmd_<wbr>buffer),<br>
                                      device->meta_state.itob.img_p_<wbr>layout,<br>
-                                     VK_SHADER_STAGE_COMPUTE_BIT, 0, 12,<br>
+                                     VK_SHADER_STAGE_COMPUTE_BIT, 0, 16,<br>
                                      push_constants);<br>
<br>
                radv_unaligned_dispatch(cmd_<wbr>buffer, rects[r].width, rects[r].height, 1);<br>
diff --git a/src/amd/vulkan/radv_private.<wbr>h b/src/amd/vulkan/radv_private.<wbr>h<br>
index 9ef1f78932..63e8b50053 100644<br>
--- a/src/amd/vulkan/radv_private.<wbr>h<br>
+++ b/src/amd/vulkan/radv_private.<wbr>h<br>
@@ -416,6 +416,7 @@ struct radv_meta_state {<br>
                VkPipelineLayout                          img_p_layout;<br>
                VkDescriptorSetLayout                     img_ds_layout;<br>
                VkPipeline pipeline;<br>
+               VkPipeline pipeline_3d;<br>
        } itob;<br>
        struct {<br>
                VkPipelineLayout                          img_p_layout;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>