blob: 9a25dad81609df7b7b360b06cab62b8425272bf6 [file] [log] [blame]
Alexis Hetu767b41b2018-09-26 11:25:46 -04001// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "VkCommandBuffer.hpp"
Alexis Hetuc65473d2018-12-07 16:26:05 -050016#include "VkBuffer.hpp"
Alexis Hetu3f5a4792019-02-01 17:49:55 -050017#include "VkEvent.hpp"
Alexis Hetu9bc7a812018-12-07 16:13:34 -050018#include "VkFramebuffer.hpp"
Alexis Hetu09056de2018-12-07 12:40:00 -050019#include "VkImage.hpp"
Chris Forbes7c33e882019-02-21 14:58:28 -080020#include "VkImageView.hpp"
Alexis Hetuc65473d2018-12-07 16:26:05 -050021#include "VkPipeline.hpp"
Ben Claytonf2be26a2019-03-08 12:02:05 +000022#include "VkPipelineLayout.hpp"
Alexis Hetuf0aa9d52019-04-01 17:06:47 -040023#include "VkQueryPool.hpp"
Chris Forbes50dd2ce2018-12-07 17:54:31 -080024#include "VkRenderPass.hpp"
Alexis Hetuc65473d2018-12-07 16:26:05 -050025#include "Device/Renderer.hpp"
Alexis Hetu767b41b2018-09-26 11:25:46 -040026
Chris Forbesf8374cf2018-12-06 13:25:59 -080027#include <cstring>
28
Alexis Hetu767b41b2018-09-26 11:25:46 -040029namespace vk
30{
31
Alexis Hetu072dc0d2018-10-31 11:41:25 -040032class CommandBuffer::Command
33{
34public:
35 // FIXME (b/119421344): change the commandBuffer argument to a CommandBuffer state
Alexis Hetu9bc7a812018-12-07 16:13:34 -050036 virtual void play(CommandBuffer::ExecutionState& executionState) = 0;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040037 virtual ~Command() {}
38};
39
40class BeginRenderPass : public CommandBuffer::Command
41{
42public:
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050043 BeginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
44 uint32_t clearValueCount, const VkClearValue* pClearValues) :
45 renderPass(Cast(renderPass)), framebuffer(Cast(framebuffer)), renderArea(renderArea),
46 clearValueCount(clearValueCount)
Alexis Hetu072dc0d2018-10-31 11:41:25 -040047 {
48 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
49 clearValues = new VkClearValue[clearValueCount];
50 memcpy(clearValues, pClearValues, clearValueCount * sizeof(VkClearValue));
51 }
52
53 ~BeginRenderPass() override
54 {
Chris Forbesf04b56f2018-12-28 16:06:16 -080055 delete [] clearValues;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040056 }
57
58protected:
Ben Clayton93317ec2019-02-20 08:53:50 +000059 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -040060 {
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050061 executionState.renderPass = renderPass;
62 executionState.renderPassFramebuffer = framebuffer;
63 renderPass->begin();
Alexis Hetu54ec7592019-03-20 14:37:16 -040064 framebuffer->clear(executionState.renderPass, clearValueCount, clearValues, renderArea);
Alexis Hetu072dc0d2018-10-31 11:41:25 -040065 }
66
67private:
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050068 RenderPass* renderPass;
69 Framebuffer* framebuffer;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040070 VkRect2D renderArea;
71 uint32_t clearValueCount;
72 VkClearValue* clearValues;
73};
74
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050075class NextSubpass : public CommandBuffer::Command
76{
77public:
78 NextSubpass()
79 {
80 }
81
82protected:
Ben Clayton93317ec2019-02-20 08:53:50 +000083 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050084 {
Alexis Hetu54ec7592019-03-20 14:37:16 -040085 bool hasResolveAttachments = (executionState.renderPass->getCurrentSubpass().pResolveAttachments != nullptr);
86 if(hasResolveAttachments)
87 {
88 // FIXME(sugoi): remove the following lines and resolve in Renderer::finishRendering()
89 // for a Draw command or after the last command of the current subpass
90 // which modifies pixels.
91 executionState.renderer->synchronize();
92 executionState.renderPassFramebuffer->resolve(executionState.renderPass);
93 }
94
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050095 executionState.renderPass->nextSubpass();
96 }
97
98private:
99};
100
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400101class EndRenderPass : public CommandBuffer::Command
102{
103public:
104 EndRenderPass()
105 {
106 }
107
108protected:
Ben Clayton93317ec2019-02-20 08:53:50 +0000109 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400110 {
Chris Forbesfc06fd12019-03-21 08:36:11 -0700111 // Execute (implicit or explicit) VkSubpassDependency to VK_SUBPASS_EXTERNAL
112 // This is somewhat heavier than the actual ordering required.
113 executionState.renderer->synchronize();
Alexis Hetu54ec7592019-03-20 14:37:16 -0400114
115 // FIXME(sugoi): remove the following line and resolve in Renderer::finishRendering()
116 // for a Draw command or after the last command of the current subpass
117 // which modifies pixels.
118 executionState.renderPassFramebuffer->resolve(executionState.renderPass);
119
120 executionState.renderPass->end();
121 executionState.renderPass = nullptr;
122 executionState.renderPassFramebuffer = nullptr;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400123 }
124
125private:
126};
127
Alexis Hetue7b2a052019-03-18 16:16:36 -0400128class ExecuteCommands : public CommandBuffer::Command
129{
130public:
131 ExecuteCommands(const VkCommandBuffer& commandBuffer) : commandBuffer(commandBuffer)
132 {
133 }
134
135protected:
136 void play(CommandBuffer::ExecutionState& executionState) override
137 {
138 Cast(commandBuffer)->submitSecondary(executionState);
139 }
140
141private:
142 const VkCommandBuffer commandBuffer;
143};
144
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400145class PipelineBind : public CommandBuffer::Command
146{
147public:
148 PipelineBind(VkPipelineBindPoint pPipelineBindPoint, VkPipeline pPipeline) :
149 pipelineBindPoint(pPipelineBindPoint), pipeline(pPipeline)
150 {
151 }
152
153protected:
Ben Clayton93317ec2019-02-20 08:53:50 +0000154 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400155 {
Ben Clayton225a1302019-04-02 12:28:22 +0100156 executionState.pipelineState[pipelineBindPoint].pipeline = Cast(pipeline);
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400157 }
158
159private:
160 VkPipelineBindPoint pipelineBindPoint;
161 VkPipeline pipeline;
162};
163
Ben Claytonf2be26a2019-03-08 12:02:05 +0000164class Dispatch : public CommandBuffer::Command
165{
166public:
167 Dispatch(uint32_t pGroupCountX, uint32_t pGroupCountY, uint32_t pGroupCountZ) :
168 groupCountX(pGroupCountX), groupCountY(pGroupCountY), groupCountZ(pGroupCountZ)
169 {
170 }
171
172protected:
173 void play(CommandBuffer::ExecutionState& executionState) override
174 {
Ben Clayton225a1302019-04-02 12:28:22 +0100175 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_COMPUTE];
176
177 ComputePipeline* pipeline = static_cast<ComputePipeline*>(pipelineState.pipeline);
Ben Claytonf2be26a2019-03-08 12:02:05 +0000178 pipeline->run(groupCountX, groupCountY, groupCountZ,
Ben Clayton225a1302019-04-02 12:28:22 +0100179 pipelineState.descriptorSets,
180 pipelineState.descriptorDynamicOffsets,
Chris Forbesa30de542019-03-18 18:51:55 -0700181 executionState.pushConstants);
Ben Claytonf2be26a2019-03-08 12:02:05 +0000182 }
183
184private:
185 uint32_t groupCountX;
186 uint32_t groupCountY;
187 uint32_t groupCountZ;
188};
189
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700190class DispatchIndirect : public CommandBuffer::Command
191{
192public:
193 DispatchIndirect(VkBuffer buffer, VkDeviceSize offset) :
194 buffer(buffer), offset(offset)
195 {
196 }
197
198protected:
199 void play(CommandBuffer::ExecutionState& executionState) override
200 {
201 auto cmd = reinterpret_cast<VkDispatchIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset));
202
Ben Clayton225a1302019-04-02 12:28:22 +0100203 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_COMPUTE];
204
205 ComputePipeline* pipeline = static_cast<ComputePipeline*>(pipelineState.pipeline);
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700206 pipeline->run(cmd->x, cmd->y, cmd->z,
Ben Clayton225a1302019-04-02 12:28:22 +0100207 pipelineState.descriptorSets,
208 pipelineState.descriptorDynamicOffsets,
209 executionState.pushConstants);
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700210 }
211
212private:
213 VkBuffer buffer;
214 VkDeviceSize offset;
215};
216
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400217struct VertexBufferBind : public CommandBuffer::Command
218{
219 VertexBufferBind(uint32_t pBinding, const VkBuffer pBuffer, const VkDeviceSize pOffset) :
220 binding(pBinding), buffer(pBuffer), offset(pOffset)
221 {
222 }
223
Ben Clayton93317ec2019-02-20 08:53:50 +0000224 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400225 {
Alexis Hetu9bc7a812018-12-07 16:13:34 -0500226 executionState.vertexInputBindings[binding] = { buffer, offset };
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400227 }
228
229 uint32_t binding;
230 const VkBuffer buffer;
231 const VkDeviceSize offset;
232};
233
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800234struct IndexBufferBind : public CommandBuffer::Command
235{
236 IndexBufferBind(const VkBuffer buffer, const VkDeviceSize offset, const VkIndexType indexType) :
237 buffer(buffer), offset(offset), indexType(indexType)
238 {
239
240 }
241
242 void play(CommandBuffer::ExecutionState& executionState) override
243 {
244 executionState.indexBufferBinding = {buffer, offset};
245 executionState.indexType = indexType;
246 }
247
248 const VkBuffer buffer;
249 const VkDeviceSize offset;
250 const VkIndexType indexType;
251};
252
Alexis Hetu73832432019-04-11 16:43:18 -0400253struct SetViewport : public CommandBuffer::Command
254{
255 SetViewport(const VkViewport& viewport, uint32_t viewportID) :
256 viewport(viewport), viewportID(viewportID)
257 {
258 }
259
260 void play(CommandBuffer::ExecutionState& executionState) override
261 {
262 executionState.dynamicState.viewport = viewport;
263 }
264
265 const VkViewport viewport;
266 uint32_t viewportID;
267};
268
269struct SetScissor : public CommandBuffer::Command
270{
271 SetScissor(const VkRect2D& scissor, uint32_t scissorID) :
272 scissor(scissor), scissorID(scissorID)
273 {
274 }
275
276 void play(CommandBuffer::ExecutionState& executionState) override
277 {
278 executionState.dynamicState.scissor = scissor;
279 }
280
281 const VkRect2D scissor;
282 uint32_t scissorID;
283};
284
285struct SetDepthBias : public CommandBuffer::Command
286{
287 SetDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor) :
288 depthBiasConstantFactor(depthBiasConstantFactor), depthBiasClamp(depthBiasClamp), depthBiasSlopeFactor(depthBiasSlopeFactor)
289 {
290 }
291
292 void play(CommandBuffer::ExecutionState& executionState) override
293 {
294 executionState.dynamicState.depthBiasConstantFactor = depthBiasConstantFactor;
295 executionState.dynamicState.depthBiasClamp = depthBiasClamp;
296 executionState.dynamicState.depthBiasSlopeFactor = depthBiasSlopeFactor;
297 }
298
299 float depthBiasConstantFactor;
300 float depthBiasClamp;
301 float depthBiasSlopeFactor;
302};
303
304struct SetBlendConstants : public CommandBuffer::Command
305{
306 SetBlendConstants(const float blendConstants[4])
307 {
308 memcpy(this->blendConstants, blendConstants, sizeof(this->blendConstants));
309 }
310
311 void play(CommandBuffer::ExecutionState& executionState) override
312 {
313 memcpy(&(executionState.dynamicState.blendConstants[0]), blendConstants, sizeof(blendConstants));
314 }
315
316 float blendConstants[4];
317};
318
319struct SetDepthBounds : public CommandBuffer::Command
320{
321 SetDepthBounds(float minDepthBounds, float maxDepthBounds) :
322 minDepthBounds(minDepthBounds), maxDepthBounds(maxDepthBounds)
323 {
324 }
325
326 void play(CommandBuffer::ExecutionState& executionState) override
327 {
328 executionState.dynamicState.minDepthBounds = minDepthBounds;
329 executionState.dynamicState.maxDepthBounds = maxDepthBounds;
330 }
331
332 float minDepthBounds;
333 float maxDepthBounds;
334};
335struct SetStencilCompareMask : public CommandBuffer::Command
336{
337 SetStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask) :
338 faceMask(faceMask), compareMask(compareMask)
339 {
340 }
341
342 void play(CommandBuffer::ExecutionState& executionState) override
343 {
344 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
345 {
346 executionState.dynamicState.compareMask[0] = compareMask;
347 }
348 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
349 {
350 executionState.dynamicState.compareMask[1] = compareMask;
351 }
352 }
353
354 VkStencilFaceFlags faceMask;
355 uint32_t compareMask;
356};
357
358struct SetStencilWriteMask : public CommandBuffer::Command
359{
360 SetStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask) :
361 faceMask(faceMask), writeMask(writeMask)
362 {
363 }
364
365 void play(CommandBuffer::ExecutionState& executionState) override
366 {
367 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
368 {
369 executionState.dynamicState.writeMask[0] = writeMask;
370 }
371 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
372 {
373 executionState.dynamicState.writeMask[1] = writeMask;
374 }
375 }
376
377 VkStencilFaceFlags faceMask;
378 uint32_t writeMask;
379};
380
381struct SetStencilReference : public CommandBuffer::Command
382{
383 SetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference) :
384 faceMask(faceMask), reference(reference)
385 {
386 }
387
388 void play(CommandBuffer::ExecutionState& executionState) override
389 {
390 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
391 {
392 executionState.dynamicState.reference[0] = reference;
393 }
394 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
395 {
396 executionState.dynamicState.reference[1] = reference;
397 }
398 }
399
400 VkStencilFaceFlags faceMask;
401 uint32_t reference;
402};
403
Chris Forbese1cf8632019-03-08 18:17:35 -0800404void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context& context, int firstVertex, int firstInstance)
Chris Forbes00ba1762019-03-08 17:10:41 -0800405{
406 for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
407 {
408 auto &attrib = context.input[i];
409 if (attrib.count)
410 {
411 const auto &vertexInput = vertexInputBindings[attrib.binding];
412 Buffer *buffer = Cast(vertexInput.buffer);
413 attrib.buffer = buffer ? buffer->getOffsetPointer(
Chris Forbese1cf8632019-03-08 18:17:35 -0800414 attrib.offset + vertexInput.offset + attrib.vertexStride * firstVertex + attrib.instanceStride * firstInstance) : nullptr;
Chris Forbes00ba1762019-03-08 17:10:41 -0800415 }
416 }
417}
418
Chris Forbes2995dc22019-03-02 14:57:20 -0800419void CommandBuffer::ExecutionState::bindAttachments()
420{
421 // Binds all the attachments for the current subpass
422 // Ideally this would be performed by BeginRenderPass and NextSubpass, but
423 // there is too much stomping of the renderer's state by setContext() in
424 // draws.
425
426 for (auto i = 0u; i < renderPass->getCurrentSubpass().colorAttachmentCount; i++)
427 {
428 auto attachmentReference = renderPass->getCurrentSubpass().pColorAttachments[i];
429 if (attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
430 {
431 auto attachment = renderPassFramebuffer->getAttachment(attachmentReference.attachment);
Chris Forbes37f2bd82019-04-19 17:24:36 -0700432 renderer->setRenderTarget(i, attachment);
Chris Forbes2995dc22019-03-02 14:57:20 -0800433 }
434 }
435
436 auto attachmentReference = renderPass->getCurrentSubpass().pDepthStencilAttachment;
437 if (attachmentReference && attachmentReference->attachment != VK_ATTACHMENT_UNUSED)
438 {
439 auto attachment = renderPassFramebuffer->getAttachment(attachmentReference->attachment);
440 if (attachment->hasDepthAspect())
441 {
Chris Forbes37f2bd82019-04-19 17:24:36 -0700442 renderer->setDepthBuffer(attachment);
Chris Forbes2995dc22019-03-02 14:57:20 -0800443 }
444 if (attachment->hasStencilAspect())
445 {
Chris Forbes37f2bd82019-04-19 17:24:36 -0700446 renderer->setStencilBuffer(attachment);
Chris Forbes2995dc22019-03-02 14:57:20 -0800447 }
448 }
449}
450
Chris Forbes48b35872019-03-22 14:12:50 -0700451struct DrawBase : public CommandBuffer::Command
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400452{
Chris Forbes48b35872019-03-22 14:12:50 -0700453 int bytesPerIndex(CommandBuffer::ExecutionState const& executionState)
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400454 {
Chris Forbes48b35872019-03-22 14:12:50 -0700455 return executionState.indexType == VK_INDEX_TYPE_UINT16 ? 2 : 4;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400456 }
457
Chris Forbes48b35872019-03-22 14:12:50 -0700458 void draw(CommandBuffer::ExecutionState& executionState, bool indexed,
459 uint32_t count, uint32_t instanceCount, uint32_t first, int32_t vertexOffset, uint32_t firstInstance)
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800460 {
Ben Clayton225a1302019-04-02 12:28:22 +0100461 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_GRAPHICS];
462
463 GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>(pipelineState.pipeline);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800464
465 sw::Context context = pipeline->getContext();
Chris Forbese1cf8632019-03-08 18:17:35 -0800466
467 executionState.bindVertexInputs(context, vertexOffset, firstInstance);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800468
Ben Clayton225a1302019-04-02 12:28:22 +0100469 context.descriptorSets = pipelineState.descriptorSets;
470 context.descriptorDynamicOffsets = pipelineState.descriptorDynamicOffsets;
Chris Forbesa30de542019-03-18 18:51:55 -0700471 context.pushConstants = executionState.pushConstants;
472
Alexis Hetu73832432019-04-11 16:43:18 -0400473 if(indexed)
Chris Forbes48b35872019-03-22 14:12:50 -0700474 {
475 context.indexBuffer = Cast(executionState.indexBufferBinding.buffer)->getOffsetPointer(
476 executionState.indexBufferBinding.offset + first * bytesPerIndex(executionState));
Chris Forbes48b35872019-03-22 14:12:50 -0700477 }
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800478
Alexis Hetu73832432019-04-11 16:43:18 -0400479 // Apply either pipeline state or dynamic state
480 executionState.renderer->setScissor(pipeline->hasDynamicState(VK_DYNAMIC_STATE_SCISSOR) ?
481 executionState.dynamicState.scissor : pipeline->getScissor());
482 executionState.renderer->setViewport(pipeline->hasDynamicState(VK_DYNAMIC_STATE_VIEWPORT) ?
483 executionState.dynamicState.viewport : pipeline->getViewport());
484 executionState.renderer->setBlendConstant(pipeline->hasDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS) ?
485 executionState.dynamicState.blendConstants : pipeline->getBlendConstants());
486 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS))
487 {
488 // If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0
489 ASSERT(executionState.dynamicState.depthBiasClamp == 0.0f);
490
491 context.depthBias = executionState.dynamicState.depthBiasConstantFactor;
492 context.slopeDepthBias = executionState.dynamicState.depthBiasSlopeFactor;
493 }
494 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS) && context.depthBoundsTestEnable)
495 {
496 // Unless the VK_EXT_depth_range_unrestricted extension is enabled minDepthBounds and maxDepthBounds must be between 0.0 and 1.0, inclusive
497 ASSERT(executionState.dynamicState.minDepthBounds >= 0.0f && executionState.dynamicState.minDepthBounds <= 1.0f);
498 ASSERT(executionState.dynamicState.maxDepthBounds >= 0.0f && executionState.dynamicState.maxDepthBounds <= 1.0f);
499
500 UNIMPLEMENTED("depthBoundsTestEnable");
501 }
502 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) && context.stencilEnable)
503 {
504 context.frontStencil.compareMask = executionState.dynamicState.compareMask[0];
505 context.backStencil.compareMask = executionState.dynamicState.compareMask[1];
506 }
507 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK) && context.stencilEnable)
508 {
509 context.frontStencil.writeMask = executionState.dynamicState.writeMask[0];
510 context.backStencil.writeMask = executionState.dynamicState.writeMask[1];
511 }
512 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE) && context.stencilEnable)
513 {
514 context.frontStencil.reference = executionState.dynamicState.reference[0];
515 context.backStencil.reference = executionState.dynamicState.reference[1];
516 }
517
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800518 executionState.renderer->setContext(context);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800519
Chris Forbes2995dc22019-03-02 14:57:20 -0800520 executionState.bindAttachments();
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800521
Chris Forbes48b35872019-03-22 14:12:50 -0700522 const uint32_t primitiveCount = pipeline->computePrimitiveCount(count);
Chris Forbese1cf8632019-03-08 18:17:35 -0800523 for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++)
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800524 {
525 executionState.renderer->setInstanceID(instance);
Chris Forbesd4e5e9e2019-04-15 12:43:38 -0700526 executionState.renderer->draw(context.topology, executionState.indexType, primitiveCount, vertexOffset);
Chris Forbese1cf8632019-03-08 18:17:35 -0800527 executionState.renderer->advanceInstanceAttributes();
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800528 }
529 }
Chris Forbes48b35872019-03-22 14:12:50 -0700530};
531
532struct Draw : public DrawBase
533{
534 Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
535 : vertexCount(vertexCount), instanceCount(instanceCount), firstVertex(firstVertex), firstInstance(firstInstance)
536 {
537 }
538
539 void play(CommandBuffer::ExecutionState& executionState) override
540 {
541 draw(executionState, false, vertexCount, instanceCount, 0, firstVertex, firstInstance);
542 }
543
544 uint32_t vertexCount;
545 uint32_t instanceCount;
546 uint32_t firstVertex;
547 uint32_t firstInstance;
548};
549
550struct DrawIndexed : public DrawBase
551{
552 DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
553 : indexCount(indexCount), instanceCount(instanceCount), firstIndex(firstIndex), vertexOffset(vertexOffset), firstInstance(firstInstance)
554 {
555 }
556
557 void play(CommandBuffer::ExecutionState& executionState) override
558 {
559 draw(executionState, true, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
560 }
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800561
562 uint32_t indexCount;
563 uint32_t instanceCount;
564 uint32_t firstIndex;
565 int32_t vertexOffset;
566 uint32_t firstInstance;
567};
568
Chris Forbes48b35872019-03-22 14:12:50 -0700569struct DrawIndirect : public DrawBase
570{
571 DrawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
572 : buffer(buffer), offset(offset), drawCount(drawCount), stride(stride)
573 {
574 }
575
576 void play(CommandBuffer::ExecutionState& executionState) override
577 {
578 for (auto drawId = 0u; drawId < drawCount; drawId++)
579 {
580 auto cmd = reinterpret_cast<VkDrawIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset + drawId * stride));
581 draw(executionState, false, cmd->vertexCount, cmd->instanceCount, 0, cmd->firstVertex, cmd->firstInstance);
582 }
583 }
584
585 VkBuffer buffer;
586 VkDeviceSize offset;
587 uint32_t drawCount;
588 uint32_t stride;
589};
590
591struct DrawIndexedIndirect : public DrawBase
592{
593 DrawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
594 : buffer(buffer), offset(offset), drawCount(drawCount), stride(stride)
595 {
596 }
597
598 void play(CommandBuffer::ExecutionState& executionState) override
599 {
600 for (auto drawId = 0u; drawId < drawCount; drawId++)
601 {
602 auto cmd = reinterpret_cast<VkDrawIndexedIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset + drawId * stride));
603 draw(executionState, true, cmd->indexCount, cmd->instanceCount, cmd->firstIndex, cmd->vertexOffset, cmd->firstInstance);
604 }
605 }
606
607 VkBuffer buffer;
608 VkDeviceSize offset;
609 uint32_t drawCount;
610 uint32_t stride;
611};
612
Alexis Hetu09056de2018-12-07 12:40:00 -0500613struct ImageToImageCopy : public CommandBuffer::Command
614{
615 ImageToImageCopy(VkImage pSrcImage, VkImage pDstImage, const VkImageCopy& pRegion) :
616 srcImage(pSrcImage), dstImage(pDstImage), region(pRegion)
617 {
618 }
619
Ben Clayton93317ec2019-02-20 08:53:50 +0000620 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu09056de2018-12-07 12:40:00 -0500621 {
622 Cast(srcImage)->copyTo(dstImage, region);
623 }
624
625private:
626 VkImage srcImage;
627 VkImage dstImage;
628 const VkImageCopy region;
629};
630
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500631struct BufferToBufferCopy : public CommandBuffer::Command
632{
633 BufferToBufferCopy(VkBuffer pSrcBuffer, VkBuffer pDstBuffer, const VkBufferCopy& pRegion) :
634 srcBuffer(pSrcBuffer), dstBuffer(pDstBuffer), region(pRegion)
635 {
636 }
637
Ben Clayton93317ec2019-02-20 08:53:50 +0000638 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500639 {
640 Cast(srcBuffer)->copyTo(Cast(dstBuffer), region);
641 }
642
643private:
644 VkBuffer srcBuffer;
645 VkBuffer dstBuffer;
646 const VkBufferCopy region;
647};
648
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400649struct ImageToBufferCopy : public CommandBuffer::Command
650{
651 ImageToBufferCopy(VkImage pSrcImage, VkBuffer pDstBuffer, const VkBufferImageCopy& pRegion) :
652 srcImage(pSrcImage), dstBuffer(pDstBuffer), region(pRegion)
653 {
654 }
655
Ben Clayton93317ec2019-02-20 08:53:50 +0000656 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400657 {
Alexis Hetu09056de2018-12-07 12:40:00 -0500658 Cast(srcImage)->copyTo(dstBuffer, region);
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400659 }
660
661private:
662 VkImage srcImage;
663 VkBuffer dstBuffer;
664 const VkBufferImageCopy region;
665};
666
Alexis Hetu09056de2018-12-07 12:40:00 -0500667struct BufferToImageCopy : public CommandBuffer::Command
668{
669 BufferToImageCopy(VkBuffer pSrcBuffer, VkImage pDstImage, const VkBufferImageCopy& pRegion) :
670 srcBuffer(pSrcBuffer), dstImage(pDstImage), region(pRegion)
671 {
672 }
673
Ben Clayton93317ec2019-02-20 08:53:50 +0000674 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu09056de2018-12-07 12:40:00 -0500675 {
676 Cast(dstImage)->copyFrom(srcBuffer, region);
677 }
678
679private:
680 VkBuffer srcBuffer;
681 VkImage dstImage;
682 const VkBufferImageCopy region;
683};
684
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500685struct FillBuffer : public CommandBuffer::Command
686{
687 FillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) :
688 dstBuffer(dstBuffer), dstOffset(dstOffset), size(size), data(data)
689 {
690 }
691
Ben Clayton93317ec2019-02-20 08:53:50 +0000692 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500693 {
694 Cast(dstBuffer)->fill(dstOffset, size, data);
695 }
696
697private:
698 VkBuffer dstBuffer;
699 VkDeviceSize dstOffset;
700 VkDeviceSize size;
701 uint32_t data;
702};
703
704struct UpdateBuffer : public CommandBuffer::Command
705{
706 UpdateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData) :
707 dstBuffer(dstBuffer), dstOffset(dstOffset), dataSize(dataSize), pData(pData)
708 {
709 }
710
Ben Clayton93317ec2019-02-20 08:53:50 +0000711 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500712 {
713 Cast(dstBuffer)->update(dstOffset, dataSize, pData);
714 }
715
716private:
717 VkBuffer dstBuffer;
718 VkDeviceSize dstOffset;
719 VkDeviceSize dataSize;
720 const void* pData;
721};
722
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500723struct ClearColorImage : public CommandBuffer::Command
Alexis Hetuf14ed322019-01-16 15:54:55 -0500724{
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500725 ClearColorImage(VkImage image, const VkClearColorValue& color, const VkImageSubresourceRange& range) :
Alexis Hetuf14ed322019-01-16 15:54:55 -0500726 image(image), color(color), range(range)
727 {
728 }
729
Ben Clayton93317ec2019-02-20 08:53:50 +0000730 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetuf14ed322019-01-16 15:54:55 -0500731 {
732 Cast(image)->clear(color, range);
733 }
734
735private:
736 VkImage image;
737 const VkClearColorValue color;
738 const VkImageSubresourceRange range;
739};
740
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500741struct ClearDepthStencilImage : public CommandBuffer::Command
742{
743 ClearDepthStencilImage(VkImage image, const VkClearDepthStencilValue& depthStencil, const VkImageSubresourceRange& range) :
744 image(image), depthStencil(depthStencil), range(range)
745 {
746 }
747
Ben Clayton93317ec2019-02-20 08:53:50 +0000748 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500749 {
750 Cast(image)->clear(depthStencil, range);
751 }
752
753private:
754 VkImage image;
755 const VkClearDepthStencilValue depthStencil;
756 const VkImageSubresourceRange range;
757};
758
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500759struct ClearAttachment : public CommandBuffer::Command
760{
761 ClearAttachment(const VkClearAttachment& attachment, const VkClearRect& rect) :
762 attachment(attachment), rect(rect)
763 {
764 }
765
Ben Clayton93317ec2019-02-20 08:53:50 +0000766 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500767 {
Chris Forbesed46cde2019-04-22 12:49:21 -0700768 // attachment clears are drawing operations, and so have rasterization-order guarantees.
769 // however, we don't do the clear through the rasterizer, so need to ensure prior drawing
770 // has completed first.
771 executionState.renderer->synchronize();
Alexis Hetu54ec7592019-03-20 14:37:16 -0400772 executionState.renderPassFramebuffer->clear(executionState.renderPass, attachment, rect);
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500773 }
774
775private:
776 const VkClearAttachment attachment;
777 const VkClearRect rect;
778};
779
Alexis Hetu809d0112018-12-17 17:00:28 -0500780struct BlitImage : public CommandBuffer::Command
781{
782 BlitImage(VkImage srcImage, VkImage dstImage, const VkImageBlit& region, VkFilter filter) :
783 srcImage(srcImage), dstImage(dstImage), region(region), filter(filter)
784 {
785 }
786
Ben Clayton93317ec2019-02-20 08:53:50 +0000787 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu809d0112018-12-17 17:00:28 -0500788 {
789 Cast(srcImage)->blit(dstImage, region, filter);
790 }
791
792private:
793 VkImage srcImage;
794 VkImage dstImage;
Ben Clayton24021a22019-02-19 11:42:31 +0000795 VkImageBlit region;
Alexis Hetu809d0112018-12-17 17:00:28 -0500796 VkFilter filter;
797};
798
Alexis Hetue5e33cd2019-04-11 10:24:52 -0400799struct ResolveImage : public CommandBuffer::Command
800{
801 ResolveImage(VkImage srcImage, VkImage dstImage, const VkImageResolve& region) :
802 srcImage(srcImage), dstImage(dstImage), region(region)
803 {
804 }
805
806 void play(CommandBuffer::ExecutionState& executionState) override
807 {
808 Cast(srcImage)->resolve(dstImage, region);
809 }
810
811private:
812 VkImage srcImage;
813 VkImage dstImage;
814 VkImageResolve region;
815};
816
Alexis Hetu9a6c28b2018-11-20 11:47:18 -0500817struct PipelineBarrier : public CommandBuffer::Command
818{
819 PipelineBarrier()
820 {
821 }
822
Ben Clayton93317ec2019-02-20 08:53:50 +0000823 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu9a6c28b2018-11-20 11:47:18 -0500824 {
Alexis Hetuead1a342019-02-26 17:03:00 -0500825 // This is a very simple implementation that simply calls sw::Renderer::synchronize(),
826 // since the driver is free to move the source stage towards the bottom of the pipe
827 // and the target stage towards the top, so a full pipeline sync is spec compliant.
828 executionState.renderer->synchronize();
Alexis Hetu9a6c28b2018-11-20 11:47:18 -0500829
830 // Right now all buffers are read-only in drawcalls but a similar mechanism will be required once we support SSBOs.
831
832 // Also note that this would be a good moment to update cube map borders or decompress compressed textures, if necessary.
833 }
834
835private:
836};
837
Alexis Hetu3f5a4792019-02-01 17:49:55 -0500838struct SignalEvent : public CommandBuffer::Command
839{
840 SignalEvent(VkEvent ev, VkPipelineStageFlags stageMask) : ev(ev), stageMask(stageMask)
841 {
842 }
843
Ben Clayton93317ec2019-02-20 08:53:50 +0000844 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu3f5a4792019-02-01 17:49:55 -0500845 {
Alexis Hetu9041bb72019-03-15 14:45:45 -0400846 if(Cast(ev)->signal())
847 {
848 // Was waiting for signal on this event, sync now
849 executionState.renderer->synchronize();
850 }
Alexis Hetu3f5a4792019-02-01 17:49:55 -0500851 }
852
853private:
854 VkEvent ev;
855 VkPipelineStageFlags stageMask; // FIXME(b/117835459) : We currently ignore the flags and signal the event at the last stage
856};
857
858struct ResetEvent : public CommandBuffer::Command
859{
860 ResetEvent(VkEvent ev, VkPipelineStageFlags stageMask) : ev(ev), stageMask(stageMask)
861 {
862 }
863
Ben Clayton93317ec2019-02-20 08:53:50 +0000864 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu3f5a4792019-02-01 17:49:55 -0500865 {
866 Cast(ev)->reset();
867 }
868
869private:
870 VkEvent ev;
871 VkPipelineStageFlags stageMask; // FIXME(b/117835459) : We currently ignore the flags and reset the event at the last stage
872};
873
Alexis Hetu9041bb72019-03-15 14:45:45 -0400874struct WaitEvent : public CommandBuffer::Command
875{
876 WaitEvent(VkEvent ev) : ev(ev)
877 {
878 }
879
880 void play(CommandBuffer::ExecutionState& executionState) override
881 {
882 if(!Cast(ev)->wait())
883 {
884 // Already signaled, sync now
885 executionState.renderer->synchronize();
886 }
887 }
888
889private:
890 VkEvent ev;
891};
892
Alexis Hetu5edafb52019-02-15 14:56:22 -0500893struct BindDescriptorSet : public CommandBuffer::Command
894{
Ben Clayton225a1302019-04-02 12:28:22 +0100895 BindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, uint32_t set, const VkDescriptorSet& descriptorSet,
896 uint32_t dynamicOffsetCount, uint32_t const *dynamicOffsets)
897 : pipelineBindPoint(pipelineBindPoint), set(set), descriptorSet(descriptorSet),
898 dynamicOffsetCount(dynamicOffsetCount)
Alexis Hetu5edafb52019-02-15 14:56:22 -0500899 {
Ben Clayton225a1302019-04-02 12:28:22 +0100900 for (uint32_t i = 0; i < dynamicOffsetCount; i++)
901 {
902 this->dynamicOffsets[i] = dynamicOffsets[i];
903 }
Alexis Hetu5edafb52019-02-15 14:56:22 -0500904 }
905
906 void play(CommandBuffer::ExecutionState& executionState)
907 {
Ben Clayton225a1302019-04-02 12:28:22 +0100908 ASSERT_OR_RETURN((pipelineBindPoint < VK_PIPELINE_BIND_POINT_RANGE_SIZE) && (set < MAX_BOUND_DESCRIPTOR_SETS));
909 auto &pipelineState = executionState.pipelineState[pipelineBindPoint];
910 auto pipelineLayout = pipelineState.pipeline->getLayout();
911 auto dynamicOffsetBase = pipelineLayout->getDynamicOffsetBase(set);
912 ASSERT_OR_RETURN(dynamicOffsetBase + dynamicOffsetCount <= MAX_DESCRIPTOR_SET_COMBINED_BUFFERS_DYNAMIC);
913
914 pipelineState.descriptorSets[set] = vk::Cast(descriptorSet);
915 for (uint32_t i = 0; i < dynamicOffsetCount; i++)
916 {
917 pipelineState.descriptorDynamicOffsets[dynamicOffsetBase + i] = dynamicOffsets[i];
918 }
Alexis Hetu5edafb52019-02-15 14:56:22 -0500919 }
920
921private:
922 VkPipelineBindPoint pipelineBindPoint;
923 uint32_t set;
924 const VkDescriptorSet descriptorSet;
Ben Clayton225a1302019-04-02 12:28:22 +0100925 uint32_t dynamicOffsetCount;
926 vk::DescriptorSet::DynamicOffsets dynamicOffsets;
Alexis Hetu5edafb52019-02-15 14:56:22 -0500927};
928
Chris Forbesa30de542019-03-18 18:51:55 -0700929struct SetPushConstants : public CommandBuffer::Command
930{
931 SetPushConstants(uint32_t offset, uint32_t size, void const *pValues)
932 : offset(offset), size(size)
933 {
934 ASSERT(offset < MAX_PUSH_CONSTANT_SIZE);
935 ASSERT(offset + size <= MAX_PUSH_CONSTANT_SIZE);
936
937 memcpy(data, pValues, size);
938 }
939
940 void play(CommandBuffer::ExecutionState& executionState)
941 {
942 memcpy(&executionState.pushConstants.data[offset], data, size);
943 }
944
945private:
946 uint32_t offset;
947 uint32_t size;
948 unsigned char data[MAX_PUSH_CONSTANT_SIZE];
949};
950
Alexis Hetuf0aa9d52019-04-01 17:06:47 -0400951struct BeginQuery : public CommandBuffer::Command
952{
953 BeginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
954 : queryPool(queryPool), query(query), flags(flags)
955 {
956 }
957
958 void play(CommandBuffer::ExecutionState& executionState)
959 {
960 executionState.renderer->addQuery(Cast(queryPool)->getQuery(query));
961 Cast(queryPool)->begin(query, flags);
962 }
963
964private:
965 VkQueryPool queryPool;
966 uint32_t query;
967 VkQueryControlFlags flags;
968};
969
970struct EndQuery : public CommandBuffer::Command
971{
972 EndQuery(VkQueryPool queryPool, uint32_t query)
973 : queryPool(queryPool), query(query)
974 {
975 }
976
977 void play(CommandBuffer::ExecutionState& executionState)
978 {
979 executionState.renderer->removeQuery(Cast(queryPool)->getQuery(query));
980 Cast(queryPool)->end(query);
981 }
982
983private:
984 VkQueryPool queryPool;
985 uint32_t query;
986};
987
988struct ResetQueryPool : public CommandBuffer::Command
989{
990 ResetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
991 : queryPool(queryPool), firstQuery(firstQuery), queryCount(queryCount)
992 {
993 }
994
995 void play(CommandBuffer::ExecutionState& executionState)
996 {
997 Cast(queryPool)->reset(firstQuery, queryCount);
998 }
999
1000private:
1001 VkQueryPool queryPool;
1002 uint32_t firstQuery;
1003 uint32_t queryCount;
1004};
1005
1006struct WriteTimeStamp : public CommandBuffer::Command
1007{
1008 WriteTimeStamp(VkQueryPool queryPool, uint32_t query)
1009 : queryPool(queryPool), query(query)
1010 {
1011 }
1012
1013 void play(CommandBuffer::ExecutionState& executionState)
1014 {
1015 Cast(queryPool)->writeTimestamp(query);
1016 }
1017
1018private:
1019 VkQueryPool queryPool;
1020 uint32_t query;
1021};
1022
1023struct CopyQueryPoolResults : public CommandBuffer::Command
1024{
1025 CopyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
1026 VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
1027 : queryPool(queryPool), firstQuery(firstQuery), queryCount(queryCount), dstBuffer(dstBuffer),
1028 dstOffset(dstOffset), stride(stride), flags(flags)
1029 {
1030 }
1031
1032 void play(CommandBuffer::ExecutionState& executionState)
1033 {
1034 vk::Buffer* buffer = Cast(dstBuffer);
1035 Cast(queryPool)->getResults(firstQuery, queryCount, buffer->getSize() - dstOffset,
1036 buffer->getOffsetPointer(dstOffset), stride, flags);
1037 }
1038
1039private:
1040 VkQueryPool queryPool;
1041 uint32_t firstQuery;
1042 uint32_t queryCount;
1043 VkBuffer dstBuffer;
1044 VkDeviceSize dstOffset;
1045 VkDeviceSize stride;
1046 VkQueryResultFlags flags;
1047};
1048
Alexis Hetu767b41b2018-09-26 11:25:46 -04001049CommandBuffer::CommandBuffer(VkCommandBufferLevel pLevel) : level(pLevel)
1050{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001051 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
1052 commands = new std::vector<std::unique_ptr<Command> >();
Alexis Hetu767b41b2018-09-26 11:25:46 -04001053}
1054
Alexis Hetua9999ce2018-10-17 08:00:43 -04001055void CommandBuffer::destroy(const VkAllocationCallbacks* pAllocator)
1056{
Alexis Hetud2791c22018-12-10 14:41:03 -05001057 delete commands;
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001058}
1059
Alexis Hetud2791c22018-12-10 14:41:03 -05001060void CommandBuffer::resetState()
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001061{
1062 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
Alexis Hetud2791c22018-12-10 14:41:03 -05001063 commands->clear();
1064
1065 state = INITIAL;
Alexis Hetua9999ce2018-10-17 08:00:43 -04001066}
1067
1068VkResult CommandBuffer::begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo* pInheritanceInfo)
1069{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001070 ASSERT((state != RECORDING) && (state != PENDING));
Alexis Hetud2791c22018-12-10 14:41:03 -05001071
Chris Forbes823ca852019-03-01 17:40:25 -08001072 // Nothing interesting to do based on flags. We don't have any optimizations
1073 // to apply for ONE_TIME_SUBMIT or (lack of) SIMULTANEOUS_USE. RENDER_PASS_CONTINUE
1074 // must also provide a non-null pInheritanceInfo, which we don't implement yet, but is caught below.
1075 (void) flags;
1076
Alexis Hetue7b2a052019-03-18 16:16:36 -04001077 // pInheritanceInfo merely contains optimization hints, so we currently ignore it
Alexis Hetud2791c22018-12-10 14:41:03 -05001078
1079 if(state != INITIAL)
1080 {
1081 // Implicit reset
1082 resetState();
1083 }
1084
Alexis Hetua9999ce2018-10-17 08:00:43 -04001085 state = RECORDING;
1086
Alexis Hetua9999ce2018-10-17 08:00:43 -04001087 return VK_SUCCESS;
1088}
1089
1090VkResult CommandBuffer::end()
1091{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001092 ASSERT(state == RECORDING);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001093
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001094 state = EXECUTABLE;
Alexis Hetua9999ce2018-10-17 08:00:43 -04001095
1096 return VK_SUCCESS;
1097}
1098
1099VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags)
1100{
1101 ASSERT(state != PENDING);
1102
Alexis Hetud2791c22018-12-10 14:41:03 -05001103 resetState();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001104
1105 return VK_SUCCESS;
1106}
1107
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001108template<typename T, typename... Args>
1109void CommandBuffer::addCommand(Args&&... args)
1110{
Alexis Hetu1a9714a2019-04-12 11:48:12 -04001111 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001112 commands->push_back(std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
1113}
1114
Alexis Hetua9999ce2018-10-17 08:00:43 -04001115void CommandBuffer::beginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001116 uint32_t clearValueCount, const VkClearValue* clearValues, VkSubpassContents contents)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001117{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001118 ASSERT(state == RECORDING);
1119
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001120 addCommand<BeginRenderPass>(renderPass, framebuffer, renderArea, clearValueCount, clearValues);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001121}
1122
1123void CommandBuffer::nextSubpass(VkSubpassContents contents)
1124{
Alexis Hetu1cd31ea2019-01-17 17:14:57 -05001125 ASSERT(state == RECORDING);
1126
1127 addCommand<NextSubpass>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001128}
1129
1130void CommandBuffer::endRenderPass()
1131{
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001132 addCommand<EndRenderPass>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001133}
1134
1135void CommandBuffer::executeCommands(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
1136{
Alexis Hetue7b2a052019-03-18 16:16:36 -04001137 ASSERT(state == RECORDING);
1138
1139 for(uint32_t i = 0; i < commandBufferCount; ++i)
1140 {
1141 addCommand<ExecuteCommands>(pCommandBuffers[i]);
1142 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001143}
1144
1145void CommandBuffer::setDeviceMask(uint32_t deviceMask)
1146{
Ben Clayton00424c12019-03-17 17:29:30 +00001147 UNIMPLEMENTED("setDeviceMask");
Alexis Hetua9999ce2018-10-17 08:00:43 -04001148}
1149
1150void CommandBuffer::dispatchBase(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
1151 uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
1152{
Ben Clayton00424c12019-03-17 17:29:30 +00001153 UNIMPLEMENTED("dispatchBase");
Alexis Hetua9999ce2018-10-17 08:00:43 -04001154}
1155
1156void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1157 VkDependencyFlags dependencyFlags,
1158 uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
1159 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
1160 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
1161{
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001162 addCommand<PipelineBarrier>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001163}
1164
1165void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
1166{
Ben Claytonf2be26a2019-03-08 12:02:05 +00001167 switch(pipelineBindPoint)
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001168 {
Ben Claytonf2be26a2019-03-08 12:02:05 +00001169 case VK_PIPELINE_BIND_POINT_COMPUTE:
1170 case VK_PIPELINE_BIND_POINT_GRAPHICS:
1171 addCommand<PipelineBind>(pipelineBindPoint, pipeline);
1172 break;
1173 default:
Ben Clayton00424c12019-03-17 17:29:30 +00001174 UNIMPLEMENTED("pipelineBindPoint");
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001175 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001176}
1177
1178void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
1179 const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
1180{
Chris Forbesfe3d4972019-02-22 17:21:23 -08001181 for(uint32_t i = 0; i < bindingCount; ++i)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001182 {
Chris Forbesfe3d4972019-02-22 17:21:23 -08001183 addCommand<VertexBufferBind>(i + firstBinding, pBuffers[i], pOffsets[i]);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001184 }
1185}
1186
1187void CommandBuffer::beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
1188{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001189 addCommand<BeginQuery>(queryPool, query, flags);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001190}
1191
1192void CommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
1193{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001194 addCommand<EndQuery>(queryPool, query);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001195}
1196
1197void CommandBuffer::resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
1198{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001199 addCommand<ResetQueryPool>(queryPool, firstQuery, queryCount);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001200}
1201
1202void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
1203{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001204 addCommand<WriteTimeStamp>(queryPool, query);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001205}
1206
1207void CommandBuffer::copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
1208 VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
1209{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001210 addCommand<CopyQueryPoolResults>(queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001211}
1212
1213void CommandBuffer::pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags,
1214 uint32_t offset, uint32_t size, const void* pValues)
1215{
Chris Forbesa30de542019-03-18 18:51:55 -07001216 addCommand<SetPushConstants>(offset, size, pValues);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001217}
1218
1219void CommandBuffer::setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
1220{
Alexis Hetu73832432019-04-11 16:43:18 -04001221 if(firstViewport != 0 || viewportCount > 1)
1222 {
1223 UNIMPLEMENTED("viewport");
1224 }
1225
1226 for(uint32_t i = 0; i < viewportCount; i++)
1227 {
1228 addCommand<SetViewport>(pViewports[i], i + firstViewport);
1229 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001230}
1231
1232void CommandBuffer::setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
1233{
Alexis Hetu73832432019-04-11 16:43:18 -04001234 if(firstScissor != 0 || scissorCount > 1)
1235 {
1236 UNIMPLEMENTED("scissor");
1237 }
1238
1239 for(uint32_t i = 0; i < scissorCount; i++)
1240 {
1241 addCommand<SetScissor>(pScissors[i], i + firstScissor);
1242 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001243}
1244
1245void CommandBuffer::setLineWidth(float lineWidth)
1246{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001247 // If the wide lines feature is not enabled, lineWidth must be 1.0
1248 ASSERT(lineWidth == 1.0f);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001249}
1250
1251void CommandBuffer::setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
1252{
Alexis Hetu73832432019-04-11 16:43:18 -04001253 addCommand<SetDepthBias>(depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001254}
1255
1256void CommandBuffer::setBlendConstants(const float blendConstants[4])
1257{
Alexis Hetu73832432019-04-11 16:43:18 -04001258 addCommand<SetBlendConstants>(blendConstants);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001259}
1260
1261void CommandBuffer::setDepthBounds(float minDepthBounds, float maxDepthBounds)
1262{
Alexis Hetu73832432019-04-11 16:43:18 -04001263 addCommand<SetDepthBounds>(minDepthBounds, maxDepthBounds);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001264}
1265
1266void CommandBuffer::setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask)
1267{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001268 // faceMask must not be 0
1269 ASSERT(faceMask != 0);
1270
Alexis Hetu73832432019-04-11 16:43:18 -04001271 addCommand<SetStencilCompareMask>(faceMask, compareMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001272}
1273
1274void CommandBuffer::setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask)
1275{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001276 // faceMask must not be 0
1277 ASSERT(faceMask != 0);
1278
Alexis Hetu73832432019-04-11 16:43:18 -04001279 addCommand<SetStencilWriteMask>(faceMask, writeMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001280}
1281
1282void CommandBuffer::setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference)
1283{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001284 // faceMask must not be 0
1285 ASSERT(faceMask != 0);
1286
Alexis Hetu73832432019-04-11 16:43:18 -04001287 addCommand<SetStencilReference>(faceMask, reference);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001288}
1289
Ben Clayton225a1302019-04-02 12:28:22 +01001290void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout vkLayout,
Alexis Hetua9999ce2018-10-17 08:00:43 -04001291 uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
1292 uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
1293{
Alexis Hetu5edafb52019-02-15 14:56:22 -05001294 ASSERT(state == RECORDING);
1295
Alexis Hetu5edafb52019-02-15 14:56:22 -05001296 for(uint32_t i = 0; i < descriptorSetCount; i++)
1297 {
Ben Clayton225a1302019-04-02 12:28:22 +01001298 auto descriptorSetIndex = firstSet + i;
1299 auto layout = vk::Cast(vkLayout);
1300 auto setLayout = layout->getDescriptorSetLayout(descriptorSetIndex);
1301
1302 auto numDynamicDescriptors = setLayout->getDynamicDescriptorCount();
1303 ASSERT(numDynamicDescriptors == 0 || pDynamicOffsets != nullptr);
1304 ASSERT(dynamicOffsetCount >= numDynamicDescriptors);
1305
1306 addCommand<BindDescriptorSet>(
1307 pipelineBindPoint, descriptorSetIndex, pDescriptorSets[i],
1308 dynamicOffsetCount, pDynamicOffsets);
1309
1310 pDynamicOffsets += numDynamicDescriptors;
1311 dynamicOffsetCount -= numDynamicDescriptors;
Alexis Hetu5edafb52019-02-15 14:56:22 -05001312 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001313}
1314
1315void CommandBuffer::bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
1316{
Chris Forbesbaf7ad32019-02-25 18:14:42 -08001317 addCommand<IndexBufferBind>(buffer, offset, indexType);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001318}
1319
1320void CommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
1321{
Ben Claytonf2be26a2019-03-08 12:02:05 +00001322 addCommand<Dispatch>(groupCountX, groupCountY, groupCountZ);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001323}
1324
1325void CommandBuffer::dispatchIndirect(VkBuffer buffer, VkDeviceSize offset)
1326{
Chris Forbesfc8a46d2019-03-22 14:47:47 -07001327 addCommand<DispatchIndirect>(buffer, offset);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001328}
1329
1330void CommandBuffer::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
1331{
Alexis Hetubb0a7f02018-12-14 16:50:43 -05001332 ASSERT(state == RECORDING);
1333
1334 for(uint32_t i = 0; i < regionCount; i++)
1335 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001336 addCommand<BufferToBufferCopy>(srcBuffer, dstBuffer, pRegions[i]);
Alexis Hetubb0a7f02018-12-14 16:50:43 -05001337 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001338}
1339
1340void CommandBuffer::copyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
1341 uint32_t regionCount, const VkImageCopy* pRegions)
1342{
Alexis Hetu09056de2018-12-07 12:40:00 -05001343 ASSERT(state == RECORDING);
1344 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1345 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1346 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1347 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1348
1349 for(uint32_t i = 0; i < regionCount; i++)
1350 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001351 addCommand<ImageToImageCopy>(srcImage, dstImage, pRegions[i]);
Alexis Hetu09056de2018-12-07 12:40:00 -05001352 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001353}
1354
1355void CommandBuffer::blitImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
1356 uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
1357{
Alexis Hetu809d0112018-12-17 17:00:28 -05001358 ASSERT(state == RECORDING);
1359 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1360 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1361 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1362 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1363
1364 for(uint32_t i = 0; i < regionCount; i++)
1365 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001366 addCommand<BlitImage>(srcImage, dstImage, pRegions[i], filter);
Alexis Hetu809d0112018-12-17 17:00:28 -05001367 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001368}
1369
1370void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout,
1371 uint32_t regionCount, const VkBufferImageCopy* pRegions)
1372{
Alexis Hetu09056de2018-12-07 12:40:00 -05001373 ASSERT(state == RECORDING);
1374
1375 for(uint32_t i = 0; i < regionCount; i++)
1376 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001377 addCommand<BufferToImageCopy>(srcBuffer, dstImage, pRegions[i]);
Alexis Hetu09056de2018-12-07 12:40:00 -05001378 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001379}
1380
1381void CommandBuffer::copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer,
1382 uint32_t regionCount, const VkBufferImageCopy* pRegions)
1383{
Alexis Hetu09056de2018-12-07 12:40:00 -05001384 ASSERT(state == RECORDING);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001385 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1386
1387 for(uint32_t i = 0; i < regionCount; i++)
1388 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001389 addCommand<ImageToBufferCopy>(srcImage, dstBuffer, pRegions[i]);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001390 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001391}
1392
1393void CommandBuffer::updateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
1394{
Alexis Hetu7fb0b732019-02-07 13:50:10 -05001395 ASSERT(state == RECORDING);
1396
1397 addCommand<UpdateBuffer>(dstBuffer, dstOffset, dataSize, pData);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001398}
1399
1400void CommandBuffer::fillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
1401{
Alexis Hetu7fb0b732019-02-07 13:50:10 -05001402 ASSERT(state == RECORDING);
1403
1404 addCommand<FillBuffer>(dstBuffer, dstOffset, size, data);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001405}
1406
1407void CommandBuffer::clearColorImage(VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
1408 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
1409{
Alexis Hetuf14ed322019-01-16 15:54:55 -05001410 ASSERT(state == RECORDING);
1411
1412 for(uint32_t i = 0; i < rangeCount; i++)
1413 {
Chris Forbesfffee5b2019-01-18 08:33:15 -08001414 addCommand<ClearColorImage>(image, pColor[i], pRanges[i]);
Alexis Hetuf14ed322019-01-16 15:54:55 -05001415 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001416}
1417
1418void CommandBuffer::clearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
1419 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
1420{
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -05001421 ASSERT(state == RECORDING);
1422
1423 for(uint32_t i = 0; i < rangeCount; i++)
1424 {
Chris Forbesfffee5b2019-01-18 08:33:15 -08001425 addCommand<ClearDepthStencilImage>(image, pDepthStencil[i], pRanges[i]);
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -05001426 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001427}
1428
1429void CommandBuffer::clearAttachments(uint32_t attachmentCount, const VkClearAttachment* pAttachments,
1430 uint32_t rectCount, const VkClearRect* pRects)
1431{
Alexis Hetu1cd31ea2019-01-17 17:14:57 -05001432 ASSERT(state == RECORDING);
1433
1434 for(uint32_t i = 0; i < attachmentCount; i++)
1435 {
1436 for(uint32_t j = 0; j < rectCount; j++)
1437 {
1438 addCommand<ClearAttachment>(pAttachments[i], pRects[j]);
1439 }
1440 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001441}
1442
1443void CommandBuffer::resolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
1444 uint32_t regionCount, const VkImageResolve* pRegions)
1445{
Alexis Hetue5e33cd2019-04-11 10:24:52 -04001446 ASSERT(state == RECORDING);
1447 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1448 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1449 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1450 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1451
1452 for(uint32_t i = 0; i < regionCount; i++)
1453 {
1454 addCommand<ResolveImage>(srcImage, dstImage, pRegions[i]);
1455 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001456}
1457
1458void CommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
1459{
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001460 ASSERT(state == RECORDING);
1461
1462 addCommand<SignalEvent>(event, stageMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001463}
1464
1465void CommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
1466{
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001467 ASSERT(state == RECORDING);
1468
1469 addCommand<ResetEvent>(event, stageMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001470}
1471
1472void CommandBuffer::waitEvents(uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask,
1473 VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
1474 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
1475 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
1476{
Alexis Hetu9041bb72019-03-15 14:45:45 -04001477 ASSERT(state == RECORDING);
1478
1479 // TODO(b/117835459): Since we always do a full barrier, all memory barrier related arguments are ignored
1480
1481 // Note: srcStageMask and dstStageMask are currently ignored
1482 for(uint32_t i = 0; i < eventCount; i++)
1483 {
1484 addCommand<WaitEvent>(pEvents[i]);
1485 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001486}
1487
1488void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
1489{
Alexis Hetud9e364c2019-01-24 16:36:53 -05001490 addCommand<Draw>(vertexCount, instanceCount, firstVertex, firstInstance);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001491}
1492
1493void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
1494{
Chris Forbesbaf7ad32019-02-25 18:14:42 -08001495 addCommand<DrawIndexed>(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001496}
1497
1498void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
1499{
Chris Forbes48b35872019-03-22 14:12:50 -07001500 addCommand<DrawIndirect>(buffer, offset, drawCount, stride);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001501}
1502
1503void CommandBuffer::drawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
1504{
Chris Forbes48b35872019-03-22 14:12:50 -07001505 addCommand<DrawIndexedIndirect>(buffer, offset, drawCount, stride);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001506}
1507
Alexis Hetu9bc7a812018-12-07 16:13:34 -05001508void CommandBuffer::submit(CommandBuffer::ExecutionState& executionState)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001509{
1510 // Perform recorded work
1511 state = PENDING;
1512
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001513 for(auto& command : *commands)
1514 {
Alexis Hetu9bc7a812018-12-07 16:13:34 -05001515 command->play(executionState);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001516 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001517
1518 // After work is completed
1519 state = EXECUTABLE;
1520}
1521
Alexis Hetue7b2a052019-03-18 16:16:36 -04001522void CommandBuffer::submitSecondary(CommandBuffer::ExecutionState& executionState) const
1523{
1524 for(auto& command : *commands)
1525 {
1526 command->play(executionState);
1527 }
1528}
1529
Chris Forbesf8374cf2018-12-06 13:25:59 -08001530} // namespace vk