Home | History | Annotate | Line # | Download | only in vulkan
      1 /*
      2  * Copyright  2021 Collabora Ltd.
      3  *
      4  * Derived from tu_cmd_buffer.c which is:
      5  * Copyright  2016 Red Hat.
      6  * Copyright  2016 Bas Nieuwenhuizen
      7  * Copyright  2015 Intel Corporation
      8  *
      9  * Permission is hereby granted, free of charge, to any person obtaining a
     10  * copy of this software and associated documentation files (the "Software"),
     11  * to deal in the Software without restriction, including without limitation
     12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     13  * and/or sell copies of the Software, and to permit persons to whom the
     14  * Software is furnished to do so, subject to the following conditions:
     15  *
     16  * The above copyright notice and this permission notice (including the next
     17  * paragraph) shall be included in all copies or substantial portions of the
     18  * Software.
     19  *
     20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     26  * DEALINGS IN THE SOFTWARE.
     27  */
     28 
     29 #include "panvk_private.h"
     30 #include "panfrost-quirks.h"
     31 
     32 #include "pan_encoder.h"
     33 
     34 #include "util/rounding.h"
     35 #include "vk_format.h"
     36 
     37 void
     38 panvk_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
     39                            uint32_t firstBinding,
     40                            uint32_t bindingCount,
     41                            const VkBuffer *pBuffers,
     42                            const VkDeviceSize *pOffsets)
     43 {
     44    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
     45 
     46    assert(firstBinding + bindingCount <= MAX_VBS);
     47 
     48    for (uint32_t i = 0; i < bindingCount; i++) {
     49       struct panvk_buffer *buf = panvk_buffer_from_handle(pBuffers[i]);
     50 
     51       cmdbuf->state.vb.bufs[firstBinding + i].address = buf->bo->ptr.gpu + pOffsets[i];
     52       cmdbuf->state.vb.bufs[firstBinding + i].size = buf->size - pOffsets[i];
     53    }
     54    cmdbuf->state.vb.count = MAX2(cmdbuf->state.vb.count, firstBinding + bindingCount);
     55    cmdbuf->state.vb.attrib_bufs = cmdbuf->state.vb.attribs = 0;
     56 }
     57 
     58 void
     59 panvk_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
     60                          VkBuffer buffer,
     61                          VkDeviceSize offset,
     62                          VkIndexType indexType)
     63 {
     64    panvk_stub();
     65 }
     66 
     67 void
     68 panvk_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
     69                             VkPipelineBindPoint pipelineBindPoint,
     70                             VkPipelineLayout _layout,
     71                             uint32_t firstSet,
     72                             uint32_t descriptorSetCount,
     73                             const VkDescriptorSet *pDescriptorSets,
     74                             uint32_t dynamicOffsetCount,
     75                             const uint32_t *pDynamicOffsets)
     76 {
     77    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
     78    VK_FROM_HANDLE(panvk_pipeline_layout, layout, _layout);
     79 
     80    struct panvk_descriptor_state *descriptors_state =
     81       &cmdbuf->bind_points[pipelineBindPoint].desc_state;
     82 
     83    for (unsigned i = 0; i < descriptorSetCount; ++i) {
     84       unsigned idx = i + firstSet;
     85       VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorSets[i]);
     86 
     87       descriptors_state->sets[idx].set = set;
     88 
     89       if (layout->num_dynoffsets) {
     90          assert(dynamicOffsetCount >= set->layout->num_dynoffsets);
     91 
     92          descriptors_state->sets[idx].dynoffsets =
     93             pan_pool_alloc_aligned(&cmdbuf->desc_pool.base,
     94                                    ALIGN(layout->num_dynoffsets, 4) *
     95                                    sizeof(*pDynamicOffsets),
     96                                    16);
     97          memcpy(descriptors_state->sets[idx].dynoffsets.cpu,
     98                 pDynamicOffsets,
     99                 sizeof(*pDynamicOffsets) * set->layout->num_dynoffsets);
    100          dynamicOffsetCount -= set->layout->num_dynoffsets;
    101          pDynamicOffsets += set->layout->num_dynoffsets;
    102       }
    103 
    104       if (set->layout->num_ubos || set->layout->num_dynoffsets)
    105          descriptors_state->ubos = 0;
    106 
    107       if (set->layout->num_textures)
    108          descriptors_state->textures = 0;
    109 
    110       if (set->layout->num_samplers)
    111          descriptors_state->samplers = 0;
    112    }
    113 
    114    assert(!dynamicOffsetCount);
    115 }
    116 
    117 void
    118 panvk_CmdPushConstants(VkCommandBuffer commandBuffer,
    119                        VkPipelineLayout layout,
    120                        VkShaderStageFlags stageFlags,
    121                        uint32_t offset,
    122                        uint32_t size,
    123                        const void *pValues)
    124 {
    125    panvk_stub();
    126 }
    127 
    128 void
    129 panvk_CmdBindPipeline(VkCommandBuffer commandBuffer,
    130                       VkPipelineBindPoint pipelineBindPoint,
    131                       VkPipeline _pipeline)
    132 {
    133    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    134    VK_FROM_HANDLE(panvk_pipeline, pipeline, _pipeline);
    135 
    136    cmdbuf->bind_points[pipelineBindPoint].pipeline = pipeline;
    137    cmdbuf->state.fs_rsd = 0;
    138    memset(cmdbuf->bind_points[pipelineBindPoint].desc_state.sysvals, 0,
    139           sizeof(cmdbuf->bind_points[0].desc_state.sysvals));
    140 
    141    if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) {
    142       cmdbuf->state.varyings = pipeline->varyings;
    143 
    144       if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_VIEWPORT)))
    145          cmdbuf->state.viewport = pipeline->viewport;
    146       if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_SCISSOR)))
    147          cmdbuf->state.scissor = pipeline->scissor;
    148    }
    149 
    150    /* Sysvals are passed through UBOs, we need dirty the UBO array if the
    151     * pipeline contain shaders using sysvals.
    152     */
    153    if (pipeline->num_sysvals)
    154       cmdbuf->bind_points[pipelineBindPoint].desc_state.ubos = 0;
    155 }
    156 
    157 void
    158 panvk_CmdSetViewport(VkCommandBuffer commandBuffer,
    159                      uint32_t firstViewport,
    160                      uint32_t viewportCount,
    161                      const VkViewport *pViewports)
    162 {
    163    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    164    assert(viewportCount == 1);
    165    assert(!firstViewport);
    166 
    167    cmdbuf->state.viewport = pViewports[0];
    168    cmdbuf->state.vpd = 0;
    169    cmdbuf->state.dirty |= PANVK_DYNAMIC_VIEWPORT;
    170 }
    171 
    172 void
    173 panvk_CmdSetScissor(VkCommandBuffer commandBuffer,
    174                     uint32_t firstScissor,
    175                     uint32_t scissorCount,
    176                     const VkRect2D *pScissors)
    177 {
    178    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    179    assert(scissorCount == 1);
    180    assert(!firstScissor);
    181 
    182    cmdbuf->state.scissor = pScissors[0];
    183    cmdbuf->state.vpd = 0;
    184    cmdbuf->state.dirty |= PANVK_DYNAMIC_SCISSOR;
    185 }
    186 
    187 void
    188 panvk_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
    189 {
    190    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    191 
    192    cmdbuf->state.rast.line_width = lineWidth;
    193    cmdbuf->state.dirty |= PANVK_DYNAMIC_LINE_WIDTH;
    194 }
    195 
    196 void
    197 panvk_CmdSetDepthBias(VkCommandBuffer commandBuffer,
    198                       float depthBiasConstantFactor,
    199                       float depthBiasClamp,
    200                       float depthBiasSlopeFactor)
    201 {
    202    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    203 
    204    cmdbuf->state.rast.depth_bias.constant_factor = depthBiasConstantFactor;
    205    cmdbuf->state.rast.depth_bias.clamp = depthBiasClamp;
    206    cmdbuf->state.rast.depth_bias.slope_factor = depthBiasSlopeFactor;
    207    cmdbuf->state.dirty |= PANVK_DYNAMIC_DEPTH_BIAS;
    208    cmdbuf->state.fs_rsd = 0;
    209 }
    210 
    211 void
    212 panvk_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
    213                            const float blendConstants[4])
    214 {
    215    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    216 
    217    for (unsigned i = 0; i < 4; i++)
    218       cmdbuf->state.blend.constants[i] = CLAMP(blendConstants[i], 0.0f, 1.0f);
    219 
    220    cmdbuf->state.dirty |= PANVK_DYNAMIC_BLEND_CONSTANTS;
    221    cmdbuf->state.fs_rsd = 0;
    222 }
    223 
    224 void
    225 panvk_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
    226                         float minDepthBounds,
    227                         float maxDepthBounds)
    228 {
    229    panvk_stub();
    230 }
    231 
    232 void
    233 panvk_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
    234                                VkStencilFaceFlags faceMask,
    235                                uint32_t compareMask)
    236 {
    237    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    238 
    239    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
    240       cmdbuf->state.zs.s_front.compare_mask = compareMask;
    241 
    242    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
    243       cmdbuf->state.zs.s_back.compare_mask = compareMask;
    244 
    245    cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_COMPARE_MASK;
    246    cmdbuf->state.fs_rsd = 0;
    247 }
    248 
    249 void
    250 panvk_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
    251                              VkStencilFaceFlags faceMask,
    252                              uint32_t writeMask)
    253 {
    254    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    255 
    256    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
    257       cmdbuf->state.zs.s_front.write_mask = writeMask;
    258 
    259    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
    260       cmdbuf->state.zs.s_back.write_mask = writeMask;
    261 
    262    cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_WRITE_MASK;
    263    cmdbuf->state.fs_rsd = 0;
    264 }
    265 
    266 void
    267 panvk_CmdSetStencilReference(VkCommandBuffer commandBuffer,
    268                              VkStencilFaceFlags faceMask,
    269                              uint32_t reference)
    270 {
    271    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    272 
    273    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
    274       cmdbuf->state.zs.s_front.ref = reference;
    275 
    276    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
    277       cmdbuf->state.zs.s_back.ref = reference;
    278 
    279    cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_REFERENCE;
    280    cmdbuf->state.fs_rsd = 0;
    281 }
    282 
    283 void
    284 panvk_CmdExecuteCommands(VkCommandBuffer commandBuffer,
    285                          uint32_t commandBufferCount,
    286                          const VkCommandBuffer *pCmdBuffers)
    287 {
    288    panvk_stub();
    289 }
    290 
    291 VkResult
    292 panvk_CreateCommandPool(VkDevice _device,
    293                         const VkCommandPoolCreateInfo *pCreateInfo,
    294                         const VkAllocationCallbacks *pAllocator,
    295                         VkCommandPool *pCmdPool)
    296 {
    297    VK_FROM_HANDLE(panvk_device, device, _device);
    298    struct panvk_cmd_pool *pool;
    299 
    300    pool = vk_object_alloc(&device->vk, pAllocator, sizeof(*pool),
    301                           VK_OBJECT_TYPE_COMMAND_POOL);
    302    if (pool == NULL)
    303       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
    304 
    305    if (pAllocator)
    306       pool->alloc = *pAllocator;
    307    else
    308       pool->alloc = device->vk.alloc;
    309 
    310    list_inithead(&pool->active_cmd_buffers);
    311    list_inithead(&pool->free_cmd_buffers);
    312 
    313    pool->queue_family_index = pCreateInfo->queueFamilyIndex;
    314    panvk_bo_pool_init(&pool->desc_bo_pool);
    315    panvk_bo_pool_init(&pool->varying_bo_pool);
    316    panvk_bo_pool_init(&pool->tls_bo_pool);
    317    *pCmdPool = panvk_cmd_pool_to_handle(pool);
    318    return VK_SUCCESS;
    319 }
    320 
    321 static void
    322 panvk_cmd_prepare_clear_values(struct panvk_cmd_buffer *cmdbuf,
    323                                const VkClearValue *in)
    324 {
    325    for (unsigned i = 0; i < cmdbuf->state.pass->attachment_count; i++) {
    326        const struct panvk_render_pass_attachment *attachment =
    327           &cmdbuf->state.pass->attachments[i];
    328        enum pipe_format fmt = attachment->format;
    329 
    330        if (util_format_is_depth_or_stencil(fmt)) {
    331           if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR ||
    332               attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
    333              cmdbuf->state.clear[i].depth = in[i].depthStencil.depth;
    334              cmdbuf->state.clear[i].stencil = in[i].depthStencil.stencil;
    335           } else {
    336              cmdbuf->state.clear[i].depth = 0;
    337              cmdbuf->state.clear[i].stencil = 0;
    338           }
    339        } else {
    340           if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
    341              union pipe_color_union *col = (union pipe_color_union *) &in[i].color;
    342              pan_pack_color(cmdbuf->state.clear[i].color, col, fmt, false);
    343           } else {
    344              memset(cmdbuf->state.clear[i].color, 0, sizeof(cmdbuf->state.clear[0].color));
    345           }
    346        }
    347    }
    348 }
    349 
    350 void
    351 panvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf)
    352 {
    353    const struct panvk_subpass *subpass = cmdbuf->state.subpass;
    354    struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
    355    const struct panvk_framebuffer *fb = cmdbuf->state.framebuffer;
    356    const struct panvk_clear_value *clears = cmdbuf->state.clear;
    357    struct panvk_image_view *view;
    358 
    359    fbinfo->nr_samples = 1;
    360    fbinfo->rt_count = subpass->color_count;
    361    memset(&fbinfo->bifrost.pre_post.dcds, 0, sizeof(fbinfo->bifrost.pre_post.dcds));
    362 
    363    for (unsigned cb = 0; cb < subpass->color_count; cb++) {
    364       int idx = subpass->color_attachments[cb].idx;
    365       view = idx != VK_ATTACHMENT_UNUSED ?
    366              fb->attachments[idx].iview : NULL;
    367       if (!view)
    368          continue;
    369       fbinfo->rts[cb].view = &view->pview;
    370       fbinfo->rts[cb].clear = subpass->color_attachments[cb].clear;
    371       fbinfo->rts[cb].preload = subpass->color_attachments[cb].preload;
    372       fbinfo->rts[cb].crc_valid = &cmdbuf->state.fb.crc_valid[cb];
    373 
    374       memcpy(fbinfo->rts[cb].clear_value, clears[idx].color,
    375              sizeof(fbinfo->rts[cb].clear_value));
    376       fbinfo->nr_samples =
    377          MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
    378    }
    379 
    380    if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) {
    381       view = fb->attachments[subpass->zs_attachment.idx].iview;
    382       const struct util_format_description *fdesc =
    383          util_format_description(view->pview.format);
    384 
    385       fbinfo->nr_samples =
    386          MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
    387 
    388       if (util_format_has_depth(fdesc)) {
    389          fbinfo->zs.clear.z = subpass->zs_attachment.clear;
    390          fbinfo->zs.clear_value.depth = clears[subpass->zs_attachment.idx].depth;
    391          fbinfo->zs.view.zs = &view->pview;
    392       }
    393 
    394       if (util_format_has_stencil(fdesc)) {
    395          fbinfo->zs.clear.s = subpass->zs_attachment.clear;
    396          fbinfo->zs.clear_value.stencil = clears[subpass->zs_attachment.idx].stencil;
    397          if (!fbinfo->zs.view.zs)
    398             fbinfo->zs.view.s = &view->pview;
    399       }
    400    }
    401 }
    402 
    403 void
    404 panvk_cmd_fb_info_init(struct panvk_cmd_buffer *cmdbuf)
    405 {
    406    struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
    407    const struct panvk_framebuffer *fb = cmdbuf->state.framebuffer;
    408 
    409    memset(cmdbuf->state.fb.crc_valid, 0, sizeof(cmdbuf->state.fb.crc_valid));
    410 
    411    *fbinfo = (struct pan_fb_info) {
    412       .width = fb->width,
    413       .height = fb->height,
    414       .extent.maxx = fb->width - 1,
    415       .extent.maxy = fb->height - 1,
    416    };
    417 }
    418 
    419 void
    420 panvk_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
    421                           const VkRenderPassBeginInfo *pRenderPassBegin,
    422                           const VkSubpassBeginInfo *pSubpassBeginInfo)
    423 {
    424    VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
    425    VK_FROM_HANDLE(panvk_render_pass, pass, pRenderPassBegin->renderPass);
    426    VK_FROM_HANDLE(panvk_framebuffer, fb, pRenderPassBegin->framebuffer);
    427 
    428    cmdbuf->state.pass = pass;
    429    cmdbuf->state.subpass = pass->subpasses;
    430    cmdbuf->state.framebuffer = fb;
    431    cmdbuf->state.render_area = pRenderPassBegin->renderArea;
    432    cmdbuf->state.batch = vk_zalloc(&cmdbuf->pool->alloc,
    433                                    sizeof(*cmdbuf->state.batch), 8,
    434                                    VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    435    util_dynarray_init(&cmdbuf->state.batch->jobs, NULL);
    436    util_dynarray_init(&cmdbuf->state.batch->event_ops, NULL);
    437    assert(pRenderPassBegin->clearValueCount <= pass->attachment_count);
    438    cmdbuf->state.clear =
    439       vk_zalloc(&cmdbuf->pool->alloc,
    440                 sizeof(*cmdbuf->state.clear) * pass->attachment_count,
    441                 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    442    panvk_cmd_prepare_clear_values(cmdbuf, pRenderPassBegin->pClearValues);
    443    panvk_cmd_fb_info_init(cmdbuf);
    444    panvk_cmd_fb_info_set_subpass(cmdbuf);
    445 }
    446 
    447 void
    448 panvk_CmdBeginRenderPass(VkCommandBuffer cmd,
    449                          const VkRenderPassBeginInfo *info,
    450                          VkSubpassContents contents)
    451 {
    452    VkSubpassBeginInfo subpass_info = {
    453       .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
    454       .contents = contents
    455    };
    456 
    457    return panvk_CmdBeginRenderPass2(cmd, info, &subpass_info);
    458 }
    459 
    460 void
    461 panvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf)
    462 {
    463    for (unsigned i = 0; i < cmdbuf->state.fb.info.rt_count; i++) {
    464       if (cmdbuf->state.fb.info.rts[i].view) {
    465          cmdbuf->state.fb.info.rts[i].clear = false;
    466          cmdbuf->state.fb.info.rts[i].preload = true;
    467       }
    468    }
    469 
    470    if (cmdbuf->state.fb.info.zs.view.zs) {
    471       cmdbuf->state.fb.info.zs.clear.z = false;
    472       cmdbuf->state.fb.info.zs.preload.z = true;
    473    }
    474 
    475    if (cmdbuf->state.fb.info.zs.view.s ||
    476        (cmdbuf->state.fb.info.zs.view.zs &&
    477         util_format_is_depth_and_stencil(cmdbuf->state.fb.info.zs.view.zs->format))) {
    478       cmdbuf->state.fb.info.zs.clear.s = false;
    479       cmdbuf->state.fb.info.zs.preload.s = true;
    480    }
    481 }
    482 
    483 struct panvk_batch *
    484 panvk_cmd_open_batch(struct panvk_cmd_buffer *cmdbuf)
    485 {
    486    assert(!cmdbuf->state.batch);
    487    cmdbuf->state.batch = vk_zalloc(&cmdbuf->pool->alloc,
    488                                    sizeof(*cmdbuf->state.batch), 8,
    489                                    VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    490    assert(cmdbuf->state.batch);
    491    return cmdbuf->state.batch;
    492 }
    493 
    494 void
    495 panvk_CmdDrawIndexed(VkCommandBuffer commandBuffer,
    496                      uint32_t indexCount,
    497                      uint32_t instanceCount,
    498                      uint32_t firstIndex,
    499                      int32_t vertexOffset,
    500                      uint32_t firstInstance)
    501 {
    502    panvk_stub();
    503 }
    504 
    505 void
    506 panvk_CmdDrawIndirect(VkCommandBuffer commandBuffer,
    507                       VkBuffer _buffer,
    508                       VkDeviceSize offset,
    509                       uint32_t drawCount,
    510                       uint32_t stride)
    511 {
    512    panvk_stub();
    513 }
    514 
    515 void
    516 panvk_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
    517                              VkBuffer _buffer,
    518                              VkDeviceSize offset,
    519                              uint32_t drawCount,
    520                              uint32_t stride)
    521 {
    522    panvk_stub();
    523 }
    524 
    525 void
    526 panvk_CmdDispatchBase(VkCommandBuffer commandBuffer,
    527                       uint32_t base_x,
    528                       uint32_t base_y,
    529                       uint32_t base_z,
    530                       uint32_t x,
    531                       uint32_t y,
    532                       uint32_t z)
    533 {
    534    panvk_stub();
    535 }
    536 
    537 void
    538 panvk_CmdDispatch(VkCommandBuffer commandBuffer,
    539                   uint32_t x,
    540                   uint32_t y,
    541                   uint32_t z)
    542 {
    543    panvk_stub();
    544 }
    545 
    546 void
    547 panvk_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
    548                           VkBuffer _buffer,
    549                           VkDeviceSize offset)
    550 {
    551    panvk_stub();
    552 }
    553 
    554 void
    555 panvk_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
    556 {
    557    panvk_stub();
    558 }
    559