3838
3939namespace 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-
6541ContextVk::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
8153ContextVk::~ContextVk ()
@@ -84,12 +56,7 @@ ContextVk::~ContextVk()
8456
8557void 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
9562gl::Error ContextVk::initialize ()
@@ -149,8 +116,8 @@ gl::Error ContextVk::initPipeline(const gl::Context *context)
149116
150117gl::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
258211gl::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-
833708gl::Error ContextVk::dispatchCompute (const gl::Context *context,
834709 GLuint numGroupsX,
835710 GLuint numGroupsY,
0 commit comments