Commit da854a27 by Jamie Madill Committed by Commit Bot

Vulkan: Clean up VAO cached resources.

We can actually store a pointer to the base ResourceVk instead of BufferVk for updating serials. This will work a little nicer with streaming vertex data, which won't have a BufferVk but will have an accessible ResourceVk pointer. Also add an element array resource pointer for serial update. This was missing and could lead to incorrect behaviour. Also change the types of the caches from std::vector to gl::AttribArray, which is a std::array. Bug: angleproject:2264 Change-Id: Ibd79b7676b5dbc3875ae9d110be477d228e01c5c Reviewed-on: https://chromium-review.googlesource.com/798170 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 9f2a8613
......@@ -295,7 +295,7 @@ gl::Error ContextVk::initPipeline(const gl::Context *context)
return gl::NoError();
}
gl::Error ContextVk::setupDraw(const gl::Context *context, GLenum mode)
gl::Error ContextVk::setupDraw(const gl::Context *context, GLenum mode, DrawType drawType)
{
if (mode != mCurrentDrawMode)
{
......@@ -321,8 +321,8 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, GLenum mode)
// Process vertex attributes. Assume zero offsets for now.
// TODO(jmadill): Offset handling.
const std::vector<VkBuffer> &vertexHandles = vkVAO->getCurrentVertexBufferHandlesCache();
angle::MemoryBuffer *zeroBuf = nullptr;
const auto &vertexHandles = vkVAO->getCurrentArrayBufferHandles();
angle::MemoryBuffer *zeroBuf = nullptr;
ANGLE_TRY(context->getZeroFilledBuffer(maxAttrib * sizeof(VkDeviceSize), &zeroBuf));
vk::CommandBufferAndState *commandBuffer = nullptr;
......@@ -335,7 +335,8 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, GLenum mode)
// TODO(jmadill): the queue serial should be bound to the pipeline.
setQueueSerial(queueSerial);
vkVAO->updateCurrentBufferSerials(programGL->getActiveAttribLocationsMask(), queueSerial);
vkVAO->updateCurrentBufferSerials(programGL->getActiveAttribLocationsMask(), queueSerial,
drawType);
// TODO(jmadill): Can probably use more dirty bits here.
ContextVk *contextVk = vk::GetImpl(context);
......@@ -360,7 +361,7 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, GLenum mode)
gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
{
ANGLE_TRY(setupDraw(context, mode));
ANGLE_TRY(setupDraw(context, mode, DrawType::Arrays));
vk::CommandBufferAndState *commandBuffer = nullptr;
ANGLE_TRY(mRenderer->getStartedCommandBuffer(&commandBuffer));
......@@ -385,7 +386,7 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
GLenum type,
const void *indices)
{
ANGLE_TRY(setupDraw(context, mode));
ANGLE_TRY(setupDraw(context, mode, DrawType::Elements));
if (indices)
{
......
......@@ -158,7 +158,7 @@ class ContextVk : public ContextImpl, public ResourceVk
private:
gl::Error initPipeline(const gl::Context *context);
gl::Error setupDraw(const gl::Context *context, GLenum mode);
gl::Error setupDraw(const gl::Context *context, GLenum mode, DrawType drawType);
RendererVk *mRenderer;
vk::Pipeline mCurrentPipeline;
......
......@@ -21,10 +21,13 @@ namespace rx
VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state)
: VertexArrayImpl(state),
mCurrentVertexBufferHandlesCache(state.getMaxAttribs(), VK_NULL_HANDLE),
mCurrentVkBuffersCache(state.getMaxAttribs(), nullptr),
mCurrentArrayBufferHandles{},
mCurrentArrayBufferResources{},
mCurrentElementArrayBufferResource(nullptr),
mCurrentVertexDescsValid(false)
{
mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
mCurrentArrayBufferResources.fill(nullptr);
mCurrentVertexBindingDescs.reserve(state.getMaxAttribs());
mCurrentVertexAttribDescs.reserve(state.getMaxAttribs());
}
......@@ -58,7 +61,18 @@ void VertexArrayVk::syncState(const gl::Context *context,
for (auto dirtyBit : dirtyBits)
{
if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
{
gl::Buffer *bufferGL = mState.getElementArrayBuffer().get();
if (bufferGL)
{
mCurrentElementArrayBufferResource = vk::GetImpl(bufferGL);
}
else
{
mCurrentElementArrayBufferResource = nullptr;
}
continue;
}
size_t attribIndex = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
......@@ -71,14 +85,14 @@ void VertexArrayVk::syncState(const gl::Context *context,
if (bufferGL)
{
BufferVk *bufferVk = vk::GetImpl(bufferGL);
mCurrentVkBuffersCache[attribIndex] = bufferVk;
mCurrentVertexBufferHandlesCache[attribIndex] = bufferVk->getVkBuffer().getHandle();
BufferVk *bufferVk = vk::GetImpl(bufferGL);
mCurrentArrayBufferResources[attribIndex] = bufferVk;
mCurrentArrayBufferHandles[attribIndex] = bufferVk->getVkBuffer().getHandle();
}
else
{
mCurrentVkBuffersCache[attribIndex] = nullptr;
mCurrentVertexBufferHandlesCache[attribIndex] = VK_NULL_HANDLE;
mCurrentArrayBufferResources[attribIndex] = nullptr;
mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
}
}
else
......@@ -88,17 +102,27 @@ void VertexArrayVk::syncState(const gl::Context *context,
}
}
const std::vector<VkBuffer> &VertexArrayVk::getCurrentVertexBufferHandlesCache() const
const gl::AttribArray<VkBuffer> &VertexArrayVk::getCurrentArrayBufferHandles() const
{
return mCurrentVertexBufferHandlesCache;
return mCurrentArrayBufferHandles;
}
void VertexArrayVk::updateCurrentBufferSerials(const gl::AttributesMask &activeAttribsMask,
Serial serial)
Serial serial,
DrawType drawType)
{
// Handle the bound array buffers.
for (auto attribIndex : activeAttribsMask)
{
mCurrentVkBuffersCache[attribIndex]->setQueueSerial(serial);
ASSERT(mCurrentArrayBufferResources[attribIndex]);
mCurrentArrayBufferResources[attribIndex]->setQueueSerial(serial);
}
// Handle the bound element array buffer.
if (drawType == DrawType::Elements)
{
ASSERT(mCurrentElementArrayBufferResource);
mCurrentElementArrayBufferResource->setQueueSerial(serial);
}
}
......
......@@ -28,9 +28,11 @@ class VertexArrayVk : public VertexArrayImpl
void syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits) override;
const std::vector<VkBuffer> &getCurrentVertexBufferHandlesCache() const;
const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const;
void updateCurrentBufferSerials(const gl::AttributesMask &activeAttribsMask, Serial serial);
void updateCurrentBufferSerials(const gl::AttributesMask &activeAttribsMask,
Serial serial,
DrawType drawType);
void invalidateVertexDescriptions();
void updateVertexDescriptions(const gl::Context *context);
......@@ -39,8 +41,9 @@ class VertexArrayVk : public VertexArrayImpl
const std::vector<VkVertexInputAttributeDescription> &getVertexAttribDescs() const;
private:
std::vector<VkBuffer> mCurrentVertexBufferHandlesCache;
std::vector<BufferVk *> mCurrentVkBuffersCache;
gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
gl::AttribArray<ResourceVk *> mCurrentArrayBufferResources;
ResourceVk *mCurrentElementArrayBufferResource;
// Keep a cache of binding and attribute descriptions for easy pipeline updates.
// TODO(jmadill): Update this when we support pipeline caching.
......
......@@ -50,6 +50,12 @@ namespace rx
{
class DisplayVk;
enum class DrawType
{
Arrays,
Elements,
};
ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_VK_OBJECT);
const char *VulkanResultString(VkResult result);
......
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