1 // 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"
16 #include "VkBuffer.hpp"
17 #include "VkEvent.hpp"
18 #include "VkFramebuffer.hpp"
19 #include "VkImage.hpp"
20 #include "VkPipeline.hpp"
21 #include "VkRenderPass.hpp"
22 #include "Device/Renderer.hpp"
23 
24 #include <cstring>
25 
26 namespace vk
27 {
28 
29 class CommandBuffer::Command
30 {
31 public:
32 	// FIXME (b/119421344): change the commandBuffer argument to a CommandBuffer state
33 	virtual void play(CommandBuffer::ExecutionState& executionState) = 0;
~Command()34 	virtual ~Command() {}
35 };
36 
37 class BeginRenderPass : public CommandBuffer::Command
38 {
39 public:
BeginRenderPass(VkRenderPass renderPass,VkFramebuffer framebuffer,VkRect2D renderArea,uint32_t clearValueCount,const VkClearValue * pClearValues)40 	BeginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
41 	                uint32_t clearValueCount, const VkClearValue* pClearValues) :
42 		renderPass(Cast(renderPass)), framebuffer(Cast(framebuffer)), renderArea(renderArea),
43 		clearValueCount(clearValueCount)
44 	{
45 		// FIXME (b/119409619): use an allocator here so we can control all memory allocations
46 		clearValues = new VkClearValue[clearValueCount];
47 		memcpy(clearValues, pClearValues, clearValueCount * sizeof(VkClearValue));
48 	}
49 
~BeginRenderPass()50 	~BeginRenderPass() override
51 	{
52 		delete [] clearValues;
53 	}
54 
55 protected:
play(CommandBuffer::ExecutionState & executionState)56 	void play(CommandBuffer::ExecutionState& executionState)
57 	{
58 		executionState.renderPass = renderPass;
59 		executionState.renderPassFramebuffer = framebuffer;
60 		renderPass->begin();
61 		framebuffer->clear(clearValueCount, clearValues, renderArea);
62 	}
63 
64 private:
65 	RenderPass* renderPass;
66 	Framebuffer* framebuffer;
67 	VkRect2D renderArea;
68 	uint32_t clearValueCount;
69 	VkClearValue* clearValues;
70 };
71 
72 class NextSubpass : public CommandBuffer::Command
73 {
74 public:
NextSubpass()75 	NextSubpass()
76 	{
77 	}
78 
79 protected:
play(CommandBuffer::ExecutionState & executionState)80 	void play(CommandBuffer::ExecutionState& executionState)
81 	{
82 		executionState.renderPass->nextSubpass();
83 	}
84 
85 private:
86 };
87 
88 class EndRenderPass : public CommandBuffer::Command
89 {
90 public:
EndRenderPass()91 	EndRenderPass()
92 	{
93 	}
94 
95 protected:
play(CommandBuffer::ExecutionState & executionState)96 	void play(CommandBuffer::ExecutionState& executionState)
97 	{
98 		executionState.renderPass->end();
99 		executionState.renderPass = nullptr;
100 		executionState.renderPassFramebuffer = nullptr;
101 	}
102 
103 private:
104 };
105 
106 class PipelineBind : public CommandBuffer::Command
107 {
108 public:
PipelineBind(VkPipelineBindPoint pPipelineBindPoint,VkPipeline pPipeline)109 	PipelineBind(VkPipelineBindPoint pPipelineBindPoint, VkPipeline pPipeline) :
110 		pipelineBindPoint(pPipelineBindPoint), pipeline(pPipeline)
111 	{
112 	}
113 
114 protected:
play(CommandBuffer::ExecutionState & executionState)115 	void play(CommandBuffer::ExecutionState& executionState)
116 	{
117 		executionState.pipelines[pipelineBindPoint] = Cast(pipeline);
118 	}
119 
120 private:
121 	VkPipelineBindPoint pipelineBindPoint;
122 	VkPipeline pipeline;
123 };
124 
125 struct VertexBufferBind : public CommandBuffer::Command
126 {
VertexBufferBindvk::VertexBufferBind127 	VertexBufferBind(uint32_t pBinding, const VkBuffer pBuffer, const VkDeviceSize pOffset) :
128 		binding(pBinding), buffer(pBuffer), offset(pOffset)
129 	{
130 	}
131 
playvk::VertexBufferBind132 	void play(CommandBuffer::ExecutionState& executionState)
133 	{
134 		executionState.vertexInputBindings[binding] = { buffer, offset };
135 	}
136 
137 	uint32_t binding;
138 	const VkBuffer buffer;
139 	const VkDeviceSize offset;
140 };
141 
142 struct Draw : public CommandBuffer::Command
143 {
Drawvk::Draw144 	Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
145 		: vertexCount(vertexCount), instanceCount(instanceCount), firstVertex(firstVertex), firstInstance(firstInstance)
146 	{
147 	}
148 
playvk::Draw149 	void play(CommandBuffer::ExecutionState& executionState)
150 	{
151 		GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>(
152 			executionState.pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS]);
153 
154 		sw::Context context = pipeline->getContext();
155 		for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
156 		{
157 			const auto& vertexInput = executionState.vertexInputBindings[i];
158 			Buffer* buffer = Cast(vertexInput.buffer);
159 			context.input[i].buffer = buffer ? buffer->getOffsetPointer(vertexInput.offset + context.input[i].stride * firstVertex) : nullptr;
160 		}
161 
162 		executionState.renderer->setContext(context);
163 		executionState.renderer->setScissor(pipeline->getScissor());
164 		executionState.renderer->setViewport(pipeline->getViewport());
165 		executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
166 
167 		const uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount);
168 		const uint32_t lastInstance = firstInstance + instanceCount - 1;
169 		for(uint32_t instance = firstInstance; instance <= lastInstance; instance++)
170 		{
171 			executionState.renderer->setInstanceID(instance);
172 			executionState.renderer->draw(context.drawType, 0, primitiveCount);
173 		}
174 	}
175 
176 	uint32_t vertexCount;
177 	uint32_t instanceCount;
178 	uint32_t firstVertex;
179 	uint32_t firstInstance;
180 };
181 
182 struct ImageToImageCopy : public CommandBuffer::Command
183 {
ImageToImageCopyvk::ImageToImageCopy184 	ImageToImageCopy(VkImage pSrcImage, VkImage pDstImage, const VkImageCopy& pRegion) :
185 		srcImage(pSrcImage), dstImage(pDstImage), region(pRegion)
186 	{
187 	}
188 
playvk::ImageToImageCopy189 	void play(CommandBuffer::ExecutionState& executionState)
190 	{
191 		Cast(srcImage)->copyTo(dstImage, region);
192 	}
193 
194 private:
195 	VkImage srcImage;
196 	VkImage dstImage;
197 	const VkImageCopy region;
198 };
199 
200 struct BufferToBufferCopy : public CommandBuffer::Command
201 {
BufferToBufferCopyvk::BufferToBufferCopy202 	BufferToBufferCopy(VkBuffer pSrcBuffer, VkBuffer pDstBuffer, const VkBufferCopy& pRegion) :
203 		srcBuffer(pSrcBuffer), dstBuffer(pDstBuffer), region(pRegion)
204 	{
205 	}
206 
playvk::BufferToBufferCopy207 	void play(CommandBuffer::ExecutionState& executionState)
208 	{
209 		Cast(srcBuffer)->copyTo(Cast(dstBuffer), region);
210 	}
211 
212 private:
213 	VkBuffer srcBuffer;
214 	VkBuffer dstBuffer;
215 	const VkBufferCopy region;
216 };
217 
218 struct ImageToBufferCopy : public CommandBuffer::Command
219 {
ImageToBufferCopyvk::ImageToBufferCopy220 	ImageToBufferCopy(VkImage pSrcImage, VkBuffer pDstBuffer, const VkBufferImageCopy& pRegion) :
221 		srcImage(pSrcImage), dstBuffer(pDstBuffer), region(pRegion)
222 	{
223 	}
224 
playvk::ImageToBufferCopy225 	void play(CommandBuffer::ExecutionState& executionState)
226 	{
227 		Cast(srcImage)->copyTo(dstBuffer, region);
228 	}
229 
230 private:
231 	VkImage srcImage;
232 	VkBuffer dstBuffer;
233 	const VkBufferImageCopy region;
234 };
235 
236 struct BufferToImageCopy : public CommandBuffer::Command
237 {
BufferToImageCopyvk::BufferToImageCopy238 	BufferToImageCopy(VkBuffer pSrcBuffer, VkImage pDstImage, const VkBufferImageCopy& pRegion) :
239 		srcBuffer(pSrcBuffer), dstImage(pDstImage), region(pRegion)
240 	{
241 	}
242 
playvk::BufferToImageCopy243 	void play(CommandBuffer::ExecutionState& executionState)
244 	{
245 		Cast(dstImage)->copyFrom(srcBuffer, region);
246 	}
247 
248 private:
249 	VkBuffer srcBuffer;
250 	VkImage dstImage;
251 	const VkBufferImageCopy region;
252 };
253 
254 struct FillBuffer : public CommandBuffer::Command
255 {
FillBuffervk::FillBuffer256 	FillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) :
257 		dstBuffer(dstBuffer), dstOffset(dstOffset), size(size), data(data)
258 	{
259 	}
260 
playvk::FillBuffer261 	void play(CommandBuffer::ExecutionState& executionState)
262 	{
263 		Cast(dstBuffer)->fill(dstOffset, size, data);
264 	}
265 
266 private:
267 	VkBuffer dstBuffer;
268 	VkDeviceSize dstOffset;
269 	VkDeviceSize size;
270 	uint32_t data;
271 };
272 
273 struct UpdateBuffer : public CommandBuffer::Command
274 {
UpdateBuffervk::UpdateBuffer275 	UpdateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData) :
276 		dstBuffer(dstBuffer), dstOffset(dstOffset), dataSize(dataSize), pData(pData)
277 	{
278 	}
279 
playvk::UpdateBuffer280 	void play(CommandBuffer::ExecutionState& executionState)
281 	{
282 		Cast(dstBuffer)->update(dstOffset, dataSize, pData);
283 	}
284 
285 private:
286 	VkBuffer dstBuffer;
287 	VkDeviceSize dstOffset;
288 	VkDeviceSize dataSize;
289 	const void* pData;
290 };
291 
292 struct ClearColorImage : public CommandBuffer::Command
293 {
ClearColorImagevk::ClearColorImage294 	ClearColorImage(VkImage image, const VkClearColorValue& color, const VkImageSubresourceRange& range) :
295 		image(image), color(color), range(range)
296 	{
297 	}
298 
playvk::ClearColorImage299 	void play(CommandBuffer::ExecutionState& executionState)
300 	{
301 		Cast(image)->clear(color, range);
302 	}
303 
304 private:
305 	VkImage image;
306 	const VkClearColorValue color;
307 	const VkImageSubresourceRange range;
308 };
309 
310 struct ClearDepthStencilImage : public CommandBuffer::Command
311 {
ClearDepthStencilImagevk::ClearDepthStencilImage312 	ClearDepthStencilImage(VkImage image, const VkClearDepthStencilValue& depthStencil, const VkImageSubresourceRange& range) :
313 		image(image), depthStencil(depthStencil), range(range)
314 	{
315 	}
316 
playvk::ClearDepthStencilImage317 	void play(CommandBuffer::ExecutionState& executionState)
318 	{
319 		Cast(image)->clear(depthStencil, range);
320 	}
321 
322 private:
323 	VkImage image;
324 	const VkClearDepthStencilValue depthStencil;
325 	const VkImageSubresourceRange range;
326 };
327 
328 struct ClearAttachment : public CommandBuffer::Command
329 {
ClearAttachmentvk::ClearAttachment330 	ClearAttachment(const VkClearAttachment& attachment, const VkClearRect& rect) :
331 		attachment(attachment), rect(rect)
332 	{
333 	}
334 
playvk::ClearAttachment335 	void play(CommandBuffer::ExecutionState& executionState)
336 	{
337 		executionState.renderPassFramebuffer->clear(attachment, rect);
338 	}
339 
340 private:
341 	const VkClearAttachment attachment;
342 	const VkClearRect rect;
343 };
344 
345 struct BlitImage : public CommandBuffer::Command
346 {
BlitImagevk::BlitImage347 	BlitImage(VkImage srcImage, VkImage dstImage, const VkImageBlit& region, VkFilter filter) :
348 		srcImage(srcImage), dstImage(dstImage), region(region), filter(filter)
349 	{
350 	}
351 
playvk::BlitImage352 	void play(CommandBuffer::ExecutionState& executionState)
353 	{
354 		Cast(srcImage)->blit(dstImage, region, filter);
355 	}
356 
357 private:
358 	VkImage srcImage;
359 	VkImage dstImage;
360 	const VkImageBlit& region;
361 	VkFilter filter;
362 };
363 
364 struct PipelineBarrier : public CommandBuffer::Command
365 {
PipelineBarriervk::PipelineBarrier366 	PipelineBarrier()
367 	{
368 	}
369 
playvk::PipelineBarrier370 	void play(CommandBuffer::ExecutionState& executionState)
371 	{
372 		// This can currently be a noop. The sw::Surface locking/unlocking mechanism used by the renderer already takes care of
373 		// making sure the read/writes always happen in order. Eventually, if we remove this synchronization mechanism, we can
374 		// have a very simple implementation that simply calls sw::Renderer::sync(), since the driver is free to move the source
375 		// stage towards the bottom of the pipe and the target stage towards the top, so a full pipeline sync is spec compliant.
376 
377 		// Right now all buffers are read-only in drawcalls but a similar mechanism will be required once we support SSBOs.
378 
379 		// Also note that this would be a good moment to update cube map borders or decompress compressed textures, if necessary.
380 	}
381 
382 private:
383 };
384 
385 struct SignalEvent : public CommandBuffer::Command
386 {
SignalEventvk::SignalEvent387 	SignalEvent(VkEvent ev, VkPipelineStageFlags stageMask) : ev(ev), stageMask(stageMask)
388 	{
389 	}
390 
playvk::SignalEvent391 	void play(CommandBuffer::ExecutionState& executionState)
392 	{
393 		Cast(ev)->signal();
394 	}
395 
396 private:
397 	VkEvent ev;
398 	VkPipelineStageFlags stageMask; // FIXME(b/117835459) : We currently ignore the flags and signal the event at the last stage
399 };
400 
401 struct ResetEvent : public CommandBuffer::Command
402 {
ResetEventvk::ResetEvent403 	ResetEvent(VkEvent ev, VkPipelineStageFlags stageMask) : ev(ev), stageMask(stageMask)
404 	{
405 	}
406 
playvk::ResetEvent407 	void play(CommandBuffer::ExecutionState& executionState)
408 	{
409 		Cast(ev)->reset();
410 	}
411 
412 private:
413 	VkEvent ev;
414 	VkPipelineStageFlags stageMask; // FIXME(b/117835459) : We currently ignore the flags and reset the event at the last stage
415 };
416 
CommandBuffer(VkCommandBufferLevel pLevel)417 CommandBuffer::CommandBuffer(VkCommandBufferLevel pLevel) : level(pLevel)
418 {
419 	// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
420 	commands = new std::vector<std::unique_ptr<Command> >();
421 }
422 
destroy(const VkAllocationCallbacks * pAllocator)423 void CommandBuffer::destroy(const VkAllocationCallbacks* pAllocator)
424 {
425 	delete commands;
426 }
427 
resetState()428 void CommandBuffer::resetState()
429 {
430 	// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
431 	commands->clear();
432 
433 	state = INITIAL;
434 }
435 
begin(VkCommandBufferUsageFlags flags,const VkCommandBufferInheritanceInfo * pInheritanceInfo)436 VkResult CommandBuffer::begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo* pInheritanceInfo)
437 {
438 	ASSERT((state != RECORDING) && (state != PENDING));
439 
440 	if(!((flags == 0) || (flags == VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)) || pInheritanceInfo)
441 	{
442 		UNIMPLEMENTED();
443 	}
444 
445 	if(state != INITIAL)
446 	{
447 		// Implicit reset
448 		resetState();
449 	}
450 
451 	state = RECORDING;
452 
453 	return VK_SUCCESS;
454 }
455 
end()456 VkResult CommandBuffer::end()
457 {
458 	ASSERT(state == RECORDING);
459 
460 	state = EXECUTABLE;
461 
462 	return VK_SUCCESS;
463 }
464 
reset(VkCommandPoolResetFlags flags)465 VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags)
466 {
467 	ASSERT(state != PENDING);
468 
469 	resetState();
470 
471 	return VK_SUCCESS;
472 }
473 
474 template<typename T, typename... Args>
addCommand(Args &&...args)475 void CommandBuffer::addCommand(Args&&... args)
476 {
477 	commands->push_back(std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
478 }
479 
beginRenderPass(VkRenderPass renderPass,VkFramebuffer framebuffer,VkRect2D renderArea,uint32_t clearValueCount,const VkClearValue * clearValues,VkSubpassContents contents)480 void CommandBuffer::beginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
481                                     uint32_t clearValueCount, const VkClearValue* clearValues, VkSubpassContents contents)
482 {
483 	ASSERT(state == RECORDING);
484 
485 	if(contents != VK_SUBPASS_CONTENTS_INLINE)
486 	{
487 		UNIMPLEMENTED();
488 	}
489 
490 	addCommand<BeginRenderPass>(renderPass, framebuffer, renderArea, clearValueCount, clearValues);
491 }
492 
nextSubpass(VkSubpassContents contents)493 void CommandBuffer::nextSubpass(VkSubpassContents contents)
494 {
495 	ASSERT(state == RECORDING);
496 
497 	addCommand<NextSubpass>();
498 }
499 
endRenderPass()500 void CommandBuffer::endRenderPass()
501 {
502 	addCommand<EndRenderPass>();
503 }
504 
executeCommands(uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)505 void CommandBuffer::executeCommands(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
506 {
507 	UNIMPLEMENTED();
508 }
509 
setDeviceMask(uint32_t deviceMask)510 void CommandBuffer::setDeviceMask(uint32_t deviceMask)
511 {
512 	UNIMPLEMENTED();
513 }
514 
dispatchBase(uint32_t baseGroupX,uint32_t baseGroupY,uint32_t baseGroupZ,uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)515 void CommandBuffer::dispatchBase(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
516                                  uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
517 {
518 	UNIMPLEMENTED();
519 }
520 
pipelineBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkDependencyFlags dependencyFlags,uint32_t memoryBarrierCount,const VkMemoryBarrier * pMemoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * pBufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * pImageMemoryBarriers)521 void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
522                                     VkDependencyFlags dependencyFlags,
523                                     uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
524                                     uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
525                                     uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
526 {
527 	addCommand<PipelineBarrier>();
528 }
529 
bindPipeline(VkPipelineBindPoint pipelineBindPoint,VkPipeline pipeline)530 void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
531 {
532 	if(pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS)
533 	{
534 		UNIMPLEMENTED();
535 	}
536 
537 	addCommand<PipelineBind>(pipelineBindPoint, pipeline);
538 }
539 
bindVertexBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets)540 void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
541                                       const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
542 {
543 	for(uint32_t i = firstBinding; i < (firstBinding + bindingCount); ++i)
544 	{
545 		addCommand<VertexBufferBind>(i, pBuffers[i], pOffsets[i]);
546 	}
547 }
548 
beginQuery(VkQueryPool queryPool,uint32_t query,VkQueryControlFlags flags)549 void CommandBuffer::beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
550 {
551 	UNIMPLEMENTED();
552 }
553 
endQuery(VkQueryPool queryPool,uint32_t query)554 void CommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
555 {
556 	UNIMPLEMENTED();
557 }
558 
resetQueryPool(VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount)559 void CommandBuffer::resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
560 {
561 	UNIMPLEMENTED();
562 }
563 
writeTimestamp(VkPipelineStageFlagBits pipelineStage,VkQueryPool queryPool,uint32_t query)564 void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
565 {
566 	UNIMPLEMENTED();
567 }
568 
copyQueryPoolResults(VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize stride,VkQueryResultFlags flags)569 void CommandBuffer::copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
570 	VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
571 {
572 	UNIMPLEMENTED();
573 }
574 
pushConstants(VkPipelineLayout layout,VkShaderStageFlags stageFlags,uint32_t offset,uint32_t size,const void * pValues)575 void CommandBuffer::pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags,
576 	uint32_t offset, uint32_t size, const void* pValues)
577 {
578 	UNIMPLEMENTED();
579 }
580 
setViewport(uint32_t firstViewport,uint32_t viewportCount,const VkViewport * pViewports)581 void CommandBuffer::setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
582 {
583 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled
584 	UNIMPLEMENTED();
585 }
586 
setScissor(uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * pScissors)587 void CommandBuffer::setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
588 {
589 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_SCISSOR dynamic state enabled
590 	UNIMPLEMENTED();
591 }
592 
setLineWidth(float lineWidth)593 void CommandBuffer::setLineWidth(float lineWidth)
594 {
595 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled
596 
597 	// If the wide lines feature is not enabled, lineWidth must be 1.0
598 	ASSERT(lineWidth == 1.0f);
599 
600 	UNIMPLEMENTED();
601 }
602 
setDepthBias(float depthBiasConstantFactor,float depthBiasClamp,float depthBiasSlopeFactor)603 void CommandBuffer::setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
604 {
605 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled
606 
607 	// If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0
608 	ASSERT(depthBiasClamp == 0.0f);
609 
610 	UNIMPLEMENTED();
611 }
612 
setBlendConstants(const float blendConstants[4])613 void CommandBuffer::setBlendConstants(const float blendConstants[4])
614 {
615 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled
616 
617 	// blendConstants is an array of four values specifying the R, G, B, and A components
618 	// of the blend constant color used in blending, depending on the blend factor.
619 
620 	UNIMPLEMENTED();
621 }
622 
setDepthBounds(float minDepthBounds,float maxDepthBounds)623 void CommandBuffer::setDepthBounds(float minDepthBounds, float maxDepthBounds)
624 {
625 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state enabled
626 
627 	// Unless the VK_EXT_depth_range_unrestricted extension is enabled minDepthBounds and maxDepthBounds must be between 0.0 and 1.0, inclusive
628 	ASSERT(minDepthBounds >= 0.0f && minDepthBounds <= 1.0f);
629 	ASSERT(maxDepthBounds >= 0.0f && maxDepthBounds <= 1.0f);
630 
631 	UNIMPLEMENTED();
632 }
633 
setStencilCompareMask(VkStencilFaceFlags faceMask,uint32_t compareMask)634 void CommandBuffer::setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask)
635 {
636 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled
637 
638 	// faceMask must not be 0
639 	ASSERT(faceMask != 0);
640 
641 	UNIMPLEMENTED();
642 }
643 
setStencilWriteMask(VkStencilFaceFlags faceMask,uint32_t writeMask)644 void CommandBuffer::setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask)
645 {
646 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled
647 
648 	// faceMask must not be 0
649 	ASSERT(faceMask != 0);
650 
651 	UNIMPLEMENTED();
652 }
653 
setStencilReference(VkStencilFaceFlags faceMask,uint32_t reference)654 void CommandBuffer::setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference)
655 {
656 	// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled
657 
658 	// faceMask must not be 0
659 	ASSERT(faceMask != 0);
660 
661 	UNIMPLEMENTED();
662 }
663 
bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)664 void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
665 	uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
666 	uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
667 {
668 	UNIMPLEMENTED();
669 }
670 
bindIndexBuffer(VkBuffer buffer,VkDeviceSize offset,VkIndexType indexType)671 void CommandBuffer::bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
672 {
673 	UNIMPLEMENTED();
674 }
675 
dispatch(uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)676 void CommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
677 {
678 	UNIMPLEMENTED();
679 }
680 
dispatchIndirect(VkBuffer buffer,VkDeviceSize offset)681 void CommandBuffer::dispatchIndirect(VkBuffer buffer, VkDeviceSize offset)
682 {
683 	UNIMPLEMENTED();
684 }
685 
copyBuffer(VkBuffer srcBuffer,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferCopy * pRegions)686 void CommandBuffer::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
687 {
688 	ASSERT(state == RECORDING);
689 
690 	for(uint32_t i = 0; i < regionCount; i++)
691 	{
692 		addCommand<BufferToBufferCopy>(srcBuffer, dstBuffer, pRegions[i]);
693 	}
694 }
695 
copyImage(VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * pRegions)696 void CommandBuffer::copyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
697 	uint32_t regionCount, const VkImageCopy* pRegions)
698 {
699 	ASSERT(state == RECORDING);
700 	ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
701 	       srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
702 	ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
703 	       dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
704 
705 	for(uint32_t i = 0; i < regionCount; i++)
706 	{
707 		addCommand<ImageToImageCopy>(srcImage, dstImage, pRegions[i]);
708 	}
709 }
710 
blitImage(VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * pRegions,VkFilter filter)711 void CommandBuffer::blitImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
712 	uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
713 {
714 	ASSERT(state == RECORDING);
715 	ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
716 	       srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
717 	ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
718 	       dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
719 
720 	for(uint32_t i = 0; i < regionCount; i++)
721 	{
722 		addCommand<BlitImage>(srcImage, dstImage, pRegions[i], filter);
723 	}
724 }
725 
copyBufferToImage(VkBuffer srcBuffer,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * pRegions)726 void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout,
727 	uint32_t regionCount, const VkBufferImageCopy* pRegions)
728 {
729 	ASSERT(state == RECORDING);
730 
731 	for(uint32_t i = 0; i < regionCount; i++)
732 	{
733 		addCommand<BufferToImageCopy>(srcBuffer, dstImage, pRegions[i]);
734 	}
735 }
736 
copyImageToBuffer(VkImage srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * pRegions)737 void CommandBuffer::copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer,
738 	uint32_t regionCount, const VkBufferImageCopy* pRegions)
739 {
740 	ASSERT(state == RECORDING);
741 	ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
742 
743 	for(uint32_t i = 0; i < regionCount; i++)
744 	{
745 		addCommand<ImageToBufferCopy>(srcImage, dstBuffer, pRegions[i]);
746 	}
747 }
748 
updateBuffer(VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize dataSize,const void * pData)749 void CommandBuffer::updateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
750 {
751 	ASSERT(state == RECORDING);
752 
753 	addCommand<UpdateBuffer>(dstBuffer, dstOffset, dataSize, pData);
754 }
755 
fillBuffer(VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)756 void CommandBuffer::fillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
757 {
758 	ASSERT(state == RECORDING);
759 
760 	addCommand<FillBuffer>(dstBuffer, dstOffset, size, data);
761 }
762 
clearColorImage(VkImage image,VkImageLayout imageLayout,const VkClearColorValue * pColor,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)763 void CommandBuffer::clearColorImage(VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
764 	uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
765 {
766 	ASSERT(state == RECORDING);
767 
768 	for(uint32_t i = 0; i < rangeCount; i++)
769 	{
770 		addCommand<ClearColorImage>(image, pColor[i], pRanges[i]);
771 	}
772 }
773 
clearDepthStencilImage(VkImage image,VkImageLayout imageLayout,const VkClearDepthStencilValue * pDepthStencil,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)774 void CommandBuffer::clearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
775 	uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
776 {
777 	ASSERT(state == RECORDING);
778 
779 	for(uint32_t i = 0; i < rangeCount; i++)
780 	{
781 		addCommand<ClearDepthStencilImage>(image, pDepthStencil[i], pRanges[i]);
782 	}
783 }
784 
clearAttachments(uint32_t attachmentCount,const VkClearAttachment * pAttachments,uint32_t rectCount,const VkClearRect * pRects)785 void CommandBuffer::clearAttachments(uint32_t attachmentCount, const VkClearAttachment* pAttachments,
786 	uint32_t rectCount, const VkClearRect* pRects)
787 {
788 	ASSERT(state == RECORDING);
789 
790 	for(uint32_t i = 0; i < attachmentCount; i++)
791 	{
792 		for(uint32_t j = 0; j < rectCount; j++)
793 		{
794 			addCommand<ClearAttachment>(pAttachments[i], pRects[j]);
795 		}
796 	}
797 }
798 
resolveImage(VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageResolve * pRegions)799 void CommandBuffer::resolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
800 	uint32_t regionCount, const VkImageResolve* pRegions)
801 {
802 	UNIMPLEMENTED();
803 }
804 
setEvent(VkEvent event,VkPipelineStageFlags stageMask)805 void CommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
806 {
807 	ASSERT(state == RECORDING);
808 
809 	addCommand<SignalEvent>(event, stageMask);
810 }
811 
resetEvent(VkEvent event,VkPipelineStageFlags stageMask)812 void CommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
813 {
814 	ASSERT(state == RECORDING);
815 
816 	addCommand<ResetEvent>(event, stageMask);
817 }
818 
waitEvents(uint32_t eventCount,const VkEvent * pEvents,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,uint32_t memoryBarrierCount,const VkMemoryBarrier * pMemoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * pBufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * pImageMemoryBarriers)819 void CommandBuffer::waitEvents(uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask,
820 	VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
821 	uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
822 	uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
823 {
824 	UNIMPLEMENTED();
825 }
826 
draw(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)827 void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
828 {
829 	addCommand<Draw>(vertexCount, instanceCount, firstVertex, firstInstance);
830 }
831 
drawIndexed(uint32_t indexCount,uint32_t instanceCount,uint32_t firstIndex,int32_t vertexOffset,uint32_t firstInstance)832 void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
833 {
834 	UNIMPLEMENTED();
835 }
836 
drawIndirect(VkBuffer buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)837 void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
838 {
839 	UNIMPLEMENTED();
840 }
841 
drawIndexedIndirect(VkBuffer buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)842 void CommandBuffer::drawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
843 {
844 	UNIMPLEMENTED();
845 }
846 
submit(CommandBuffer::ExecutionState & executionState)847 void CommandBuffer::submit(CommandBuffer::ExecutionState& executionState)
848 {
849 	// Perform recorded work
850 	state = PENDING;
851 
852 	for(auto& command : *commands)
853 	{
854 		command->play(executionState);
855 	}
856 
857 	// After work is completed
858 	state = EXECUTABLE;
859 }
860 
861 } // namespace vk
862