mesa/src/panfrost/vulkan/panvk_cmd_buffer.c
Jason Ekstrand a463c58e22 panvk: Put SSBO addresses in the descriptor buffer
Instead of storing SSBO pointers in the very limited sysval space, store
them in the UBO we've attached to the descriptor set.  This gives us a
virtually unlimited number of SSBOs.  Dynamic SSBOs still live in the
sysval space so we can update them as part of vkCmdBindDescriptorSets().
Also, the new code (based on the code in ANV) loads those SSBO addresses
in a way that never chases the deref chain back to the variable so we
should now be able to handle all of variable pointers.  The code as
written in this patch is a bit overly generic because it switches on
address modes a bit more than panvk needs but we ended up needing all
that flexibility in ANV so we may as well leave hooks for it in panvk.

Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16276>
2022-05-12 10:53:16 +00:00

618 lines
21 KiB
C

/*
* Copyright © 2021 Collabora Ltd.
*
* Derived from tu_cmd_buffer.c which is:
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
* Copyright © 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "panvk_private.h"
#include "pan_encoder.h"
#include "util/rounding.h"
#include "vk_format.h"
void
panvk_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *pBuffers,
const VkDeviceSize *pOffsets)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_descriptor_state *desc_state =
panvk_cmd_get_desc_state(cmdbuf, GRAPHICS);
assert(firstBinding + bindingCount <= MAX_VBS);
for (uint32_t i = 0; i < bindingCount; i++) {
VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]);
cmdbuf->state.vb.bufs[firstBinding + i].address =
panvk_buffer_gpu_ptr(buffer, pOffsets[i]);
cmdbuf->state.vb.bufs[firstBinding + i].size =
panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE);
}
cmdbuf->state.vb.count = MAX2(cmdbuf->state.vb.count, firstBinding + bindingCount);
desc_state->vs_attrib_bufs = desc_state->vs_attribs = 0;
}
void
panvk_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
VkBuffer buffer,
VkDeviceSize offset,
VkIndexType indexType)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_buffer, buf, buffer);
cmdbuf->state.ib.buffer = buf;
cmdbuf->state.ib.offset = offset;
switch (indexType) {
case VK_INDEX_TYPE_UINT16:
cmdbuf->state.ib.index_size = 16;
break;
case VK_INDEX_TYPE_UINT32:
cmdbuf->state.ib.index_size = 32;
break;
case VK_INDEX_TYPE_NONE_KHR:
cmdbuf->state.ib.index_size = 0;
break;
case VK_INDEX_TYPE_UINT8_EXT:
cmdbuf->state.ib.index_size = 8;
break;
default:
unreachable("Invalid index type\n");
}
}
static void
panvk_set_dyn_ssbo_pointers(struct panvk_descriptor_state *desc_state,
unsigned dyn_ssbo_offset,
struct panvk_descriptor_set *set)
{
struct panvk_sysvals *sysvals = &desc_state->sysvals;
for (unsigned i = 0; i < set->layout->num_dyn_ssbos; i++) {
const struct panvk_buffer_desc *ssbo =
&desc_state->dyn.ssbos[dyn_ssbo_offset + i];
sysvals->dyn_ssbos[dyn_ssbo_offset + i] = (struct panvk_ssbo_addr) {
.base_addr = panvk_buffer_gpu_ptr(ssbo->buffer, ssbo->offset),
.size = panvk_buffer_range(ssbo->buffer, ssbo->offset, ssbo->size),
};
}
desc_state->sysvals_ptr = 0;
}
void
panvk_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout,
uint32_t firstSet,
uint32_t descriptorSetCount,
const VkDescriptorSet *pDescriptorSets,
uint32_t dynamicOffsetCount,
const uint32_t *pDynamicOffsets)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_pipeline_layout, playout, layout);
struct panvk_descriptor_state *descriptors_state =
&cmdbuf->bind_points[pipelineBindPoint].desc_state;
unsigned dynoffset_idx = 0;
for (unsigned i = 0; i < descriptorSetCount; ++i) {
unsigned idx = i + firstSet;
VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorSets[i]);
descriptors_state->sets[idx] = set;
if (set->layout->num_dyn_ssbos || set->layout->num_dyn_ubos) {
unsigned dyn_ubo_offset = playout->sets[idx].dyn_ubo_offset;
unsigned dyn_ssbo_offset = playout->sets[idx].dyn_ssbo_offset;
for (unsigned b = 0; b < set->layout->binding_count; b++) {
for (unsigned e = 0; e < set->layout->bindings[b].array_size; e++) {
struct panvk_buffer_desc *bdesc = NULL;
if (set->layout->bindings[b].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
bdesc = &descriptors_state->dyn.ubos[dyn_ubo_offset++];
*bdesc = set->dyn_ubos[set->layout->bindings[b].dyn_ubo_idx + e];
} else if (set->layout->bindings[b].type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
bdesc = &descriptors_state->dyn.ssbos[dyn_ssbo_offset++];
*bdesc = set->dyn_ssbos[set->layout->bindings[b].dyn_ssbo_idx + e];
}
if (bdesc) {
bdesc->offset += pDynamicOffsets[dynoffset_idx++];
}
}
}
}
if (set->layout->num_dyn_ssbos) {
panvk_set_dyn_ssbo_pointers(descriptors_state,
playout->sets[idx].dyn_ssbo_offset,
set);
}
if (set->layout->num_dyn_ssbos)
descriptors_state->dirty |= PANVK_DYNAMIC_SSBO;
if (set->layout->num_ubos || set->layout->num_dyn_ubos ||
set->layout->num_dyn_ssbos || set->layout->desc_ubo_size)
descriptors_state->ubos = 0;
if (set->layout->num_textures)
descriptors_state->textures = 0;
if (set->layout->num_samplers)
descriptors_state->samplers = 0;
if (set->layout->num_imgs) {
descriptors_state->vs_attrib_bufs = descriptors_state->non_vs_attrib_bufs = 0;
descriptors_state->vs_attribs = descriptors_state->non_vs_attribs = 0;
}
}
assert(dynoffset_idx == dynamicOffsetCount);
}
void
panvk_CmdPushConstants(VkCommandBuffer commandBuffer,
VkPipelineLayout layout,
VkShaderStageFlags stageFlags,
uint32_t offset,
uint32_t size,
const void *pValues)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
memcpy(cmdbuf->push_constants + offset, pValues, size);
if (stageFlags & VK_SHADER_STAGE_ALL_GRAPHICS) {
struct panvk_descriptor_state *desc_state =
panvk_cmd_get_desc_state(cmdbuf, GRAPHICS);
desc_state->ubos = 0;
desc_state->push_constants = 0;
}
if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) {
struct panvk_descriptor_state *desc_state =
panvk_cmd_get_desc_state(cmdbuf, COMPUTE);
desc_state->ubos = 0;
desc_state->push_constants = 0;
}
}
void
panvk_CmdBindPipeline(VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipeline _pipeline)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_pipeline, pipeline, _pipeline);
cmdbuf->bind_points[pipelineBindPoint].pipeline = pipeline;
cmdbuf->state.fs_rsd = 0;
if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) {
cmdbuf->state.varyings = pipeline->varyings;
if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_VIEWPORT))) {
cmdbuf->state.viewport = pipeline->viewport;
cmdbuf->state.dirty |= PANVK_DYNAMIC_VIEWPORT;
}
if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_SCISSOR))) {
cmdbuf->state.scissor = pipeline->scissor;
cmdbuf->state.dirty |= PANVK_DYNAMIC_SCISSOR;
}
}
/* Sysvals are passed through UBOs, we need dirty the UBO array if the
* pipeline contain shaders using sysvals.
*/
cmdbuf->bind_points[pipelineBindPoint].desc_state.ubos = 0;
}
void
panvk_CmdSetViewport(VkCommandBuffer commandBuffer,
uint32_t firstViewport,
uint32_t viewportCount,
const VkViewport *pViewports)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
assert(viewportCount == 1);
assert(!firstViewport);
cmdbuf->state.viewport = pViewports[0];
cmdbuf->state.vpd = 0;
cmdbuf->state.dirty |= PANVK_DYNAMIC_VIEWPORT;
}
void
panvk_CmdSetScissor(VkCommandBuffer commandBuffer,
uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D *pScissors)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
assert(scissorCount == 1);
assert(!firstScissor);
cmdbuf->state.scissor = pScissors[0];
cmdbuf->state.vpd = 0;
cmdbuf->state.dirty |= PANVK_DYNAMIC_SCISSOR;
}
void
panvk_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
cmdbuf->state.rast.line_width = lineWidth;
cmdbuf->state.dirty |= PANVK_DYNAMIC_LINE_WIDTH;
}
void
panvk_CmdSetDepthBias(VkCommandBuffer commandBuffer,
float depthBiasConstantFactor,
float depthBiasClamp,
float depthBiasSlopeFactor)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
cmdbuf->state.rast.depth_bias.constant_factor = depthBiasConstantFactor;
cmdbuf->state.rast.depth_bias.clamp = depthBiasClamp;
cmdbuf->state.rast.depth_bias.slope_factor = depthBiasSlopeFactor;
cmdbuf->state.dirty |= PANVK_DYNAMIC_DEPTH_BIAS;
cmdbuf->state.fs_rsd = 0;
}
void
panvk_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
const float blendConstants[4])
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
for (unsigned i = 0; i < 4; i++)
cmdbuf->state.blend.constants[i] = CLAMP(blendConstants[i], 0.0f, 1.0f);
cmdbuf->state.dirty |= PANVK_DYNAMIC_BLEND_CONSTANTS;
cmdbuf->state.fs_rsd = 0;
}
void
panvk_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
float minDepthBounds,
float maxDepthBounds)
{
panvk_stub();
}
void
panvk_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t compareMask)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmdbuf->state.zs.s_front.compare_mask = compareMask;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmdbuf->state.zs.s_back.compare_mask = compareMask;
cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_COMPARE_MASK;
cmdbuf->state.fs_rsd = 0;
}
void
panvk_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t writeMask)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmdbuf->state.zs.s_front.write_mask = writeMask;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmdbuf->state.zs.s_back.write_mask = writeMask;
cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_WRITE_MASK;
cmdbuf->state.fs_rsd = 0;
}
void
panvk_CmdSetStencilReference(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t reference)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmdbuf->state.zs.s_front.ref = reference;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmdbuf->state.zs.s_back.ref = reference;
cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_REFERENCE;
cmdbuf->state.fs_rsd = 0;
}
VkResult
panvk_CreateCommandPool(VkDevice _device,
const VkCommandPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkCommandPool *pCmdPool)
{
VK_FROM_HANDLE(panvk_device, device, _device);
struct panvk_cmd_pool *pool;
pool = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pool == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = vk_command_pool_init(&pool->vk, &device->vk,
pCreateInfo, pAllocator);
if (result != VK_SUCCESS) {
vk_free2(&device->vk.alloc, pAllocator, pool);
return result;
}
list_inithead(&pool->active_cmd_buffers);
list_inithead(&pool->free_cmd_buffers);
panvk_bo_pool_init(&pool->desc_bo_pool);
panvk_bo_pool_init(&pool->varying_bo_pool);
panvk_bo_pool_init(&pool->tls_bo_pool);
*pCmdPool = panvk_cmd_pool_to_handle(pool);
return VK_SUCCESS;
}
static void
panvk_cmd_prepare_clear_values(struct panvk_cmd_buffer *cmdbuf,
const VkClearValue *in)
{
for (unsigned i = 0; i < cmdbuf->state.pass->attachment_count; i++) {
const struct panvk_render_pass_attachment *attachment =
&cmdbuf->state.pass->attachments[i];
enum pipe_format fmt = attachment->format;
if (util_format_is_depth_or_stencil(fmt)) {
if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR ||
attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
cmdbuf->state.clear[i].depth = in[i].depthStencil.depth;
cmdbuf->state.clear[i].stencil = in[i].depthStencil.stencil;
} else {
cmdbuf->state.clear[i].depth = 0;
cmdbuf->state.clear[i].stencil = 0;
}
} else {
if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
union pipe_color_union *col = (union pipe_color_union *) &in[i].color;
pan_pack_color(cmdbuf->state.clear[i].color, col, fmt, false);
} else {
memset(cmdbuf->state.clear[i].color, 0, sizeof(cmdbuf->state.clear[0].color));
}
}
}
}
void
panvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf)
{
const struct panvk_subpass *subpass = cmdbuf->state.subpass;
struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
const struct panvk_framebuffer *fb = cmdbuf->state.framebuffer;
const struct panvk_clear_value *clears = cmdbuf->state.clear;
struct panvk_image_view *view;
fbinfo->nr_samples = 1;
fbinfo->rt_count = subpass->color_count;
memset(&fbinfo->bifrost.pre_post.dcds, 0, sizeof(fbinfo->bifrost.pre_post.dcds));
for (unsigned cb = 0; cb < subpass->color_count; cb++) {
int idx = subpass->color_attachments[cb].idx;
view = idx != VK_ATTACHMENT_UNUSED ?
fb->attachments[idx].iview : NULL;
if (!view)
continue;
fbinfo->rts[cb].view = &view->pview;
fbinfo->rts[cb].clear = subpass->color_attachments[cb].clear;
fbinfo->rts[cb].preload = subpass->color_attachments[cb].preload;
fbinfo->rts[cb].crc_valid = &cmdbuf->state.fb.crc_valid[cb];
memcpy(fbinfo->rts[cb].clear_value, clears[idx].color,
sizeof(fbinfo->rts[cb].clear_value));
fbinfo->nr_samples =
MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
}
if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) {
view = fb->attachments[subpass->zs_attachment.idx].iview;
const struct util_format_description *fdesc =
util_format_description(view->pview.format);
fbinfo->nr_samples =
MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
if (util_format_has_depth(fdesc)) {
fbinfo->zs.clear.z = subpass->zs_attachment.clear;
fbinfo->zs.clear_value.depth = clears[subpass->zs_attachment.idx].depth;
fbinfo->zs.view.zs = &view->pview;
}
if (util_format_has_stencil(fdesc)) {
fbinfo->zs.clear.s = subpass->zs_attachment.clear;
fbinfo->zs.clear_value.stencil = clears[subpass->zs_attachment.idx].stencil;
if (!fbinfo->zs.view.zs)
fbinfo->zs.view.s = &view->pview;
}
}
}
void
panvk_cmd_fb_info_init(struct panvk_cmd_buffer *cmdbuf)
{
struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
const struct panvk_framebuffer *fb = cmdbuf->state.framebuffer;
memset(cmdbuf->state.fb.crc_valid, 0, sizeof(cmdbuf->state.fb.crc_valid));
*fbinfo = (struct pan_fb_info) {
.width = fb->width,
.height = fb->height,
.extent.maxx = fb->width - 1,
.extent.maxy = fb->height - 1,
};
}
void
panvk_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo *pRenderPassBegin,
const VkSubpassBeginInfo *pSubpassBeginInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_render_pass, pass, pRenderPassBegin->renderPass);
VK_FROM_HANDLE(panvk_framebuffer, fb, pRenderPassBegin->framebuffer);
cmdbuf->state.pass = pass;
cmdbuf->state.subpass = pass->subpasses;
cmdbuf->state.framebuffer = fb;
cmdbuf->state.render_area = pRenderPassBegin->renderArea;
cmdbuf->state.batch = vk_zalloc(&cmdbuf->pool->vk.alloc,
sizeof(*cmdbuf->state.batch), 8,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
util_dynarray_init(&cmdbuf->state.batch->jobs, NULL);
util_dynarray_init(&cmdbuf->state.batch->event_ops, NULL);
assert(pRenderPassBegin->clearValueCount <= pass->attachment_count);
cmdbuf->state.clear =
vk_zalloc(&cmdbuf->pool->vk.alloc,
sizeof(*cmdbuf->state.clear) * pass->attachment_count,
8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
panvk_cmd_prepare_clear_values(cmdbuf, pRenderPassBegin->pClearValues);
panvk_cmd_fb_info_init(cmdbuf);
panvk_cmd_fb_info_set_subpass(cmdbuf);
}
void
panvk_CmdBeginRenderPass(VkCommandBuffer cmd,
const VkRenderPassBeginInfo *info,
VkSubpassContents contents)
{
VkSubpassBeginInfo subpass_info = {
.sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
.contents = contents
};
return panvk_CmdBeginRenderPass2(cmd, info, &subpass_info);
}
void
panvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf)
{
for (unsigned i = 0; i < cmdbuf->state.fb.info.rt_count; i++) {
if (cmdbuf->state.fb.info.rts[i].view) {
cmdbuf->state.fb.info.rts[i].clear = false;
cmdbuf->state.fb.info.rts[i].preload = true;
}
}
if (cmdbuf->state.fb.info.zs.view.zs) {
cmdbuf->state.fb.info.zs.clear.z = false;
cmdbuf->state.fb.info.zs.preload.z = true;
}
if (cmdbuf->state.fb.info.zs.view.s ||
(cmdbuf->state.fb.info.zs.view.zs &&
util_format_is_depth_and_stencil(cmdbuf->state.fb.info.zs.view.zs->format))) {
cmdbuf->state.fb.info.zs.clear.s = false;
cmdbuf->state.fb.info.zs.preload.s = true;
}
}
struct panvk_batch *
panvk_cmd_open_batch(struct panvk_cmd_buffer *cmdbuf)
{
assert(!cmdbuf->state.batch);
cmdbuf->state.batch = vk_zalloc(&cmdbuf->pool->vk.alloc,
sizeof(*cmdbuf->state.batch), 8,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
assert(cmdbuf->state.batch);
return cmdbuf->state.batch;
}
void
panvk_CmdDrawIndirect(VkCommandBuffer commandBuffer,
VkBuffer _buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
panvk_stub();
}
void
panvk_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
VkBuffer _buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
panvk_stub();
}
void
panvk_CmdDispatchBase(VkCommandBuffer commandBuffer,
uint32_t base_x,
uint32_t base_y,
uint32_t base_z,
uint32_t x,
uint32_t y,
uint32_t z)
{
panvk_stub();
}
void
panvk_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
VkBuffer _buffer,
VkDeviceSize offset)
{
panvk_stub();
}
void
panvk_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
{
panvk_stub();
}