Skip to content

Commit c3755fc

Browse files
null77Commit Bot
authored andcommitted
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: Yuly Novikov <ynovikov@chromium.org>
1 parent e7b3fe2 commit c3755fc

File tree

9 files changed

+419
-300
lines changed

9 files changed

+419
-300
lines changed

src/libANGLE/renderer/vulkan/ContextVk.cpp

Lines changed: 23 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -38,44 +38,16 @@
3838

3939
namespace rx
4040
{
41-
42-
namespace
43-
{
44-
45-
VkIndexType GetVkIndexType(GLenum glIndexType)
46-
{
47-
switch (glIndexType)
48-
{
49-
case GL_UNSIGNED_BYTE:
50-
case GL_UNSIGNED_SHORT:
51-
return VK_INDEX_TYPE_UINT16;
52-
case GL_UNSIGNED_INT:
53-
return VK_INDEX_TYPE_UINT32;
54-
default:
55-
UNREACHABLE();
56-
return VK_INDEX_TYPE_MAX_ENUM;
57-
}
58-
}
59-
60-
constexpr size_t kDynamicVertexDataSize = 1024 * 1024;
61-
constexpr size_t kDynamicIndexDataSize = 1024 * 8;
62-
63-
} // anonymous namespace
64-
6541
ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
6642
: ContextImpl(state),
6743
mRenderer(renderer),
6844
mCurrentDrawMode(GL_NONE),
6945
mDynamicDescriptorPool(),
70-
mVertexArrayDirty(false),
7146
mTexturesDirty(false),
72-
mDynamicVertexData(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, kDynamicVertexDataSize),
73-
mDynamicIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize)
47+
mVertexArrayBindingHasChanged(false)
7448
{
7549
memset(&mClearColorValue, 0, sizeof(mClearColorValue));
7650
memset(&mClearDepthStencilValue, 0, sizeof(mClearDepthStencilValue));
77-
mDynamicVertexData.init(1);
78-
mDynamicIndexData.init(1);
7951
}
8052

8153
ContextVk::~ContextVk()
@@ -84,12 +56,7 @@ ContextVk::~ContextVk()
8456

8557
void ContextVk::onDestroy(const gl::Context *context)
8658
{
87-
VkDevice device = mRenderer->getDevice();
88-
8959
mDynamicDescriptorPool.destroy(mRenderer);
90-
mDynamicVertexData.destroy(device);
91-
mDynamicIndexData.destroy(device);
92-
mLineLoopHandler.destroy(device);
9360
}
9461

9562
gl::Error ContextVk::initialize()
@@ -149,8 +116,8 @@ gl::Error ContextVk::initPipeline(const gl::Context *context)
149116

150117
gl::Error ContextVk::setupDraw(const gl::Context *context,
151118
const gl::DrawCallParams &drawCallParams,
152-
ResourceVk *elementArrayBufferOverride,
153-
vk::CommandBuffer **commandBufferOut)
119+
vk::CommandGraphNode **drawNodeOut,
120+
bool *newCommandBufferOut)
154121
{
155122
if (drawCallParams.mode() != mCurrentDrawMode)
156123
{
@@ -166,12 +133,9 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
166133
const auto &state = mState.getState();
167134
const gl::Program *programGL = state.getProgram();
168135
ProgramVk *programVk = vk::GetImpl(programGL);
169-
const gl::VertexArray *vao = state.getVertexArray();
170-
VertexArrayVk *vkVAO = vk::GetImpl(vao);
171136
const auto *drawFBO = state.getDrawFramebuffer();
172137
FramebufferVk *vkFBO = vk::GetImpl(drawFBO);
173138
Serial queueSerial = mRenderer->getCurrentQueueSerial();
174-
uint32_t maxAttrib = programGL->getState().getMaxActiveAttribLocation();
175139

176140
vk::CommandGraphNode *graphNode = nullptr;
177141
ANGLE_TRY(vkFBO->getCommandGraphNodeForDraw(context, &graphNode));
@@ -180,23 +144,15 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
180144

181145
if (!graphNode->getInsideRenderPassCommands()->valid())
182146
{
183-
mVertexArrayDirty = true;
184147
mTexturesDirty = true;
148+
*newCommandBufferOut = true;
185149
ANGLE_TRY(graphNode->beginInsideRenderPassRecording(mRenderer, &commandBuffer));
186150
}
187151
else
188152
{
189-
commandBuffer = graphNode->getInsideRenderPassCommands();
190-
}
191-
192-
// Ensure any writes to the VAO buffers are flushed before we read from them.
193-
if (mVertexArrayDirty || elementArrayBufferOverride != nullptr)
194-
{
195-
196-
mVertexArrayDirty = false;
197-
vkVAO->updateDrawDependencies(graphNode, programGL->getActiveAttribLocationsMask(),
198-
elementArrayBufferOverride, queueSerial,
199-
drawCallParams.isDrawElements());
153+
*newCommandBufferOut = mVertexArrayBindingHasChanged;
154+
mVertexArrayBindingHasChanged = false;
155+
commandBuffer = graphNode->getInsideRenderPassCommands();
200156
}
201157

202158
// Ensure any writes to the textures are flushed before we read from them.
@@ -224,9 +180,6 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
224180
}
225181

226182
commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline->get());
227-
ANGLE_TRY(vkVAO->streamVertexData(context, &mDynamicVertexData, drawCallParams));
228-
commandBuffer->bindVertexBuffers(0, maxAttrib, vkVAO->getCurrentArrayBufferHandles().data(),
229-
vkVAO->getCurrentArrayBufferOffsets().data());
230183

