Commit c3755fc5 by Jamie Madill Committed by Commit Bot

Vulkan: Move Streaming data to VertexArrayVk.

Instead of the ContextVk owning the translations for the various attributes, make the VertexArrayVk own them. This way they can handle the dirty bit state notifications directly instead of needing their own Observers. Bug: angleproject:2389 Change-Id: I5e571ba6c563e820a4c0d5f92db35031e6f2428a Reviewed-on: https://chromium-review.googlesource.com/989258 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent e7b3fe21
...@@ -155,7 +155,6 @@ class ContextVk : public ContextImpl ...@@ -155,7 +155,6 @@ class ContextVk : public ContextImpl
RendererVk *getRenderer() { return mRenderer; } RendererVk *getRenderer() { return mRenderer; }
void invalidateCurrentPipeline(); void invalidateCurrentPipeline();
void onVertexArrayChange();
DynamicDescriptorPool *getDynamicDescriptorPool(); DynamicDescriptorPool *getDynamicDescriptorPool();
...@@ -167,8 +166,8 @@ class ContextVk : public ContextImpl ...@@ -167,8 +166,8 @@ class ContextVk : public ContextImpl
gl::Error initPipeline(const gl::Context *context); gl::Error initPipeline(const gl::Context *context);
gl::Error setupDraw(const gl::Context *context, gl::Error setupDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
ResourceVk *elementArrayBufferOverride, vk::CommandGraphNode **drawNodeOut,
vk::CommandBuffer **commandBufferOut); bool *newCommandBufferOut);
RendererVk *mRenderer; RendererVk *mRenderer;
vk::PipelineAndSerial *mCurrentPipeline; vk::PipelineAndSerial *mCurrentPipeline;
...@@ -183,17 +182,12 @@ class ContextVk : public ContextImpl ...@@ -183,17 +182,12 @@ class ContextVk : public ContextImpl
DynamicDescriptorPool mDynamicDescriptorPool; DynamicDescriptorPool mDynamicDescriptorPool;
// Triggers adding dependencies to the command graph. // Triggers adding dependencies to the command graph.
bool mVertexArrayDirty;
bool mTexturesDirty; bool mTexturesDirty;
bool mVertexArrayBindingHasChanged;
// Cached clear value for color and depth/stencil. // Cached clear value for color and depth/stencil.
VkClearValue mClearColorValue; VkClearValue mClearColorValue;
VkClearValue mClearDepthStencilValue; VkClearValue mClearDepthStencilValue;
DynamicBuffer mDynamicVertexData;
DynamicBuffer mDynamicIndexData;
vk::LineLoopHandler mLineLoopHandler;
}; };
} // namespace rx } // namespace rx
......
...@@ -44,7 +44,7 @@ bool DynamicBuffer::valid() ...@@ -44,7 +44,7 @@ bool DynamicBuffer::valid()
return mAlignment > 0; return mAlignment > 0;
} }
vk::Error DynamicBuffer::allocate(ContextVk *context, vk::Error DynamicBuffer::allocate(RendererVk *renderer,
size_t sizeInBytes, size_t sizeInBytes,
uint8_t **ptrOut, uint8_t **ptrOut,
VkBuffer *handleOut, VkBuffer *handleOut,
...@@ -52,11 +52,7 @@ vk::Error DynamicBuffer::allocate(ContextVk *context, ...@@ -52,11 +52,7 @@ vk::Error DynamicBuffer::allocate(ContextVk *context,
bool *outNewBufferAllocated) bool *outNewBufferAllocated)
{ {
ASSERT(valid()); ASSERT(valid());
RendererVk *renderer = context->getRenderer(); VkDevice device = renderer->getDevice();
// TODO(fjhenigman): Update this when we have buffers that need to
// persist longer than one frame.
updateQueueSerial(renderer->getCurrentQueueSerial());
size_t sizeToAllocate = roundUp(sizeInBytes, mAlignment); size_t sizeToAllocate = roundUp(sizeInBytes, mAlignment);
...@@ -65,16 +61,15 @@ vk::Error DynamicBuffer::allocate(ContextVk *context, ...@@ -65,16 +61,15 @@ vk::Error DynamicBuffer::allocate(ContextVk *context,
if (!checkedNextWriteOffset.IsValid() || checkedNextWriteOffset.ValueOrDie() > mSize) if (!checkedNextWriteOffset.IsValid() || checkedNextWriteOffset.ValueOrDie() > mSize)
{ {
VkDevice device = context->getDevice();
if (mMappedMemory) if (mMappedMemory)
{ {
ANGLE_TRY(flush(context)); ANGLE_TRY(flush(device));
mMemory.unmap(device); mMemory.unmap(device);
mMappedMemory = nullptr; mMappedMemory = nullptr;
} }
renderer->releaseResource(*this, &mBuffer); Serial currentSerial = renderer->getCurrentQueueSerial();
renderer->releaseResource(*this, &mMemory); renderer->releaseObject(currentSerial, &mBuffer);
renderer->releaseObject(currentSerial, &mMemory);
VkBufferCreateInfo createInfo; VkBufferCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
...@@ -121,7 +116,7 @@ vk::Error DynamicBuffer::allocate(ContextVk *context, ...@@ -121,7 +116,7 @@ vk::Error DynamicBuffer::allocate(ContextVk *context,
return vk::NoError(); return vk::NoError();
} }
vk::Error DynamicBuffer::flush(ContextVk *context) vk::Error DynamicBuffer::flush(VkDevice device)
{ {
if (mNextWriteOffset > mLastFlushOffset) if (mNextWriteOffset > mLastFlushOffset)
{ {
...@@ -131,7 +126,7 @@ vk::Error DynamicBuffer::flush(ContextVk *context) ...@@ -131,7 +126,7 @@ vk::Error DynamicBuffer::flush(ContextVk *context)
range.memory = mMemory.getHandle(); range.memory = mMemory.getHandle();
range.offset = mLastFlushOffset; range.offset = mLastFlushOffset;
range.size = mNextWriteOffset - mLastFlushOffset; range.size = mNextWriteOffset - mLastFlushOffset;
ANGLE_VK_TRY(vkFlushMappedMemoryRanges(context->getDevice(), 1, &range)); ANGLE_VK_TRY(vkFlushMappedMemoryRanges(device, 1, &range));
mLastFlushOffset = mNextWriteOffset; mLastFlushOffset = mNextWriteOffset;
} }
......
...@@ -20,16 +20,17 @@ class DynamicBuffer : public ResourceVk ...@@ -20,16 +20,17 @@ class DynamicBuffer : public ResourceVk
{ {
public: public:
DynamicBuffer(VkBufferUsageFlags usage, size_t minSize); DynamicBuffer(VkBufferUsageFlags usage, size_t minSize);
~DynamicBuffer();
void init(size_t alignment); void init(size_t alignment);
bool valid(); bool valid();
~DynamicBuffer(); vk::Error allocate(RendererVk *renderer,
vk::Error allocate(ContextVk *context,
size_t sizeInBytes, size_t sizeInBytes,
uint8_t **ptrOut, uint8_t **ptrOut,
VkBuffer *handleOut, VkBuffer *handleOut,
uint32_t *offsetOut, uint32_t *offsetOut,
bool *outNewBufferAllocated); bool *outNewBufferAllocated);
vk::Error flush(ContextVk *context); vk::Error flush(VkDevice device);
void destroy(VkDevice device); void destroy(VkDevice device);
VkBuffer getCurrentBufferHandle() const; VkBuffer getCurrentBufferHandle() const;
......
...@@ -113,8 +113,8 @@ void ReadFromDefaultUniformBlock(int componentCount, ...@@ -113,8 +113,8 @@ void ReadFromDefaultUniformBlock(int componentCount,
} }
} }
vk::Error SyncDefaultUniformBlock(ContextVk *contextVk, vk::Error SyncDefaultUniformBlock(RendererVk *renderer,
DynamicBuffer &dynamicBuffer, DynamicBuffer *dynamicBuffer,
const angle::MemoryBuffer &bufferData, const angle::MemoryBuffer &bufferData,
uint32_t *outOffset, uint32_t *outOffset,
bool *outBufferModified) bool *outBufferModified)
...@@ -123,11 +123,11 @@ vk::Error SyncDefaultUniformBlock(ContextVk *contextVk, ...@@ -123,11 +123,11 @@ vk::Error SyncDefaultUniformBlock(ContextVk *contextVk,
uint8_t *data = nullptr; uint8_t *data = nullptr;
VkBuffer *outBuffer = nullptr; VkBuffer *outBuffer = nullptr;
uint32_t offset; uint32_t offset;
ANGLE_TRY(dynamicBuffer.allocate(contextVk, bufferData.size(), &data, outBuffer, &offset, ANGLE_TRY(dynamicBuffer->allocate(renderer, bufferData.size(), &data, outBuffer, &offset,
outBufferModified)); outBufferModified));
*outOffset = offset; *outOffset = offset;
memcpy(data, bufferData.data(), bufferData.size()); memcpy(data, bufferData.data(), bufferData.size());
ANGLE_TRY(dynamicBuffer.flush(contextVk)); ANGLE_TRY(dynamicBuffer->flush(renderer->getDevice()));
return vk::NoError(); return vk::NoError();
} }
...@@ -754,7 +754,7 @@ vk::Error ProgramVk::updateUniforms(ContextVk *contextVk) ...@@ -754,7 +754,7 @@ vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
if (uniformBlock.uniformsDirty) if (uniformBlock.uniformsDirty)
{ {
bool bufferModified = false; bool bufferModified = false;
ANGLE_TRY(SyncDefaultUniformBlock(contextVk, uniformBlock.storage, ANGLE_TRY(SyncDefaultUniformBlock(contextVk->getRenderer(), &uniformBlock.storage,
uniformBlock.uniformData, uniformBlock.uniformData,
&mUniformBlocksOffsets[index], &bufferModified)); &mUniformBlocksOffsets[index], &bufferModified));
uniformBlock.uniformsDirty = false; uniformBlock.uniformsDirty = false;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_ #define LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
#include "libANGLE/renderer/VertexArrayImpl.h" #include "libANGLE/renderer/VertexArrayImpl.h"
#include "libANGLE/renderer/vulkan/DynamicBuffer.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h" #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
namespace gl namespace gl
...@@ -31,10 +32,6 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -31,10 +32,6 @@ class VertexArrayVk : public VertexArrayImpl
void destroy(const gl::Context *context) override; void destroy(const gl::Context *context) override;
gl::Error streamVertexData(const gl::Context *context,
DynamicBuffer *dynamicBuffer,
const gl::DrawCallParams &drawCallParams);
gl::Error syncState(const gl::Context *context, gl::Error syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits, const gl::VertexArray::DirtyBits &dirtyBits,
const gl::VertexArray::DirtyAttribBitsArray &attribBits, const gl::VertexArray::DirtyAttribBitsArray &attribBits,
...@@ -43,14 +40,20 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -43,14 +40,20 @@ class VertexArrayVk : public VertexArrayImpl
const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const; const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const;
const gl::AttribArray<VkDeviceSize> &getCurrentArrayBufferOffsets() const; const gl::AttribArray<VkDeviceSize> &getCurrentArrayBufferOffsets() const;
void updateDrawDependencies(vk::CommandGraphNode *readNode,
const gl::AttributesMask &activeAttribsMask,
ResourceVk *elementArrayBufferOverride,
Serial serial,
bool isDrawElements);
void getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc); void getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc);
// Draw call handling.
gl::Error drawArrays(const gl::Context *context,
RendererVk *renderer,
const gl::DrawCallParams &drawCallParams,
vk::CommandGraphNode *drawNode,
bool newCommandBuffer);
gl::Error drawElements(const gl::Context *context,
RendererVk *renderer,
const gl::DrawCallParams &drawCallParams,
vk::CommandGraphNode *drawNode,
bool newCommandBuffer);
private: private:
// This will update any dirty packed input descriptions, regardless if they're used by the // This will update any dirty packed input descriptions, regardless if they're used by the
// active program. This could lead to slight inefficiencies when the app would repeatedly // active program. This could lead to slight inefficiencies when the app would repeatedly
...@@ -62,11 +65,34 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -62,11 +65,34 @@ class VertexArrayVk : public VertexArrayImpl
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
const gl::VertexAttribute &attrib); const gl::VertexAttribute &attrib);
gl::AttributesMask getAttribsToStream(const gl::Context *context) const; void updateArrayBufferReadDependencies(vk::CommandGraphNode *drawNode,
const gl::AttributesMask &activeAttribsMask,
Serial serial);
void updateElementArrayBufferReadDependency(vk::CommandGraphNode *drawNode, Serial serial);
gl::Error streamVertexData(RendererVk *renderer,
const gl::AttributesMask &attribsToStream,
const gl::DrawCallParams &drawCallParams);
gl::Error streamIndexData(RendererVk *renderer, const gl::DrawCallParams &drawCallParams);
gl::Error onDraw(const gl::Context *context,
RendererVk *renderer,
const gl::DrawCallParams &drawCallParams,
vk::CommandGraphNode *drawNode,
bool newCommandBuffer);
gl::Error onIndexedDraw(const gl::Context *context,
RendererVk *renderer,
const gl::DrawCallParams &drawCallParams,
vk::CommandGraphNode *drawNode,
bool newCommandBuffer);
gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles; gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets; gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets;
gl::AttribArray<ResourceVk *> mCurrentArrayBufferResources; gl::AttribArray<ResourceVk *> mCurrentArrayBufferResources;
VkBuffer mCurrentElementArrayBufferHandle;
VkDeviceSize mCurrentElementArrayBufferOffset;
ResourceVk *mCurrentElementArrayBufferResource; ResourceVk *mCurrentElementArrayBufferResource;
// Keep a cache of binding and attribute descriptions for easy pipeline updates. // Keep a cache of binding and attribute descriptions for easy pipeline updates.
...@@ -78,6 +104,17 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -78,6 +104,17 @@ class VertexArrayVk : public VertexArrayImpl
// Which attributes need to be copied from client memory. // Which attributes need to be copied from client memory.
// TODO(jmadill): Move this to VertexArrayState. http://anglebug.com/2389 // TODO(jmadill): Move this to VertexArrayState. http://anglebug.com/2389
gl::AttributesMask mClientMemoryAttribs; gl::AttributesMask mClientMemoryAttribs;
DynamicBuffer mDynamicVertexData;
DynamicBuffer mDynamicIndexData;
vk::LineLoopHandler mLineLoopHandler;
Optional<int> mLineLoopBufferFirstIndex;
Optional<int> mLineLoopBufferLastIndex;
// Cache variable for determining whether or not to store new dependencies in the node.
bool mVertexBuffersDirty;
bool mIndexBufferDirty;
}; };
} // namespace rx } // namespace rx
......
...@@ -1179,93 +1179,84 @@ LineLoopHandler::LineLoopHandler() ...@@ -1179,93 +1179,84 @@ LineLoopHandler::LineLoopHandler()
: mObserverBinding(this, 0u), : mObserverBinding(this, 0u),
mDynamicLineLoopIndicesData( mDynamicLineLoopIndicesData(
new DynamicBuffer(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, new DynamicBuffer(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
kLineLoopDynamicBufferMinSize)), kLineLoopDynamicBufferMinSize))
mLineLoopIndexBuffer(VK_NULL_HANDLE),
mLineLoopIndexBufferOffset(VK_NULL_HANDLE)
{ {
mDynamicLineLoopIndicesData->init(1); mDynamicLineLoopIndicesData->init(1);
} }
LineLoopHandler::~LineLoopHandler() = default; LineLoopHandler::~LineLoopHandler() = default;
void LineLoopHandler::bindIndexBuffer(VkIndexType indexType, vk::CommandBuffer **commandBuffer) gl::Error LineLoopHandler::createIndexBuffer(RendererVk *renderer,
const gl::DrawCallParams &drawCallParams,
VkBuffer *bufferHandleOut,
VkDeviceSize *offsetOut)
{ {
(*commandBuffer)->bindIndexBuffer(mLineLoopIndexBuffer, mLineLoopIndexBufferOffset, indexType);
}
gl::Error LineLoopHandler::createIndexBuffer(ContextVk *contextVk, int firstVertex, int count)
{
int lastVertex = firstVertex + count;
if (mLineLoopIndexBuffer == VK_NULL_HANDLE || !mLineLoopBufferFirstIndex.valid() ||
!mLineLoopBufferLastIndex.valid() || mLineLoopBufferFirstIndex != firstVertex ||
mLineLoopBufferLastIndex != lastVertex)
{
uint32_t *indices = nullptr; uint32_t *indices = nullptr;
size_t allocateBytes = sizeof(uint32_t) * (count + 1); size_t allocateBytes = sizeof(uint32_t) * (drawCallParams.vertexCount() + 1);
ANGLE_TRY(mDynamicLineLoopIndicesData->allocate( uint32_t offset = 0;
contextVk, allocateBytes, reinterpret_cast<uint8_t **>(&indices), &mLineLoopIndexBuffer, ANGLE_TRY(mDynamicLineLoopIndicesData->allocate(renderer, allocateBytes,
&mLineLoopIndexBufferOffset, nullptr)); reinterpret_cast<uint8_t **>(&indices),
bufferHandleOut, &offset, nullptr));
auto unsignedFirstVertex = static_cast<uint32_t>(firstVertex); *offsetOut = static_cast<VkDeviceSize>(offset);
for (auto vertexIndex = unsignedFirstVertex; vertexIndex < (count + unsignedFirstVertex);
vertexIndex++) uint32_t unsignedFirstVertex = static_cast<uint32_t>(drawCallParams.firstVertex());
uint32_t vertexCount = (drawCallParams.vertexCount() + unsignedFirstVertex);
for (uint32_t vertexIndex = unsignedFirstVertex; vertexIndex < vertexCount; vertexIndex++)
{ {
*indices++ = vertexIndex; *indices++ = vertexIndex;
} }
*indices = unsignedFirstVertex; *indices = unsignedFirstVertex;
// Since we are not using the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT flag when creating the // Since we are not using the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT flag when creating the
// device memory in the DynamicBuffer, we always need to make sure we flush it after // device memory in the StreamingBuffer, we always need to make sure we flush it after
// writing. // writing.
ANGLE_TRY(mDynamicLineLoopIndicesData->flush(contextVk)); ANGLE_TRY(mDynamicLineLoopIndicesData->flush(renderer->getDevice()));
mLineLoopBufferFirstIndex = firstVertex;
mLineLoopBufferLastIndex = lastVertex;
}
return gl::NoError(); return gl::NoError();
} }
gl::Error LineLoopHandler::createIndexBufferFromElementArrayBuffer(ContextVk *contextVk, gl::Error LineLoopHandler::createIndexBufferFromElementArrayBuffer(RendererVk *renderer,
BufferVk *bufferVk, BufferVk *elementArrayBufferVk,
VkIndexType indexType, VkIndexType indexType,
int count) int indexCount,
VkBuffer *bufferHandleOut,
VkDeviceSize *bufferOffsetOut)
{ {
ASSERT(indexType == VK_INDEX_TYPE_UINT16 || indexType == VK_INDEX_TYPE_UINT32); ASSERT(indexType == VK_INDEX_TYPE_UINT16 || indexType == VK_INDEX_TYPE_UINT32);
if (bufferVk == mObserverBinding.getSubject() && mLineLoopIndexBuffer != VK_NULL_HANDLE) if (elementArrayBufferVk == mObserverBinding.getSubject())
{ {
return gl::NoError(); return gl::NoError();
} }
// We want to know if the bufferVk changes at any point in time, because if it does we need to // We want to know if the bufferVk changes at any point in time, because if it does we need to
// recopy our data on the next call. // recopy our data on the next call.
mObserverBinding.bind(bufferVk); mObserverBinding.bind(elementArrayBufferVk);
uint32_t *indices = nullptr; uint32_t *indices = nullptr;
uint32_t offset = 0;
auto unitSize = (indexType == VK_INDEX_TYPE_UINT16 ? sizeof(uint16_t) : sizeof(uint32_t)); auto unitSize = (indexType == VK_INDEX_TYPE_UINT16 ? sizeof(uint16_t) : sizeof(uint32_t));
size_t allocateBytes = unitSize * (count + 1); size_t allocateBytes = unitSize * (indexCount + 1);
ANGLE_TRY(mDynamicLineLoopIndicesData->allocate( ANGLE_TRY(mDynamicLineLoopIndicesData->allocate(renderer, allocateBytes,
contextVk, allocateBytes, reinterpret_cast<uint8_t **>(&indices), &mLineLoopIndexBuffer, reinterpret_cast<uint8_t **>(&indices),
&mLineLoopIndexBufferOffset, nullptr)); bufferHandleOut, &offset, nullptr));
*bufferOffsetOut = static_cast<VkDeviceSize>(offset);
VkBufferCopy copy1 = {0, mLineLoopIndexBufferOffset,
static_cast<VkDeviceSize>(count) * unitSize}; VkBufferCopy copy1 = {0, offset, static_cast<VkDeviceSize>(indexCount) * unitSize};
VkBufferCopy copy2 = { VkBufferCopy copy2 = {0, offset + static_cast<VkDeviceSize>(indexCount) * unitSize, unitSize};
0, mLineLoopIndexBufferOffset + static_cast<VkDeviceSize>(count) * unitSize, unitSize};
std::array<VkBufferCopy, 2> copies = {{copy1, copy2}}; std::array<VkBufferCopy, 2> copies = {{copy1, copy2}};
vk::CommandBuffer *commandBuffer; vk::CommandBuffer *commandBuffer;
mDynamicLineLoopIndicesData->beginWriteResource(contextVk->getRenderer(), &commandBuffer); mDynamicLineLoopIndicesData->beginWriteResource(renderer, &commandBuffer);
Serial currentSerial = contextVk->getRenderer()->getCurrentQueueSerial(); Serial currentSerial = renderer->getCurrentQueueSerial();
bufferVk->onReadResource(mDynamicLineLoopIndicesData->getCurrentWritingNode(currentSerial), elementArrayBufferVk->onReadResource(
currentSerial); mDynamicLineLoopIndicesData->getCurrentWritingNode(currentSerial), currentSerial);
commandBuffer->copyBuffer(bufferVk->getVkBuffer().getHandle(), mLineLoopIndexBuffer, 2, commandBuffer->copyBuffer(elementArrayBufferVk->getVkBuffer().getHandle(), *bufferHandleOut, 2,
copies.data()); copies.data());
ANGLE_TRY(mDynamicLineLoopIndicesData->flush(contextVk)); ANGLE_TRY(mDynamicLineLoopIndicesData->flush(renderer->getDevice()));
return gl::NoError(); return gl::NoError();
} }
...@@ -1275,13 +1266,11 @@ void LineLoopHandler::destroy(VkDevice device) ...@@ -1275,13 +1266,11 @@ void LineLoopHandler::destroy(VkDevice device)
mDynamicLineLoopIndicesData->destroy(device); mDynamicLineLoopIndicesData->destroy(device);
} }
gl::Error LineLoopHandler::draw(int count, CommandBuffer *commandBuffer) // static
void LineLoopHandler::Draw(int count, CommandBuffer *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 createIndexBuffer*.
// bindLineLoopIndexBuffer.
commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0); commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0);
return gl::NoError();
} }
ResourceVk *LineLoopHandler::getLineLoopBufferResource() ResourceVk *LineLoopHandler::getLineLoopBufferResource()
...@@ -1296,7 +1285,7 @@ void LineLoopHandler::onSubjectStateChange(const gl::Context *context, ...@@ -1296,7 +1285,7 @@ void LineLoopHandler::onSubjectStateChange(const gl::Context *context,
// Indicate we want to recopy on next draw since something changed in the buffer. // Indicate we want to recopy on next draw since something changed in the buffer.
if (message == angle::SubjectMessage::CONTENTS_CHANGED) if (message == angle::SubjectMessage::CONTENTS_CHANGED)
{ {
mLineLoopIndexBuffer = VK_NULL_HANDLE; mObserverBinding.reset();
} }
} }
...@@ -1768,6 +1757,21 @@ VkComponentSwizzle GetSwizzle(const GLenum swizzle) ...@@ -1768,6 +1757,21 @@ VkComponentSwizzle GetSwizzle(const GLenum swizzle)
return VK_COMPONENT_SWIZZLE_IDENTITY; return VK_COMPONENT_SWIZZLE_IDENTITY;
} }
} }
VkIndexType GetIndexType(GLenum elementType)
{
switch (elementType)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT:
return VK_INDEX_TYPE_UINT16;
case GL_UNSIGNED_INT:
return VK_INDEX_TYPE_UINT32;
default:
UNREACHABLE();
return VK_INDEX_TYPE_MAX_ENUM;
}
}
} // namespace gl_vk } // namespace gl_vk
ResourceVk::ResourceVk() : mCurrentWritingNode(nullptr) ResourceVk::ResourceVk() : mCurrentWritingNode(nullptr)
......
...@@ -38,6 +38,7 @@ class Display; ...@@ -38,6 +38,7 @@ class Display;
namespace gl namespace gl
{ {
struct Box; struct Box;
class DrawCallParams;
struct Extents; struct Extents;
struct RasterizerState; struct RasterizerState;
struct Rectangle; struct Rectangle;
...@@ -641,27 +642,32 @@ Error AllocateImageMemory(RendererVk *renderer, ...@@ -641,27 +642,32 @@ Error AllocateImageMemory(RendererVk *renderer,
DeviceMemory *deviceMemoryOut, DeviceMemory *deviceMemoryOut,
size_t *requiredSizeOut); size_t *requiredSizeOut);
// This class responsibility is to bind an indexed buffer needed to support line loops in Vulkan. // This class' responsibility is to create index buffers needed to support line loops in Vulkan.
// In the setup phase of drawing, the bindLineLoopIndexBuffer method should be called with the // In the setup phase of drawing, the createIndexBuffer method should be called with the
// first/last vertex and the current commandBuffer. If the user wants to draw a loop between [v1, // current draw call parameters. If an element array buffer is bound for an indexed draw, use
// v2, v3], we will create an indexed buffer with these indexes: [0, 1, 2, 3, 0] to emulate the // createIndexBufferFromElementArrayBuffer.
// loop. //
// If the user wants to draw a loop between [v1, v2, v3], we will create an indexed buffer with
// these indexes: [0, 1, 2, 3, 0] to emulate the loop.
class LineLoopHandler final : angle::NonCopyable, angle::ObserverInterface class LineLoopHandler final : angle::NonCopyable, angle::ObserverInterface
{ {
public: public:
LineLoopHandler(); LineLoopHandler();
~LineLoopHandler(); ~LineLoopHandler();
void bindIndexBuffer(VkIndexType indexType, CommandBuffer **commandBuffer); gl::Error createIndexBuffer(RendererVk *renderer,
const gl::DrawCallParams &drawCallParams,
gl::Error createIndexBuffer(ContextVk *contextVk, int firstVertex, int count); VkBuffer *bufferHandleOut,
gl::Error createIndexBufferFromElementArrayBuffer(ContextVk *contextVk, VkDeviceSize *offsetOut);
BufferVk *bufferVk, gl::Error createIndexBufferFromElementArrayBuffer(RendererVk *renderer,
BufferVk *elementArrayBufferVk,
VkIndexType indexType, VkIndexType indexType,
int count); int indexCount,
VkBuffer *bufferHandleOut,
VkDeviceSize *bufferOffsetOut);
void destroy(VkDevice device); void destroy(VkDevice device);
gl::Error draw(int count, CommandBuffer *commandBuffer); static void Draw(int count, CommandBuffer *commandBuffer);
ResourceVk *getLineLoopBufferResource(); ResourceVk *getLineLoopBufferResource();
...@@ -673,10 +679,6 @@ class LineLoopHandler final : angle::NonCopyable, angle::ObserverInterface ...@@ -673,10 +679,6 @@ class LineLoopHandler final : angle::NonCopyable, angle::ObserverInterface
private: private:
angle::ObserverBinding mObserverBinding; angle::ObserverBinding mObserverBinding;
std::unique_ptr<DynamicBuffer> mDynamicLineLoopIndicesData; std::unique_ptr<DynamicBuffer> mDynamicLineLoopIndicesData;
VkBuffer mLineLoopIndexBuffer;
uint32_t mLineLoopIndexBufferOffset;
Optional<int> mLineLoopBufferFirstIndex;
Optional<int> mLineLoopBufferLastIndex;
}; };
class ImageHelper final : angle::NonCopyable class ImageHelper final : angle::NonCopyable
...@@ -771,6 +773,7 @@ VkCullModeFlags GetCullMode(const gl::RasterizerState &rasterState); ...@@ -771,6 +773,7 @@ VkCullModeFlags GetCullMode(const gl::RasterizerState &rasterState);
VkFrontFace GetFrontFace(GLenum frontFace); VkFrontFace GetFrontFace(GLenum frontFace);
VkSampleCountFlagBits GetSamples(GLint sampleCount); VkSampleCountFlagBits GetSamples(GLint sampleCount);
VkComponentSwizzle GetSwizzle(const GLenum swizzle); VkComponentSwizzle GetSwizzle(const GLenum swizzle);
VkIndexType GetIndexType(GLenum elementType);
} // namespace gl_vk } // namespace gl_vk
// This is a helper class for back-end objects used in Vk command buffers. It records a serial // This is a helper class for back-end objects used in Vk command buffers. It records a serial
......
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