blob: 59df7e33b42551ab44a95827a09236bac12d326b [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 Hetue1f51b92019-04-23 15:34:34 -040018#include "VkFence.hpp"
Alexis Hetu9bc7a812018-12-07 16:13:34 -050019#include "VkFramebuffer.hpp"
Alexis Hetu09056de2018-12-07 12:40:00 -050020#include "VkImage.hpp"
Chris Forbes7c33e882019-02-21 14:58:28 -080021#include "VkImageView.hpp"
Alexis Hetuc65473d2018-12-07 16:26:05 -050022#include "VkPipeline.hpp"
Ben Claytonf2be26a2019-03-08 12:02:05 +000023#include "VkPipelineLayout.hpp"
Alexis Hetuf0aa9d52019-04-01 17:06:47 -040024#include "VkQueryPool.hpp"
Chris Forbes50dd2ce2018-12-07 17:54:31 -080025#include "VkRenderPass.hpp"
Alexis Hetuc65473d2018-12-07 16:26:05 -050026#include "Device/Renderer.hpp"
Alexis Hetu767b41b2018-09-26 11:25:46 -040027
Chris Forbesf8374cf2018-12-06 13:25:59 -080028#include <cstring>
29
Alexis Hetu767b41b2018-09-26 11:25:46 -040030namespace vk
31{
32
Alexis Hetu072dc0d2018-10-31 11:41:25 -040033class CommandBuffer::Command
34{
35public:
36 // FIXME (b/119421344): change the commandBuffer argument to a CommandBuffer state
Alexis Hetu9bc7a812018-12-07 16:13:34 -050037 virtual void play(CommandBuffer::ExecutionState& executionState) = 0;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040038 virtual ~Command() {}
39};
40
41class BeginRenderPass : public CommandBuffer::Command
42{
43public:
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050044 BeginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
45 uint32_t clearValueCount, const VkClearValue* pClearValues) :
46 renderPass(Cast(renderPass)), framebuffer(Cast(framebuffer)), renderArea(renderArea),
47 clearValueCount(clearValueCount)
Alexis Hetu072dc0d2018-10-31 11:41:25 -040048 {
49 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
50 clearValues = new VkClearValue[clearValueCount];
51 memcpy(clearValues, pClearValues, clearValueCount * sizeof(VkClearValue));
52 }
53
54 ~BeginRenderPass() override
55 {
Chris Forbesf04b56f2018-12-28 16:06:16 -080056 delete [] clearValues;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040057 }
58
59protected:
Ben Clayton93317ec2019-02-20 08:53:50 +000060 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -040061 {
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050062 executionState.renderPass = renderPass;
63 executionState.renderPassFramebuffer = framebuffer;
64 renderPass->begin();
Alexis Hetu54ec7592019-03-20 14:37:16 -040065 framebuffer->clear(executionState.renderPass, clearValueCount, clearValues, renderArea);
Alexis Hetu072dc0d2018-10-31 11:41:25 -040066 }
67
68private:
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050069 RenderPass* renderPass;
70 Framebuffer* framebuffer;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040071 VkRect2D renderArea;
72 uint32_t clearValueCount;
73 VkClearValue* clearValues;
74};
75
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050076class NextSubpass : public CommandBuffer::Command
77{
78public:
79 NextSubpass()
80 {
81 }
82
83protected:
Ben Clayton93317ec2019-02-20 08:53:50 +000084 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050085 {
Alexis Hetu54ec7592019-03-20 14:37:16 -040086 bool hasResolveAttachments = (executionState.renderPass->getCurrentSubpass().pResolveAttachments != nullptr);
87 if(hasResolveAttachments)
88 {
89 // FIXME(sugoi): remove the following lines and resolve in Renderer::finishRendering()
90 // for a Draw command or after the last command of the current subpass
91 // which modifies pixels.
92 executionState.renderer->synchronize();
93 executionState.renderPassFramebuffer->resolve(executionState.renderPass);
94 }
95
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050096 executionState.renderPass->nextSubpass();
97 }
98
99private:
100};
101
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400102class EndRenderPass : public CommandBuffer::Command
103{
104public:
105 EndRenderPass()
106 {
107 }
108
109protected:
Ben Clayton93317ec2019-02-20 08:53:50 +0000110 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400111 {
Chris Forbesfc06fd12019-03-21 08:36:11 -0700112 // Execute (implicit or explicit) VkSubpassDependency to VK_SUBPASS_EXTERNAL
113 // This is somewhat heavier than the actual ordering required.
114 executionState.renderer->synchronize();
Alexis Hetu54ec7592019-03-20 14:37:16 -0400115
116 // FIXME(sugoi): remove the following line and resolve in Renderer::finishRendering()
117 // for a Draw command or after the last command of the current subpass
118 // which modifies pixels.
119 executionState.renderPassFramebuffer->resolve(executionState.renderPass);
120
121 executionState.renderPass->end();
122 executionState.renderPass = nullptr;
123 executionState.renderPassFramebuffer = nullptr;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400124 }
125
126private:
127};
128
Alexis Hetue7b2a052019-03-18 16:16:36 -0400129class ExecuteCommands : public CommandBuffer::Command
130{
131public:
132 ExecuteCommands(const VkCommandBuffer& commandBuffer) : commandBuffer(commandBuffer)
133 {
134 }
135
136protected:
137 void play(CommandBuffer::ExecutionState& executionState) override
138 {
139 Cast(commandBuffer)->submitSecondary(executionState);
140 }
141
142private:
143 const VkCommandBuffer commandBuffer;
144};
145
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400146class PipelineBind : public CommandBuffer::Command
147{
148public:
149 PipelineBind(VkPipelineBindPoint pPipelineBindPoint, VkPipeline pPipeline) :
150 pipelineBindPoint(pPipelineBindPoint), pipeline(pPipeline)
151 {
152 }
153
154protected:
Ben Clayton93317ec2019-02-20 08:53:50 +0000155 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400156 {
Ben Clayton225a1302019-04-02 12:28:22 +0100157 executionState.pipelineState[pipelineBindPoint].pipeline = Cast(pipeline);
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400158 }
159
160private:
161 VkPipelineBindPoint pipelineBindPoint;
162 VkPipeline pipeline;
163};
164
Ben Claytonf2be26a2019-03-08 12:02:05 +0000165class Dispatch : public CommandBuffer::Command
166{
167public:
168 Dispatch(uint32_t pGroupCountX, uint32_t pGroupCountY, uint32_t pGroupCountZ) :
169 groupCountX(pGroupCountX), groupCountY(pGroupCountY), groupCountZ(pGroupCountZ)
170 {
171 }
172
173protected:
174 void play(CommandBuffer::ExecutionState& executionState) override
175 {
Ben Clayton225a1302019-04-02 12:28:22 +0100176 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_COMPUTE];
177
178 ComputePipeline* pipeline = static_cast<ComputePipeline*>(pipelineState.pipeline);
Ben Claytonf2be26a2019-03-08 12:02:05 +0000179 pipeline->run(groupCountX, groupCountY, groupCountZ,
Ben Clayton225a1302019-04-02 12:28:22 +0100180 pipelineState.descriptorSets,
181 pipelineState.descriptorDynamicOffsets,
Chris Forbesa30de542019-03-18 18:51:55 -0700182 executionState.pushConstants);
Ben Claytonf2be26a2019-03-08 12:02:05 +0000183 }
184
185private:
186 uint32_t groupCountX;
187 uint32_t groupCountY;
188 uint32_t groupCountZ;
189};
190
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700191class DispatchIndirect : public CommandBuffer::Command
192{
193public:
194 DispatchIndirect(VkBuffer buffer, VkDeviceSize offset) :
195 buffer(buffer), offset(offset)
196 {
197 }
198
199protected:
200 void play(CommandBuffer::ExecutionState& executionState) override
201 {
202 auto cmd = reinterpret_cast<VkDispatchIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset));
203
Ben Clayton225a1302019-04-02 12:28:22 +0100204 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_COMPUTE];
205
206 ComputePipeline* pipeline = static_cast<ComputePipeline*>(pipelineState.pipeline);
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700207 pipeline->run(cmd->x, cmd->y, cmd->z,
Ben Clayton225a1302019-04-02 12:28:22 +0100208 pipelineState.descriptorSets,
209 pipelineState.descriptorDynamicOffsets,
210 executionState.pushConstants);
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700211 }
212
213private:
214 VkBuffer buffer;
215 VkDeviceSize offset;
216};
217
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400218struct VertexBufferBind : public CommandBuffer::Command
219{
220 VertexBufferBind(uint32_t pBinding, const VkBuffer pBuffer, const VkDeviceSize pOffset) :
221 binding(pBinding), buffer(pBuffer), offset(pOffset)
222 {
223 }
224
Ben Clayton93317ec2019-02-20 08:53:50 +0000225 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400226 {
Alexis Hetu9bc7a812018-12-07 16:13:34 -0500227 executionState.vertexInputBindings[binding] = { buffer, offset };
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400228 }
229
230 uint32_t binding;
231 const VkBuffer buffer;
232 const VkDeviceSize offset;
233};
234
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800235struct IndexBufferBind : public CommandBuffer::Command
236{
237 IndexBufferBind(const VkBuffer buffer, const VkDeviceSize offset, const VkIndexType indexType) :
238 buffer(buffer), offset(offset), indexType(indexType)
239 {
240
241 }
242
243 void play(CommandBuffer::ExecutionState& executionState) override
244 {
245 executionState.indexBufferBinding = {buffer, offset};
246 executionState.indexType = indexType;
247 }
248
249 const VkBuffer buffer;
250 const VkDeviceSize offset;
251 const VkIndexType indexType;
252};
253
Alexis Hetu73832432019-04-11 16:43:18 -0400254struct SetViewport : public CommandBuffer::Command
255{
256 SetViewport(const VkViewport& viewport, uint32_t viewportID) :
257 viewport(viewport), viewportID(viewportID)
258 {
259 }
260
261 void play(CommandBuffer::ExecutionState& executionState) override
262 {
263 executionState.dynamicState.viewport = viewport;
264 }
265
266 const VkViewport viewport;
267 uint32_t viewportID;
268};
269
270struct SetScissor : public CommandBuffer::Command
271{
272 SetScissor(const VkRect2D& scissor, uint32_t scissorID) :
273 scissor(scissor), scissorID(scissorID)
274 {
275 }
276
277 void play(CommandBuffer::ExecutionState& executionState) override
278 {
279 executionState.dynamicState.scissor = scissor;
280 }
281
282 const VkRect2D scissor;
283 uint32_t scissorID;
284};
285
286struct SetDepthBias : public CommandBuffer::Command
287{
288 SetDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor) :
289 depthBiasConstantFactor(depthBiasConstantFactor), depthBiasClamp(depthBiasClamp), depthBiasSlopeFactor(depthBiasSlopeFactor)
290 {
291 }
292
293 void play(CommandBuffer::ExecutionState& executionState) override
294 {
295 executionState.dynamicState.depthBiasConstantFactor = depthBiasConstantFactor;
296 executionState.dynamicState.depthBiasClamp = depthBiasClamp;
297 executionState.dynamicState.depthBiasSlopeFactor = depthBiasSlopeFactor;
298 }
299
300 float depthBiasConstantFactor;
301 float depthBiasClamp;
302 float depthBiasSlopeFactor;
303};
304
305struct SetBlendConstants : public CommandBuffer::Command
306{
307 SetBlendConstants(const float blendConstants[4])
308 {
309 memcpy(this->blendConstants, blendConstants, sizeof(this->blendConstants));
310 }
311
312 void play(CommandBuffer::ExecutionState& executionState) override
313 {
314 memcpy(&(executionState.dynamicState.blendConstants[0]), blendConstants, sizeof(blendConstants));
315 }
316
317 float blendConstants[4];
318};
319
320struct SetDepthBounds : public CommandBuffer::Command
321{
322 SetDepthBounds(float minDepthBounds, float maxDepthBounds) :
323 minDepthBounds(minDepthBounds), maxDepthBounds(maxDepthBounds)
324 {
325 }
326
327 void play(CommandBuffer::ExecutionState& executionState) override
328 {
329 executionState.dynamicState.minDepthBounds = minDepthBounds;
330 executionState.dynamicState.maxDepthBounds = maxDepthBounds;
331 }
332
333 float minDepthBounds;
334 float maxDepthBounds;
335};
336struct SetStencilCompareMask : public CommandBuffer::Command
337{
338 SetStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask) :
339 faceMask(faceMask), compareMask(compareMask)
340 {
341 }
342
343 void play(CommandBuffer::ExecutionState& executionState) override
344 {
345 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
346 {
347 executionState.dynamicState.compareMask[0] = compareMask;
348 }
349 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
350 {
351 executionState.dynamicState.compareMask[1] = compareMask;
352 }
353 }
354
355 VkStencilFaceFlags faceMask;
356 uint32_t compareMask;
357};
358
359struct SetStencilWriteMask : public CommandBuffer::Command
360{
361 SetStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask) :
362 faceMask(faceMask), writeMask(writeMask)
363 {
364 }
365
366 void play(CommandBuffer::ExecutionState& executionState) override
367 {
368 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
369 {
370 executionState.dynamicState.writeMask[0] = writeMask;
371 }
372 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
373 {
374 executionState.dynamicState.writeMask[1] = writeMask;
375 }
376 }
377
378 VkStencilFaceFlags faceMask;
379 uint32_t writeMask;
380};
381
382struct SetStencilReference : public CommandBuffer::Command
383{
384 SetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference) :
385 faceMask(faceMask), reference(reference)
386 {
387 }
388
389 void play(CommandBuffer::ExecutionState& executionState) override
390 {
391 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
392 {
393 executionState.dynamicState.reference[0] = reference;
394 }
395 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
396 {
397 executionState.dynamicState.reference[1] = reference;
398 }
399 }
400
401 VkStencilFaceFlags faceMask;
402 uint32_t reference;
403};
404
Chris Forbese1cf8632019-03-08 18:17:35 -0800405void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context& context, int firstVertex, int firstInstance)
Chris Forbes00ba1762019-03-08 17:10:41 -0800406{
407 for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
408 {
409 auto &attrib = context.input[i];
410 if (attrib.count)
411 {
412 const auto &vertexInput = vertexInputBindings[attrib.binding];
413 Buffer *buffer = Cast(vertexInput.buffer);
414 attrib.buffer = buffer ? buffer->getOffsetPointer(
Chris Forbese1cf8632019-03-08 18:17:35 -0800415 attrib.offset + vertexInput.offset + attrib.vertexStride * firstVertex + attrib.instanceStride * firstInstance) : nullptr;
Chris Forbes00ba1762019-03-08 17:10:41 -0800416 }
417 }
418}
419
Chris Forbes2995dc22019-03-02 14:57:20 -0800420void CommandBuffer::ExecutionState::bindAttachments()
421{
422 // Binds all the attachments for the current subpass
423 // Ideally this would be performed by BeginRenderPass and NextSubpass, but
424 // there is too much stomping of the renderer's state by setContext() in
425 // draws.
426
427 for (auto i = 0u; i < renderPass->getCurrentSubpass().colorAttachmentCount; i++)
428 {
429 auto attachmentReference = renderPass->getCurrentSubpass().pColorAttachments[i];
430 if (attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
431 {
432 auto attachment = renderPassFramebuffer->getAttachment(attachmentReference.attachment);
Chris Forbes37f2bd82019-04-19 17:24:36 -0700433 renderer->setRenderTarget(i, attachment);
Chris Forbes2995dc22019-03-02 14:57:20 -0800434 }
435 }
436
437 auto attachmentReference = renderPass->getCurrentSubpass().pDepthStencilAttachment;
438 if (attachmentReference && attachmentReference->attachment != VK_ATTACHMENT_UNUSED)
439 {
440 auto attachment = renderPassFramebuffer->getAttachment(attachmentReference->attachment);
441 if (attachment->hasDepthAspect())
442 {
Chris Forbes37f2bd82019-04-19 17:24:36 -0700443 renderer->setDepthBuffer(attachment);
Chris Forbes2995dc22019-03-02 14:57:20 -0800444 }
445 if (attachment->hasStencilAspect())
446 {
Chris Forbes37f2bd82019-04-19 17:24:36 -0700447 renderer->setStencilBuffer(attachment);
Chris Forbes2995dc22019-03-02 14:57:20 -0800448 }
449 }
450}
451
Chris Forbes48b35872019-03-22 14:12:50 -0700452struct DrawBase : public CommandBuffer::Command
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400453{
Chris Forbes48b35872019-03-22 14:12:50 -0700454 int bytesPerIndex(CommandBuffer::ExecutionState const& executionState)
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400455 {
Chris Forbes48b35872019-03-22 14:12:50 -0700456 return executionState.indexType == VK_INDEX_TYPE_UINT16 ? 2 : 4;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400457 }
458
Chris Forbes48b35872019-03-22 14:12:50 -0700459 void draw(CommandBuffer::ExecutionState& executionState, bool indexed,
460 uint32_t count, uint32_t instanceCount, uint32_t first, int32_t vertexOffset, uint32_t firstInstance)
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800461 {
Ben Clayton225a1302019-04-02 12:28:22 +0100462 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_GRAPHICS];
463
464 GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>(pipelineState.pipeline);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800465
466 sw::Context context = pipeline->getContext();
Chris Forbese1cf8632019-03-08 18:17:35 -0800467
468 executionState.bindVertexInputs(context, vertexOffset, firstInstance);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800469
Ben Clayton225a1302019-04-02 12:28:22 +0100470 context.descriptorSets = pipelineState.descriptorSets;
471 context.descriptorDynamicOffsets = pipelineState.descriptorDynamicOffsets;
Chris Forbesa30de542019-03-18 18:51:55 -0700472 context.pushConstants = executionState.pushConstants;
473
Alexis Hetu73832432019-04-11 16:43:18 -0400474 if(indexed)
Chris Forbes48b35872019-03-22 14:12:50 -0700475 {
476 context.indexBuffer = Cast(executionState.indexBufferBinding.buffer)->getOffsetPointer(
477 executionState.indexBufferBinding.offset + first * bytesPerIndex(executionState));
Chris Forbes48b35872019-03-22 14:12:50 -0700478 }
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800479
Alexis Hetu73832432019-04-11 16:43:18 -0400480 // Apply either pipeline state or dynamic state
481 executionState.renderer->setScissor(pipeline->hasDynamicState(VK_DYNAMIC_STATE_SCISSOR) ?
482 executionState.dynamicState.scissor : pipeline->getScissor());
483 executionState.renderer->setViewport(pipeline->hasDynamicState(VK_DYNAMIC_STATE_VIEWPORT) ?
484 executionState.dynamicState.viewport : pipeline->getViewport());
485 executionState.renderer->setBlendConstant(pipeline->hasDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS) ?
486 executionState.dynamicState.blendConstants : pipeline->getBlendConstants());
487 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS))
488 {
489 // If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0
490 ASSERT(executionState.dynamicState.depthBiasClamp == 0.0f);
491
492 context.depthBias = executionState.dynamicState.depthBiasConstantFactor;
493 context.slopeDepthBias = executionState.dynamicState.depthBiasSlopeFactor;
494 }
495 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS) && context.depthBoundsTestEnable)
496 {
497 // Unless the VK_EXT_depth_range_unrestricted extension is enabled minDepthBounds and maxDepthBounds must be between 0.0 and 1.0, inclusive
498 ASSERT(executionState.dynamicState.minDepthBounds >= 0.0f && executionState.dynamicState.minDepthBounds <= 1.0f);
499 ASSERT(executionState.dynamicState.maxDepthBounds >= 0.0f && executionState.dynamicState.maxDepthBounds <= 1.0f);
500
501 UNIMPLEMENTED("depthBoundsTestEnable");
502 }
503 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) && context.stencilEnable)
504 {
505 context.frontStencil.compareMask = executionState.dynamicState.compareMask[0];
506 context.backStencil.compareMask = executionState.dynamicState.compareMask[1];
507 }
508 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK) && context.stencilEnable)
509 {
510 context.frontStencil.writeMask = executionState.dynamicState.writeMask[0];
511 context.backStencil.writeMask = executionState.dynamicState.writeMask[1];
512 }
513 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE) && context.stencilEnable)
514 {
515 context.frontStencil.reference = executionState.dynamicState.reference[0];
516 context.backStencil.reference = executionState.dynamicState.reference[1];
517 }
518
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800519 executionState.renderer->setContext(context);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800520
Chris Forbes2995dc22019-03-02 14:57:20 -0800521 executionState.bindAttachments();
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800522
Chris Forbes48b35872019-03-22 14:12:50 -0700523 const uint32_t primitiveCount = pipeline->computePrimitiveCount(count);
Chris Forbese1cf8632019-03-08 18:17:35 -0800524 for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++)
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800525 {
526 executionState.renderer->setInstanceID(instance);
Alexis Hetue1f51b92019-04-23 15:34:34 -0400527 executionState.renderer->draw(context.topology, executionState.indexType, primitiveCount, vertexOffset,
528 executionState.fence);
Chris Forbese1cf8632019-03-08 18:17:35 -0800529 executionState.renderer->advanceInstanceAttributes();
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800530 }
531 }
Chris Forbes48b35872019-03-22 14:12:50 -0700532};
533
534struct Draw : public DrawBase
535{
536 Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
537 : vertexCount(vertexCount), instanceCount(instanceCount), firstVertex(firstVertex), firstInstance(firstInstance)
538 {
539 }
540
541 void play(CommandBuffer::ExecutionState& executionState) override
542 {
543 draw(executionState, false, vertexCount, instanceCount, 0, firstVertex, firstInstance);
544 }
545
546 uint32_t vertexCount;
547 uint32_t instanceCount;
548 uint32_t firstVertex;
549 uint32_t firstInstance;
550};
551
552struct DrawIndexed : public DrawBase
553{
554 DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
555 : indexCount(indexCount), instanceCount(instanceCount), firstIndex(firstIndex), vertexOffset(vertexOffset), firstInstance(firstInstance)
556 {
557 }
558
559 void play(CommandBuffer::ExecutionState& executionState) override
560 {
561 draw(executionState, true, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
562 }
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800563
564 uint32_t indexCount;
565 uint32_t instanceCount;
566 uint32_t firstIndex;
567 int32_t vertexOffset;
568 uint32_t firstInstance;
569};
570
Chris Forbes48b35872019-03-22 14:12:50 -0700571struct DrawIndirect : public DrawBase
572{
573 DrawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
574 : buffer(buffer), offset(offset), drawCount(drawCount), stride(stride)
575 {
576 }
577
578 void play(CommandBuffer::ExecutionState& executionState) override
579 {
580 for (auto drawId = 0u; drawId < drawCount; drawId++)
581 {
582 auto cmd = reinterpret_cast<VkDrawIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset + drawId * stride));
583 draw(executionState, false, cmd->vertexCount, cmd->instanceCount, 0, cmd->firstVertex, cmd->firstInstance);
584 }
585 }
586
587 VkBuffer buffer;
588 VkDeviceSize offset;
589 uint32_t drawCount;
590 uint32_t stride;
591};
592
593struct DrawIndexedIndirect : public DrawBase
594{
595 DrawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
596 : buffer(buffer), offset(offset), drawCount(drawCount), stride(stride)
597 {
598 }
599
600 void play(CommandBuffer::ExecutionState& executionState) override
601 {
602 for (auto drawId = 0u; drawId < drawCount; drawId++)
603 {
604 auto cmd = reinterpret_cast<VkDrawIndexedIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset + drawId * stride));
605 draw(executionState, true, cmd->indexCount, cmd->instanceCount, cmd->firstIndex, cmd->vertexOffset, cmd->firstInstance);
606 }
607 }
608
609 VkBuffer buffer;
610 VkDeviceSize offset;
611 uint32_t drawCount;
612 uint32_t stride;
613};
614
Alexis Hetu09056de2018-12-07 12:40:00 -0500615struct ImageToImageCopy : public CommandBuffer::Command
616{
617 ImageToImageCopy(VkImage pSrcImage, VkImage pDstImage, const VkImageCopy& pRegion) :
618 srcImage(pSrcImage), dstImage(pDstImage), region(pRegion)
619 {
620 }
621
Ben Clayton93317ec2019-02-20 08:53:50 +0000622 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu09056de2018-12-07 12:40:00 -0500623 {
624 Cast(srcImage)->copyTo(dstImage, region);
625 }
626
627private:
628 VkImage srcImage;
629 VkImage dstImage;
630 const VkImageCopy region;
631};
632
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500633struct BufferToBufferCopy : public CommandBuffer::Command
634{
635 BufferToBufferCopy(VkBuffer pSrcBuffer, VkBuffer pDstBuffer, const VkBufferCopy& pRegion) :
636 srcBuffer(pSrcBuffer), dstBuffer(pDstBuffer), region(pRegion)
637 {
638 }
639
Ben Clayton93317ec2019-02-20 08:53:50 +0000640 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500641 {
642 Cast(srcBuffer)->copyTo(Cast(dstBuffer), region);
643 }
644
645private:
646 VkBuffer srcBuffer;
647 VkBuffer dstBuffer;
648 const VkBufferCopy region;
649};
650
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400651struct ImageToBufferCopy : public CommandBuffer::Command
652{
653 ImageToBufferCopy(VkImage pSrcImage, VkBuffer pDstBuffer, const VkBufferImageCopy& pRegion) :
654 srcImage(pSrcImage), dstBuffer(pDstBuffer), region(pRegion)
655 {
656 }
657
Ben Clayton93317ec2019-02-20 08:53:50 +0000658 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400659 {
Alexis Hetu09056de2018-12-07 12:40:00 -0500660 Cast(srcImage)->copyTo(dstBuffer, region);
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400661 }
662
663private:
664 VkImage srcImage;
665 VkBuffer dstBuffer;
666 const VkBufferImageCopy region;
667};
668
Alexis Hetu09056de2018-12-07 12:40:00 -0500669struct BufferToImageCopy : public CommandBuffer::Command
670{
671 BufferToImageCopy(VkBuffer pSrcBuffer, VkImage pDstImage, const VkBufferImageCopy& pRegion) :
672 srcBuffer(pSrcBuffer), dstImage(pDstImage), region(pRegion)
673 {
674 }
675
Ben Clayton93317ec2019-02-20 08:53:50 +0000676 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu09056de2018-12-07 12:40:00 -0500677 {
678 Cast(dstImage)->copyFrom(srcBuffer, region);
679 }
680
681private:
682 VkBuffer srcBuffer;
683 VkImage dstImage;
684 const VkBufferImageCopy region;
685};
686
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500687struct FillBuffer : public CommandBuffer::Command
688{
689 FillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) :
690 dstBuffer(dstBuffer), dstOffset(dstOffset), size(size), data(data)
691 {
692 }
693
Ben Clayton93317ec2019-02-20 08:53:50 +0000694 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500695 {
696 Cast(dstBuffer)->fill(dstOffset, size, data);
697 }
698
699private:
700 VkBuffer dstBuffer;
701 VkDeviceSize dstOffset;
702 VkDeviceSize size;
703 uint32_t data;
704};
705
706struct UpdateBuffer : public CommandBuffer::Command
707{
708 UpdateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData) :
709 dstBuffer(dstBuffer), dstOffset(dstOffset), dataSize(dataSize), pData(pData)
710 {
711 }
712
Ben Clayton93317ec2019-02-20 08:53:50 +0000713 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500714 {
715 Cast(dstBuffer)->update(dstOffset, dataSize, pData);
716 }
717
718private:
719 VkBuffer dstBuffer;
720 VkDeviceSize dstOffset;
721 VkDeviceSize dataSize;
722 const void* pData;
723};
724
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500725struct ClearColorImage : public CommandBuffer::Command
Alexis Hetuf14ed322019-01-16 15:54:55 -0500726{
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500727 ClearColorImage(VkImage image, const VkClearColorValue& color, const VkImageSubresourceRange& range) :
Alexis Hetuf14ed322019-01-16 15:54:55 -0500728 image(image), color(color), range(range)
729 {
730 }
731
Ben Clayton93317ec2019-02-20 08:53:50 +0000732 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetuf14ed322019-01-16 15:54:55 -0500733 {
734 Cast(image)->clear(color, range);
735 }
736
737private:
738 VkImage image;
739 const VkClearColorValue color;
740 const VkImageSubresourceRange range;
741};
742
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500743struct ClearDepthStencilImage : public CommandBuffer::Command
744{
745 ClearDepthStencilImage(VkImage image, const VkClearDepthStencilValue& depthStencil, const VkImageSubresourceRange& range) :
746 image(image), depthStencil(depthStencil), range(range)
747 {
748 }
749
Ben Clayton93317ec2019-02-20 08:53:50 +0000750 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500751 {
752 Cast(image)->clear(depthStencil, range);
753 }
754
755private:
756 VkImage image;
757 const VkClearDepthStencilValue depthStencil;
758 const VkImageSubresourceRange range;
759};
760
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500761struct ClearAttachment : public CommandBuffer::Command
762{
763 ClearAttachment(const VkClearAttachment& attachment, const VkClearRect& rect) :
764 attachment(attachment), rect(rect)
765 {
766 }
767
Ben Clayton93317ec2019-02-20 08:53:50 +0000768 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500769 {
Chris Forbesed46cde2019-04-22 12:49:21 -0700770 // attachment clears are drawing operations, and so have rasterization-order guarantees.
771 // however, we don't do the clear through the rasterizer, so need to ensure prior drawing
772 // has completed first.
773 executionState.renderer->synchronize();
Alexis Hetu54ec7592019-03-20 14:37:16 -0400774 executionState.renderPassFramebuffer->clear(executionState.renderPass, attachment, rect);
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500775 }
776
777private:
778 const VkClearAttachment attachment;
779 const VkClearRect rect;
780};
781
Alexis Hetu809d0112018-12-17 17:00:28 -0500782struct BlitImage : public CommandBuffer::Command
783{
784 BlitImage(VkImage srcImage, VkImage dstImage, const VkImageBlit& region, VkFilter filter) :
785 srcImage(srcImage), dstImage(dstImage), region(region), filter(filter)
786 {
787 }
788
Ben Clayton93317ec2019-02-20 08:53:50 +0000789 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu809d0112018-12-17 17:00:28 -0500790 {
791 Cast(srcImage)->blit(dstImage, region, filter);
792 }
793
794private:
795 VkImage srcImage;
796 VkImage dstImage;
Ben Clayton24021a22019-02-19 11:42:31 +0000797 VkImageBlit region;
Alexis Hetu809d0112018-12-17 17:00:28 -0500798 VkFilter filter;
799};
800
Alexis Hetue5e33cd2019-04-11 10:24:52 -0400801struct ResolveImage : public CommandBuffer::Command
802{
803 ResolveImage(VkImage srcImage, VkImage dstImage, const VkImageResolve& region) :
804 srcImage(srcImage), dstImage(dstImage), region(region)
805 {
806 }
807
808 void play(CommandBuffer::ExecutionState& executionState) override
809 {
810 Cast(srcImage)->resolve(dstImage, region);
811 }
812
813private:
814 VkImage srcImage;
815 VkImage dstImage;
816 VkImageResolve region;
817};
818
Alexis Hetu9a6c28b2018-11-20 11:47:18 -0500819struct PipelineBarrier : public CommandBuffer::Command
820{
821 PipelineBarrier()
822 {
823 }
824
Ben Clayton93317ec2019-02-20 08:53:50 +0000825 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu9a6c28b2018-11-20 11:47:18 -0500826 {
Alexis Hetuead1a342019-02-26 17:03:00 -0500827 // This is a very simple implementation that simply calls sw::Renderer::synchronize(),
828 // since the driver is free to move the source stage towards the bottom of the pipe
829 // and the target stage towards the top, so a full pipeline sync is spec compliant.
830 executionState.renderer->synchronize();
Alexis Hetu9a6c28b2018-11-20 11:47:18 -0500831
832 // Right now all buffers are read-only in drawcalls but a similar mechanism will be required once we support SSBOs.
833
834 // Also note that this would be a good moment to update cube map borders or decompress compressed textures, if necessary.
835 }
836
837private:
838};
839
Alexis Hetu3f5a4792019-02-01 17:49:55 -0500840struct SignalEvent : public CommandBuffer::Command
841{
842 SignalEvent(VkEvent ev, VkPipelineStageFlags stageMask) : ev(ev), stageMask(stageMask)
843 {
844 }
845
Ben Clayton93317ec2019-02-20 08:53:50 +0000846 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu3f5a4792019-02-01 17:49:55 -0500847 {
Alexis Hetue1f51b92019-04-23 15:34:34 -0400848 executionState.renderer->synchronize();
849 Cast(ev)->signal();
Alexis Hetu3f5a4792019-02-01 17:49:55 -0500850 }
851
852private:
853 VkEvent ev;
854 VkPipelineStageFlags stageMask; // FIXME(b/117835459) : We currently ignore the flags and signal the event at the last stage
855};
856
857struct ResetEvent : public CommandBuffer::Command
858{
859 ResetEvent(VkEvent ev, VkPipelineStageFlags stageMask) : ev(ev), stageMask(stageMask)
860 {
861 }
862
Ben Clayton93317ec2019-02-20 08:53:50 +0000863 void play(CommandBuffer::ExecutionState& executionState) override
Alexis Hetu3f5a4792019-02-01 17:49:55 -0500864 {
865 Cast(ev)->reset();
866 }
867
868private:
869 VkEvent ev;
870 VkPipelineStageFlags stageMask; // FIXME(b/117835459) : We currently ignore the flags and reset the event at the last stage
871};
872
Alexis Hetu9041bb72019-03-15 14:45:45 -0400873struct WaitEvent : public CommandBuffer::Command
874{
875 WaitEvent(VkEvent ev) : ev(ev)
876 {
877 }
878
879 void play(CommandBuffer::ExecutionState& executionState) override
880 {
Alexis Hetue1f51b92019-04-23 15:34:34 -0400881 executionState.renderer->synchronize();
882 Cast(ev)->wait();
Alexis Hetu9041bb72019-03-15 14:45:45 -0400883 }
884
885private:
886 VkEvent ev;
887};
888
Alexis Hetu5edafb52019-02-15 14:56:22 -0500889struct BindDescriptorSet : public CommandBuffer::Command
890{
Ben Clayton225a1302019-04-02 12:28:22 +0100891 BindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, uint32_t set, const VkDescriptorSet& descriptorSet,
892 uint32_t dynamicOffsetCount, uint32_t const *dynamicOffsets)
893 : pipelineBindPoint(pipelineBindPoint), set(set), descriptorSet(descriptorSet),
894 dynamicOffsetCount(dynamicOffsetCount)
Alexis Hetu5edafb52019-02-15 14:56:22 -0500895 {
Ben Clayton225a1302019-04-02 12:28:22 +0100896 for (uint32_t i = 0; i < dynamicOffsetCount; i++)
897 {
898 this->dynamicOffsets[i] = dynamicOffsets[i];
899 }
Alexis Hetu5edafb52019-02-15 14:56:22 -0500900 }
901
902 void play(CommandBuffer::ExecutionState& executionState)
903 {
Ben Clayton225a1302019-04-02 12:28:22 +0100904 ASSERT_OR_RETURN((pipelineBindPoint < VK_PIPELINE_BIND_POINT_RANGE_SIZE) && (set < MAX_BOUND_DESCRIPTOR_SETS));
905 auto &pipelineState = executionState.pipelineState[pipelineBindPoint];
906 auto pipelineLayout = pipelineState.pipeline->getLayout();
907 auto dynamicOffsetBase = pipelineLayout->getDynamicOffsetBase(set);
908 ASSERT_OR_RETURN(dynamicOffsetBase + dynamicOffsetCount <= MAX_DESCRIPTOR_SET_COMBINED_BUFFERS_DYNAMIC);
909
910 pipelineState.descriptorSets[set] = vk::Cast(descriptorSet);
911 for (uint32_t i = 0; i < dynamicOffsetCount; i++)
912 {
913 pipelineState.descriptorDynamicOffsets[dynamicOffsetBase + i] = dynamicOffsets[i];
914 }
Alexis Hetu5edafb52019-02-15 14:56:22 -0500915 }
916
917private:
918 VkPipelineBindPoint pipelineBindPoint;
919 uint32_t set;
920 const VkDescriptorSet descriptorSet;
Ben Clayton225a1302019-04-02 12:28:22 +0100921 uint32_t dynamicOffsetCount;
922 vk::DescriptorSet::DynamicOffsets dynamicOffsets;
Alexis Hetu5edafb52019-02-15 14:56:22 -0500923};
924
Chris Forbesa30de542019-03-18 18:51:55 -0700925struct SetPushConstants : public CommandBuffer::Command
926{
927 SetPushConstants(uint32_t offset, uint32_t size, void const *pValues)
928 : offset(offset), size(size)
929 {
930 ASSERT(offset < MAX_PUSH_CONSTANT_SIZE);
931 ASSERT(offset + size <= MAX_PUSH_CONSTANT_SIZE);
932
933 memcpy(data, pValues, size);
934 }
935
936 void play(CommandBuffer::ExecutionState& executionState)
937 {
938 memcpy(&executionState.pushConstants.data[offset], data, size);
939 }
940
941private:
942 uint32_t offset;
943 uint32_t size;
944 unsigned char data[MAX_PUSH_CONSTANT_SIZE];
945};
946
Alexis Hetuf0aa9d52019-04-01 17:06:47 -0400947struct BeginQuery : public CommandBuffer::Command
948{
949 BeginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
950 : queryPool(queryPool), query(query), flags(flags)
951 {
952 }
953
954 void play(CommandBuffer::ExecutionState& executionState)
955 {
956 executionState.renderer->addQuery(Cast(queryPool)->getQuery(query));
957 Cast(queryPool)->begin(query, flags);
958 }
959
960private:
961 VkQueryPool queryPool;
962 uint32_t query;
963 VkQueryControlFlags flags;
964};
965
966struct EndQuery : public CommandBuffer::Command
967{
968 EndQuery(VkQueryPool queryPool, uint32_t query)
969 : queryPool(queryPool), query(query)
970 {
971 }
972
973 void play(CommandBuffer::ExecutionState& executionState)
974 {
975 executionState.renderer->removeQuery(Cast(queryPool)->getQuery(query));
976 Cast(queryPool)->end(query);
977 }
978
979private:
980 VkQueryPool queryPool;
981 uint32_t query;
982};
983
984struct ResetQueryPool : public CommandBuffer::Command
985{
986 ResetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
987 : queryPool(queryPool), firstQuery(firstQuery), queryCount(queryCount)
988 {
989 }
990
991 void play(CommandBuffer::ExecutionState& executionState)
992 {
993 Cast(queryPool)->reset(firstQuery, queryCount);
994 }
995
996private:
997 VkQueryPool queryPool;
998 uint32_t firstQuery;
999 uint32_t queryCount;
1000};
1001
1002struct WriteTimeStamp : public CommandBuffer::Command
1003{
1004 WriteTimeStamp(VkQueryPool queryPool, uint32_t query)
1005 : queryPool(queryPool), query(query)
1006 {
1007 }
1008
1009 void play(CommandBuffer::ExecutionState& executionState)
1010 {
1011 Cast(queryPool)->writeTimestamp(query);
1012 }
1013
1014private:
1015 VkQueryPool queryPool;
1016 uint32_t query;
1017};
1018
1019struct CopyQueryPoolResults : public CommandBuffer::Command
1020{
1021 CopyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
1022 VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
1023 : queryPool(queryPool), firstQuery(firstQuery), queryCount(queryCount), dstBuffer(dstBuffer),
1024 dstOffset(dstOffset), stride(stride), flags(flags)
1025 {
1026 }
1027
1028 void play(CommandBuffer::ExecutionState& executionState)
1029 {
1030 vk::Buffer* buffer = Cast(dstBuffer);
1031 Cast(queryPool)->getResults(firstQuery, queryCount, buffer->getSize() - dstOffset,
1032 buffer->getOffsetPointer(dstOffset), stride, flags);
1033 }
1034
1035private:
1036 VkQueryPool queryPool;
1037 uint32_t firstQuery;
1038 uint32_t queryCount;
1039 VkBuffer dstBuffer;
1040 VkDeviceSize dstOffset;
1041 VkDeviceSize stride;
1042 VkQueryResultFlags flags;
1043};
1044
Alexis Hetu767b41b2018-09-26 11:25:46 -04001045CommandBuffer::CommandBuffer(VkCommandBufferLevel pLevel) : level(pLevel)
1046{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001047 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
1048 commands = new std::vector<std::unique_ptr<Command> >();
Alexis Hetu767b41b2018-09-26 11:25:46 -04001049}
1050
Alexis Hetua9999ce2018-10-17 08:00:43 -04001051void CommandBuffer::destroy(const VkAllocationCallbacks* pAllocator)
1052{
Alexis Hetud2791c22018-12-10 14:41:03 -05001053 delete commands;
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001054}
1055
Alexis Hetud2791c22018-12-10 14:41:03 -05001056void CommandBuffer::resetState()
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001057{
1058 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
Alexis Hetud2791c22018-12-10 14:41:03 -05001059 commands->clear();
1060
1061 state = INITIAL;
Alexis Hetua9999ce2018-10-17 08:00:43 -04001062}
1063
1064VkResult CommandBuffer::begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo* pInheritanceInfo)
1065{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001066 ASSERT((state != RECORDING) && (state != PENDING));
Alexis Hetud2791c22018-12-10 14:41:03 -05001067
Chris Forbes823ca852019-03-01 17:40:25 -08001068 // Nothing interesting to do based on flags. We don't have any optimizations
1069 // to apply for ONE_TIME_SUBMIT or (lack of) SIMULTANEOUS_USE. RENDER_PASS_CONTINUE
1070 // must also provide a non-null pInheritanceInfo, which we don't implement yet, but is caught below.
1071 (void) flags;
1072
Alexis Hetue7b2a052019-03-18 16:16:36 -04001073 // pInheritanceInfo merely contains optimization hints, so we currently ignore it
Alexis Hetud2791c22018-12-10 14:41:03 -05001074
1075 if(state != INITIAL)
1076 {
1077 // Implicit reset
1078 resetState();
1079 }
1080
Alexis Hetua9999ce2018-10-17 08:00:43 -04001081 state = RECORDING;
1082
Alexis Hetua9999ce2018-10-17 08:00:43 -04001083 return VK_SUCCESS;
1084}
1085
1086VkResult CommandBuffer::end()
1087{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001088 ASSERT(state == RECORDING);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001089
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001090 state = EXECUTABLE;
Alexis Hetua9999ce2018-10-17 08:00:43 -04001091
1092 return VK_SUCCESS;
1093}
1094
1095VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags)
1096{
1097 ASSERT(state != PENDING);
1098
Alexis Hetud2791c22018-12-10 14:41:03 -05001099 resetState();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001100
1101 return VK_SUCCESS;
1102}
1103
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001104template<typename T, typename... Args>
1105void CommandBuffer::addCommand(Args&&... args)
1106{
Alexis Hetu1a9714a2019-04-12 11:48:12 -04001107 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001108 commands->push_back(std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
1109}
1110
Alexis Hetua9999ce2018-10-17 08:00:43 -04001111void CommandBuffer::beginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001112 uint32_t clearValueCount, const VkClearValue* clearValues, VkSubpassContents contents)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001113{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001114 ASSERT(state == RECORDING);
1115
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001116 addCommand<BeginRenderPass>(renderPass, framebuffer, renderArea, clearValueCount, clearValues);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001117}
1118
1119void CommandBuffer::nextSubpass(VkSubpassContents contents)
1120{
Alexis Hetu1cd31ea2019-01-17 17:14:57 -05001121 ASSERT(state == RECORDING);
1122
1123 addCommand<NextSubpass>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001124}
1125
1126void CommandBuffer::endRenderPass()
1127{
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001128 addCommand<EndRenderPass>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001129}
1130
1131void CommandBuffer::executeCommands(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
1132{
Alexis Hetue7b2a052019-03-18 16:16:36 -04001133 ASSERT(state == RECORDING);
1134
1135 for(uint32_t i = 0; i < commandBufferCount; ++i)
1136 {
1137 addCommand<ExecuteCommands>(pCommandBuffers[i]);
1138 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001139}
1140
1141void CommandBuffer::setDeviceMask(uint32_t deviceMask)
1142{
Ben Clayton00424c12019-03-17 17:29:30 +00001143 UNIMPLEMENTED("setDeviceMask");
Alexis Hetua9999ce2018-10-17 08:00:43 -04001144}
1145
1146void CommandBuffer::dispatchBase(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
1147 uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
1148{
Ben Clayton00424c12019-03-17 17:29:30 +00001149 UNIMPLEMENTED("dispatchBase");
Alexis Hetua9999ce2018-10-17 08:00:43 -04001150}
1151
1152void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1153 VkDependencyFlags dependencyFlags,
1154 uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
1155 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
1156 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
1157{
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001158 addCommand<PipelineBarrier>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001159}
1160
1161void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
1162{
Ben Claytonf2be26a2019-03-08 12:02:05 +00001163 switch(pipelineBindPoint)
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001164 {
Ben Claytonf2be26a2019-03-08 12:02:05 +00001165 case VK_PIPELINE_BIND_POINT_COMPUTE:
1166 case VK_PIPELINE_BIND_POINT_GRAPHICS:
1167 addCommand<PipelineBind>(pipelineBindPoint, pipeline);
1168 break;
1169 default:
Ben Clayton00424c12019-03-17 17:29:30 +00001170 UNIMPLEMENTED("pipelineBindPoint");
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001171 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001172}
1173
1174void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
1175 const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
1176{
Chris Forbesfe3d4972019-02-22 17:21:23 -08001177 for(uint32_t i = 0; i < bindingCount; ++i)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001178 {
Chris Forbesfe3d4972019-02-22 17:21:23 -08001179 addCommand<VertexBufferBind>(i + firstBinding, pBuffers[i], pOffsets[i]);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001180 }
1181}
1182
1183void CommandBuffer::beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
1184{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001185 addCommand<BeginQuery>(queryPool, query, flags);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001186}
1187
1188void CommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
1189{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001190 addCommand<EndQuery>(queryPool, query);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001191}
1192
1193void CommandBuffer::resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
1194{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001195 addCommand<ResetQueryPool>(queryPool, firstQuery, queryCount);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001196}
1197
1198void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
1199{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001200 addCommand<WriteTimeStamp>(queryPool, query);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001201}
1202
1203void CommandBuffer::copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
1204 VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
1205{
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001206 addCommand<CopyQueryPoolResults>(queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001207}
1208
1209void CommandBuffer::pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags,
1210 uint32_t offset, uint32_t size, const void* pValues)
1211{
Chris Forbesa30de542019-03-18 18:51:55 -07001212 addCommand<SetPushConstants>(offset, size, pValues);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001213}
1214
1215void CommandBuffer::setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
1216{
Alexis Hetu73832432019-04-11 16:43:18 -04001217 if(firstViewport != 0 || viewportCount > 1)
1218 {
1219 UNIMPLEMENTED("viewport");
1220 }
1221
1222 for(uint32_t i = 0; i < viewportCount; i++)
1223 {
1224 addCommand<SetViewport>(pViewports[i], i + firstViewport);
1225 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001226}
1227
1228void CommandBuffer::setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
1229{
Alexis Hetu73832432019-04-11 16:43:18 -04001230 if(firstScissor != 0 || scissorCount > 1)
1231 {
1232 UNIMPLEMENTED("scissor");
1233 }
1234
1235 for(uint32_t i = 0; i < scissorCount; i++)
1236 {
1237 addCommand<SetScissor>(pScissors[i], i + firstScissor);
1238 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001239}
1240
1241void CommandBuffer::setLineWidth(float lineWidth)
1242{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001243 // If the wide lines feature is not enabled, lineWidth must be 1.0
1244 ASSERT(lineWidth == 1.0f);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001245}
1246
1247void CommandBuffer::setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
1248{
Alexis Hetu73832432019-04-11 16:43:18 -04001249 addCommand<SetDepthBias>(depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001250}
1251
1252void CommandBuffer::setBlendConstants(const float blendConstants[4])
1253{
Alexis Hetu73832432019-04-11 16:43:18 -04001254 addCommand<SetBlendConstants>(blendConstants);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001255}
1256
1257void CommandBuffer::setDepthBounds(float minDepthBounds, float maxDepthBounds)
1258{
Alexis Hetu73832432019-04-11 16:43:18 -04001259 addCommand<SetDepthBounds>(minDepthBounds, maxDepthBounds);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001260}
1261
1262void CommandBuffer::setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask)
1263{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001264 // faceMask must not be 0
1265 ASSERT(faceMask != 0);
1266
Alexis Hetu73832432019-04-11 16:43:18 -04001267 addCommand<SetStencilCompareMask>(faceMask, compareMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001268}
1269
1270void CommandBuffer::setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask)
1271{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001272 // faceMask must not be 0
1273 ASSERT(faceMask != 0);
1274
Alexis Hetu73832432019-04-11 16:43:18 -04001275 addCommand<SetStencilWriteMask>(faceMask, writeMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001276}
1277
1278void CommandBuffer::setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference)
1279{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001280 // faceMask must not be 0
1281 ASSERT(faceMask != 0);
1282
Alexis Hetu73832432019-04-11 16:43:18 -04001283 addCommand<SetStencilReference>(faceMask, reference);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001284}
1285
Ben Clayton225a1302019-04-02 12:28:22 +01001286void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout vkLayout,
Alexis Hetua9999ce2018-10-17 08:00:43 -04001287 uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
1288 uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
1289{
Alexis Hetu5edafb52019-02-15 14:56:22 -05001290 ASSERT(state == RECORDING);
1291
Alexis Hetu5edafb52019-02-15 14:56:22 -05001292 for(uint32_t i = 0; i < descriptorSetCount; i++)
1293 {
Ben Clayton225a1302019-04-02 12:28:22 +01001294 auto descriptorSetIndex = firstSet + i;
1295 auto layout = vk::Cast(vkLayout);
1296 auto setLayout = layout->getDescriptorSetLayout(descriptorSetIndex);
1297
1298 auto numDynamicDescriptors = setLayout->getDynamicDescriptorCount();
1299 ASSERT(numDynamicDescriptors == 0 || pDynamicOffsets != nullptr);
1300 ASSERT(dynamicOffsetCount >= numDynamicDescriptors);
1301
1302 addCommand<BindDescriptorSet>(
1303 pipelineBindPoint, descriptorSetIndex, pDescriptorSets[i],
1304 dynamicOffsetCount, pDynamicOffsets);
1305
1306 pDynamicOffsets += numDynamicDescriptors;
1307 dynamicOffsetCount -= numDynamicDescriptors;
Alexis Hetu5edafb52019-02-15 14:56:22 -05001308 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001309}
1310
1311void CommandBuffer::bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
1312{
Chris Forbesbaf7ad32019-02-25 18:14:42 -08001313 addCommand<IndexBufferBind>(buffer, offset, indexType);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001314}
1315
1316void CommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
1317{
Ben Claytonf2be26a2019-03-08 12:02:05 +00001318 addCommand<Dispatch>(groupCountX, groupCountY, groupCountZ);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001319}
1320
1321void CommandBuffer::dispatchIndirect(VkBuffer buffer, VkDeviceSize offset)
1322{
Chris Forbesfc8a46d2019-03-22 14:47:47 -07001323 addCommand<DispatchIndirect>(buffer, offset);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001324}
1325
1326void CommandBuffer::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
1327{
Alexis Hetubb0a7f02018-12-14 16:50:43 -05001328 ASSERT(state == RECORDING);
1329
1330 for(uint32_t i = 0; i < regionCount; i++)
1331 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001332 addCommand<BufferToBufferCopy>(srcBuffer, dstBuffer, pRegions[i]);
Alexis Hetubb0a7f02018-12-14 16:50:43 -05001333 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001334}
1335
1336void CommandBuffer::copyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
1337 uint32_t regionCount, const VkImageCopy* pRegions)
1338{
Alexis Hetu09056de2018-12-07 12:40:00 -05001339 ASSERT(state == RECORDING);
1340 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1341 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1342 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1343 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1344
1345 for(uint32_t i = 0; i < regionCount; i++)
1346 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001347 addCommand<ImageToImageCopy>(srcImage, dstImage, pRegions[i]);
Alexis Hetu09056de2018-12-07 12:40:00 -05001348 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001349}
1350
1351void CommandBuffer::blitImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
1352 uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
1353{
Alexis Hetu809d0112018-12-17 17:00:28 -05001354 ASSERT(state == RECORDING);
1355 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1356 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1357 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1358 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1359
1360 for(uint32_t i = 0; i < regionCount; i++)
1361 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001362 addCommand<BlitImage>(srcImage, dstImage, pRegions[i], filter);
Alexis Hetu809d0112018-12-17 17:00:28 -05001363 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001364}
1365
1366void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout,
1367 uint32_t regionCount, const VkBufferImageCopy* pRegions)
1368{
Alexis Hetu09056de2018-12-07 12:40:00 -05001369 ASSERT(state == RECORDING);
1370
1371 for(uint32_t i = 0; i < regionCount; i++)
1372 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001373 addCommand<BufferToImageCopy>(srcBuffer, dstImage, pRegions[i]);
Alexis Hetu09056de2018-12-07 12:40:00 -05001374 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001375}
1376
1377void CommandBuffer::copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer,
1378 uint32_t regionCount, const VkBufferImageCopy* pRegions)
1379{
Alexis Hetu09056de2018-12-07 12:40:00 -05001380 ASSERT(state == RECORDING);
Chris Forbesa2457f72019-05-04 13:34:32 -07001381 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL || srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001382
1383 for(uint32_t i = 0; i < regionCount; i++)
1384 {
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001385 addCommand<ImageToBufferCopy>(srcImage, dstBuffer, pRegions[i]);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001386 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001387}
1388
1389void CommandBuffer::updateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
1390{
Alexis Hetu7fb0b732019-02-07 13:50:10 -05001391 ASSERT(state == RECORDING);
1392
1393 addCommand<UpdateBuffer>(dstBuffer, dstOffset, dataSize, pData);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001394}
1395
1396void CommandBuffer::fillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
1397{
Alexis Hetu7fb0b732019-02-07 13:50:10 -05001398 ASSERT(state == RECORDING);
1399
1400 addCommand<FillBuffer>(dstBuffer, dstOffset, size, data);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001401}
1402
1403void CommandBuffer::clearColorImage(VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
1404 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
1405{
Alexis Hetuf14ed322019-01-16 15:54:55 -05001406 ASSERT(state == RECORDING);
1407
1408 for(uint32_t i = 0; i < rangeCount; i++)
1409 {
Chris Forbesfffee5b2019-01-18 08:33:15 -08001410 addCommand<ClearColorImage>(image, pColor[i], pRanges[i]);
Alexis Hetuf14ed322019-01-16 15:54:55 -05001411 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001412}
1413
1414void CommandBuffer::clearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
1415 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
1416{
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -05001417 ASSERT(state == RECORDING);
1418
1419 for(uint32_t i = 0; i < rangeCount; i++)
1420 {
Chris Forbesfffee5b2019-01-18 08:33:15 -08001421 addCommand<ClearDepthStencilImage>(image, pDepthStencil[i], pRanges[i]);
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -05001422 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001423}
1424
1425void CommandBuffer::clearAttachments(uint32_t attachmentCount, const VkClearAttachment* pAttachments,
1426 uint32_t rectCount, const VkClearRect* pRects)
1427{
Alexis Hetu1cd31ea2019-01-17 17:14:57 -05001428 ASSERT(state == RECORDING);
1429
1430 for(uint32_t i = 0; i < attachmentCount; i++)
1431 {
1432 for(uint32_t j = 0; j < rectCount; j++)
1433 {
1434 addCommand<ClearAttachment>(pAttachments[i], pRects[j]);
1435 }
1436 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001437}
1438
1439void CommandBuffer::resolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
1440 uint32_t regionCount, const VkImageResolve* pRegions)
1441{
Alexis Hetue5e33cd2019-04-11 10:24:52 -04001442 ASSERT(state == RECORDING);
1443 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1444 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1445 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1446 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1447
1448 for(uint32_t i = 0; i < regionCount; i++)
1449 {
1450 addCommand<ResolveImage>(srcImage, dstImage, pRegions[i]);
1451 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001452}
1453
1454void CommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
1455{
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001456 ASSERT(state == RECORDING);
1457
1458 addCommand<SignalEvent>(event, stageMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001459}
1460
1461void CommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
1462{
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001463 ASSERT(state == RECORDING);
1464
1465 addCommand<ResetEvent>(event, stageMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001466}
1467
1468void CommandBuffer::waitEvents(uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask,
1469 VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
1470 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
1471 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
1472{
Alexis Hetu9041bb72019-03-15 14:45:45 -04001473 ASSERT(state == RECORDING);
1474
1475 // TODO(b/117835459): Since we always do a full barrier, all memory barrier related arguments are ignored
1476
1477 // Note: srcStageMask and dstStageMask are currently ignored
1478 for(uint32_t i = 0; i < eventCount; i++)
1479 {
1480 addCommand<WaitEvent>(pEvents[i]);
1481 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001482}
1483
1484void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
1485{
Alexis Hetud9e364c2019-01-24 16:36:53 -05001486 addCommand<Draw>(vertexCount, instanceCount, firstVertex, firstInstance);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001487}
1488
1489void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
1490{
Chris Forbesbaf7ad32019-02-25 18:14:42 -08001491 addCommand<DrawIndexed>(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001492}
1493
1494void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
1495{
Chris Forbes48b35872019-03-22 14:12:50 -07001496 addCommand<DrawIndirect>(buffer, offset, drawCount, stride);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001497}
1498
1499void CommandBuffer::drawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
1500{
Chris Forbes48b35872019-03-22 14:12:50 -07001501 addCommand<DrawIndexedIndirect>(buffer, offset, drawCount, stride);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001502}
1503
Alexis Hetu9bc7a812018-12-07 16:13:34 -05001504void CommandBuffer::submit(CommandBuffer::ExecutionState& executionState)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001505{
1506 // Perform recorded work
1507 state = PENDING;
1508
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001509 for(auto& command : *commands)
1510 {
Alexis Hetu9bc7a812018-12-07 16:13:34 -05001511 command->play(executionState);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001512 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001513
1514 // After work is completed
1515 state = EXECUTABLE;
1516}
1517
Alexis Hetue7b2a052019-03-18 16:16:36 -04001518void CommandBuffer::submitSecondary(CommandBuffer::ExecutionState& executionState) const
1519{
1520 for(auto& command : *commands)
1521 {
1522 command->play(executionState);
1523 }
1524}
1525
Chris Forbesf8374cf2018-12-06 13:25:59 -08001526} // namespace vk