xref: /aosp_15_r20/external/swiftshader/tests/VulkanWrapper/DrawTester.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2021 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "DrawTester.hpp"
16*03ce13f7SAndroid Build Coastguard Worker 
17*03ce13f7SAndroid Build Coastguard Worker #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
18*03ce13f7SAndroid Build Coastguard Worker 
DrawTester(Multisample multisample)19*03ce13f7SAndroid Build Coastguard Worker DrawTester::DrawTester(Multisample multisample)
20*03ce13f7SAndroid Build Coastguard Worker     : multisample(multisample == Multisample::True)
21*03ce13f7SAndroid Build Coastguard Worker {
22*03ce13f7SAndroid Build Coastguard Worker }
23*03ce13f7SAndroid Build Coastguard Worker 
~DrawTester()24*03ce13f7SAndroid Build Coastguard Worker DrawTester::~DrawTester()
25*03ce13f7SAndroid Build Coastguard Worker {
26*03ce13f7SAndroid Build Coastguard Worker 	device.freeCommandBuffers(commandPool, commandBuffers);
27*03ce13f7SAndroid Build Coastguard Worker 
28*03ce13f7SAndroid Build Coastguard Worker 	device.destroyDescriptorPool(descriptorPool);
29*03ce13f7SAndroid Build Coastguard Worker 	for(auto &sampler : samplers)
30*03ce13f7SAndroid Build Coastguard Worker 	{
31*03ce13f7SAndroid Build Coastguard Worker 		device.destroySampler(sampler, nullptr);
32*03ce13f7SAndroid Build Coastguard Worker 	}
33*03ce13f7SAndroid Build Coastguard Worker 	images.clear();
34*03ce13f7SAndroid Build Coastguard Worker 	device.destroyCommandPool(commandPool, nullptr);
35*03ce13f7SAndroid Build Coastguard Worker 
36*03ce13f7SAndroid Build Coastguard Worker 	for(auto &fence : waitFences)
37*03ce13f7SAndroid Build Coastguard Worker 	{
38*03ce13f7SAndroid Build Coastguard Worker 		device.destroyFence(fence, nullptr);
39*03ce13f7SAndroid Build Coastguard Worker 	}
40*03ce13f7SAndroid Build Coastguard Worker 
41*03ce13f7SAndroid Build Coastguard Worker 	device.destroySemaphore(renderCompleteSemaphore, nullptr);
42*03ce13f7SAndroid Build Coastguard Worker 	device.destroySemaphore(presentCompleteSemaphore, nullptr);
43*03ce13f7SAndroid Build Coastguard Worker 
44*03ce13f7SAndroid Build Coastguard Worker 	device.destroyPipeline(pipeline);
45*03ce13f7SAndroid Build Coastguard Worker 	device.destroyPipelineLayout(pipelineLayout, nullptr);
46*03ce13f7SAndroid Build Coastguard Worker 	device.destroyDescriptorSetLayout(descriptorSetLayout);
47*03ce13f7SAndroid Build Coastguard Worker 
48*03ce13f7SAndroid Build Coastguard Worker 	device.freeMemory(vertices.memory, nullptr);
49*03ce13f7SAndroid Build Coastguard Worker 	device.destroyBuffer(vertices.buffer, nullptr);
50*03ce13f7SAndroid Build Coastguard Worker 
51*03ce13f7SAndroid Build Coastguard Worker 	for(auto &framebuffer : framebuffers)
52*03ce13f7SAndroid Build Coastguard Worker 	{
53*03ce13f7SAndroid Build Coastguard Worker 		framebuffer.reset();
54*03ce13f7SAndroid Build Coastguard Worker 	}
55*03ce13f7SAndroid Build Coastguard Worker 
56*03ce13f7SAndroid Build Coastguard Worker 	device.destroyRenderPass(renderPass, nullptr);
57*03ce13f7SAndroid Build Coastguard Worker 
58*03ce13f7SAndroid Build Coastguard Worker 	swapchain.reset();
59*03ce13f7SAndroid Build Coastguard Worker 	window.reset();
60*03ce13f7SAndroid Build Coastguard Worker }
61*03ce13f7SAndroid Build Coastguard Worker 
initialize()62*03ce13f7SAndroid Build Coastguard Worker void DrawTester::initialize()
63*03ce13f7SAndroid Build Coastguard Worker {
64*03ce13f7SAndroid Build Coastguard Worker 	VulkanTester::initialize();
65*03ce13f7SAndroid Build Coastguard Worker 
66*03ce13f7SAndroid Build Coastguard Worker 	window.reset(new Window(instance, windowSize));
67*03ce13f7SAndroid Build Coastguard Worker 	swapchain.reset(new Swapchain(physicalDevice, device, *window));
68*03ce13f7SAndroid Build Coastguard Worker 
69*03ce13f7SAndroid Build Coastguard Worker 	renderPass = createRenderPass(swapchain->colorFormat);
70*03ce13f7SAndroid Build Coastguard Worker 	createFramebuffers(renderPass);
71*03ce13f7SAndroid Build Coastguard Worker 
72*03ce13f7SAndroid Build Coastguard Worker 	prepareVertices();
73*03ce13f7SAndroid Build Coastguard Worker 
74*03ce13f7SAndroid Build Coastguard Worker 	pipeline = createGraphicsPipeline(renderPass);
75*03ce13f7SAndroid Build Coastguard Worker 
76*03ce13f7SAndroid Build Coastguard Worker 	createSynchronizationPrimitives();
77*03ce13f7SAndroid Build Coastguard Worker 
78*03ce13f7SAndroid Build Coastguard Worker 	createCommandBuffers(renderPass);
79*03ce13f7SAndroid Build Coastguard Worker }
80*03ce13f7SAndroid Build Coastguard Worker 
renderFrame()81*03ce13f7SAndroid Build Coastguard Worker void DrawTester::renderFrame()
82*03ce13f7SAndroid Build Coastguard Worker {
83*03ce13f7SAndroid Build Coastguard Worker 	swapchain->acquireNextImage(presentCompleteSemaphore, currentFrameBuffer);
84*03ce13f7SAndroid Build Coastguard Worker 
85*03ce13f7SAndroid Build Coastguard Worker 	device.waitForFences(1, &waitFences[currentFrameBuffer], VK_TRUE, UINT64_MAX);
86*03ce13f7SAndroid Build Coastguard Worker 	device.resetFences(1, &waitFences[currentFrameBuffer]);
87*03ce13f7SAndroid Build Coastguard Worker 
88*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineStageFlags waitStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
89*03ce13f7SAndroid Build Coastguard Worker 
90*03ce13f7SAndroid Build Coastguard Worker 	vk::SubmitInfo submitInfo;
91*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.pWaitDstStageMask = &waitStageMask;
92*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.pWaitSemaphores = &presentCompleteSemaphore;
93*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.waitSemaphoreCount = 1;
94*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.pSignalSemaphores = &renderCompleteSemaphore;
95*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.signalSemaphoreCount = 1;
96*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.pCommandBuffers = &commandBuffers[currentFrameBuffer];
97*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.commandBufferCount = 1;
98*03ce13f7SAndroid Build Coastguard Worker 
99*03ce13f7SAndroid Build Coastguard Worker 	queue.submit(1, &submitInfo, waitFences[currentFrameBuffer]);
100*03ce13f7SAndroid Build Coastguard Worker 
101*03ce13f7SAndroid Build Coastguard Worker 	swapchain->queuePresent(queue, currentFrameBuffer, renderCompleteSemaphore);
102*03ce13f7SAndroid Build Coastguard Worker }
103*03ce13f7SAndroid Build Coastguard Worker 
show()104*03ce13f7SAndroid Build Coastguard Worker void DrawTester::show()
105*03ce13f7SAndroid Build Coastguard Worker {
106*03ce13f7SAndroid Build Coastguard Worker 	window->show();
107*03ce13f7SAndroid Build Coastguard Worker }
108*03ce13f7SAndroid Build Coastguard Worker 
createRenderPass(vk::Format colorFormat)109*03ce13f7SAndroid Build Coastguard Worker vk::RenderPass DrawTester::createRenderPass(vk::Format colorFormat)
110*03ce13f7SAndroid Build Coastguard Worker {
111*03ce13f7SAndroid Build Coastguard Worker 	std::vector<vk::AttachmentDescription> attachments(multisample ? 2 : 1);
112*03ce13f7SAndroid Build Coastguard Worker 
113*03ce13f7SAndroid Build Coastguard Worker 	if(multisample)
114*03ce13f7SAndroid Build Coastguard Worker 	{
115*03ce13f7SAndroid Build Coastguard Worker 		// Color attachment
116*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].format = colorFormat;
117*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].samples = vk::SampleCountFlagBits::e4;
118*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].loadOp = vk::AttachmentLoadOp::eClear;
119*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].storeOp = vk::AttachmentStoreOp::eStore;
120*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
121*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
122*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].initialLayout = vk::ImageLayout::eUndefined;
123*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].finalLayout = vk::ImageLayout::eColorAttachmentOptimal;
124*03ce13f7SAndroid Build Coastguard Worker 
125*03ce13f7SAndroid Build Coastguard Worker 		// Resolve attachment
126*03ce13f7SAndroid Build Coastguard Worker 		attachments[1].format = colorFormat;
127*03ce13f7SAndroid Build Coastguard Worker 		attachments[1].samples = vk::SampleCountFlagBits::e1;
128*03ce13f7SAndroid Build Coastguard Worker 		attachments[1].loadOp = vk::AttachmentLoadOp::eDontCare;
129*03ce13f7SAndroid Build Coastguard Worker 		attachments[1].storeOp = vk::AttachmentStoreOp::eStore;
130*03ce13f7SAndroid Build Coastguard Worker 		attachments[1].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
131*03ce13f7SAndroid Build Coastguard Worker 		attachments[1].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
132*03ce13f7SAndroid Build Coastguard Worker 		attachments[1].initialLayout = vk::ImageLayout::eUndefined;
133*03ce13f7SAndroid Build Coastguard Worker 		attachments[1].finalLayout = vk::ImageLayout::ePresentSrcKHR;
134*03ce13f7SAndroid Build Coastguard Worker 	}
135*03ce13f7SAndroid Build Coastguard Worker 	else
136*03ce13f7SAndroid Build Coastguard Worker 	{
137*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].format = colorFormat;
138*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].samples = vk::SampleCountFlagBits::e1;
139*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].loadOp = vk::AttachmentLoadOp::eDontCare;
140*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].storeOp = vk::AttachmentStoreOp::eStore;
141*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
142*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
143*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].initialLayout = vk::ImageLayout::eUndefined;
144*03ce13f7SAndroid Build Coastguard Worker 		attachments[0].finalLayout = vk::ImageLayout::ePresentSrcKHR;
145*03ce13f7SAndroid Build Coastguard Worker 	}
146*03ce13f7SAndroid Build Coastguard Worker 
147*03ce13f7SAndroid Build Coastguard Worker 	vk::AttachmentReference attachment0;
148*03ce13f7SAndroid Build Coastguard Worker 	attachment0.attachment = 0;
149*03ce13f7SAndroid Build Coastguard Worker 	attachment0.layout = vk::ImageLayout::eColorAttachmentOptimal;
150*03ce13f7SAndroid Build Coastguard Worker 
151*03ce13f7SAndroid Build Coastguard Worker 	vk::AttachmentReference attachment1;
152*03ce13f7SAndroid Build Coastguard Worker 	attachment1.attachment = 1;
153*03ce13f7SAndroid Build Coastguard Worker 	attachment1.layout = vk::ImageLayout::eColorAttachmentOptimal;
154*03ce13f7SAndroid Build Coastguard Worker 
155*03ce13f7SAndroid Build Coastguard Worker 	vk::SubpassDescription subpassDescription;
156*03ce13f7SAndroid Build Coastguard Worker 	subpassDescription.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
157*03ce13f7SAndroid Build Coastguard Worker 	subpassDescription.colorAttachmentCount = 1;
158*03ce13f7SAndroid Build Coastguard Worker 	subpassDescription.pResolveAttachments = multisample ? &attachment1 : nullptr;
159*03ce13f7SAndroid Build Coastguard Worker 	subpassDescription.pColorAttachments = &attachment0;
160*03ce13f7SAndroid Build Coastguard Worker 
161*03ce13f7SAndroid Build Coastguard Worker 	std::array<vk::SubpassDependency, 2> dependencies;
162*03ce13f7SAndroid Build Coastguard Worker 
163*03ce13f7SAndroid Build Coastguard Worker 	dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
164*03ce13f7SAndroid Build Coastguard Worker 	dependencies[0].dstSubpass = 0;
165*03ce13f7SAndroid Build Coastguard Worker 	dependencies[0].srcStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
166*03ce13f7SAndroid Build Coastguard Worker 	dependencies[0].dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
167*03ce13f7SAndroid Build Coastguard Worker 	dependencies[0].srcAccessMask = vk::AccessFlagBits::eMemoryRead;
168*03ce13f7SAndroid Build Coastguard Worker 	dependencies[0].dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
169*03ce13f7SAndroid Build Coastguard Worker 	dependencies[0].dependencyFlags = vk::DependencyFlagBits::eByRegion;
170*03ce13f7SAndroid Build Coastguard Worker 
171*03ce13f7SAndroid Build Coastguard Worker 	dependencies[1].srcSubpass = 0;
172*03ce13f7SAndroid Build Coastguard Worker 	dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
173*03ce13f7SAndroid Build Coastguard Worker 	dependencies[1].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
174*03ce13f7SAndroid Build Coastguard Worker 	dependencies[1].dstStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
175*03ce13f7SAndroid Build Coastguard Worker 	dependencies[1].srcAccessMask = vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite;
176*03ce13f7SAndroid Build Coastguard Worker 	dependencies[1].dstAccessMask = vk::AccessFlagBits::eMemoryRead;
177*03ce13f7SAndroid Build Coastguard Worker 	dependencies[1].dependencyFlags = vk::DependencyFlagBits::eByRegion;
178*03ce13f7SAndroid Build Coastguard Worker 
179*03ce13f7SAndroid Build Coastguard Worker 	vk::RenderPassCreateInfo renderPassInfo;
180*03ce13f7SAndroid Build Coastguard Worker 	renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
181*03ce13f7SAndroid Build Coastguard Worker 	renderPassInfo.pAttachments = attachments.data();
182*03ce13f7SAndroid Build Coastguard Worker 	renderPassInfo.subpassCount = 1;
183*03ce13f7SAndroid Build Coastguard Worker 	renderPassInfo.pSubpasses = &subpassDescription;
184*03ce13f7SAndroid Build Coastguard Worker 	renderPassInfo.dependencyCount = static_cast<uint32_t>(dependencies.size());
185*03ce13f7SAndroid Build Coastguard Worker 	renderPassInfo.pDependencies = dependencies.data();
186*03ce13f7SAndroid Build Coastguard Worker 
187*03ce13f7SAndroid Build Coastguard Worker 	return device.createRenderPass(renderPassInfo);
188*03ce13f7SAndroid Build Coastguard Worker }
189*03ce13f7SAndroid Build Coastguard Worker 
createFramebuffers(vk::RenderPass renderPass)190*03ce13f7SAndroid Build Coastguard Worker void DrawTester::createFramebuffers(vk::RenderPass renderPass)
191*03ce13f7SAndroid Build Coastguard Worker {
192*03ce13f7SAndroid Build Coastguard Worker 	framebuffers.resize(swapchain->imageCount());
193*03ce13f7SAndroid Build Coastguard Worker 
194*03ce13f7SAndroid Build Coastguard Worker 	for(size_t i = 0; i < framebuffers.size(); i++)
195*03ce13f7SAndroid Build Coastguard Worker 	{
196*03ce13f7SAndroid Build Coastguard Worker 		framebuffers[i].reset(new Framebuffer(device, physicalDevice, swapchain->getImageView(i), swapchain->colorFormat, renderPass, swapchain->getExtent(), multisample));
197*03ce13f7SAndroid Build Coastguard Worker 	}
198*03ce13f7SAndroid Build Coastguard Worker }
199*03ce13f7SAndroid Build Coastguard Worker 
prepareVertices()200*03ce13f7SAndroid Build Coastguard Worker void DrawTester::prepareVertices()
201*03ce13f7SAndroid Build Coastguard Worker {
202*03ce13f7SAndroid Build Coastguard Worker 	hooks.createVertexBuffers(*this);
203*03ce13f7SAndroid Build Coastguard Worker }
204*03ce13f7SAndroid Build Coastguard Worker 
createGraphicsPipeline(vk::RenderPass renderPass)205*03ce13f7SAndroid Build Coastguard Worker vk::Pipeline DrawTester::createGraphicsPipeline(vk::RenderPass renderPass)
206*03ce13f7SAndroid Build Coastguard Worker {
207*03ce13f7SAndroid Build Coastguard Worker 	auto setLayoutBindings = hooks.createDescriptorSetLayout(*this);
208*03ce13f7SAndroid Build Coastguard Worker 
209*03ce13f7SAndroid Build Coastguard Worker 	std::vector<vk::DescriptorSetLayout> setLayouts;
210*03ce13f7SAndroid Build Coastguard Worker 	if(!setLayoutBindings.empty())
211*03ce13f7SAndroid Build Coastguard Worker 	{
212*03ce13f7SAndroid Build Coastguard Worker 		vk::DescriptorSetLayoutCreateInfo layoutInfo;
213*03ce13f7SAndroid Build Coastguard Worker 		layoutInfo.bindingCount = static_cast<uint32_t>(setLayoutBindings.size());
214*03ce13f7SAndroid Build Coastguard Worker 		layoutInfo.pBindings = setLayoutBindings.data();
215*03ce13f7SAndroid Build Coastguard Worker 		descriptorSetLayout = device.createDescriptorSetLayout(layoutInfo);
216*03ce13f7SAndroid Build Coastguard Worker 
217*03ce13f7SAndroid Build Coastguard Worker 		setLayouts.push_back(descriptorSetLayout);
218*03ce13f7SAndroid Build Coastguard Worker 	}
219*03ce13f7SAndroid Build Coastguard Worker 
220*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
221*03ce13f7SAndroid Build Coastguard Worker 	pipelineLayoutCreateInfo.setLayoutCount = static_cast<uint32_t>(setLayouts.size());
222*03ce13f7SAndroid Build Coastguard Worker 	pipelineLayoutCreateInfo.pSetLayouts = setLayouts.data();
223*03ce13f7SAndroid Build Coastguard Worker 	pipelineLayout = device.createPipelineLayout(pipelineLayoutCreateInfo);
224*03ce13f7SAndroid Build Coastguard Worker 
225*03ce13f7SAndroid Build Coastguard Worker 	vk::GraphicsPipelineCreateInfo pipelineCreateInfo;
226*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.layout = pipelineLayout;
227*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.renderPass = renderPass;
228*03ce13f7SAndroid Build Coastguard Worker 
229*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineInputAssemblyStateCreateInfo inputAssemblyState;
230*03ce13f7SAndroid Build Coastguard Worker 	inputAssemblyState.topology = vk::PrimitiveTopology::eTriangleList;
231*03ce13f7SAndroid Build Coastguard Worker 
232*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineRasterizationStateCreateInfo rasterizationState;
233*03ce13f7SAndroid Build Coastguard Worker 	rasterizationState.depthClampEnable = VK_FALSE;
234*03ce13f7SAndroid Build Coastguard Worker 	rasterizationState.rasterizerDiscardEnable = VK_FALSE;
235*03ce13f7SAndroid Build Coastguard Worker 	rasterizationState.polygonMode = vk::PolygonMode::eFill;
236*03ce13f7SAndroid Build Coastguard Worker 	rasterizationState.cullMode = vk::CullModeFlagBits::eNone;
237*03ce13f7SAndroid Build Coastguard Worker 	rasterizationState.frontFace = vk::FrontFace::eCounterClockwise;
238*03ce13f7SAndroid Build Coastguard Worker 	rasterizationState.depthBiasEnable = VK_FALSE;
239*03ce13f7SAndroid Build Coastguard Worker 	rasterizationState.lineWidth = 1.0f;
240*03ce13f7SAndroid Build Coastguard Worker 
241*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineColorBlendAttachmentState blendAttachmentState;
242*03ce13f7SAndroid Build Coastguard Worker 	blendAttachmentState.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA;
243*03ce13f7SAndroid Build Coastguard Worker 	blendAttachmentState.blendEnable = VK_FALSE;
244*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineColorBlendStateCreateInfo colorBlendState;
245*03ce13f7SAndroid Build Coastguard Worker 	colorBlendState.attachmentCount = 1;
246*03ce13f7SAndroid Build Coastguard Worker 	colorBlendState.pAttachments = &blendAttachmentState;
247*03ce13f7SAndroid Build Coastguard Worker 
248*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineViewportStateCreateInfo viewportState;
249*03ce13f7SAndroid Build Coastguard Worker 	viewportState.viewportCount = 1;
250*03ce13f7SAndroid Build Coastguard Worker 	viewportState.scissorCount = 1;
251*03ce13f7SAndroid Build Coastguard Worker 
252*03ce13f7SAndroid Build Coastguard Worker 	std::vector<vk::DynamicState> dynamicStateEnables;
253*03ce13f7SAndroid Build Coastguard Worker 	dynamicStateEnables.push_back(vk::DynamicState::eViewport);
254*03ce13f7SAndroid Build Coastguard Worker 	dynamicStateEnables.push_back(vk::DynamicState::eScissor);
255*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineDynamicStateCreateInfo dynamicState = {};
256*03ce13f7SAndroid Build Coastguard Worker 	dynamicState.pDynamicStates = dynamicStateEnables.data();
257*03ce13f7SAndroid Build Coastguard Worker 	dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStateEnables.size());
258*03ce13f7SAndroid Build Coastguard Worker 
259*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineDepthStencilStateCreateInfo depthStencilState;
260*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.depthTestEnable = VK_FALSE;
261*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.depthWriteEnable = VK_FALSE;
262*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.depthCompareOp = vk::CompareOp::eLessOrEqual;
263*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.depthBoundsTestEnable = VK_FALSE;
264*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.back.failOp = vk::StencilOp::eKeep;
265*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.back.passOp = vk::StencilOp::eKeep;
266*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.back.compareOp = vk::CompareOp::eAlways;
267*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.stencilTestEnable = VK_FALSE;
268*03ce13f7SAndroid Build Coastguard Worker 	depthStencilState.front = depthStencilState.back;
269*03ce13f7SAndroid Build Coastguard Worker 
270*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineMultisampleStateCreateInfo multisampleState;
271*03ce13f7SAndroid Build Coastguard Worker 	multisampleState.rasterizationSamples = multisample ? vk::SampleCountFlagBits::e4 : vk::SampleCountFlagBits::e1;
272*03ce13f7SAndroid Build Coastguard Worker 	multisampleState.pSampleMask = nullptr;
273*03ce13f7SAndroid Build Coastguard Worker 
274*03ce13f7SAndroid Build Coastguard Worker 	vk::ShaderModule vertexModule = hooks.createVertexShader(*this);
275*03ce13f7SAndroid Build Coastguard Worker 	vk::ShaderModule fragmentModule = hooks.createFragmentShader(*this);
276*03ce13f7SAndroid Build Coastguard Worker 
277*03ce13f7SAndroid Build Coastguard Worker 	assert(vertexModule);    // TODO: if nullptr, use a default
278*03ce13f7SAndroid Build Coastguard Worker 	assert(fragmentModule);  // TODO: if nullptr, use a default
279*03ce13f7SAndroid Build Coastguard Worker 
280*03ce13f7SAndroid Build Coastguard Worker 	std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages;
281*03ce13f7SAndroid Build Coastguard Worker 
282*03ce13f7SAndroid Build Coastguard Worker 	shaderStages[0].module = vertexModule;
283*03ce13f7SAndroid Build Coastguard Worker 	shaderStages[0].stage = vk::ShaderStageFlagBits::eVertex;
284*03ce13f7SAndroid Build Coastguard Worker 	shaderStages[0].pName = "main";
285*03ce13f7SAndroid Build Coastguard Worker 
286*03ce13f7SAndroid Build Coastguard Worker 	shaderStages[1].module = fragmentModule;
287*03ce13f7SAndroid Build Coastguard Worker 	shaderStages[1].stage = vk::ShaderStageFlagBits::eFragment;
288*03ce13f7SAndroid Build Coastguard Worker 	shaderStages[1].pName = "main";
289*03ce13f7SAndroid Build Coastguard Worker 
290*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
291*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pStages = shaderStages.data();
292*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pVertexInputState = &vertices.inputState;
293*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
294*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pRasterizationState = &rasterizationState;
295*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pColorBlendState = &colorBlendState;
296*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pMultisampleState = &multisampleState;
297*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pViewportState = &viewportState;
298*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pDepthStencilState = &depthStencilState;
299*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.renderPass = renderPass;
300*03ce13f7SAndroid Build Coastguard Worker 	pipelineCreateInfo.pDynamicState = &dynamicState;
301*03ce13f7SAndroid Build Coastguard Worker 
302*03ce13f7SAndroid Build Coastguard Worker 	auto pipeline = device.createGraphicsPipeline(nullptr, pipelineCreateInfo).value;
303*03ce13f7SAndroid Build Coastguard Worker 
304*03ce13f7SAndroid Build Coastguard Worker 	device.destroyShaderModule(fragmentModule);
305*03ce13f7SAndroid Build Coastguard Worker 	device.destroyShaderModule(vertexModule);
306*03ce13f7SAndroid Build Coastguard Worker 
307*03ce13f7SAndroid Build Coastguard Worker 	return pipeline;
308*03ce13f7SAndroid Build Coastguard Worker }
309*03ce13f7SAndroid Build Coastguard Worker 
createSynchronizationPrimitives()310*03ce13f7SAndroid Build Coastguard Worker void DrawTester::createSynchronizationPrimitives()
311*03ce13f7SAndroid Build Coastguard Worker {
312*03ce13f7SAndroid Build Coastguard Worker 	vk::SemaphoreCreateInfo semaphoreCreateInfo;
313*03ce13f7SAndroid Build Coastguard Worker 	presentCompleteSemaphore = device.createSemaphore(semaphoreCreateInfo);
314*03ce13f7SAndroid Build Coastguard Worker 	renderCompleteSemaphore = device.createSemaphore(semaphoreCreateInfo);
315*03ce13f7SAndroid Build Coastguard Worker 
316*03ce13f7SAndroid Build Coastguard Worker 	vk::FenceCreateInfo fenceCreateInfo;
317*03ce13f7SAndroid Build Coastguard Worker 	fenceCreateInfo.flags = vk::FenceCreateFlagBits::eSignaled;
318*03ce13f7SAndroid Build Coastguard Worker 	waitFences.resize(swapchain->imageCount());
319*03ce13f7SAndroid Build Coastguard Worker 	for(auto &fence : waitFences)
320*03ce13f7SAndroid Build Coastguard Worker 	{
321*03ce13f7SAndroid Build Coastguard Worker 		fence = device.createFence(fenceCreateInfo);
322*03ce13f7SAndroid Build Coastguard Worker 	}
323*03ce13f7SAndroid Build Coastguard Worker }
324*03ce13f7SAndroid Build Coastguard Worker 
createCommandBuffers(vk::RenderPass renderPass)325*03ce13f7SAndroid Build Coastguard Worker void DrawTester::createCommandBuffers(vk::RenderPass renderPass)
326*03ce13f7SAndroid Build Coastguard Worker {
327*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandPoolCreateInfo commandPoolCreateInfo;
328*03ce13f7SAndroid Build Coastguard Worker 	commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex;
329*03ce13f7SAndroid Build Coastguard Worker 	commandPoolCreateInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
330*03ce13f7SAndroid Build Coastguard Worker 	commandPool = device.createCommandPool(commandPoolCreateInfo);
331*03ce13f7SAndroid Build Coastguard Worker 
332*03ce13f7SAndroid Build Coastguard Worker 	std::vector<vk::DescriptorSet> descriptorSets;
333*03ce13f7SAndroid Build Coastguard Worker 	if(descriptorSetLayout)
334*03ce13f7SAndroid Build Coastguard Worker 	{
335*03ce13f7SAndroid Build Coastguard Worker 		std::array<vk::DescriptorPoolSize, 1> poolSizes = {};
336*03ce13f7SAndroid Build Coastguard Worker 		poolSizes[0].type = vk::DescriptorType::eCombinedImageSampler;
337*03ce13f7SAndroid Build Coastguard Worker 		poolSizes[0].descriptorCount = 1;
338*03ce13f7SAndroid Build Coastguard Worker 
339*03ce13f7SAndroid Build Coastguard Worker 		vk::DescriptorPoolCreateInfo poolInfo;
340*03ce13f7SAndroid Build Coastguard Worker 		poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
341*03ce13f7SAndroid Build Coastguard Worker 		poolInfo.pPoolSizes = poolSizes.data();
342*03ce13f7SAndroid Build Coastguard Worker 		poolInfo.maxSets = 1;
343*03ce13f7SAndroid Build Coastguard Worker 
344*03ce13f7SAndroid Build Coastguard Worker 		descriptorPool = device.createDescriptorPool(poolInfo);
345*03ce13f7SAndroid Build Coastguard Worker 
346*03ce13f7SAndroid Build Coastguard Worker 		std::vector<vk::DescriptorSetLayout> layouts(1, descriptorSetLayout);
347*03ce13f7SAndroid Build Coastguard Worker 		vk::DescriptorSetAllocateInfo allocInfo;
348*03ce13f7SAndroid Build Coastguard Worker 		allocInfo.descriptorPool = descriptorPool;
349*03ce13f7SAndroid Build Coastguard Worker 		allocInfo.descriptorSetCount = 1;
350*03ce13f7SAndroid Build Coastguard Worker 		allocInfo.pSetLayouts = layouts.data();
351*03ce13f7SAndroid Build Coastguard Worker 
352*03ce13f7SAndroid Build Coastguard Worker 		descriptorSets = device.allocateDescriptorSets(allocInfo);
353*03ce13f7SAndroid Build Coastguard Worker 
354*03ce13f7SAndroid Build Coastguard Worker 		hooks.updateDescriptorSet(*this, commandPool, descriptorSets[0]);
355*03ce13f7SAndroid Build Coastguard Worker 	}
356*03ce13f7SAndroid Build Coastguard Worker 
357*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandBufferAllocateInfo commandBufferAllocateInfo;
358*03ce13f7SAndroid Build Coastguard Worker 	commandBufferAllocateInfo.commandPool = commandPool;
359*03ce13f7SAndroid Build Coastguard Worker 	commandBufferAllocateInfo.commandBufferCount = static_cast<uint32_t>(swapchain->imageCount());
360*03ce13f7SAndroid Build Coastguard Worker 	commandBufferAllocateInfo.level = vk::CommandBufferLevel::ePrimary;
361*03ce13f7SAndroid Build Coastguard Worker 
362*03ce13f7SAndroid Build Coastguard Worker 	commandBuffers = device.allocateCommandBuffers(commandBufferAllocateInfo);
363*03ce13f7SAndroid Build Coastguard Worker 
364*03ce13f7SAndroid Build Coastguard Worker 	for(size_t i = 0; i < commandBuffers.size(); i++)
365*03ce13f7SAndroid Build Coastguard Worker 	{
366*03ce13f7SAndroid Build Coastguard Worker 		vk::CommandBufferBeginInfo commandBufferBeginInfo;
367*03ce13f7SAndroid Build Coastguard Worker 		commandBuffers[i].begin(commandBufferBeginInfo);
368*03ce13f7SAndroid Build Coastguard Worker 
369*03ce13f7SAndroid Build Coastguard Worker 		vk::ClearValue clearValues[1];
370*03ce13f7SAndroid Build Coastguard Worker 		clearValues[0].color = vk::ClearColorValue(std::array<float, 4>{ 0.5f, 0.5f, 0.5f, 1.0f });
371*03ce13f7SAndroid Build Coastguard Worker 
372*03ce13f7SAndroid Build Coastguard Worker 		vk::RenderPassBeginInfo renderPassBeginInfo;
373*03ce13f7SAndroid Build Coastguard Worker 		renderPassBeginInfo.framebuffer = framebuffers[i]->getFramebuffer();
374*03ce13f7SAndroid Build Coastguard Worker 		renderPassBeginInfo.renderPass = renderPass;
375*03ce13f7SAndroid Build Coastguard Worker 		renderPassBeginInfo.renderArea.offset.x = 0;
376*03ce13f7SAndroid Build Coastguard Worker 		renderPassBeginInfo.renderArea.offset.y = 0;
377*03ce13f7SAndroid Build Coastguard Worker 		renderPassBeginInfo.renderArea.extent = windowSize;
378*03ce13f7SAndroid Build Coastguard Worker 		renderPassBeginInfo.clearValueCount = ARRAY_SIZE(clearValues);
379*03ce13f7SAndroid Build Coastguard Worker 		renderPassBeginInfo.pClearValues = clearValues;
380*03ce13f7SAndroid Build Coastguard Worker 		commandBuffers[i].beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline);
381*03ce13f7SAndroid Build Coastguard Worker 
382*03ce13f7SAndroid Build Coastguard Worker 		// Set dynamic state
383*03ce13f7SAndroid Build Coastguard Worker 		vk::Viewport viewport(0.0f, 0.0f, static_cast<float>(windowSize.width), static_cast<float>(windowSize.height), 0.0f, 1.0f);
384*03ce13f7SAndroid Build Coastguard Worker 		commandBuffers[i].setViewport(0, 1, &viewport);
385*03ce13f7SAndroid Build Coastguard Worker 
386*03ce13f7SAndroid Build Coastguard Worker 		vk::Rect2D scissor(vk::Offset2D(0, 0), windowSize);
387*03ce13f7SAndroid Build Coastguard Worker 		commandBuffers[i].setScissor(0, 1, &scissor);
388*03ce13f7SAndroid Build Coastguard Worker 
389*03ce13f7SAndroid Build Coastguard Worker 		if(!descriptorSets.empty())
390*03ce13f7SAndroid Build Coastguard Worker 		{
391*03ce13f7SAndroid Build Coastguard Worker 			commandBuffers[i].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, 1, &descriptorSets[0], 0, nullptr);
392*03ce13f7SAndroid Build Coastguard Worker 		}
393*03ce13f7SAndroid Build Coastguard Worker 
394*03ce13f7SAndroid Build Coastguard Worker 		// Draw
395*03ce13f7SAndroid Build Coastguard Worker 		if(vertices.numVertices > 0)
396*03ce13f7SAndroid Build Coastguard Worker 		{
397*03ce13f7SAndroid Build Coastguard Worker 			commandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
398*03ce13f7SAndroid Build Coastguard Worker 			VULKAN_HPP_NAMESPACE::DeviceSize offset = 0;
399*03ce13f7SAndroid Build Coastguard Worker 			commandBuffers[i].bindVertexBuffers(0, 1, &vertices.buffer, &offset);
400*03ce13f7SAndroid Build Coastguard Worker 			commandBuffers[i].draw(vertices.numVertices, 1, 0, 0);
401*03ce13f7SAndroid Build Coastguard Worker 		}
402*03ce13f7SAndroid Build Coastguard Worker 
403*03ce13f7SAndroid Build Coastguard Worker 		commandBuffers[i].endRenderPass();
404*03ce13f7SAndroid Build Coastguard Worker 		commandBuffers[i].end();
405*03ce13f7SAndroid Build Coastguard Worker 	}
406*03ce13f7SAndroid Build Coastguard Worker }
407*03ce13f7SAndroid Build Coastguard Worker 
addVertexBuffer(void * vertexBufferData,size_t vertexBufferDataSize,size_t vertexSize,std::vector<vk::VertexInputAttributeDescription> inputAttributes)408*03ce13f7SAndroid Build Coastguard Worker void DrawTester::addVertexBuffer(void *vertexBufferData, size_t vertexBufferDataSize, size_t vertexSize, std::vector<vk::VertexInputAttributeDescription> inputAttributes)
409*03ce13f7SAndroid Build Coastguard Worker {
410*03ce13f7SAndroid Build Coastguard Worker 	assert(!vertices.buffer);  // For now, only support adding once
411*03ce13f7SAndroid Build Coastguard Worker 
412*03ce13f7SAndroid Build Coastguard Worker 	vk::BufferCreateInfo vertexBufferInfo;
413*03ce13f7SAndroid Build Coastguard Worker 	vertexBufferInfo.size = vertexBufferDataSize;
414*03ce13f7SAndroid Build Coastguard Worker 	vertexBufferInfo.usage = vk::BufferUsageFlagBits::eVertexBuffer;
415*03ce13f7SAndroid Build Coastguard Worker 	vertices.buffer = device.createBuffer(vertexBufferInfo);
416*03ce13f7SAndroid Build Coastguard Worker 
417*03ce13f7SAndroid Build Coastguard Worker 	vk::MemoryAllocateInfo memoryAllocateInfo;
418*03ce13f7SAndroid Build Coastguard Worker 	vk::MemoryRequirements memoryRequirements = device.getBufferMemoryRequirements(vertices.buffer);
419*03ce13f7SAndroid Build Coastguard Worker 	memoryAllocateInfo.allocationSize = memoryRequirements.size;
420*03ce13f7SAndroid Build Coastguard Worker 	memoryAllocateInfo.memoryTypeIndex = Util::getMemoryTypeIndex(physicalDevice, memoryRequirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
421*03ce13f7SAndroid Build Coastguard Worker 	vertices.memory = device.allocateMemory(memoryAllocateInfo);
422*03ce13f7SAndroid Build Coastguard Worker 
423*03ce13f7SAndroid Build Coastguard Worker 	void *data = device.mapMemory(vertices.memory, 0, VK_WHOLE_SIZE);
424*03ce13f7SAndroid Build Coastguard Worker 	memcpy(data, vertexBufferData, vertexBufferDataSize);
425*03ce13f7SAndroid Build Coastguard Worker 	device.unmapMemory(vertices.memory);
426*03ce13f7SAndroid Build Coastguard Worker 	device.bindBufferMemory(vertices.buffer, vertices.memory, 0);
427*03ce13f7SAndroid Build Coastguard Worker 
428*03ce13f7SAndroid Build Coastguard Worker 	vertices.inputBinding.binding = 0;
429*03ce13f7SAndroid Build Coastguard Worker 	vertices.inputBinding.stride = static_cast<uint32_t>(vertexSize);
430*03ce13f7SAndroid Build Coastguard Worker 	vertices.inputBinding.inputRate = vk::VertexInputRate::eVertex;
431*03ce13f7SAndroid Build Coastguard Worker 
432*03ce13f7SAndroid Build Coastguard Worker 	vertices.inputAttributes = std::move(inputAttributes);
433*03ce13f7SAndroid Build Coastguard Worker 
434*03ce13f7SAndroid Build Coastguard Worker 	vertices.inputState.vertexBindingDescriptionCount = 1;
435*03ce13f7SAndroid Build Coastguard Worker 	vertices.inputState.pVertexBindingDescriptions = &vertices.inputBinding;
436*03ce13f7SAndroid Build Coastguard Worker 	vertices.inputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertices.inputAttributes.size());
437*03ce13f7SAndroid Build Coastguard Worker 	vertices.inputState.pVertexAttributeDescriptions = vertices.inputAttributes.data();
438*03ce13f7SAndroid Build Coastguard Worker 
439*03ce13f7SAndroid Build Coastguard Worker 	// Note that we assume data is tightly packed
440*03ce13f7SAndroid Build Coastguard Worker 	vertices.numVertices = static_cast<uint32_t>(vertexBufferDataSize / vertexSize);
441*03ce13f7SAndroid Build Coastguard Worker }
442*03ce13f7SAndroid Build Coastguard Worker 
createShaderModule(const char * glslSource,EShLanguage glslLanguage)443*03ce13f7SAndroid Build Coastguard Worker vk::ShaderModule DrawTester::createShaderModule(const char *glslSource, EShLanguage glslLanguage)
444*03ce13f7SAndroid Build Coastguard Worker {
445*03ce13f7SAndroid Build Coastguard Worker 	auto spirv = Util::compileGLSLtoSPIRV(glslSource, glslLanguage);
446*03ce13f7SAndroid Build Coastguard Worker 
447*03ce13f7SAndroid Build Coastguard Worker 	vk::ShaderModuleCreateInfo moduleCreateInfo;
448*03ce13f7SAndroid Build Coastguard Worker 	moduleCreateInfo.codeSize = spirv.size() * sizeof(uint32_t);
449*03ce13f7SAndroid Build Coastguard Worker 	moduleCreateInfo.pCode = (uint32_t *)spirv.data();
450*03ce13f7SAndroid Build Coastguard Worker 
451*03ce13f7SAndroid Build Coastguard Worker 	return device.createShaderModule(moduleCreateInfo);
452*03ce13f7SAndroid Build Coastguard Worker }
453