1
0
mirror of https://github.com/Yours3lf/rpi-vk-driver.git synced 2024-12-14 02:23:55 +01:00
rpi-vk-driver/driver/draw.c

537 lines
19 KiB
C
Raw Normal View History

2018-10-15 23:37:09 +02:00
#include "common.h"
#include "kernel/vc4_packet.h"
2019-09-23 21:27:07 +02:00
//returns max index
static uint32_t drawCommon(VkCommandBuffer commandBuffer)
2018-10-15 23:37:09 +02:00
{
assert(commandBuffer);
_commandBuffer* cb = commandBuffer;
2019-08-25 22:59:18 +02:00
//TODO handle cases when submitting >65k vertices in a VBO
//TODO HW-2116 workaround
//TODO GFXH-515 / SW-5891 workaround
2019-09-08 00:30:52 +02:00
//TODO make this as lightweight as possible to make sure
//as many drawcalls can be submitted as possible
2018-10-15 23:37:09 +02:00
//uint32_t vertexBufferDirty;
//uint32_t indexBufferDirty;
///uint32_t viewportDirty;
///uint32_t lineWidthDirty;
///uint32_t depthBiasDirty;
///uint32_t depthBoundsDirty;
//uint32_t graphicsPipelineDirty;
//uint32_t computePipelineDirty;
//uint32_t subpassDirty;
//uint32_t blendConstantsDirty;
//uint32_t scissorDirty;
//uint32_t stencilCompareMaskDirty;
//uint32_t stencilWriteMaskDirty;
//uint32_t stencilReferenceDirty;
//uint32_t descriptorSetDirty;
//uint32_t pushConstantDirty;
2019-09-20 11:30:03 +02:00
//TODO multiple viewports
VkViewport vp;
vp = cb->graphicsPipeline->viewports[0];
for(uint32_t c = 0; c < cb->graphicsPipeline->dynamicStateCount; ++c)
{
if(cb->graphicsPipeline->dynamicStates[c] == VK_DYNAMIC_STATE_VIEWPORT)
{
vp = cb->viewport;
}
}
//if(cb->lineWidthDirty)
{
//Line width
clFit(commandBuffer, &commandBuffer->binCl, V3D21_LINE_WIDTH_length);
clInsertLineWidth(&commandBuffer->binCl, cb->graphicsPipeline->lineWidth);
2018-10-15 23:37:09 +02:00
cb->lineWidthDirty = 0;
}
2018-10-15 23:37:09 +02:00
//if(cb->viewportDirty)
{
//Clip Window
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIP_WINDOW_length);
clInsertClipWindow(&commandBuffer->binCl,
2019-09-20 11:30:03 +02:00
vp.width,
vp.height,
vp.y, //bottom pixel coord
vp.x); //left pixel coord
//TODO why flipped???
//Clipper XY Scaling
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIPPER_XY_SCALING_length);
2019-09-20 11:30:03 +02:00
clInsertClipperXYScaling(&commandBuffer->binCl, (float)(vp.width) * 0.5f * 16.0f, -1.0f * (float)(vp.height) * 0.5f * 16.0f);
//Viewport Offset
clFit(commandBuffer, &commandBuffer->binCl, V3D21_VIEWPORT_OFFSET_length);
clInsertViewPortOffset(&commandBuffer->binCl, vp.width * 0.5f, vp.height * 0.5f);
cb->viewportDirty = 0;
}
//if(cb->depthBiasDirty || cb->depthBoundsDirty)
{
//Configuration Bits
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CONFIGURATION_BITS_length);
clInsertConfigurationBits(&commandBuffer->binCl,
2020-04-20 14:45:17 +02:00
1, //earlyz updates enable
2019-09-23 20:40:36 +02:00
cb->graphicsPipeline->depthTestEnable, //earlyz enable
2020-04-20 14:45:17 +02:00
cb->graphicsPipeline->depthWriteEnable && cb->graphicsPipeline->depthTestEnable, //z updates enable
2019-09-23 18:51:31 +02:00
cb->graphicsPipeline->depthTestEnable ? getCompareOp(cb->graphicsPipeline->depthCompareOp) : V3D_COMPARE_FUNC_ALWAYS, //depth compare func
0, //coverage read mode
0, //coverage pipe select
0, //coverage update mode
0, //coverage read type
2020-02-16 19:14:45 +01:00
cb->graphicsPipeline->rasterizationSamples > 1, //rasterizer oversample mode
cb->graphicsPipeline->depthBiasEnable, //depth offset enable
cb->graphicsPipeline->frontFace == VK_FRONT_FACE_CLOCKWISE, //clockwise
!(cb->graphicsPipeline->cullMode & VK_CULL_MODE_BACK_BIT), //enable back facing primitives
!(cb->graphicsPipeline->cullMode & VK_CULL_MODE_FRONT_BIT)); //enable front facing primitives
//TODO Depth Offset
clFit(commandBuffer, &commandBuffer->binCl, V3D21_DEPTH_OFFSET_length);
clInsertDepthOffset(&commandBuffer->binCl, cb->graphicsPipeline->depthBiasConstantFactor, cb->graphicsPipeline->depthBiasSlopeFactor);
//TODO how is this calculated?
//it's Zc to Zs scale and bias
//seems to go from -1.0 .. 1.0 to 0.0 .. 1.0
//eg. x * 0.5 + 0.5
//cb->graphicsPipeline->minDepthBounds;
//Clipper Z Scale and Offset
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIPPER_Z_SCALE_AND_OFFSET_length);
clInsertClipperZScaleOffset(&commandBuffer->binCl, 0.5f, 0.5f);
cb->vertexBufferDirty = 0;
cb->depthBoundsDirty = 0;
}
2018-10-15 23:37:09 +02:00
//Point size
clFit(commandBuffer, &commandBuffer->binCl, V3D21_POINT_SIZE_length);
clInsertPointSize(&commandBuffer->binCl, 1.0f);
//TODO?
//Flat Shade Flags
clFit(commandBuffer, &commandBuffer->binCl, V3D21_FLAT_SHADE_FLAGS_length);
clInsertFlatShadeFlags(&commandBuffer->binCl, 0);
//GL Shader State
clFit(commandBuffer, &commandBuffer->binCl, V3D21_GL_SHADER_STATE_length);
clInsertShaderState(&commandBuffer->binCl,
0, //shader state record address
0, //extended shader state record
2019-09-22 17:40:06 +02:00
cb->graphicsPipeline->vertexAttributeDescriptionCount & 0x7); //number of attribute arrays, 0 -> 8
2018-10-15 23:37:09 +02:00
_shaderModule* vertModule = 0, *fragModule = 0;
//it could be that all stages are contained in a single module, or have separate modules
if(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_FRAGMENT_BIT)])
{
fragModule = cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_FRAGMENT_BIT)];
}
if(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)])
{
2020-04-21 22:38:21 +02:00
vertModule = cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)];
}
if(!vertModule)
{
vertModule = fragModule;
}
if(!fragModule)
{
fragModule = vertModule;
}
2018-10-15 23:37:09 +02:00
//emit shader record
ControlListAddress fragCode = {
.handle = fragModule->bos[VK_RPI_ASSEMBLY_TYPE_FRAGMENT],
2018-10-15 23:37:09 +02:00
.offset = 0,
};
ControlListAddress vertCode = {
.handle = vertModule->bos[VK_RPI_ASSEMBLY_TYPE_VERTEX],
2018-10-15 23:37:09 +02:00
.offset = 0,
};
ControlListAddress coordCode = {
.handle = vertModule->bos[VK_RPI_ASSEMBLY_TYPE_COORDINATE],
2018-10-15 23:37:09 +02:00
.offset = 0,
};
//TODO
commandBuffer->shaderRecCount++;
clFit(commandBuffer, &commandBuffer->shaderRecCl, V3D21_SHADER_RECORD_length);
ControlList relocCl = commandBuffer->shaderRecCl;
2019-09-22 17:40:06 +02:00
uint32_t attribCount = 0;
uint32_t attribSelectBits = 0;
for(uint32_t c = 0 ; c < cb->graphicsPipeline->vertexAttributeDescriptionCount; ++c)
{
if(cb->vertexBuffers[cb->graphicsPipeline->vertexAttributeDescriptions[c].binding])
{
2019-09-22 17:40:06 +02:00
attribCount++;
attribSelectBits |= 1 << cb->graphicsPipeline->vertexAttributeDescriptions[c].location;
}
}
uint32_t attribSize = 0;
for(uint32_t c = 0; c < cb->graphicsPipeline->vertexAttributeDescriptionCount; ++c)
{
attribSize += getFormatByteSize(cb->graphicsPipeline->vertexAttributeDescriptions[c].format);
}
2019-09-23 20:40:36 +02:00
//number of attribs
2018-10-15 23:37:09 +02:00
//3 is the number of type of possible shaders
2019-09-22 17:40:06 +02:00
for(int c = 0; c < (3 + attribCount)*4; ++c)
2018-10-15 23:37:09 +02:00
{
clInsertNop(&commandBuffer->shaderRecCl);
}
clInsertShaderRecord(&commandBuffer->shaderRecCl,
&relocCl,
&commandBuffer->handlesCl,
cb->binCl.currMarker->handlesBuf,
cb->binCl.currMarker->handlesSize,
!fragModule->hasThreadSwitch,
2019-08-25 22:59:18 +02:00
0, //TODO point size included in shaded vertex data?
2019-09-08 00:30:52 +02:00
1, //enable clipping
0, //TODO fragment number of used uniforms?
fragModule->numVaryings, //fragment number of varyings
2018-10-15 23:37:09 +02:00
0, //fragment uniform address?
fragCode, //fragment code address
0, //TODO vertex number of used uniforms?
2019-09-22 17:40:06 +02:00
attribSelectBits, //vertex attribute array select bits
attribSize, //vertex total attribute size
2018-10-15 23:37:09 +02:00
0, //vertex uniform address
vertCode, //vertex shader code address
0, //TODO coordinate number of used uniforms?
2019-09-22 17:40:06 +02:00
//TODO how do we know which attribute contains the vertices?
//for now the first one will be hardcoded to have the vertices...
1 << 0, //coordinate attribute array select bits
getFormatByteSize(cb->graphicsPipeline->vertexAttributeDescriptions[0].format), //coordinate total attribute size
2018-10-15 23:37:09 +02:00
0, //coordinate uniform address
coordCode //coordinate shader code address
);
2019-09-23 21:27:07 +02:00
uint32_t maxIndex = 0xffff;
for(uint32_t c = 0 ; c < cb->graphicsPipeline->vertexAttributeDescriptionCount; ++c)
{
if(cb->vertexBuffers[cb->graphicsPipeline->vertexAttributeDescriptions[c].binding])
{
2019-09-23 21:27:07 +02:00
uint32_t formatByteSize = getFormatByteSize(cb->graphicsPipeline->vertexAttributeDescriptions[c].format);
//TODO the indexing here is incorrect....
uint32_t stride = cb->graphicsPipeline->vertexBindingDescriptions[cb->graphicsPipeline->vertexAttributeDescriptions[c].binding].stride;
if(stride > 0)
{
//TODO offset
uint32_t usedIndices = (cb->vertexBuffers[cb->graphicsPipeline->vertexAttributeDescriptions[c].binding]->boundMem->size - formatByteSize) / stride;
if(usedIndices < maxIndex)
{
maxIndex = usedIndices;
}
}
ControlListAddress vertexBuffer = {
.handle = cb->vertexBuffers[cb->graphicsPipeline->vertexAttributeDescriptions[c].binding]->boundMem->bo,
.offset = cb->graphicsPipeline->vertexAttributeDescriptions[c].offset,
};
clFit(commandBuffer, &commandBuffer->shaderRecCl, V3D21_ATTRIBUTE_RECORD_length);
clInsertAttributeRecord(&commandBuffer->shaderRecCl,
&relocCl,
&commandBuffer->handlesCl,
cb->binCl.currMarker->handlesBuf,
cb->binCl.currMarker->handlesSize,
vertexBuffer, //reloc address
2019-09-23 21:27:07 +02:00
formatByteSize,
stride,
2019-09-22 17:40:06 +02:00
cb->graphicsPipeline->vertexAttributeDescriptions[c].offset, //vertex vpm offset
cb->graphicsPipeline->vertexAttributeDescriptions[c].offset //coordinte vpm offset
);
}
}
2018-10-15 23:37:09 +02:00
//write uniforms
_pipelineLayout* pl = cb->graphicsPipeline->layout;
//kernel side expects relocations first!
for(uint32_t c = 0; c < fragModule->numMappings[VK_RPI_ASSEMBLY_TYPE_FRAGMENT]; ++c)
{
VkRpiAssemblyMappingEXT mapping = fragModule->mappings[VK_RPI_ASSEMBLY_TYPE_FRAGMENT][c];
if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_DESCRIPTOR)
{
if(mapping.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
mapping.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
mapping.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
{
_descriptorSet* ds = getMapElement(pl->descriptorSetBindingMap, mapping.descriptorSet);
_descriptorImage* di = getMapElement(ds->imageBindingMap, mapping.descriptorBinding);
di += mapping.descriptorArrayElement;
//emit reloc for texture BO
clFit(commandBuffer, &commandBuffer->handlesCl, 4);
uint32_t idx = clGetHandleIndex(&commandBuffer->handlesCl, cb->binCl.currMarker->handlesBuf, cb->binCl.currMarker->handlesSize, di->imageView->image->boundMem->bo);
//emit tex bo reloc index
clFit(commandBuffer, &commandBuffer->uniformsCl, 4);
clInsertData(&commandBuffer->uniformsCl, 4, &idx);
}
else if(mapping.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
mapping.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
mapping.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
mapping.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
{
_descriptorSet* ds = getMapElement(pl->descriptorSetBindingMap, mapping.descriptorSet);
_descriptorBuffer* db = getMapElement(ds->bufferBindingMap, mapping.descriptorBinding);
db += mapping.descriptorArrayElement;
//emit reloc for BO
clFit(commandBuffer, &commandBuffer->handlesCl, 4);
uint32_t idx = clGetHandleIndex(&commandBuffer->handlesCl, cb->binCl.currMarker->handlesBuf, cb->binCl.currMarker->handlesSize, db->buffer->boundMem->bo);
//emit bo reloc index
clFit(commandBuffer, &commandBuffer->uniformsCl, 4);
clInsertData(&commandBuffer->uniformsCl, 4, &idx);
}
else if(mapping.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
mapping.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
{
_descriptorSet* ds = getMapElement(pl->descriptorSetBindingMap, mapping.descriptorSet);
_descriptorTexelBuffer* dtb = getMapElement(ds->texelBufferBindingMap, mapping.descriptorBinding);
dtb += mapping.descriptorArrayElement;
//emit reloc for BO
clFit(commandBuffer, &commandBuffer->handlesCl, 4);
uint32_t idx = clGetHandleIndex(&commandBuffer->handlesCl, cb->binCl.currMarker->handlesBuf, cb->binCl.currMarker->handlesSize, dtb->bufferView->buffer->boundMem->bo);
//emit bo reloc index
clFit(commandBuffer, &commandBuffer->uniformsCl, 4);
clInsertData(&commandBuffer->uniformsCl, 4, &idx);
}
else
{
assert(0); //shouldn't happen
}
}
}
//after relocs we can proceed with the usual uniforms
for(uint32_t c = 0; c < fragModule->numMappings[VK_RPI_ASSEMBLY_TYPE_FRAGMENT]; ++c)
{
VkRpiAssemblyMappingEXT mapping = fragModule->mappings[VK_RPI_ASSEMBLY_TYPE_FRAGMENT][c];
if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT)
{
clFit(commandBuffer, &commandBuffer->uniformsCl, 4);
clInsertData(&commandBuffer->uniformsCl, 4, cb->pushConstantBufferPixel + mapping.resourceOffset);
}
else if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_DESCRIPTOR)
{
if(mapping.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
mapping.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
mapping.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
{
_descriptorSet* ds = getMapElement(pl->descriptorSetBindingMap, mapping.descriptorSet);
_descriptorImage* di = getMapElement(ds->imageBindingMap, mapping.descriptorBinding);
di += mapping.descriptorArrayElement;
uint32_t cubemapStride = (di->imageView->image->width * di->imageView->image->height * getFormatBpp(di->imageView->interpretedFormat)) >> 3;
2020-04-26 21:21:18 +02:00
//fprintf(stderr, "cubemap stride %i\n", cubemapStride);
uint32_t numLevels = 0;
numLevels = di->imageView->subresourceRange.levelCount < di->imageView->image->miplevels ? di->imageView->subresourceRange.levelCount : di->imageView->image->miplevels;
uint32_t params[4];
encodeTextureUniform(params,
2020-04-26 21:21:18 +02:00
numLevels - 1,
getTextureDataType(di->imageView->interpretedFormat),
di->imageView->viewType == VK_IMAGE_VIEW_TYPE_CUBE,
2020-04-26 21:21:18 +02:00
cubemapStride >> 12, //cubemap stride in multiples of 4KB
di->imageView->image->levelOffsets[0] >> 12, //Image level 0 offset in multiples of 4KB
di->imageView->image->height & 2047,
di->imageView->image->width & 2047,
getMinFilterType(di->sampler->minFilter, di->sampler->mipmapMode),// di->sampler->maxLod),
di->sampler->magFilter == VK_FILTER_NEAREST,
getWrapMode(di->sampler->addressModeU),
getWrapMode(di->sampler->addressModeV),
di->sampler->disableAutoLod
);
uint32_t size = 0;
if(di->imageView->viewType == VK_IMAGE_VIEW_TYPE_1D)
{
size = 4;
}
else if(di->imageView->viewType == VK_IMAGE_VIEW_TYPE_2D)
{
size = 8;
}
else if(di->imageView->viewType == VK_IMAGE_VIEW_TYPE_CUBE)
{
size = 12;
}
else
{
assert(0); //unsupported
}
//TMU0_B requires an extra uniform written
//we need to signal that somehow from API side
//if mode is cubemap we don't need an extra uniform, it's included!
if(di->imageView->viewType != VK_IMAGE_VIEW_TYPE_CUBE && di->sampler->disableAutoLod)
{
size += 4;
}
//emit tex parameters
clFit(commandBuffer, &commandBuffer->uniformsCl, size);
clInsertData(&commandBuffer->uniformsCl, size, params);
}
}
}
2019-09-23 21:27:07 +02:00
//vertex and then coordinate
for(uint32_t c = 0; c < vertModule->numMappings[VK_RPI_ASSEMBLY_TYPE_VERTEX]; ++c)
{
VkRpiAssemblyMappingEXT mapping = vertModule->mappings[VK_RPI_ASSEMBLY_TYPE_VERTEX][c];
if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT)
{
clFit(commandBuffer, &commandBuffer->uniformsCl, 4);
clInsertData(&commandBuffer->uniformsCl, 4, cb->pushConstantBufferVertex + mapping.resourceOffset);
}
else if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_DESCRIPTOR)
{
}
else
{
assert(0); //shouldn't happen
}
}
//if there are no coordinate mappings, just use the vertex ones
VkRpiAssemblyTypeEXT coordMappingType = VK_RPI_ASSEMBLY_TYPE_COORDINATE;
if(vertModule->numMappings[VK_RPI_ASSEMBLY_TYPE_COORDINATE] < 1)
{
coordMappingType = VK_RPI_ASSEMBLY_TYPE_VERTEX;
}
for(uint32_t c = 0; c < vertModule->numMappings[coordMappingType]; ++c)
{
VkRpiAssemblyMappingEXT mapping = vertModule->mappings[coordMappingType][c];
if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT)
{
clFit(commandBuffer, &commandBuffer->uniformsCl, 4);
clInsertData(&commandBuffer->uniformsCl, 4, cb->pushConstantBufferVertex + mapping.resourceOffset);
}
else if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_DESCRIPTOR)
{
}
else
{
assert(0); //shouldn't happen
}
}
2019-09-23 21:27:07 +02:00
return maxIndex;
2019-09-23 20:40:36 +02:00
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCmdDraw
*/
2019-09-30 00:52:21 +02:00
void rpi_vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
2019-09-23 20:40:36 +02:00
{
assert(commandBuffer);
2019-09-23 21:27:07 +02:00
if(instanceCount != 1 || firstInstance != 0)
{
unsigned instancing;
UNSUPPORTED(instancing);
}
2019-09-23 20:40:36 +02:00
drawCommon(commandBuffer);
_commandBuffer* cb = commandBuffer;
//Submit draw call: vertex Array Primitives
clFit(commandBuffer, &commandBuffer->binCl, V3D21_VERTEX_ARRAY_PRIMITIVES_length);
clInsertVertexArrayPrimitives(&commandBuffer->binCl, firstVertex, vertexCount, getPrimitiveMode(cb->graphicsPipeline->topology));
cb->numDrawCallsSubmitted++;
2018-10-15 23:37:09 +02:00
}
2019-04-22 15:58:27 +02:00
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkCmdDrawIndexed(
VkCommandBuffer commandBuffer,
uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
uint32_t firstInstance)
{
2019-09-23 20:40:36 +02:00
assert(commandBuffer);
2019-09-23 21:27:07 +02:00
if(instanceCount != 1 || firstInstance != 0)
{
unsigned instancing;
UNSUPPORTED(instancing);
}
uint32_t maxIndex = drawCommon(commandBuffer);
2019-09-23 20:40:36 +02:00
_commandBuffer* cb = commandBuffer;
clFit(commandBuffer, &commandBuffer->handlesCl, 4);
2019-09-23 21:27:07 +02:00
uint32_t idx = clGetHandleIndex(&commandBuffer->handlesCl, cb->binCl.currMarker->handlesBuf, cb->binCl.currMarker->handlesSize, cb->indexBuffer->boundMem->bo);
2019-09-23 20:40:36 +02:00
2019-09-23 21:27:07 +02:00
clInsertGEMRelocations(&commandBuffer->binCl, idx, 0);
2019-09-23 20:40:36 +02:00
//Submit draw call: vertex Array Primitives
clFit(commandBuffer, &commandBuffer->binCl, V3D21_VERTEX_ARRAY_PRIMITIVES_length);
clInsertIndexedPrimitiveList(&commandBuffer->binCl,
2019-09-23 21:27:07 +02:00
maxIndex, //max index
2019-09-23 20:40:36 +02:00
0, //TODO we can pass an offset here
indexCount,
1, //we only support 16 bit indices
getPrimitiveMode(cb->graphicsPipeline->topology));
cb->numDrawCallsSubmitted++;
}
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkCmdDrawIndexedIndirect(
2019-04-22 15:58:27 +02:00
VkCommandBuffer commandBuffer,
VkBuffer buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
2020-04-17 14:04:28 +02:00
UNSUPPORTED(vkCmdDrawIndexedIndirect);
2019-04-22 15:58:27 +02:00
}
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkCmdDrawIndirect(
2019-04-22 15:58:27 +02:00
VkCommandBuffer commandBuffer,
VkBuffer buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
2020-04-17 14:04:28 +02:00
UNSUPPORTED(vkCmdDrawIndirect);
2019-04-22 15:58:27 +02:00
}