Commit 32fd63bc by Jamie Madill Committed by Commit Bot

Vulkan: Use DrawCallParams in draw methods.

This cleans up some of the vertex streaming logic. Bug: angleproject:2389 Change-Id: I8ed2f8acd06bbdd97db40acac35e5692112a3efe Reviewed-on: https://chromium-review.googlesource.com/989257 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 0946393d
......@@ -148,17 +148,14 @@ gl::Error ContextVk::initPipeline(const gl::Context *context)
}
gl::Error ContextVk::setupDraw(const gl::Context *context,
GLenum mode,
DrawType drawType,
size_t firstVertex,
size_t lastVertex,
const gl::DrawCallParams &drawCallParams,
ResourceVk *elementArrayBufferOverride,
vk::CommandBuffer **commandBuffer)
vk::CommandBuffer **commandBufferOut)
{
if (mode != mCurrentDrawMode)
if (drawCallParams.mode() != mCurrentDrawMode)
{
invalidateCurrentPipeline();
mCurrentDrawMode = mode;
mCurrentDrawMode = drawCallParams.mode();
}
if (!mCurrentPipeline)
......@@ -179,15 +176,17 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
vk::CommandGraphNode *graphNode = nullptr;
ANGLE_TRY(vkFBO->getCommandGraphNodeForDraw(context, &graphNode));
vk::CommandBuffer *commandBuffer = nullptr;
if (!graphNode->getInsideRenderPassCommands()->valid())
{
mVertexArrayDirty = true;
mTexturesDirty = true;
ANGLE_TRY(graphNode->beginInsideRenderPassRecording(mRenderer, commandBuffer));
ANGLE_TRY(graphNode->beginInsideRenderPassRecording(mRenderer, &commandBuffer));
}
else
{
*commandBuffer = graphNode->getInsideRenderPassCommands();
commandBuffer = graphNode->getInsideRenderPassCommands();
}
// Ensure any writes to the VAO buffers are flushed before we read from them.
......@@ -196,7 +195,8 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
mVertexArrayDirty = false;
vkVAO->updateDrawDependencies(graphNode, programGL->getActiveAttribLocationsMask(),
elementArrayBufferOverride, queueSerial, drawType);
elementArrayBufferOverride, queueSerial,
drawCallParams.isDrawElements());
}
// Ensure any writes to the textures are flushed before we read from them.
......@@ -223,12 +223,10 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
}
}
(*commandBuffer)->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline->get());
ContextVk *contextVk = vk::GetImpl(context);
ANGLE_TRY(vkVAO->streamVertexData(contextVk, &mStreamingVertexData, firstVertex, lastVertex));
(*commandBuffer)
->bindVertexBuffers(0, maxAttrib, vkVAO->getCurrentArrayBufferHandles().data(),
vkVAO->getCurrentArrayBufferOffsets().data());
commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline->get());
ANGLE_TRY(vkVAO->streamVertexData(context, &mStreamingVertexData, drawCallParams));
commandBuffer->bindVertexBuffers(0, maxAttrib, vkVAO->getCurrentArrayBufferHandles().data(),
vkVAO->getCurrentArrayBufferOffsets().data());
// Update the queue serial for the pipeline object.
ASSERT(mCurrentPipeline && mCurrentPipeline->valid());
......@@ -247,21 +245,22 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
ASSERT(!descriptorSets.empty());
const vk::PipelineLayout &pipelineLayout = mRenderer->getGraphicsPipelineLayout();
(*commandBuffer)
->bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, usedRange.low(),
usedRange.length(), &descriptorSets[usedRange.low()],
programVk->getDynamicOffsetsCount(),
programVk->getDynamicOffsets());
commandBuffer->bindDescriptorSets(
VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, usedRange.low(), usedRange.length(),
&descriptorSets[usedRange.low()], programVk->getDynamicOffsetsCount(),
programVk->getDynamicOffsets());
}
*commandBufferOut = commandBuffer;
return gl::NoError();
}
gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
{
const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(setupDraw(context, mode, DrawType::Arrays, first, first + count - 1, nullptr,
&commandBuffer));
ANGLE_TRY(setupDraw(context, drawCallParams, nullptr, &commandBuffer));
if (mode == GL_LINE_LOOP)
{
......@@ -293,6 +292,8 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
GLenum type,
const void *indices)
{
const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
gl::VertexArray *vao = mState.getState().getVertexArray();
const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
vk::CommandBuffer *commandBuffer = nullptr;
......@@ -311,8 +312,8 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
this, elementArrayBufferVk, GetVkIndexType(type), count));
// TODO(fjhenigman): calculate the index range and pass to setupDraw()
ANGLE_TRY(setupDraw(context, mode, DrawType::Elements, 0, 0,
mLineLoopHandler.getLineLoopBufferResource(), &commandBuffer));
ANGLE_TRY(setupDraw(context, drawCallParams, mLineLoopHandler.getLineLoopBufferResource(),
&commandBuffer));
mLineLoopHandler.bindIndexBuffer(GetVkIndexType(type), &commandBuffer);
commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0);
......@@ -320,7 +321,6 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
else
{
ContextVk *contextVk = vk::GetImpl(context);
const bool computeIndexRange = vk::GetImpl(vao)->attribsToStream(contextVk).any();
gl::IndexRange range;
VkBuffer buffer = VK_NULL_HANDLE;
uint32_t offset = 0;
......@@ -338,12 +338,6 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
buffer = elementArrayBufferVk->getVkBuffer().getHandle();
offset = 0;
if (computeIndexRange)
{
ANGLE_TRY(elementArrayBufferVk->getIndexRange(
context, type, 0, count, false /*primitiveRestartEnabled*/, &range));
}
}
else
{
......@@ -368,16 +362,9 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
memcpy(dst, indices, amount);
}
ANGLE_TRY(mStreamingIndexData.flush(contextVk));
if (computeIndexRange)
{
range =
gl::ComputeIndexRange(type, indices, count, false /*primitiveRestartEnabled*/);
}
}
ANGLE_TRY(setupDraw(context, mode, DrawType::Elements, range.start, range.end, nullptr,
&commandBuffer));
ANGLE_TRY(setupDraw(context, drawCallParams, nullptr, &commandBuffer));
commandBuffer->bindIndexBuffer(buffer, offset, GetVkIndexType(type));
commandBuffer->drawIndexed(count, 1, 0, 0, 0);
}
......
......@@ -166,12 +166,9 @@ class ContextVk : public ContextImpl
private:
gl::Error initPipeline(const gl::Context *context);
gl::Error setupDraw(const gl::Context *context,
GLenum mode,
DrawType drawType,
size_t firstVertex,
size_t lastVertex,
const gl::DrawCallParams &drawCallParams,
ResourceVk *elementArrayBufferOverride,
vk::CommandBuffer **commandBuffer);
vk::CommandBuffer **commandBufferOut);
RendererVk *mRenderer;
vk::PipelineAndSerial *mCurrentPipeline;
......
......@@ -43,23 +43,27 @@ void VertexArrayVk::destroy(const gl::Context *context)
{
}
gl::AttributesMask VertexArrayVk::attribsToStream(ContextVk *context) const
gl::AttributesMask VertexArrayVk::getAttribsToStream(const gl::Context *context) const
{
const gl::Program *programGL = context->getGLState().getProgram();
return mClientMemoryAttribs & programGL->getActiveAttribLocationsMask();
}
gl::Error VertexArrayVk::streamVertexData(ContextVk *context,
gl::Error VertexArrayVk::streamVertexData(const gl::Context *context,
StreamingBuffer *stream,
size_t firstVertex,
size_t lastVertex)
const gl::DrawCallParams &drawCallParams)
{
ContextVk *contextVk = vk::GetImpl(context);
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
const size_t lastVertex = drawCallParams.firstVertex() + drawCallParams.vertexCount();
// TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
// un-interleaved, wasting space and copying time. Consider improving on that.
for (auto attribIndex : attribsToStream(context))
for (auto attribIndex : getAttribsToStream(context))
{
const gl::VertexAttribute &attrib = attribs[attribIndex];
const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
......@@ -77,19 +81,19 @@ gl::Error VertexArrayVk::streamVertexData(ContextVk *context,
// will work. If we don't start at zero all the indices will be off.
// TODO(fjhenigman): See if we can account for indices being off by adjusting
// the offset, thus avoiding wasted memory.
const size_t firstByte = firstVertex * binding.getStride();
const size_t firstByte = drawCallParams.firstVertex() * binding.getStride();
const size_t lastByte =
lastVertex * binding.getStride() + gl::ComputeVertexAttributeTypeSize(attrib);
uint8_t *dst = nullptr;
uint32_t offset = 0;
ANGLE_TRY(stream->allocate(context, lastByte, &dst,
ANGLE_TRY(stream->allocate(contextVk, lastByte, &dst,
&mCurrentArrayBufferHandles[attribIndex], &offset, nullptr));
mCurrentArrayBufferOffsets[attribIndex] = static_cast<VkDeviceSize>(offset);
memcpy(dst + firstByte, static_cast<const uint8_t *>(attrib.pointer) + firstByte,
lastByte - firstByte);
}
ANGLE_TRY(stream->flush(context));
ANGLE_TRY(stream->flush(contextVk));
return gl::NoError();
}
......@@ -188,7 +192,7 @@ void VertexArrayVk::updateDrawDependencies(vk::CommandGraphNode *readNode,
const gl::AttributesMask &activeAttribsMask,
ResourceVk *elementArrayBufferOverride,
Serial serial,
DrawType drawType)
bool isDrawElements)
{
// Handle the bound array buffers.
for (auto attribIndex : activeAttribsMask)
......@@ -198,7 +202,7 @@ void VertexArrayVk::updateDrawDependencies(vk::CommandGraphNode *readNode,
}
// Handle the bound element array buffer.
if (drawType == DrawType::Elements)
if (isDrawElements)
{
if (elementArrayBufferOverride != nullptr)
{
......
......@@ -13,6 +13,11 @@
#include "libANGLE/renderer/VertexArrayImpl.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
namespace gl
{
class DrawCallParams;
} // namespace gl
namespace rx
{
class BufferVk;
......@@ -26,11 +31,9 @@ class VertexArrayVk : public VertexArrayImpl
void destroy(const gl::Context *context) override;
gl::AttributesMask attribsToStream(ContextVk *context) const;
gl::Error streamVertexData(ContextVk *context,
gl::Error streamVertexData(const gl::Context *context,
StreamingBuffer *stream,
size_t firstVertex,
size_t lastVertex);
const gl::DrawCallParams &drawCallParams);
gl::Error syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits,
const gl::VertexArray::DirtyAttribBitsArray &attribBits,
......@@ -43,7 +46,7 @@ class VertexArrayVk : public VertexArrayImpl
const gl::AttributesMask &activeAttribsMask,
ResourceVk *elementArrayBufferOverride,
Serial serial,
DrawType drawType);
bool isDrawElements);
void getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc);
......@@ -58,6 +61,8 @@ class VertexArrayVk : public VertexArrayImpl
const gl::VertexBinding &binding,
const gl::VertexAttribute &attrib);
gl::AttributesMask getAttribsToStream(const gl::Context *context) const;
gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets;
gl::AttribArray<ResourceVk *> mCurrentArrayBufferResources;
......
......@@ -59,12 +59,6 @@ class ResourceVk;
class RenderPassCache;
class StreamingBuffer;
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