Commit baf7ad35 by Chris Forbes

Implement indexed draws

Adds support for vkBindIndexBuffer and vkDrawIndexed. There is significant duplication currently between Draw::play and DrawIndexed::play, but most of it is going to evaporate when we solve the context stomping problems. Bug: b/118619338 Change-Id: If8e9f7b1f11a3c763e73663733697fddd3e1fcac Reviewed-on: https://swiftshader-review.googlesource.com/c/25508Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 5edafb5a
...@@ -197,7 +197,7 @@ namespace sw ...@@ -197,7 +197,7 @@ namespace sw
vk::ImageView *texture[TOTAL_IMAGE_UNITS]; vk::ImageView *texture[TOTAL_IMAGE_UNITS];
Stream input[MAX_VERTEX_INPUTS]; Stream input[MAX_VERTEX_INPUTS];
uint8_t *indexBuffer; void *indexBuffer;
vk::ImageView *renderTarget[RENDERTARGETS]; vk::ImageView *renderTarget[RENDERTARGETS];
unsigned int renderTargetLayer[RENDERTARGETS]; unsigned int renderTargetLayer[RENDERTARGETS];
......
...@@ -77,11 +77,6 @@ namespace sw ...@@ -77,11 +77,6 @@ namespace sw
context->renderTargetLayer[index] = layer; context->renderTargetLayer[index] = layer;
} }
vk::ImageView* PixelProcessor::getRenderTarget(int index)
{
return context->renderTarget[index];
}
void PixelProcessor::setDepthBuffer(vk::ImageView *depthBuffer, unsigned int layer) void PixelProcessor::setDepthBuffer(vk::ImageView *depthBuffer, unsigned int layer)
{ {
context->depthBuffer = depthBuffer; context->depthBuffer = depthBuffer;
......
...@@ -146,7 +146,6 @@ namespace sw ...@@ -146,7 +146,6 @@ namespace sw
virtual ~PixelProcessor(); virtual ~PixelProcessor();
void setRenderTarget(int index, vk::ImageView *renderTarget, unsigned int layer = 0); void setRenderTarget(int index, vk::ImageView *renderTarget, unsigned int layer = 0);
vk::ImageView *getRenderTarget(int index);
void setDepthBuffer(vk::ImageView *depthBuffer, unsigned int layer = 0); void setDepthBuffer(vk::ImageView *depthBuffer, unsigned int layer = 0);
void setStencilBuffer(vk::ImageView *stencilBuffer, unsigned int layer = 0); void setStencilBuffer(vk::ImageView *stencilBuffer, unsigned int layer = 0);
......
...@@ -211,7 +211,7 @@ namespace sw ...@@ -211,7 +211,7 @@ namespace sw
sw::deallocate(mem); sw::deallocate(mem);
} }
void Renderer::draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update) void Renderer::draw(DrawType drawType, unsigned int count, bool update)
{ {
#ifndef NDEBUG #ifndef NDEBUG
if(count < minPrimitives || count > maxPrimitives) if(count < minPrimitives || count > maxPrimitives)
...@@ -315,23 +315,15 @@ namespace sw ...@@ -315,23 +315,15 @@ namespace sw
for(int i = 0; i < MAX_VERTEX_INPUTS; i++) for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
{ {
draw->vertexStream[i] = context->input[i].resource;
data->input[i] = context->input[i].buffer; data->input[i] = context->input[i].buffer;
data->stride[i] = context->input[i].stride; data->stride[i] = context->input[i].stride;
if(draw->vertexStream[i])
{
draw->vertexStream[i]->lock(PUBLIC, PRIVATE);
}
} }
if(context->indexBuffer) if(context->indexBuffer)
{ {
data->indices = &context->indexBuffer[indexOffset]; data->indices = context->indexBuffer;
} }
draw->indexBuffer = context->indexBuffer;
for(int sampler = 0; sampler < TOTAL_IMAGE_UNITS; sampler++) for(int sampler = 0; sampler < TOTAL_IMAGE_UNITS; sampler++)
{ {
draw->texture[sampler] = 0; draw->texture[sampler] = 0;
...@@ -834,14 +826,6 @@ namespace sw ...@@ -834,14 +826,6 @@ namespace sw
draw.queries = 0; draw.queries = 0;
} }
for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
{
if(draw.vertexStream[i])
{
draw.vertexStream[i]->unlock();
}
}
draw.vertexRoutine->unbind(); draw.vertexRoutine->unbind();
draw.setupRoutine->unbind(); draw.setupRoutine->unbind();
draw.pixelRoutine->unbind(); draw.pixelRoutine->unbind();
...@@ -1575,11 +1559,6 @@ namespace sw ...@@ -1575,11 +1559,6 @@ namespace sw
} }
} }
void Renderer::setIndexBuffer(uint8_t *indexBuffer)
{
context->indexBuffer = indexBuffer;
}
void Renderer::setMultiSampleMask(unsigned int mask) void Renderer::setMultiSampleMask(unsigned int mask)
{ {
context->sampleMask = mask; context->sampleMask = mask;
......
...@@ -247,14 +247,13 @@ namespace sw ...@@ -247,14 +247,13 @@ namespace sw
void *operator new(size_t size); void *operator new(size_t size);
void operator delete(void * mem); void operator delete(void * mem);
void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true); void draw(DrawType drawType, unsigned int count, bool update = true);
void clear(void *value, VkFormat format, Surface *dest, const Rect &rect, unsigned int rgbaMask); void clear(void *value, VkFormat format, Surface *dest, const Rect &rect, unsigned int rgbaMask);
void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false, bool sRGBconversion = true); void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false, bool sRGBconversion = true);
void blit3D(Surface *source, Surface *dest); void blit3D(Surface *source, Surface *dest);
void setContext(const sw::Context& context); void setContext(const sw::Context& context);
void setIndexBuffer(uint8_t *indexBuffer);
void setMultiSampleMask(unsigned int mask); void setMultiSampleMask(unsigned int mask);
void setTransparencyAntialiasing(TransparencyAntialiasing transparencyAntialiasing); void setTransparencyAntialiasing(TransparencyAntialiasing transparencyAntialiasing);
...@@ -423,8 +422,6 @@ namespace sw ...@@ -423,8 +422,6 @@ namespace sw
int (Renderer::*setupPrimitives)(int batch, int count); int (Renderer::*setupPrimitives)(int batch, int count);
SetupProcessor::State setupState; SetupProcessor::State setupState;
Resource *vertexStream[MAX_VERTEX_INPUTS];
uint8_t *indexBuffer;
vk::ImageView *renderTarget[RENDERTARGETS]; vk::ImageView *renderTarget[RENDERTARGETS];
vk::ImageView *depthBuffer; vk::ImageView *depthBuffer;
vk::ImageView *stencilBuffer; vk::ImageView *stencilBuffer;
......
...@@ -140,6 +140,25 @@ struct VertexBufferBind : public CommandBuffer::Command ...@@ -140,6 +140,25 @@ struct VertexBufferBind : public CommandBuffer::Command
const VkDeviceSize offset; const VkDeviceSize offset;
}; };
struct IndexBufferBind : public CommandBuffer::Command
{
IndexBufferBind(const VkBuffer buffer, const VkDeviceSize offset, const VkIndexType indexType) :
buffer(buffer), offset(offset), indexType(indexType)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
executionState.indexBufferBinding = {buffer, offset};
executionState.indexType = indexType;
}
const VkBuffer buffer;
const VkDeviceSize offset;
const VkIndexType indexType;
};
struct Draw : public CommandBuffer::Command struct Draw : public CommandBuffer::Command
{ {
Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
...@@ -185,7 +204,7 @@ struct Draw : public CommandBuffer::Command ...@@ -185,7 +204,7 @@ struct Draw : public CommandBuffer::Command
for(uint32_t instance = firstInstance; instance <= lastInstance; instance++) for(uint32_t instance = firstInstance; instance <= lastInstance; instance++)
{ {
executionState.renderer->setInstanceID(instance); executionState.renderer->setInstanceID(instance);
executionState.renderer->draw(context.drawType, 0, primitiveCount); executionState.renderer->draw(context.drawType, primitiveCount);
} }
} }
...@@ -195,6 +214,68 @@ struct Draw : public CommandBuffer::Command ...@@ -195,6 +214,68 @@ struct Draw : public CommandBuffer::Command
uint32_t firstInstance; uint32_t firstInstance;
}; };
struct DrawIndexed : public CommandBuffer::Command
{
DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
: indexCount(indexCount), instanceCount(instanceCount), firstIndex(firstIndex), vertexOffset(vertexOffset), firstInstance(firstInstance)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>(
executionState.pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS]);
sw::Context context = pipeline->getContext();
for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
{
auto &attrib = context.input[i];
if (attrib.count)
{
const auto &vertexInput = executionState.vertexInputBindings[attrib.binding];
Buffer *buffer = Cast(vertexInput.buffer);
attrib.buffer = buffer ? buffer->getOffsetPointer(
attrib.offset + vertexInput.offset + attrib.stride * vertexOffset) : nullptr;
}
}
context.indexBuffer = Cast(executionState.indexBufferBinding.buffer)->getOffsetPointer(
executionState.indexBufferBinding.offset + firstIndex * (executionState.indexType == VK_INDEX_TYPE_UINT16 ? 2 : 4));
executionState.renderer->setContext(context);
executionState.renderer->setScissor(pipeline->getScissor());
executionState.renderer->setViewport(pipeline->getViewport());
executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
for (auto i = 0u; i < executionState.renderPass->getCurrentSubpass().colorAttachmentCount; i++)
{
auto attachmentReference = executionState.renderPass->getCurrentSubpass().pColorAttachments[i];
if (attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
{
auto attachment = executionState.renderPassFramebuffer->getAttachment(attachmentReference.attachment);
executionState.renderer->setRenderTarget(i, attachment, 0);
}
}
auto drawType = executionState.indexType == VK_INDEX_TYPE_UINT16
? (context.drawType | sw::DRAW_INDEXED16) : (context.drawType | sw::DRAW_INDEXED32);
const uint32_t primitiveCount = pipeline->computePrimitiveCount(indexCount);
const uint32_t lastInstance = firstInstance + instanceCount - 1;
for(uint32_t instance = firstInstance; instance <= lastInstance; instance++)
{
executionState.renderer->setInstanceID(instance);
executionState.renderer->draw(static_cast<sw::DrawType>(drawType), primitiveCount);
}
}
uint32_t indexCount;
uint32_t instanceCount;
uint32_t firstIndex;
int32_t vertexOffset;
uint32_t firstInstance;
};
struct ImageToImageCopy : public CommandBuffer::Command struct ImageToImageCopy : public CommandBuffer::Command
{ {
ImageToImageCopy(VkImage pSrcImage, VkImage pDstImage, const VkImageCopy& pRegion) : ImageToImageCopy(VkImage pSrcImage, VkImage pDstImage, const VkImageCopy& pRegion) :
...@@ -715,7 +796,7 @@ void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, Vk ...@@ -715,7 +796,7 @@ void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, Vk
void CommandBuffer::bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) void CommandBuffer::bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
{ {
UNIMPLEMENTED(); addCommand<IndexBufferBind>(buffer, offset, indexType);
} }
void CommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) void CommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
...@@ -876,7 +957,7 @@ void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t ...@@ -876,7 +957,7 @@ void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t
void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
{ {
UNIMPLEMENTED(); addCommand<DrawIndexed>(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
} }
void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride) void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
......
...@@ -133,6 +133,8 @@ public: ...@@ -133,6 +133,8 @@ public:
VkDeviceSize offset; VkDeviceSize offset;
}; };
VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {}; VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
VertexInputBinding indexBufferBinding;
VkIndexType indexType;
}; };
void submit(CommandBuffer::ExecutionState& executionState); void submit(CommandBuffer::ExecutionState& executionState);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment