Commit 78e39b3f by Luc Ferron Committed by Commit Bot

Vulkan: Line loops for indexed draw calls

Bug: angleproject:2335 Change-Id: Iabd6ae8181c6d3fb487f953a6fbf699db568a1c9 Reviewed-on: https://chromium-review.googlesource.com/941261 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent b27b03a2
...@@ -56,7 +56,7 @@ gl::Error BufferVk::setData(const gl::Context *context, ...@@ -56,7 +56,7 @@ gl::Error BufferVk::setData(const gl::Context *context,
const VkImageUsageFlags usageFlags = const VkImageUsageFlags usageFlags =
(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | (VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_INDEX_BUFFER_BIT); VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
// TODO(jmadill): Proper usage bit implementation. Likely will involve multiple backing // TODO(jmadill): Proper usage bit implementation. Likely will involve multiple backing
// buffers like in D3D11. // buffers like in D3D11.
......
...@@ -161,6 +161,7 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, ...@@ -161,6 +161,7 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
DrawType drawType, DrawType drawType,
int firstVertex, int firstVertex,
int lastVertex, int lastVertex,
ResourceVk *elementArrayBufferOverride,
vk::CommandBuffer **commandBuffer) vk::CommandBuffer **commandBuffer)
{ {
if (mode != mCurrentDrawMode) if (mode != mCurrentDrawMode)
...@@ -199,11 +200,12 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, ...@@ -199,11 +200,12 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
} }
// Ensure any writes to the VAO buffers are flushed before we read from them. // Ensure any writes to the VAO buffers are flushed before we read from them.
if (mVertexArrayDirty) if (mVertexArrayDirty || elementArrayBufferOverride != nullptr)
{ {
mVertexArrayDirty = false; mVertexArrayDirty = false;
vkVAO->updateDrawDependencies(renderNode, programGL->getActiveAttribLocationsMask(), vkVAO->updateDrawDependencies(renderNode, programGL->getActiveAttribLocationsMask(),
queueSerial, drawType); elementArrayBufferOverride, queueSerial, drawType);
} }
// Ensure any writes to the textures are flushed before we read from them. // Ensure any writes to the textures are flushed before we read from them.
...@@ -264,11 +266,14 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, ...@@ -264,11 +266,14 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count) gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
{ {
vk::CommandBuffer *commandBuffer = nullptr; vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(setupDraw(context, mode, DrawType::Arrays, first, first + count - 1, &commandBuffer)); ANGLE_TRY(setupDraw(context, mode, DrawType::Arrays, first, first + count - 1, nullptr,
&commandBuffer));
if (mode == GL_LINE_LOOP) if (mode == GL_LINE_LOOP)
{ {
ANGLE_TRY(mLineLoopHandler.draw(this, first, count, commandBuffer)); ANGLE_TRY(mLineLoopHandler.createIndexBuffer(this, first, count));
mLineLoopHandler.bindIndexBuffer(VK_INDEX_TYPE_UINT32, &commandBuffer);
ANGLE_TRY(mLineLoopHandler.draw(count, commandBuffer));
} }
else else
{ {
...@@ -294,32 +299,49 @@ gl::Error ContextVk::drawElements(const gl::Context *context, ...@@ -294,32 +299,49 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
GLenum type, GLenum type,
const void *indices) const void *indices)
{ {
vk::CommandBuffer *commandBuffer; const gl::Buffer *elementArrayBuffer =
// TODO(fjhenigman): calculate the index range and pass to setupDraw() mState.getState().getVertexArray()->getElementArrayBuffer().get();
ANGLE_TRY(setupDraw(context, mode, DrawType::Elements, 0, 0, &commandBuffer)); ASSERT(elementArrayBuffer);
if (indices) BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
{ vk::CommandBuffer *commandBuffer = nullptr;
// TODO(jmadill): Buffer offsets and immediate data.
UNIMPLEMENTED();
return gl::InternalError() << "Only zero-offset index buffers are currently implemented.";
}
if (type == GL_UNSIGNED_BYTE) if (mode == GL_LINE_LOOP)
{ {
// TODO(jmadill): Index translation. ANGLE_TRY(mLineLoopHandler.createIndexBufferFromElementArrayBuffer(
UNIMPLEMENTED(); this, elementArrayBufferVk, GetVkIndexType(type), count));
return gl::InternalError() << "Unsigned byte translation is not yet implemented.";
// TODO(fjhenigman): calculate the index range and pass to setupDraw()
ANGLE_TRY(setupDraw(context, mode, DrawType::Elements, 0, 0,
mLineLoopHandler.getLineLoopBufferResource(), &commandBuffer));
mLineLoopHandler.bindIndexBuffer(GetVkIndexType(type), &commandBuffer);
commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0);
} }
else
{
// TODO(fjhenigman): calculate the index range and pass to setupDraw()
ANGLE_TRY(setupDraw(context, mode, DrawType::Elements, 0, 0, nullptr, &commandBuffer));
const gl::Buffer *elementArrayBuffer = if (indices)
mState.getState().getVertexArray()->getElementArrayBuffer().get(); {
ASSERT(elementArrayBuffer); // TODO(jmadill): Buffer offsets and immediate data.
UNIMPLEMENTED();
return gl::InternalError()
<< "Only zero-offset index buffers are currently implemented.";
}
BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer); if (type == GL_UNSIGNED_BYTE)
{
// TODO(jmadill): Index translation.
UNIMPLEMENTED();
return gl::InternalError() << "Unsigned byte translation is not yet implemented.";
}
commandBuffer->bindIndexBuffer(elementArrayBufferVk->getVkBuffer(), 0, GetVkIndexType(type)); commandBuffer->bindIndexBuffer(elementArrayBufferVk->getVkBuffer(), 0,
commandBuffer->drawIndexed(count, 1, 0, 0, 0); GetVkIndexType(type));
commandBuffer->drawIndexed(count, 1, 0, 0, 0);
}
return gl::NoError(); return gl::NoError();
} }
......
...@@ -168,6 +168,7 @@ class ContextVk : public ContextImpl ...@@ -168,6 +168,7 @@ class ContextVk : public ContextImpl
DrawType drawType, DrawType drawType,
int firstVertex, int firstVertex,
int lastVertex, int lastVertex,
ResourceVk *elementArrayBufferOverride,
vk::CommandBuffer **commandBuffer); vk::CommandBuffer **commandBuffer);
RendererVk *mRenderer; RendererVk *mRenderer;
......
...@@ -68,6 +68,7 @@ gl::Error StreamingBuffer::allocate(ContextVk *context, ...@@ -68,6 +68,7 @@ gl::Error StreamingBuffer::allocate(ContextVk *context,
createInfo.queueFamilyIndexCount = 0; createInfo.queueFamilyIndexCount = 0;
createInfo.pQueueFamilyIndices = nullptr; createInfo.pQueueFamilyIndices = nullptr;
ANGLE_TRY(mBuffer.init(device, createInfo)); ANGLE_TRY(mBuffer.init(device, createInfo));
ANGLE_TRY(vk::AllocateBufferMemory(renderer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &mBuffer, ANGLE_TRY(vk::AllocateBufferMemory(renderer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &mBuffer,
&mMemory, &mSize)); &mMemory, &mSize));
ANGLE_TRY(mMemory.map(device, 0, mSize, 0, &mMappedMemory)); ANGLE_TRY(mMemory.map(device, 0, mSize, 0, &mMappedMemory));
......
...@@ -165,6 +165,7 @@ const gl::AttribArray<VkDeviceSize> &VertexArrayVk::getCurrentArrayBufferOffsets ...@@ -165,6 +165,7 @@ const gl::AttribArray<VkDeviceSize> &VertexArrayVk::getCurrentArrayBufferOffsets
void VertexArrayVk::updateDrawDependencies(vk::CommandGraphNode *readNode, void VertexArrayVk::updateDrawDependencies(vk::CommandGraphNode *readNode,
const gl::AttributesMask &activeAttribsMask, const gl::AttributesMask &activeAttribsMask,
ResourceVk *elementArrayBufferOverride,
Serial serial, Serial serial,
DrawType drawType) DrawType drawType)
{ {
...@@ -178,8 +179,15 @@ void VertexArrayVk::updateDrawDependencies(vk::CommandGraphNode *readNode, ...@@ -178,8 +179,15 @@ void VertexArrayVk::updateDrawDependencies(vk::CommandGraphNode *readNode,
// Handle the bound element array buffer. // Handle the bound element array buffer.
if (drawType == DrawType::Elements) if (drawType == DrawType::Elements)
{ {
ASSERT(mCurrentElementArrayBufferResource); if (elementArrayBufferOverride != nullptr)
mCurrentElementArrayBufferResource->onReadResource(readNode, serial); {
elementArrayBufferOverride->onReadResource(readNode, serial);
}
else
{
ASSERT(mCurrentElementArrayBufferResource);
mCurrentElementArrayBufferResource->onReadResource(readNode, serial);
}
} }
} }
......
...@@ -38,6 +38,7 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -38,6 +38,7 @@ class VertexArrayVk : public VertexArrayImpl
void updateDrawDependencies(vk::CommandGraphNode *readNode, void updateDrawDependencies(vk::CommandGraphNode *readNode,
const gl::AttributesMask &activeAttribsMask, const gl::AttributesMask &activeAttribsMask,
ResourceVk *elementArrayBufferOverride,
Serial serial, Serial serial,
DrawType drawType); DrawType drawType);
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#include "libANGLE/renderer/vulkan/vk_utils.h" #include "libANGLE/renderer/vulkan/vk_utils.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h" #include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx namespace rx
...@@ -459,6 +459,15 @@ void CommandBuffer::copyBuffer(const vk::Buffer &srcBuffer, ...@@ -459,6 +459,15 @@ void CommandBuffer::copyBuffer(const vk::Buffer &srcBuffer,
vkCmdCopyBuffer(mHandle, srcBuffer.getHandle(), destBuffer.getHandle(), regionCount, regions); vkCmdCopyBuffer(mHandle, srcBuffer.getHandle(), destBuffer.getHandle(), regionCount, regions);
} }
void CommandBuffer::copyBuffer(const VkBuffer &srcBuffer,
const VkBuffer &destBuffer,
uint32_t regionCount,
const VkBufferCopy *regions)
{
ASSERT(valid());
vkCmdCopyBuffer(mHandle, srcBuffer, destBuffer, regionCount, regions);
}
void CommandBuffer::clearSingleColorImage(const vk::Image &image, const VkClearColorValue &color) void CommandBuffer::clearSingleColorImage(const vk::Image &image, const VkClearColorValue &color)
{ {
ASSERT(valid()); ASSERT(valid());
...@@ -1322,7 +1331,8 @@ void GarbageObject::destroy(VkDevice device) ...@@ -1322,7 +1331,8 @@ void GarbageObject::destroy(VkDevice device)
LineLoopHandler::LineLoopHandler() LineLoopHandler::LineLoopHandler()
: mStreamingLineLoopIndicesData( : mStreamingLineLoopIndicesData(
new StreamingBuffer(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kLineLoopStreamingBufferMinSize)), new StreamingBuffer(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
kLineLoopStreamingBufferMinSize)),
mLineLoopIndexBuffer(VK_NULL_HANDLE), mLineLoopIndexBuffer(VK_NULL_HANDLE),
mLineLoopIndexBufferOffset(VK_NULL_HANDLE) mLineLoopIndexBufferOffset(VK_NULL_HANDLE)
{ {
...@@ -1330,10 +1340,12 @@ LineLoopHandler::LineLoopHandler() ...@@ -1330,10 +1340,12 @@ LineLoopHandler::LineLoopHandler()
LineLoopHandler::~LineLoopHandler() = default; LineLoopHandler::~LineLoopHandler() = default;
gl::Error LineLoopHandler::bindLineLoopIndexBuffer(ContextVk *contextVk, void LineLoopHandler::bindIndexBuffer(VkIndexType indexType, vk::CommandBuffer **commandBuffer)
int firstVertex, {
int count, (*commandBuffer)->bindIndexBuffer(mLineLoopIndexBuffer, mLineLoopIndexBufferOffset, indexType);
vk::CommandBuffer **commandBuffer) }
gl::Error LineLoopHandler::createIndexBuffer(ContextVk *contextVk, int firstVertex, int count)
{ {
int lastVertex = firstVertex + count; int lastVertex = firstVertex + count;
if (mLineLoopIndexBuffer == VK_NULL_HANDLE || !mLineLoopBufferFirstIndex.valid() || if (mLineLoopIndexBuffer == VK_NULL_HANDLE || !mLineLoopBufferFirstIndex.valid() ||
...@@ -1363,8 +1375,48 @@ gl::Error LineLoopHandler::bindLineLoopIndexBuffer(ContextVk *contextVk, ...@@ -1363,8 +1375,48 @@ gl::Error LineLoopHandler::bindLineLoopIndexBuffer(ContextVk *contextVk,
mLineLoopBufferLastIndex = lastVertex; mLineLoopBufferLastIndex = lastVertex;
} }
(*commandBuffer) return gl::NoError();
->bindIndexBuffer(mLineLoopIndexBuffer, mLineLoopIndexBufferOffset, VK_INDEX_TYPE_UINT32); }
gl::Error LineLoopHandler::createIndexBufferFromElementArrayBuffer(ContextVk *contextVk,
BufferVk *bufferVk,
VkIndexType indexType,
int count)
{
ASSERT(indexType == VK_INDEX_TYPE_UINT16 || indexType == VK_INDEX_TYPE_UINT32);
if (mLineLoopIndexBuffer != VK_NULL_HANDLE)
{
return gl::NoError();
}
uint32_t *indices = nullptr;
// TODO: Use the signal_utils to know when the user's bufferVk has changed and if it did we copy
// again. Otherwise if we already created that fake index buffer we keep it and avoid recopying
// every time.
auto unitSize = (indexType == VK_INDEX_TYPE_UINT16 ? sizeof(uint16_t) : sizeof(uint32_t));
ANGLE_TRY(mStreamingLineLoopIndicesData->allocate(
contextVk, unitSize * (count + 1), reinterpret_cast<uint8_t **>(&indices),
&mLineLoopIndexBuffer, &mLineLoopIndexBufferOffset));
VkBufferCopy copy1 = {0, mLineLoopIndexBufferOffset,
static_cast<VkDeviceSize>(count) * unitSize};
VkBufferCopy copy2 = {
0, mLineLoopIndexBufferOffset + static_cast<VkDeviceSize>(count) * unitSize, unitSize};
std::array<VkBufferCopy, 2> copies = {{copy1, copy2}};
vk::CommandBuffer *commandBuffer;
mStreamingLineLoopIndicesData->beginWriteResource(contextVk->getRenderer(), &commandBuffer);
Serial currentSerial = contextVk->getRenderer()->getCurrentQueueSerial();
bufferVk->onReadResource(mStreamingLineLoopIndicesData->getCurrentWritingNode(currentSerial),
currentSerial);
commandBuffer->copyBuffer(bufferVk->getVkBuffer().getHandle(), mLineLoopIndexBuffer, 2,
copies.data());
ANGLE_TRY(mStreamingLineLoopIndicesData->flush(contextVk));
return gl::NoError(); return gl::NoError();
} }
...@@ -1373,13 +1425,8 @@ void LineLoopHandler::destroy(VkDevice device) ...@@ -1373,13 +1425,8 @@ void LineLoopHandler::destroy(VkDevice device)
mStreamingLineLoopIndicesData->destroy(device); mStreamingLineLoopIndicesData->destroy(device);
} }
gl::Error LineLoopHandler::draw(ContextVk *contextVk, gl::Error LineLoopHandler::draw(int count, CommandBuffer *commandBuffer)
int firstVertex,
int count,
CommandBuffer *commandBuffer)
{ {
ANGLE_TRY(bindLineLoopIndexBuffer(contextVk, firstVertex, count, &commandBuffer));
// Our first index is always 0 because that's how we set it up in the // Our first index is always 0 because that's how we set it up in the
// bindLineLoopIndexBuffer. // bindLineLoopIndexBuffer.
commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0); commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0);
...@@ -1387,6 +1434,10 @@ gl::Error LineLoopHandler::draw(ContextVk *contextVk, ...@@ -1387,6 +1434,10 @@ gl::Error LineLoopHandler::draw(ContextVk *contextVk,
return gl::NoError(); return gl::NoError();
} }
ResourceVk *LineLoopHandler::getLineLoopBufferResource()
{
return mStreamingLineLoopIndicesData.get();
}
} // namespace vk } // namespace vk
namespace gl_vk namespace gl_vk
......
...@@ -346,6 +346,11 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer> ...@@ -346,6 +346,11 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
uint32_t regionCount, uint32_t regionCount,
const VkBufferCopy *regions); const VkBufferCopy *regions);
void copyBuffer(const VkBuffer &srcBuffer,
const VkBuffer &destBuffer,
uint32_t regionCount,
const VkBufferCopy *regions);
void copySingleImage(const vk::Image &srcImage, void copySingleImage(const vk::Image &srcImage,
const vk::Image &destImage, const vk::Image &destImage,
const gl::Box &copyRegion, const gl::Box &copyRegion,
...@@ -681,15 +686,20 @@ class LineLoopHandler final : angle::NonCopyable ...@@ -681,15 +686,20 @@ class LineLoopHandler final : angle::NonCopyable
LineLoopHandler(); LineLoopHandler();
~LineLoopHandler(); ~LineLoopHandler();
void bindIndexBuffer(VkIndexType indexType, vk::CommandBuffer **commandBuffer);
gl::Error createIndexBuffer(ContextVk *contextVk, int firstVertex, int count);
gl::Error createIndexBufferFromElementArrayBuffer(ContextVk *contextVk,
BufferVk *bufferVk,
VkIndexType indexType,
int count);
void destroy(VkDevice device); void destroy(VkDevice device);
gl::Error draw(ContextVk *contextVk, int firstVertex, int count, CommandBuffer *commandBuffer); gl::Error draw(int count, CommandBuffer *commandBuffer);
ResourceVk *getLineLoopBufferResource();
private: private:
gl::Error bindLineLoopIndexBuffer(ContextVk *contextVk,
int firstVertex,
int count,
vk::CommandBuffer **commandBuffer);
std::unique_ptr<StreamingBuffer> mStreamingLineLoopIndicesData; std::unique_ptr<StreamingBuffer> mStreamingLineLoopIndicesData;
VkBuffer mLineLoopIndexBuffer; VkBuffer mLineLoopIndexBuffer;
VkDeviceSize mLineLoopIndexBufferOffset; VkDeviceSize mLineLoopIndexBufferOffset;
......
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