231184
// Update the queue serial for the pipeline object.
232185
ASSERT(mCurrentPipeline && mCurrentPipeline->valid());
@@ -251,27 +204,21 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
251204
programVk->getDynamicOffsets());
252205
}
253206

254-
*commandBufferOut = commandBuffer;
207+
*drawNodeOut = graphNode;
255208
return gl::NoError();
256209
}
257210

258211
gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
259212
{
260213
const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
261214

262-
vk::CommandBuffer *commandBuffer = nullptr;
263-
ANGLE_TRY(setupDraw(context, drawCallParams, nullptr, &commandBuffer));
215+
vk::CommandGraphNode *drawNode = nullptr;
216+
bool newCommands = false;
217+
ANGLE_TRY(setupDraw(context, drawCallParams, &drawNode, &newCommands));
264218

265-
if (mode == GL_LINE_LOOP)
266-
{
267-
ANGLE_TRY(mLineLoopHandler.createIndexBuffer(this, first, count));
268-
mLineLoopHandler.bindIndexBuffer(VK_INDEX_TYPE_UINT32, &commandBuffer);
269-
ANGLE_TRY(mLineLoopHandler.draw(count, commandBuffer));
270-
}
271-
else
272-
{
273-
commandBuffer->draw(count, 1, first, 0);
274-
}
219+
const gl::VertexArray *vertexArray = context->getGLState().getVertexArray();
220+
VertexArrayVk *vertexArrayVk = vk::GetImpl(vertexArray);
221+
ANGLE_TRY(vertexArrayVk->drawArrays(context, mRenderer, drawCallParams, drawNode, newCommands));
275222

276223
return gl::NoError();
277224
}
@@ -294,80 +241,14 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
294241
{
295242
const gl::DrawCallParams &drawCallParams = context->getParams<gl::DrawCallParams>();
296243

297-
gl::VertexArray *vao = mState.getState().getVertexArray();
298-
const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
299-
vk::CommandBuffer *commandBuffer = nullptr;
300-
301-
if (mode == GL_LINE_LOOP)
302-
{
303-
if (!elementArrayBuffer)
304-
{
305-
UNIMPLEMENTED();
306-
return gl::InternalError() << "Line loop indices in client memory not supported";
307-
}
308-
309-
BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
310-
311-
ANGLE_TRY(mLineLoopHandler.createIndexBufferFromElementArrayBuffer(
312-
this, elementArrayBufferVk, GetVkIndexType(type), count));
313-
314-
// TODO(fjhenigman): calculate the index range and pass to setupDraw()
315-
ANGLE_TRY(setupDraw(context, drawCallParams, mLineLoopHandler.getLineLoopBufferResource(),
316-
&commandBuffer));
317-
318-
mLineLoopHandler.bindIndexBuffer(GetVkIndexType(type), &commandBuffer);
319-
commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0);
320-
}
321-
else
322-
{
323-
ContextVk *contextVk = vk::GetImpl(context);
324-
gl::IndexRange range;
325-
VkBuffer buffer = VK_NULL_HANDLE;
326-
uint32_t offset = 0;
327-
328-
if (elementArrayBuffer)
329-
{
330-
if (type == GL_UNSIGNED_BYTE)
331-
{
332-
// TODO(fjhenigman): Index format translation.
333-
UNIMPLEMENTED();
334-
return gl::InternalError() << "Unsigned byte translation is not implemented for "
335-
<< "indices in a buffer object";
336-
}
337-
338-
BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
339-
buffer = elementArrayBufferVk->getVkBuffer().getHandle();
340-
offset = 0;
341-
}
342-
else
343-
{
344-
const GLsizei amount = sizeof(GLushort) * count;
345-
GLubyte *dst = nullptr;
346-
347-
ANGLE_TRY(
348-
mDynamicIndexData.allocate(contextVk, amount, &dst, &buffer, &offset, nullptr));
349-
if (type == GL_UNSIGNED_BYTE)
350-
{
351-
// Unsigned bytes don't have direct support in Vulkan so we have to expand the
352-
// memory to a GLushort.
353-
const GLubyte *in = static_cast<const GLubyte *>(indices);
354-
GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
355-
for (GLsizei index = 0; index < count; index++)
356-
{
357-
expandedDst[index] = static_cast<GLushort>(in[index]);
358-
}
359-
}
360-
else
361-
{
362-
memcpy(dst, indices, amount);
363-
}
364-
ANGLE_TRY(mDynamicIndexData.flush(contextVk));
365-
}
244+
vk::CommandGraphNode *drawNode = nullptr;
245+
bool newCommands = false;
246+
ANGLE_TRY(setupDraw(context, drawCallParams, &drawNode, &newCommands));
366247

367-
ANGLE_TRY(setupDraw(context, drawCallParams, nullptr, &commandBuffer));
368-
commandBuffer->bindIndexBuffer(buffer, offset, GetVkIndexType(type));
369-
commandBuffer->drawIndexed(count, 1, 0, 0, 0);
370-
}
248+
gl::VertexArray *vao = mState.getState().getVertexArray();
249+
VertexArrayVk *vertexArrayVk = vk::GetImpl(vao);
250+
ANGLE_TRY(
251+
vertexArrayVk->drawElements(context, mRenderer, drawCallParams, drawNode, newCommands));
371252

372253
return gl::NoError();
373254
}
@@ -636,7 +517,8 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits
636517
WARN() << "DIRTY_BIT_RENDERBUFFER_BINDING unimplemented";
637518
break;
638519
case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
639-
mVertexArrayDirty = true;
520+
invalidateCurrentPipeline();
521+
mVertexArrayBindingHasChanged = true;
640522
break;
641523
case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
642524
WARN() << "DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING unimplemented";
@@ -823,13 +705,6 @@ void ContextVk::invalidateCurrentPipeline()
823705
mCurrentPipeline = nullptr;
824706
}
825707

826-
void ContextVk::onVertexArrayChange()
827-
{
828-
// TODO(jmadill): Does not handle dependent state changes.
829-
mVertexArrayDirty = true;
830-
invalidateCurrentPipeline();
831-
}
832-
833708
gl::Error ContextVk::dispatchCompute(const gl::Context *context,
834709
GLuint numGroupsX,
835710
GLuint numGroupsY,

src/libANGLE/renderer/vulkan/ContextVk.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ class ContextVk : public ContextImpl
155155
RendererVk *getRenderer() { return mRenderer; }
156156

157157
void invalidateCurrentPipeline();
158-
void onVertexArrayChange();
159158

160159
DynamicDescriptorPool *getDynamicDescriptorPool();
161160

@@ -167,8 +166,8 @@ class ContextVk : public ContextImpl
167166
gl::Error initPipeline(const gl::Context *context);
168167
gl::Error setupDraw(const gl::Context *context,
169168
const gl::DrawCallParams &drawCallParams,
170-
ResourceVk *elementArrayBufferOverride,
171-
vk::CommandBuffer **commandBufferOut);
169+
vk::CommandGraphNode **drawNodeOut,
170+
bool *newCommandBufferOut);
172171

173172
RendererVk *mRenderer;
174173
vk::PipelineAndSerial *mCurrentPipeline;
@@ -183,17 +182,12 @@ class ContextVk : public ContextImpl
183182
DynamicDescriptorPool mDynamicDescriptorPool;
184183

185184
// Triggers adding dependencies to the command graph.
186-
bool mVertexArrayDirty;
187185
bool mTexturesDirty;
186+
bool mVertexArrayBindingHasChanged;
188187

189188
// Cached clear value for color and depth/stencil.
190189
VkClearValue mClearColorValue;
191190
VkClearValue mClearDepthStencilValue;
192-
193-
DynamicBuffer mDynamicVertexData;
194-
DynamicBuffer mDynamicIndexData;
195-
196-
vk::LineLoopHandler mLineLoopHandler;
197191
};
198192

199193
} // namespace rx

src/libANGLE/renderer/vulkan/DynamicBuffer.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,15 @@ bool DynamicBuffer::valid()
4444
return mAlignment > 0;
4545
}
4646

47-
vk::Error DynamicBuffer::allocate(ContextVk *context,
47+
vk::Error DynamicBuffer::allocate(RendererVk *renderer,
4848
size_t sizeInBytes,
4949
uint8_t **ptrOut,
5050
VkBuffer *handleOut,
5151
uint32_t *offsetOut,
5252
bool *outNewBufferAllocated)
5353
{
5454
ASSERT(valid());
55-
RendererVk *renderer = context->getRenderer();
56-
57-
// TODO(fjhenigman): Update this when we have buffers that need to
58-
// persist longer than one frame.
59-
updateQueueSerial(renderer->getCurrentQueueSerial());
55+
VkDevice device = renderer->getDevice();
6056

6157
size_t sizeToAllocate = roundUp(sizeInBytes, mAlignment);
6258

@@ -65,16 +61,15 @@ vk::Error DynamicBuffer::allocate(ContextVk *context,
6561

6662
if (!checkedNextWriteOffset.IsValid() || checkedNextWriteOffset.ValueOrDie() > mSize)
6763
{
68-
VkDevice device = context->getDevice();
69-
7064
if (mMappedMemory)
7165
{
72-
ANGLE_TRY(flush(context));
66+
ANGLE_TRY(flush(device));
7367
mMemory.unmap(device);
7468
mMappedMemory = nullptr;
7569
}
76-
renderer->releaseResource(*this, &mBuffer);
77-
renderer->releaseResource(*this, &mMemory);
70+
Serial currentSerial = renderer->getCurrentQueueSerial();
71+
renderer->releaseObject(currentSerial, &mBuffer);
72+
renderer->releaseObject(currentSerial, &mMemory);
7873

7974
VkBufferCreateInfo createInfo;
8075
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@@ -121,7 +116,7 @@ vk::Error DynamicBuffer::allocate(ContextVk *context,
121116
return vk::NoError();
122117
}
123118

124-
vk::Error DynamicBuffer::flush(ContextVk *context)
119+
vk::Error DynamicBuffer::flush(VkDevice device)
125120
{
126121
if (mNextWriteOffset > mLastFlushOffset)
127122
{
@@ -131,7 +126,7 @@ vk::Error DynamicBuffer::flush(ContextVk *context)
131126
range.memory = mMemory.getHandle();
132127
range.offset = mLastFlushOffset;
133128
range.size = mNextWriteOffset - mLastFlushOffset;
134-
ANGLE_VK_TRY(vkFlushMappedMemoryRanges(context->getDevice(), 1, &range));
129+
ANGLE_VK_TRY(vkFlushMappedMemoryRanges(device, 1, &range));
135130

136131
mLastFlushOffset = mNextWriteOffset;
137132
}

src/libANGLE/renderer/vulkan/DynamicBuffer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@ class DynamicBuffer : public ResourceVk
2020
{
2121
public:
2222
DynamicBuffer(VkBufferUsageFlags usage, size_t minSize);
23+
~DynamicBuffer();
24+
2325
void init(size_t alignment);
2426
bool valid();
25-
~DynamicBuffer();
26-
vk::Error allocate(ContextVk *context,
27+
vk::Error allocate(RendererVk *renderer,
2728
size_t sizeInBytes,
2829
uint8_t **ptrOut,
2930
VkBuffer *handleOut,
3031
uint32_t *offsetOut,
3132
bool *outNewBufferAllocated);
32-
vk::Error flush(ContextVk *context);
33+
vk::Error flush(VkDevice device);
3334
void destroy(VkDevice device);
3435
VkBuffer getCurrentBufferHandle() const;
3536

0 commit comments

Comments
 (0)