Home | History | Annotate | Line # | Download | only in vulkan
      1 /*
      2  * Copyright  2021 Valve Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #define AC_SURFACE_INCLUDE_NIR
     25 #include "ac_surface.h"
     26 
     27 #include "radv_meta.h"
     28 #include "radv_private.h"
     29 #include "vk_format.h"
     30 
     31 void
     32 radv_device_finish_meta_copy_vrs_htile_state(struct radv_device *device)
     33 {
     34    struct radv_meta_state *state = &device->meta_state;
     35 
     36    radv_DestroyPipeline(radv_device_to_handle(device), state->copy_vrs_htile_pipeline,
     37                         &state->alloc);
     38    radv_DestroyPipelineLayout(radv_device_to_handle(device), state->copy_vrs_htile_p_layout,
     39                               &state->alloc);
     40    radv_DestroyDescriptorSetLayout(radv_device_to_handle(device), state->copy_vrs_htile_ds_layout,
     41                                    &state->alloc);
     42 }
     43 
     44 static nir_shader *
     45 build_copy_vrs_htile_shader(struct radv_device *device, struct radeon_surf *surf)
     46 {
     47    nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, NULL, "meta_copy_vrs_htile");
     48    b.shader->info.workgroup_size[0] = 8;
     49    b.shader->info.workgroup_size[1] = 8;
     50    b.shader->info.workgroup_size[2] = 1;
     51 
     52    /* Get coordinates. */
     53    nir_ssa_def *global_id = get_global_ids(&b, 2);
     54 
     55    /* Multiply the coordinates by the HTILE block size. */
     56    nir_ssa_def *coord = nir_imul(&b, global_id, nir_imm_ivec2(&b, 8, 8));
     57 
     58    /* Load constants. */
     59    nir_ssa_def *constants = nir_load_push_constant(&b, 3, 32, nir_imm_int(&b, 0), .range = 12);
     60    nir_ssa_def *htile_pitch = nir_channel(&b, constants, 0);
     61    nir_ssa_def *htile_slice_size = nir_channel(&b, constants, 1);
     62    nir_ssa_def *read_htile_value = nir_channel(&b, constants, 2);
     63 
     64    /* Get the HTILE addr from coordinates. */
     65    nir_ssa_def *zero = nir_imm_int(&b, 0);
     66    nir_ssa_def *htile_addr = ac_nir_htile_addr_from_coord(
     67       &b, &device->physical_device->rad_info, &surf->u.gfx9.zs.htile_equation, htile_pitch,
     68       htile_slice_size, nir_channel(&b, coord, 0), nir_channel(&b, coord, 1), zero, zero);
     69 
     70    /* Set up the input VRS image descriptor. */
     71    const struct glsl_type *vrs_sampler_type =
     72       glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT);
     73    nir_variable *input_vrs_img =
     74       nir_variable_create(b.shader, nir_var_uniform, vrs_sampler_type, "input_vrs_image");
     75    input_vrs_img->data.descriptor_set = 0;
     76    input_vrs_img->data.binding = 0;
     77 
     78    nir_ssa_def *input_vrs_img_deref = &nir_build_deref_var(&b, input_vrs_img)->dest.ssa;
     79 
     80    /* Load the VRS rates from the 2D image. */
     81    nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
     82    tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
     83    tex->op = nir_texop_txf;
     84    tex->src[0].src_type = nir_tex_src_coord;
     85    tex->src[0].src = nir_src_for_ssa(global_id);
     86    tex->src[1].src_type = nir_tex_src_lod;
     87    tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
     88    tex->src[2].src_type = nir_tex_src_texture_deref;
     89    tex->src[2].src = nir_src_for_ssa(input_vrs_img_deref);
     90    tex->dest_type = nir_type_float32;
     91    tex->is_array = false;
     92    tex->coord_components = 2;
     93 
     94    nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
     95    nir_builder_instr_insert(&b, &tex->instr);
     96 
     97    /* Extract the X/Y rates and clamp them because the maximum supported VRS rate is 2x2 (1x1 in
     98     * hardware).
     99     *
    100     * VRS rate X = min(value >> 2, 1)
    101     * VRS rate Y = min(value & 3, 1)
    102     */
    103    nir_ssa_def *x_rate = nir_ushr(&b, &tex->dest.ssa, nir_imm_int(&b, 2));
    104    x_rate = nir_umin(&b, x_rate, nir_imm_int(&b, 1));
    105 
    106    nir_ssa_def *y_rate = nir_iand(&b, &tex->dest.ssa, nir_imm_int(&b, 3));
    107    y_rate = nir_umin(&b, y_rate, nir_imm_int(&b, 1));
    108 
    109    /* Compute the final VRS rate. */
    110    nir_ssa_def *vrs_rates = nir_ior(&b, nir_ishl(&b, y_rate, nir_imm_int(&b, 10)),
    111                                     nir_ishl(&b, x_rate, nir_imm_int(&b, 6)));
    112 
    113    /* Load the HTILE buffer descriptor. */
    114    nir_ssa_def *htile_buf = radv_meta_load_descriptor(&b, 0, 1);
    115 
    116    /* Load the HTILE value if requested, otherwise use the default value. */
    117    nir_variable *htile_value = nir_local_variable_create(b.impl, glsl_int_type(), "htile_value");
    118 
    119    nir_push_if(&b, nir_ieq(&b, read_htile_value, nir_imm_int(&b, 1)));
    120    {
    121       /* Load the existing HTILE 32-bit value for this 8x8 pixels area. */
    122       nir_ssa_def *input_value = nir_load_ssbo(&b, 1, 32, htile_buf, htile_addr, .align_mul = 4);
    123 
    124       /* Clear the 4-bit VRS rates. */
    125       nir_store_var(&b, htile_value, nir_iand(&b, input_value, nir_imm_int(&b, 0xfffff33f)), 0x1);
    126    }
    127    nir_push_else(&b, NULL);
    128    {
    129       nir_store_var(&b, htile_value, nir_imm_int(&b, 0xfffff33f), 0x1);
    130    }
    131    nir_pop_if(&b, NULL);
    132 
    133    /* Set the VRS rates loaded from the image. */
    134    nir_ssa_def *output_value = nir_ior(&b, nir_load_var(&b, htile_value), vrs_rates);
    135 
    136    /* Store the updated HTILE 32-bit which contains the VRS rates. */
    137    nir_store_ssbo(&b, output_value, htile_buf, htile_addr, .write_mask = 0x1,
    138                   .access = ACCESS_NON_READABLE, .align_mul = 4);
    139 
    140    return b.shader;
    141 }
    142 
    143 static VkResult
    144 radv_device_init_meta_copy_vrs_htile_state(struct radv_device *device,
    145                                            struct radeon_surf *surf)
    146 {
    147    struct radv_meta_state *state = &device->meta_state;
    148    nir_shader *cs = build_copy_vrs_htile_shader(device, surf);
    149    VkResult result;
    150 
    151    VkDescriptorSetLayoutCreateInfo ds_layout_info = {
    152       .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
    153       .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
    154       .bindingCount = 2,
    155       .pBindings = (VkDescriptorSetLayoutBinding[]){
    156          {.binding = 0,
    157           .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
    158           .descriptorCount = 1,
    159           .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
    160           .pImmutableSamplers = NULL},
    161          {.binding = 1,
    162           .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
    163           .descriptorCount = 1,
    164           .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
    165           .pImmutableSamplers = NULL},
    166       }};
    167 
    168    result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_layout_info,
    169                                            &state->alloc, &state->copy_vrs_htile_ds_layout);
    170    if (result != VK_SUCCESS)
    171       goto fail;
    172 
    173    VkPipelineLayoutCreateInfo p_layout_info = {
    174       .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
    175       .setLayoutCount = 1,
    176       .pSetLayouts = &state->copy_vrs_htile_ds_layout,
    177       .pushConstantRangeCount = 1,
    178       .pPushConstantRanges =
    179          &(VkPushConstantRange){
    180             VK_SHADER_STAGE_COMPUTE_BIT,
    181             0,
    182             12,
    183          },
    184    };
    185 
    186    result = radv_CreatePipelineLayout(radv_device_to_handle(device), &p_layout_info, &state->alloc,
    187                                       &state->copy_vrs_htile_p_layout);
    188    if (result != VK_SUCCESS)
    189       goto fail;
    190 
    191    VkPipelineShaderStageCreateInfo shader_stage = {
    192       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
    193       .stage = VK_SHADER_STAGE_COMPUTE_BIT,
    194       .module = vk_shader_module_handle_from_nir(cs),
    195       .pName = "main",
    196       .pSpecializationInfo = NULL,
    197    };
    198 
    199    VkComputePipelineCreateInfo pipeline_info = {
    200       .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
    201       .stage = shader_stage,
    202       .flags = 0,
    203       .layout = state->copy_vrs_htile_p_layout,
    204    };
    205 
    206    result = radv_CreateComputePipelines(radv_device_to_handle(device),
    207                                         radv_pipeline_cache_to_handle(&state->cache), 1,
    208                                         &pipeline_info, NULL, &state->copy_vrs_htile_pipeline);
    209 fail:
    210    ralloc_free(cs);
    211    return result;
    212 }
    213 
    214 void
    215 radv_copy_vrs_htile(struct radv_cmd_buffer *cmd_buffer, struct radv_image *vrs_image,
    216                     VkExtent2D *extent, struct radv_image *dst_image,
    217                     struct radv_buffer *htile_buffer, bool read_htile_value)
    218 {
    219    struct radv_device *device = cmd_buffer->device;
    220    struct radv_meta_state *state = &device->meta_state;
    221    struct radv_meta_saved_state saved_state;
    222    struct radv_image_view vrs_iview;
    223 
    224    assert(radv_image_has_htile(dst_image));
    225 
    226    if (!cmd_buffer->device->meta_state.copy_vrs_htile_pipeline) {
    227       VkResult ret = radv_device_init_meta_copy_vrs_htile_state(cmd_buffer->device,
    228                                                                 &dst_image->planes[0].surface);
    229       if (ret != VK_SUCCESS) {
    230          cmd_buffer->record_result = ret;
    231          return;
    232       }
    233    }
    234 
    235    cmd_buffer->state.flush_bits |=
    236       radv_src_access_flush(cmd_buffer, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, NULL) |
    237       radv_dst_access_flush(cmd_buffer, VK_ACCESS_SHADER_READ_BIT, NULL);
    238 
    239    radv_meta_save(
    240       &saved_state, cmd_buffer,
    241       RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS);
    242 
    243    radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
    244                         state->copy_vrs_htile_pipeline);
    245 
    246    radv_image_view_init(&vrs_iview, cmd_buffer->device,
    247                         &(VkImageViewCreateInfo){
    248                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
    249                            .image = radv_image_to_handle(vrs_image),
    250                            .viewType = VK_IMAGE_VIEW_TYPE_2D,
    251                            .format = vrs_image->vk_format,
    252                            .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
    253                                                 .baseMipLevel = 0,
    254                                                 .levelCount = 1,
    255                                                 .baseArrayLayer = 0,
    256                                                 .layerCount = 1},
    257                         },
    258                         NULL);
    259 
    260    radv_meta_push_descriptor_set(
    261       cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, state->copy_vrs_htile_p_layout, 0, /* set */
    262       2, /* descriptorWriteCount */
    263       (VkWriteDescriptorSet[]){
    264          {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
    265           .dstBinding = 0,
    266           .dstArrayElement = 0,
    267           .descriptorCount = 1,
    268           .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
    269           .pImageInfo =
    270              (VkDescriptorImageInfo[]){
    271                 {
    272                    .sampler = VK_NULL_HANDLE,
    273                    .imageView = radv_image_view_to_handle(&vrs_iview),
    274                    .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
    275                 },
    276              }},
    277          {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
    278           .dstBinding = 1,
    279           .dstArrayElement = 0,
    280           .descriptorCount = 1,
    281           .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
    282           .pBufferInfo = &(VkDescriptorBufferInfo){.buffer = radv_buffer_to_handle(htile_buffer),
    283                                                    .offset = 0,
    284                                                    .range = htile_buffer->size}}});
    285 
    286    const unsigned constants[3] = {
    287       dst_image->planes[0].surface.meta_pitch, dst_image->planes[0].surface.meta_slice_size,
    288       read_htile_value,
    289    };
    290 
    291    radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), state->copy_vrs_htile_p_layout,
    292                          VK_SHADER_STAGE_COMPUTE_BIT, 0, 12, constants);
    293 
    294    uint32_t width = DIV_ROUND_UP(extent->width, 8);
    295    uint32_t height = DIV_ROUND_UP(extent->height, 8);
    296 
    297    radv_unaligned_dispatch(cmd_buffer, width, height, 1);
    298 
    299    radv_image_view_finish(&vrs_iview);
    300 
    301    radv_meta_restore(&saved_state, cmd_buffer);
    302 
    303    cmd_buffer->state.flush_bits |=
    304       RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE |
    305       radv_src_access_flush(cmd_buffer, VK_ACCESS_SHADER_WRITE_BIT, NULL);
    306 }
    307