xref: /aosp_15_r20/external/swiftshader/tests/VulkanWrapper/Util.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 "Util.hpp"
16*03ce13f7SAndroid Build Coastguard Worker #include "SPIRV/GlslangToSpv.h"
17*03ce13f7SAndroid Build Coastguard Worker #include "glslang/Public/ResourceLimits.h"
18*03ce13f7SAndroid Build Coastguard Worker 
19*03ce13f7SAndroid Build Coastguard Worker #include <memory>
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker namespace Util {
22*03ce13f7SAndroid Build Coastguard Worker 
getMemoryTypeIndex(vk::PhysicalDevice physicalDevice,uint32_t typeBits,vk::MemoryPropertyFlags properties)23*03ce13f7SAndroid Build Coastguard Worker uint32_t getMemoryTypeIndex(vk::PhysicalDevice physicalDevice, uint32_t typeBits, vk::MemoryPropertyFlags properties)
24*03ce13f7SAndroid Build Coastguard Worker {
25*03ce13f7SAndroid Build Coastguard Worker 	vk::PhysicalDeviceMemoryProperties deviceMemoryProperties = physicalDevice.getMemoryProperties();
26*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < deviceMemoryProperties.memoryTypeCount; i++)
27*03ce13f7SAndroid Build Coastguard Worker 	{
28*03ce13f7SAndroid Build Coastguard Worker 		if((typeBits & 1) == 1)
29*03ce13f7SAndroid Build Coastguard Worker 		{
30*03ce13f7SAndroid Build Coastguard Worker 			if((deviceMemoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
31*03ce13f7SAndroid Build Coastguard Worker 			{
32*03ce13f7SAndroid Build Coastguard Worker 				return i;
33*03ce13f7SAndroid Build Coastguard Worker 			}
34*03ce13f7SAndroid Build Coastguard Worker 		}
35*03ce13f7SAndroid Build Coastguard Worker 		typeBits >>= 1;
36*03ce13f7SAndroid Build Coastguard Worker 	}
37*03ce13f7SAndroid Build Coastguard Worker 
38*03ce13f7SAndroid Build Coastguard Worker 	assert(false);
39*03ce13f7SAndroid Build Coastguard Worker 	return -1;
40*03ce13f7SAndroid Build Coastguard Worker }
41*03ce13f7SAndroid Build Coastguard Worker 
beginSingleTimeCommands(vk::Device device,vk::CommandPool commandPool)42*03ce13f7SAndroid Build Coastguard Worker vk::CommandBuffer beginSingleTimeCommands(vk::Device device, vk::CommandPool commandPool)
43*03ce13f7SAndroid Build Coastguard Worker {
44*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandBufferAllocateInfo allocInfo{};
45*03ce13f7SAndroid Build Coastguard Worker 	allocInfo.level = vk::CommandBufferLevel::ePrimary;
46*03ce13f7SAndroid Build Coastguard Worker 	allocInfo.commandPool = commandPool;
47*03ce13f7SAndroid Build Coastguard Worker 	allocInfo.commandBufferCount = 1;
48*03ce13f7SAndroid Build Coastguard Worker 
49*03ce13f7SAndroid Build Coastguard Worker 	auto commandBuffer = device.allocateCommandBuffers(allocInfo);
50*03ce13f7SAndroid Build Coastguard Worker 
51*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandBufferBeginInfo beginInfo{};
52*03ce13f7SAndroid Build Coastguard Worker 	beginInfo.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
53*03ce13f7SAndroid Build Coastguard Worker 
54*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer[0].begin(beginInfo);
55*03ce13f7SAndroid Build Coastguard Worker 
56*03ce13f7SAndroid Build Coastguard Worker 	return commandBuffer[0];
57*03ce13f7SAndroid Build Coastguard Worker }
58*03ce13f7SAndroid Build Coastguard Worker 
endSingleTimeCommands(vk::Device device,vk::CommandPool commandPool,vk::Queue queue,vk::CommandBuffer commandBuffer)59*03ce13f7SAndroid Build Coastguard Worker void endSingleTimeCommands(vk::Device device, vk::CommandPool commandPool, vk::Queue queue, vk::CommandBuffer commandBuffer)
60*03ce13f7SAndroid Build Coastguard Worker {
61*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer.end();
62*03ce13f7SAndroid Build Coastguard Worker 
63*03ce13f7SAndroid Build Coastguard Worker 	vk::SubmitInfo submitInfo{};
64*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.commandBufferCount = 1;
65*03ce13f7SAndroid Build Coastguard Worker 	submitInfo.pCommandBuffers = &commandBuffer;
66*03ce13f7SAndroid Build Coastguard Worker 
67*03ce13f7SAndroid Build Coastguard Worker 	vk::Fence fence = {};  // TODO: pass in fence?
68*03ce13f7SAndroid Build Coastguard Worker 	queue.submit(1, &submitInfo, fence);
69*03ce13f7SAndroid Build Coastguard Worker 	queue.waitIdle();
70*03ce13f7SAndroid Build Coastguard Worker 
71*03ce13f7SAndroid Build Coastguard Worker 	device.freeCommandBuffers(commandPool, 1, &commandBuffer);
72*03ce13f7SAndroid Build Coastguard Worker }
73*03ce13f7SAndroid Build Coastguard Worker 
transitionImageLayout(vk::Device device,vk::CommandPool commandPool,vk::Queue queue,vk::Image image,vk::Format format,vk::ImageLayout oldLayout,vk::ImageLayout newLayout)74*03ce13f7SAndroid Build Coastguard Worker void transitionImageLayout(vk::Device device, vk::CommandPool commandPool, vk::Queue queue, vk::Image image, vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout)
75*03ce13f7SAndroid Build Coastguard Worker {
76*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandBuffer commandBuffer = beginSingleTimeCommands(device, commandPool);
77*03ce13f7SAndroid Build Coastguard Worker 
78*03ce13f7SAndroid Build Coastguard Worker 	vk::ImageMemoryBarrier barrier{};
79*03ce13f7SAndroid Build Coastguard Worker 	barrier.oldLayout = oldLayout;
80*03ce13f7SAndroid Build Coastguard Worker 	barrier.newLayout = newLayout;
81*03ce13f7SAndroid Build Coastguard Worker 	barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
82*03ce13f7SAndroid Build Coastguard Worker 	barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
83*03ce13f7SAndroid Build Coastguard Worker 	barrier.image = image;
84*03ce13f7SAndroid Build Coastguard Worker 	barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
85*03ce13f7SAndroid Build Coastguard Worker 	barrier.subresourceRange.baseMipLevel = 0;
86*03ce13f7SAndroid Build Coastguard Worker 	barrier.subresourceRange.levelCount = 1;
87*03ce13f7SAndroid Build Coastguard Worker 	barrier.subresourceRange.baseArrayLayer = 0;
88*03ce13f7SAndroid Build Coastguard Worker 	barrier.subresourceRange.layerCount = 1;
89*03ce13f7SAndroid Build Coastguard Worker 
90*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineStageFlags sourceStage;
91*03ce13f7SAndroid Build Coastguard Worker 	vk::PipelineStageFlags destinationStage;
92*03ce13f7SAndroid Build Coastguard Worker 
93*03ce13f7SAndroid Build Coastguard Worker 	if(oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal)
94*03ce13f7SAndroid Build Coastguard Worker 	{
95*03ce13f7SAndroid Build Coastguard Worker 		barrier.srcAccessMask = {};
96*03ce13f7SAndroid Build Coastguard Worker 		barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
97*03ce13f7SAndroid Build Coastguard Worker 
98*03ce13f7SAndroid Build Coastguard Worker 		sourceStage = vk::PipelineStageFlagBits::eTopOfPipe;
99*03ce13f7SAndroid Build Coastguard Worker 		destinationStage = vk::PipelineStageFlagBits::eTransfer;
100*03ce13f7SAndroid Build Coastguard Worker 	}
101*03ce13f7SAndroid Build Coastguard Worker 	else if(oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal)
102*03ce13f7SAndroid Build Coastguard Worker 	{
103*03ce13f7SAndroid Build Coastguard Worker 		barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
104*03ce13f7SAndroid Build Coastguard Worker 		barrier.dstAccessMask = vk::AccessFlagBits::eTransferRead;
105*03ce13f7SAndroid Build Coastguard Worker 
106*03ce13f7SAndroid Build Coastguard Worker 		sourceStage = vk::PipelineStageFlagBits::eTransfer;
107*03ce13f7SAndroid Build Coastguard Worker 		destinationStage = vk::PipelineStageFlagBits::eFragmentShader;
108*03ce13f7SAndroid Build Coastguard Worker 	}
109*03ce13f7SAndroid Build Coastguard Worker 	else
110*03ce13f7SAndroid Build Coastguard Worker 	{
111*03ce13f7SAndroid Build Coastguard Worker 		assert(false && "unsupported layout transition!");
112*03ce13f7SAndroid Build Coastguard Worker 	}
113*03ce13f7SAndroid Build Coastguard Worker 
114*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer.pipelineBarrier(sourceStage, destinationStage, vk::DependencyFlags{}, 0, nullptr, 0, nullptr, 1, &barrier);
115*03ce13f7SAndroid Build Coastguard Worker 
116*03ce13f7SAndroid Build Coastguard Worker 	endSingleTimeCommands(device, commandPool, queue, commandBuffer);
117*03ce13f7SAndroid Build Coastguard Worker }
118*03ce13f7SAndroid Build Coastguard Worker 
copyBufferToImage(vk::Device device,vk::CommandPool commandPool,vk::Queue queue,vk::Buffer buffer,vk::Image image,uint32_t width,uint32_t height)119*03ce13f7SAndroid Build Coastguard Worker void copyBufferToImage(vk::Device device, vk::CommandPool commandPool, vk::Queue queue, vk::Buffer buffer, vk::Image image, uint32_t width, uint32_t height)
120*03ce13f7SAndroid Build Coastguard Worker {
121*03ce13f7SAndroid Build Coastguard Worker 	vk::CommandBuffer commandBuffer = beginSingleTimeCommands(device, commandPool);
122*03ce13f7SAndroid Build Coastguard Worker 
123*03ce13f7SAndroid Build Coastguard Worker 	vk::BufferImageCopy region{};
124*03ce13f7SAndroid Build Coastguard Worker 	region.bufferOffset = 0;
125*03ce13f7SAndroid Build Coastguard Worker 	region.bufferRowLength = 0;
126*03ce13f7SAndroid Build Coastguard Worker 	region.bufferImageHeight = 0;
127*03ce13f7SAndroid Build Coastguard Worker 	region.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eColor;
128*03ce13f7SAndroid Build Coastguard Worker 	region.imageSubresource.mipLevel = 0;
129*03ce13f7SAndroid Build Coastguard Worker 	region.imageSubresource.baseArrayLayer = 0;
130*03ce13f7SAndroid Build Coastguard Worker 	region.imageSubresource.layerCount = 1;
131*03ce13f7SAndroid Build Coastguard Worker 	region.imageOffset = vk::Offset3D{ 0, 0, 0 };
132*03ce13f7SAndroid Build Coastguard Worker 	region.imageExtent = vk::Extent3D{ width, height, 1 };
133*03ce13f7SAndroid Build Coastguard Worker 
134*03ce13f7SAndroid Build Coastguard Worker 	commandBuffer.copyBufferToImage(buffer, image, vk::ImageLayout::eTransferDstOptimal, 1, &region);
135*03ce13f7SAndroid Build Coastguard Worker 
136*03ce13f7SAndroid Build Coastguard Worker 	endSingleTimeCommands(device, commandPool, queue, commandBuffer);
137*03ce13f7SAndroid Build Coastguard Worker }
138*03ce13f7SAndroid Build Coastguard Worker 
compileGLSLtoSPIRV(const char * glslSource,EShLanguage glslLanguage)139*03ce13f7SAndroid Build Coastguard Worker std::vector<uint32_t> compileGLSLtoSPIRV(const char *glslSource, EShLanguage glslLanguage)
140*03ce13f7SAndroid Build Coastguard Worker {
141*03ce13f7SAndroid Build Coastguard Worker 	// glslang requires one-time initialization.
142*03ce13f7SAndroid Build Coastguard Worker 	const struct GlslangProcessInitialiser
143*03ce13f7SAndroid Build Coastguard Worker 	{
144*03ce13f7SAndroid Build Coastguard Worker 		GlslangProcessInitialiser() { glslang::InitializeProcess(); }
145*03ce13f7SAndroid Build Coastguard Worker 		~GlslangProcessInitialiser() { glslang::FinalizeProcess(); }
146*03ce13f7SAndroid Build Coastguard Worker 	} glslangInitialiser;
147*03ce13f7SAndroid Build Coastguard Worker 
148*03ce13f7SAndroid Build Coastguard Worker 	std::unique_ptr<glslang::TShader> glslangShader = std::make_unique<glslang::TShader>(glslLanguage);
149*03ce13f7SAndroid Build Coastguard Worker 
150*03ce13f7SAndroid Build Coastguard Worker 	glslangShader->setStrings(&glslSource, 1);
151*03ce13f7SAndroid Build Coastguard Worker 	glslangShader->setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1);
152*03ce13f7SAndroid Build Coastguard Worker 	glslangShader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3);
153*03ce13f7SAndroid Build Coastguard Worker 
154*03ce13f7SAndroid Build Coastguard Worker 	const int defaultVersion = 100;
155*03ce13f7SAndroid Build Coastguard Worker 	EShMessages messages = static_cast<EShMessages>(EShMessages::EShMsgDefault | EShMessages::EShMsgSpvRules | EShMessages::EShMsgVulkanRules);
156*03ce13f7SAndroid Build Coastguard Worker 	bool parseResult = glslangShader->parse(GetDefaultResources(), defaultVersion, false, messages);
157*03ce13f7SAndroid Build Coastguard Worker 
158*03ce13f7SAndroid Build Coastguard Worker 	if(!parseResult)
159*03ce13f7SAndroid Build Coastguard Worker 	{
160*03ce13f7SAndroid Build Coastguard Worker 		std::string debugLog = glslangShader->getInfoDebugLog();
161*03ce13f7SAndroid Build Coastguard Worker 		std::string infoLog = glslangShader->getInfoLog();
162*03ce13f7SAndroid Build Coastguard Worker 		assert(false && "Failed to parse shader");
163*03ce13f7SAndroid Build Coastguard Worker 	}
164*03ce13f7SAndroid Build Coastguard Worker 
165*03ce13f7SAndroid Build Coastguard Worker 	glslang::TIntermediate *intermediateRepresentation = glslangShader->getIntermediate();
166*03ce13f7SAndroid Build Coastguard Worker 	assert(intermediateRepresentation);
167*03ce13f7SAndroid Build Coastguard Worker 
168*03ce13f7SAndroid Build Coastguard Worker 	std::vector<uint32_t> spirv;
169*03ce13f7SAndroid Build Coastguard Worker 	glslang::SpvOptions options;
170*03ce13f7SAndroid Build Coastguard Worker 	glslang::GlslangToSpv(*intermediateRepresentation, spirv, &options);
171*03ce13f7SAndroid Build Coastguard Worker 	assert(spirv.size() != 0);
172*03ce13f7SAndroid Build Coastguard Worker 
173*03ce13f7SAndroid Build Coastguard Worker 	return spirv;
174*03ce13f7SAndroid Build Coastguard Worker }
175*03ce13f7SAndroid Build Coastguard Worker 
176*03ce13f7SAndroid Build Coastguard Worker }  // namespace Util
177