1 #include "main.h"
2 #include "container.h"
3 #include "backend.h"
4 #include "CompositorResource.h"
5 #include "compositor.h"
6 
7 #include <algorithm>
8 #include <tuple>
9 //#include <gbm.h>
10 #include <unistd.h>
11 
12 #include "spirv_reflect.h"
13 
14 namespace Compositor{
15 
TextureBase(uint _w,uint _h,VkFormat format,const VkComponentMapping * pcomponentMapping,uint _flags,const CompositorInterface * _pcomp)16 TextureBase::TextureBase(uint _w, uint _h, VkFormat format, const VkComponentMapping *pcomponentMapping, uint _flags, const CompositorInterface *_pcomp) : w(_w), h(_h), flags(_flags), imageLayout(VK_IMAGE_LAYOUT_UNDEFINED), pcomp(_pcomp){
17 	//
18 	auto m = std::find_if(formatSizeMap.begin(),formatSizeMap.end(),[&](auto &r)->bool{
19 		return r.first == format;
20 	});
21 	formatIndex = m-formatSizeMap.begin();
22 
23 	//DebugPrintf(stdout,"*** creating texture: %u, (%ux%u)\n",(*m).second,w,h);
24 	componentMappingHash = GetComponentMappingHash(pcomponentMapping);
25 
26 	//image
27 	VkImageCreateInfo imageCreateInfo = {};
28 	imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
29 	imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
30 	imageCreateInfo.extent.width = w;
31 	imageCreateInfo.extent.height = h;
32 	imageCreateInfo.extent.depth = 1;
33 	imageCreateInfo.mipLevels = 1;
34 	imageCreateInfo.arrayLayers = 1;
35 	imageCreateInfo.format = format;
36 	imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
37 	imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
38 	imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT;
39 	imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
40 	imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
41 	imageCreateInfo.flags = 0;
42 	if(vkCreateImage(pcomp->logicalDev,&imageCreateInfo,0,&image) != VK_SUCCESS)
43 		throw Exception("Failed to create an image.");
44 
45 	VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProps;
46 	vkGetPhysicalDeviceMemoryProperties(pcomp->physicalDev,&physicalDeviceMemoryProps);
47 
48 	VkMemoryRequirements memoryRequirements;
49 	vkGetImageMemoryRequirements(pcomp->logicalDev,image,&memoryRequirements);
50 
51 	VkMemoryAllocateInfo memoryAllocateInfo = {};
52 	memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
53 	memoryAllocateInfo.allocationSize = memoryRequirements.size;
54 	for(memoryAllocateInfo.memoryTypeIndex = 0; memoryAllocateInfo.memoryTypeIndex < physicalDeviceMemoryProps.memoryTypeCount; memoryAllocateInfo.memoryTypeIndex++){
55 		if(memoryRequirements.memoryTypeBits & (1<<memoryAllocateInfo.memoryTypeIndex) && physicalDeviceMemoryProps.memoryTypes[memoryAllocateInfo.memoryTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
56 			break;
57 	}
58 
59 	if(vkAllocateMemory(pcomp->logicalDev,&memoryAllocateInfo,0,&deviceMemory) != VK_SUCCESS)
60 		throw Exception("Failed to allocate image memory.");
61 	if(vkBindImageMemory(pcomp->logicalDev,image,deviceMemory,0) != VK_SUCCESS)
62 		throw Exception("Failed to bind image memory.");
63 
64 	VkImageViewCreateInfo imageViewCreateInfo = {};
65 	imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
66 	imageViewCreateInfo.image = image;
67 	imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
68 	imageViewCreateInfo.format = format;
69 	/*if(flags & FLAG_SWIZZLE_PIXMAP){
70 		imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_B;//VK_COMPONENT_SWIZZLE_IDENTITY;
71 		imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_G;//VK_COMPONENT_SWIZZLE_IDENTITY;
72 		imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_R;//VK_COMPONENT_SWIZZLE_IDENTITY;
73 	}else{
74 		imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
75 		imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
76 		imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
77 	}
78 	imageViewCreateInfo.components.a = (flags & FLAG_IGNORE_ALPHA)?VK_COMPONENT_SWIZZLE_ONE:VK_COMPONENT_SWIZZLE_IDENTITY;*/
79 	imageViewCreateInfo.components = *pcomponentMapping;
80 	imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
81 	imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
82 	imageViewCreateInfo.subresourceRange.levelCount = 1;
83 	imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
84 	imageViewCreateInfo.subresourceRange.layerCount = 1;
85 	if(vkCreateImageView(pcomp->logicalDev,&imageViewCreateInfo,0,&imageView) != VK_SUCCESS)
86 		throw Exception("Failed to create texture image view.");
87 
88 }
89 
~TextureBase()90 TextureBase::~TextureBase(){
91 	vkDestroyImageView(pcomp->logicalDev,imageView,0);
92 
93 	vkFreeMemory(pcomp->logicalDev,deviceMemory,0);
94 	vkDestroyImage(pcomp->logicalDev,image,0);
95 }
96 
97 const std::vector<std::pair<VkFormat, uint>> TextureBase::formatSizeMap = {
98 	{VK_FORMAT_R8_UNORM,1},
99 	{VK_FORMAT_R8G8B8A8_UNORM,4}
100 };
101 
102 const VkComponentMapping TextureBase::defaultComponentMapping = {
103 	VK_COMPONENT_SWIZZLE_IDENTITY,
104 	VK_COMPONENT_SWIZZLE_IDENTITY,
105 	VK_COMPONENT_SWIZZLE_IDENTITY,
106 	VK_COMPONENT_SWIZZLE_IDENTITY
107 };
108 
TextureStaged(uint _w,uint _h,VkFormat _format,const VkComponentMapping * _pcomponentMapping,uint _flags,const CompositorInterface * _pcomp)109 TextureStaged::TextureStaged(uint _w, uint _h, VkFormat _format, const VkComponentMapping *_pcomponentMapping,uint _flags, const CompositorInterface *_pcomp) : TextureBase(_w,_h,_format,_pcomponentMapping,_flags,_pcomp){
110 	//
111 	//staging buffer
112 	VkBufferCreateInfo bufferCreateInfo = {};
113 	bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
114 	bufferCreateInfo.size = formatSizeMap[formatIndex].second*w*h;//(*m).second*w*h;
115 	bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
116 	bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
117 	if(vkCreateBuffer(pcomp->logicalDev,&bufferCreateInfo,0,&stagingBuffer) != VK_SUCCESS)
118 		throw Exception("Failed to create a staging buffer.");
119 
120 	VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProps;
121 	vkGetPhysicalDeviceMemoryProperties(pcomp->physicalDev,&physicalDeviceMemoryProps);
122 
123 	VkMemoryRequirements memoryRequirements;
124 	vkGetBufferMemoryRequirements(pcomp->logicalDev,stagingBuffer,&memoryRequirements);
125 
126 	VkMemoryAllocateInfo memoryAllocateInfo = {};
127 	memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
128 	memoryAllocateInfo.allocationSize = memoryRequirements.size;
129 	for(memoryAllocateInfo.memoryTypeIndex = 0; memoryAllocateInfo.memoryTypeIndex < physicalDeviceMemoryProps.memoryTypeCount; memoryAllocateInfo.memoryTypeIndex++){
130 		if(memoryRequirements.memoryTypeBits & (1<<memoryAllocateInfo.memoryTypeIndex) && physicalDeviceMemoryProps.memoryTypes[memoryAllocateInfo.memoryTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
131 			break;
132 	}
133 	if(vkAllocateMemory(pcomp->logicalDev,&memoryAllocateInfo,0,&stagingMemory) != VK_SUCCESS)
134 		throw Exception("Failed to allocate staging buffer memory.");
135 	if(vkBindBufferMemory(pcomp->logicalDev,stagingBuffer,stagingMemory,0) != VK_SUCCESS)
136 		throw Exception("Failed to bind staging buffer memory.");
137 
138 	stagingMemorySize = memoryRequirements.size;
139 }
140 
~TextureStaged()141 TextureStaged::~TextureStaged(){
142 	vkFreeMemory(pcomp->logicalDev,stagingMemory,0);
143 	vkDestroyBuffer(pcomp->logicalDev,stagingBuffer,0);
144 }
145 
Map() const146 const void * TextureStaged::Map() const{
147 	void *pdata;
148 	if(vkMapMemory(pcomp->logicalDev,stagingMemory,0,stagingMemorySize,0,&pdata) != VK_SUCCESS)
149 		return 0;
150 	return pdata;
151 }
152 
Unmap(const VkCommandBuffer * pcommandBuffer,const VkRect2D * prects,uint rectCount)153 void TextureStaged::Unmap(const VkCommandBuffer *pcommandBuffer, const VkRect2D *prects, uint rectCount){
154 	vkUnmapMemory(pcomp->logicalDev,stagingMemory);
155 
156 	VkImageSubresourceRange imageSubresourceRange = {};
157 	imageSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
158 	imageSubresourceRange.baseMipLevel = 0;
159 	imageSubresourceRange.levelCount = 1;
160 	imageSubresourceRange.baseArrayLayer = 0;
161 	imageSubresourceRange.layerCount = 1;
162 
163 	//create in host stage (map), use in transfer stage
164 	VkImageMemoryBarrier imageMemoryBarrier = {};
165 	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
166 	imageMemoryBarrier.image = image;
167 	imageMemoryBarrier.subresourceRange = imageSubresourceRange;
168 	imageMemoryBarrier.srcAccessMask = 0;
169 	imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
170 	imageMemoryBarrier.oldLayout = imageLayout;//VK_IMAGE_LAYOUT_UNDEFINED;
171 	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
172 	vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_HOST_BIT,VK_PIPELINE_STAGE_TRANSFER_BIT,0,
173 		0,0,0,0,1,&imageMemoryBarrier);
174 
175 	//transfer "stage"
176 	bufferImageCopyBuffer.reserve(rectCount);
177 	for(uint i = 0; i < rectCount; ++i){
178 		bufferImageCopyBuffer[i].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
179 		bufferImageCopyBuffer[i].imageSubresource.mipLevel = 0;
180 		bufferImageCopyBuffer[i].imageSubresource.baseArrayLayer = 0;
181 		bufferImageCopyBuffer[i].imageSubresource.layerCount = 1;
182 		bufferImageCopyBuffer[i].imageExtent.width = prects[i].extent.width;//w/4; //w
183 		bufferImageCopyBuffer[i].imageExtent.height = prects[i].extent.height;//h
184 		bufferImageCopyBuffer[i].imageExtent.depth = 1;
185 		bufferImageCopyBuffer[i].imageOffset = (VkOffset3D){prects[i].offset.x,prects[i].offset.y,0};//(VkOffset3D){w/4,0,0}; //x,y
186 		bufferImageCopyBuffer[i].bufferOffset = (w*prects[i].offset.y+prects[i].offset.x)*formatSizeMap[formatIndex].second;//w/4*4; //(w*y+x)*format
187 		bufferImageCopyBuffer[i].bufferRowLength = w;
188 		bufferImageCopyBuffer[i].bufferImageHeight = h;
189 	}
190 	vkCmdCopyBufferToImage(*pcommandBuffer,stagingBuffer,image,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,rectCount,bufferImageCopyBuffer.data());
191 
192 	//create in transfer stage, use in fragment shader stage
193 	imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
194 	imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
195 	imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
196 	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
197 	vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_TRANSFER_BIT,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,0,
198 		0,0,0,0,1,&imageMemoryBarrier);
199 
200 	imageLayout = imageMemoryBarrier.newLayout;
201 }
202 
TexturePixmap(uint _w,uint _h,const VkComponentMapping * _pcomponentMapping,uint _flags,const CompositorInterface * _pcomp)203 TexturePixmap::TexturePixmap(uint _w, uint _h, const VkComponentMapping *_pcomponentMapping, uint _flags, const CompositorInterface *_pcomp) : TextureBase(_w,_h,VK_FORMAT_R8G8B8A8_UNORM,_pcomponentMapping,_flags,_pcomp), transferImageLayout(VK_IMAGE_LAYOUT_PREINITIALIZED){
204 	pcomp11 = dynamic_cast<const X11Compositor *>(pcomp);
205 }
206 
~TexturePixmap()207 TexturePixmap::~TexturePixmap(){
208 	//
209 }
210 
211 //only pixmaps that correspond to the created texture in size should be attached
Attach(xcb_pixmap_t pixmap)212 void TexturePixmap::Attach(xcb_pixmap_t pixmap){
213 	xcb_dri3_buffer_from_pixmap_cookie_t bufferFromPixmapCookie = xcb_dri3_buffer_from_pixmap(pcomp11->pbackend->pcon,pixmap);
214 	xcb_dri3_buffer_from_pixmap_reply_t *pbufferFromPixmapReply = xcb_dri3_buffer_from_pixmap_reply(pcomp11->pbackend->pcon,bufferFromPixmapCookie,0);
215 
216 	dmafd = xcb_dri3_buffer_from_pixmap_reply_fds(pcomp11->pbackend->pcon,pbufferFromPixmapReply)[0]; //TODO: get all planes?
217 
218 	/*struct gbm_import_fd_data gbmImportFdData = {
219 		.fd = dmafd,
220 		.width = w,
221 		.height = h,
222 		.stride = pbufferFromPixmapReply->stride,
223 		.format = GBM_FORMAT_ARGB8888
224 	};
225 	pgbmBufferObject = gbm_bo_import(pcomp11->pgbmdev,GBM_BO_IMPORT_FD,&gbmImportFdData,0);//GBM_BO_USE_LINEAR);
226 	if(!pgbmBufferObject) //TODO: import once for the first buffer, assume same modifiers and format for all?
227 		throw Exception("Failed to import GBM buffer object.");*/
228 
229 	VkSubresourceLayout subresourceLayout = {};
230 	subresourceLayout.offset = 0;
231 	subresourceLayout.size = (uint)pbufferFromPixmapReply->size;//(uint)pbufferFromPixmapReply->stride*h;
232 	subresourceLayout.rowPitch = (uint)pbufferFromPixmapReply->stride;
233 	subresourceLayout.arrayPitch = subresourceLayout.size;
234 	subresourceLayout.depthPitch = subresourceLayout.size;
235 
236 	uint64_t modifier = 0;//gbm_bo_get_modifier(pgbmBufferObject);
237 	/*sint planeCount = gbm_bo_get_plane_count(pgbmBufferObject);
238 	DebugPrintf(stdout,"Image modifier: %llu, plane count: %d\n",modifier,planeCount);*/
239 
240 	VkImageDrmFormatModifierExplicitCreateInfoEXT imageDrmFormatModifierExpCreateInfo = {};
241 	imageDrmFormatModifierExpCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
242 	imageDrmFormatModifierExpCreateInfo.drmFormatModifier = modifier;//gbm_bo_get_modifier(pgbmBufferObject);
243 	imageDrmFormatModifierExpCreateInfo.drmFormatModifierPlaneCount = 1;
244 	imageDrmFormatModifierExpCreateInfo.pPlaneLayouts = &subresourceLayout;
245 
246 	VkExternalMemoryImageCreateInfo externalMemoryCreateInfo = {};
247 	externalMemoryCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
248 	externalMemoryCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
249 	externalMemoryCreateInfo.pNext = &imageDrmFormatModifierExpCreateInfo;
250 
251 	VkImageCreateInfo imageCreateInfo = {};
252 	imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
253 	imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
254 	imageCreateInfo.extent.width = w;
255 	imageCreateInfo.extent.height = h;
256 	imageCreateInfo.extent.depth = 1;
257 	imageCreateInfo.mipLevels = 1;
258 	imageCreateInfo.arrayLayers = 1;
259 	imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM; //todo: format from image reply?
260 	//imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;//VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
261 	imageCreateInfo.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; //need the extension
262 	imageCreateInfo.initialLayout = transferImageLayout;//VK_IMAGE_LAYOUT_PREINITIALIZED;//VK_IMAGE_LAYOUT_UNDEFINED;
263 	//imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
264 	imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
265 	imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
266 	imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
267 	imageCreateInfo.flags = 0;
268 	imageCreateInfo.pNext = &externalMemoryCreateInfo;
269 	if(vkCreateImage(pcomp->logicalDev,&imageCreateInfo,0,&transferImage) != VK_SUCCESS)
270 		throw Exception("Failed to create an image.");
271 
272 	VkMemoryFdPropertiesKHR memoryFdProps;
273 	memoryFdProps.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR;
274 	if(((PFN_vkGetMemoryFdPropertiesKHR)vkGetInstanceProcAddr(pcomp11->instance,"vkGetMemoryFdPropertiesKHR"))(pcomp->logicalDev,VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,dmafd,&memoryFdProps) != VK_SUCCESS)
275 		throw Exception("Failed to get memory fd properties.");
276 
277 	VkMemoryRequirements memoryRequirements;
278 	vkGetImageMemoryRequirements(pcomp->logicalDev,transferImage,&memoryRequirements);
279 
280 	VkMemoryDedicatedAllocateInfo memoryDedicatedAllocateInfo = {};
281 	memoryDedicatedAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
282 	memoryDedicatedAllocateInfo.image = transferImage;
283 
284 	VkImportMemoryFdInfoKHR importMemoryFdInfo = {};
285 	importMemoryFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
286 	importMemoryFdInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
287 	importMemoryFdInfo.fd = dmafd;
288 	importMemoryFdInfo.pNext = &memoryDedicatedAllocateInfo;
289 
290 	VkMemoryAllocateInfo memoryAllocateInfo = {};
291 	memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
292 	memoryAllocateInfo.allocationSize = memoryRequirements.size;
293 	memoryAllocateInfo.pNext = &importMemoryFdInfo;
294 	//for(memoryAllocateInfo.memoryTypeIndex = 0; memoryAllocateInfo.memoryTypeIndex < physicalDeviceMemoryProps.memoryTypeCount; memoryAllocateInfo.memoryTypeIndex++){
295 	for(memoryAllocateInfo.memoryTypeIndex = 0;; memoryAllocateInfo.memoryTypeIndex++){
296 		if(memoryFdProps.memoryTypeBits & (1<<memoryAllocateInfo.memoryTypeIndex))
297 			break;
298 	}
299 	if(vkAllocateMemory(pcomp->logicalDev,&memoryAllocateInfo,0,&transferMemory) != VK_SUCCESS)
300 		throw Exception("Failed to allocate transfer image memory."); //NOTE: may return invalid handle, if the buffer that we're trying to import is only shortly available (for example firefox animating it's url menu by resizing). Need xcb_dri3 fences to keep the handle alive most likely.
301 	if(vkBindImageMemory(pcomp->logicalDev,transferImage,transferMemory,0) != VK_SUCCESS)
302 		throw Exception("Failed to bind transfer image memory.");
303 
304 	free(pbufferFromPixmapReply);
305 }
306 
Detach()307 void TexturePixmap::Detach(){
308 	vkFreeMemory(pcomp->logicalDev,transferMemory,0);
309 	vkDestroyImage(pcomp->logicalDev,transferImage,0);
310 
311 	//gbm_bo_destroy(pgbmBufferObject);
312 	close(dmafd);
313 }
314 
Update(const VkCommandBuffer * pcommandBuffer,const VkRect2D * prects,uint rectCount)315 void TexturePixmap::Update(const VkCommandBuffer *pcommandBuffer, const VkRect2D *prects, uint rectCount){
316 	//
317 	VkImageSubresourceRange imageSubresourceRange = {};
318 	imageSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
319 	imageSubresourceRange.baseMipLevel = 0;
320 	imageSubresourceRange.levelCount = 1;
321 	imageSubresourceRange.baseArrayLayer = 0;
322 	imageSubresourceRange.layerCount = 1;
323 
324 	VkImageMemoryBarrier transferImageMemoryBarrier = {};
325 	transferImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
326 	transferImageMemoryBarrier.image = transferImage;
327 	transferImageMemoryBarrier.subresourceRange = imageSubresourceRange;
328 	transferImageMemoryBarrier.srcAccessMask = 0;
329 	transferImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
330 	//transferImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
331 	transferImageMemoryBarrier.oldLayout = transferImageLayout;
332 	transferImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
333 	//vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_HOST_BIT,VK_PIPELINE_STAGE_TRANSFER_BIT,0,
334 		//0,0,0,0,1,&transferImageMemoryBarrier);
335 
336 	VkImageMemoryBarrier imageMemoryBarrier = {};
337 	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
338 	imageMemoryBarrier.image = image;
339 	imageMemoryBarrier.subresourceRange = imageSubresourceRange;
340 	imageMemoryBarrier.srcAccessMask = 0;
341 	imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
342 	imageMemoryBarrier.oldLayout = imageLayout;//VK_IMAGE_LAYOUT_UNDEFINED;
343 	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
344 	//vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_HOST_BIT,VK_PIPELINE_STAGE_TRANSFER_BIT,0,
345 		//0,0,0,0,1,&imageMemoryBarrier);
346 	const VkImageMemoryBarrier barriers[] = {imageMemoryBarrier,transferImageMemoryBarrier};
347 	vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_TRANSFER_BIT,0,
348 		0,0,0,0,2,barriers);
349 
350 	VkImageSubresourceLayers imageSubresourceLayers = {};
351 	imageSubresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
352 	imageSubresourceLayers.mipLevel = 0;
353 	imageSubresourceLayers.baseArrayLayer = 0;
354 	imageSubresourceLayers.layerCount = 1;
355 
356 	imageCopyBuffer.reserve(rectCount);
357 	for(uint i = 0; i < rectCount; ++i){
358 		imageCopyBuffer[i].srcSubresource = imageSubresourceLayers;
359 		imageCopyBuffer[i].srcOffset = (VkOffset3D){prects[i].offset.x,prects[i].offset.y,0};
360 		imageCopyBuffer[i].dstSubresource = imageSubresourceLayers;
361 		imageCopyBuffer[i].dstOffset = imageCopyBuffer[i].srcOffset;
362 		imageCopyBuffer[i].extent = (VkExtent3D){prects[i].extent.width,prects[i].extent.height,1};
363 	}
364 	vkCmdCopyImage(*pcommandBuffer,transferImage,VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,image,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,rectCount,imageCopyBuffer.data());
365 
366 	//create in transfer stage, use in fragment shader stage
367 	imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
368 	imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
369 	imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
370 	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
371 	vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_TRANSFER_BIT,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,0,
372 		0,0,0,0,1,&imageMemoryBarrier);
373 
374 	imageLayout = imageMemoryBarrier.newLayout;
375 	transferImageLayout = transferImageMemoryBarrier.newLayout;
376 }
377 
378 const VkComponentMapping TexturePixmap::pixmapComponentMapping = {
379 	VK_COMPONENT_SWIZZLE_B,
380 	VK_COMPONENT_SWIZZLE_G,
381 	VK_COMPONENT_SWIZZLE_R,
382 	VK_COMPONENT_SWIZZLE_IDENTITY
383 };
384 
385 const VkComponentMapping TexturePixmap::pixmapComponentMapping24 = {
386 	VK_COMPONENT_SWIZZLE_B,
387 	VK_COMPONENT_SWIZZLE_G,
388 	VK_COMPONENT_SWIZZLE_R,
389 	VK_COMPONENT_SWIZZLE_ONE
390 };
391 
TextureHostPointer(uint _w,uint _h,const VkComponentMapping * _pcomponentMapping,uint _flags,const CompositorInterface * _pcomp)392 TextureHostPointer::TextureHostPointer(uint _w, uint _h, const VkComponentMapping *_pcomponentMapping, uint _flags, const CompositorInterface *_pcomp) : TextureBase(_w,_h,VK_FORMAT_R8G8B8A8_UNORM,_pcomponentMapping,_flags,_pcomp){
393 	//
394 	discards.reserve(2);
395 }
396 
~TextureHostPointer()397 TextureHostPointer::~TextureHostPointer(){
398 	discards.erase(std::remove_if(discards.begin(),discards.end(),[&](auto &t)->bool{
399 		vkFreeMemory(pcomp->logicalDev,std::get<1>(t),0);
400 		vkDestroyBuffer(pcomp->logicalDev,std::get<2>(t),0);
401 		return true;
402 	}));
403 }
404 
Attach(unsigned char * pchpixels)405 bool TextureHostPointer::Attach(unsigned char *pchpixels){
406 	VkExternalMemoryBufferCreateInfo externalMemoryBufferCreateInfo = {};
407 	externalMemoryBufferCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO;
408 	externalMemoryBufferCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
409 
410 	VkBufferCreateInfo bufferCreateInfo = {};
411 	bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
412 	bufferCreateInfo.size = formatSizeMap[formatIndex].second*w*h;
413 	bufferCreateInfo.size = (bufferCreateInfo.size-1)+pcomp->physicalDevExternalMemoryHostProps.minImportedHostPointerAlignment-(bufferCreateInfo.size-1)%pcomp->physicalDevExternalMemoryHostProps.minImportedHostPointerAlignment;
414 	bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
415 	bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
416 	bufferCreateInfo.pNext = &externalMemoryBufferCreateInfo;
417 	if(vkCreateBuffer(pcomp->logicalDev,&bufferCreateInfo,0,&transferBuffer) != VK_SUCCESS){
418 		//throw Exception("Failed to create a transfer buffer.");
419 		DebugPrintf(stderr,"Failed to create a transfer buffer.");
420 		return false;
421 	}
422 
423 	VkMemoryHostPointerPropertiesEXT memoryHostPointerProps;
424 	memoryHostPointerProps.sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT;
425 	if(((PFN_vkGetMemoryHostPointerPropertiesEXT)vkGetInstanceProcAddr(pcomp->instance,"vkGetMemoryHostPointerPropertiesEXT"))(pcomp->logicalDev,VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,pchpixels,&memoryHostPointerProps) != VK_SUCCESS){
426 		DebugPrintf(stderr,"Failed to get memory host pointer properties.");
427 		vkDestroyBuffer(pcomp->logicalDev,transferBuffer,0);
428 		return false;
429 	}
430 
431 	VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProps;
432 	vkGetPhysicalDeviceMemoryProperties(pcomp->physicalDev,&physicalDeviceMemoryProps);
433 
434 	VkMemoryRequirements memoryRequirements;
435 	vkGetBufferMemoryRequirements(pcomp->logicalDev,transferBuffer,&memoryRequirements);
436 
437 	VkMemoryDedicatedAllocateInfo memoryDedicatedAllocateInfo = {};
438 	memoryDedicatedAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
439 	memoryDedicatedAllocateInfo.buffer = transferBuffer;
440 
441 	VkImportMemoryHostPointerInfoEXT importMemoryHostPointerInfo = {};
442 	importMemoryHostPointerInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT;
443 	importMemoryHostPointerInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
444 	importMemoryHostPointerInfo.pHostPointer = pchpixels;
445 	importMemoryHostPointerInfo.pNext = &memoryDedicatedAllocateInfo; //not necessary?
446 
447 	VkMemoryAllocateInfo memoryAllocateInfo = {};
448 	memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
449 	memoryAllocateInfo.allocationSize = memoryRequirements.size;
450 	memoryAllocateInfo.pNext = &importMemoryHostPointerInfo;
451 	for(memoryAllocateInfo.memoryTypeIndex = 0;; memoryAllocateInfo.memoryTypeIndex++){
452 		//if(memoryHostPointerProps.memoryTypeBits & (1<<memoryAllocateInfo.memoryTypeIndex) && physicalDeviceMemoryProps.memoryTypes[memoryAllocateInfo.memoryTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
453 		if((memoryRequirements.memoryTypeBits & memoryHostPointerProps.memoryTypeBits) & (1<<memoryAllocateInfo.memoryTypeIndex) && physicalDeviceMemoryProps.memoryTypes[memoryAllocateInfo.memoryTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
454 			break;
455 	}
456 	if(vkAllocateMemory(pcomp->logicalDev,&memoryAllocateInfo,0,&transferMemory) != VK_SUCCESS){
457 		DebugPrintf(stderr,"Failed to allocate transfer buffer memory.");
458 		vkDestroyBuffer(pcomp->logicalDev,transferBuffer,0);
459 		return false;
460 	}
461 	if(vkBindBufferMemory(pcomp->logicalDev,transferBuffer,transferMemory,0) != VK_SUCCESS){
462 		DebugPrintf(stderr,"Failed to bind transfer buffer memory.");
463 		vkFreeMemory(pcomp->logicalDev,transferMemory,0);
464 		vkDestroyBuffer(pcomp->logicalDev,transferBuffer,0);
465 		return false;
466 	}
467 	return true;
468 }
469 
Detach(uint64 releaseTag)470 void TextureHostPointer::Detach(uint64 releaseTag){
471 	discards.erase(std::remove_if(discards.begin(),discards.end(),[&](auto &t)->bool{
472 		if(releaseTag < std::get<0>(t)+pcomp->swapChainImageCount+1)
473 			return false;
474 		vkFreeMemory(pcomp->logicalDev,std::get<1>(t),0);
475 		vkDestroyBuffer(pcomp->logicalDev,std::get<2>(t),0);
476 		return true;
477 	}));
478 	//discards.push_back(std::tuple<uint64, VkDeviceMemory, VkBuffer>(releaseTag,transferMemory,transferBuffer));
479 	vkDeviceWaitIdle(pcomp->logicalDev); //TODO: remove, and fix the buffer freeing
480 	vkFreeMemory(pcomp->logicalDev,transferMemory,0);
481 	vkDestroyBuffer(pcomp->logicalDev,transferBuffer,0);
482 }
483 
Update(const VkCommandBuffer * pcommandBuffer,const VkRect2D * prects,uint rectCount)484 void TextureHostPointer::Update(const VkCommandBuffer *pcommandBuffer, const VkRect2D *prects, uint rectCount){
485 	//
486 	VkImageSubresourceRange imageSubresourceRange = {};
487 	imageSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
488 	imageSubresourceRange.baseMipLevel = 0;
489 	imageSubresourceRange.levelCount = 1;
490 	imageSubresourceRange.baseArrayLayer = 0;
491 	imageSubresourceRange.layerCount = 1;
492 
493 	VkImageMemoryBarrier imageMemoryBarrier = {};
494 	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
495 	imageMemoryBarrier.image = image;
496 	imageMemoryBarrier.subresourceRange = imageSubresourceRange;
497 	imageMemoryBarrier.srcAccessMask = 0;
498 	imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
499 	imageMemoryBarrier.oldLayout = imageLayout;//VK_IMAGE_LAYOUT_UNDEFINED;
500 	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
501 	vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_HOST_BIT,VK_PIPELINE_STAGE_TRANSFER_BIT,0,
502 		0,0,0,0,1,&imageMemoryBarrier);
503 
504 	//transfer "stage"
505 	bufferImageCopyBuffer.reserve(rectCount);
506 	for(uint i = 0; i < rectCount; ++i){
507 		bufferImageCopyBuffer[i].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
508 		bufferImageCopyBuffer[i].imageSubresource.mipLevel = 0;
509 		bufferImageCopyBuffer[i].imageSubresource.baseArrayLayer = 0;
510 		bufferImageCopyBuffer[i].imageSubresource.layerCount = 1;
511 		bufferImageCopyBuffer[i].imageExtent.width = prects[i].extent.width;//w/4; //w
512 		bufferImageCopyBuffer[i].imageExtent.height = prects[i].extent.height;//h
513 		bufferImageCopyBuffer[i].imageExtent.depth = 1;
514 		bufferImageCopyBuffer[i].imageOffset = (VkOffset3D){prects[i].offset.x,prects[i].offset.y,0};//(VkOffset3D){w/4,0,0}; //x,y
515 		bufferImageCopyBuffer[i].bufferOffset = (w*prects[i].offset.y+prects[i].offset.x)*formatSizeMap[formatIndex].second;//w/4*4; //(w*y+x)*format
516 		bufferImageCopyBuffer[i].bufferRowLength = w;
517 		bufferImageCopyBuffer[i].bufferImageHeight = h;
518 	}
519 	vkCmdCopyBufferToImage(*pcommandBuffer,transferBuffer,image,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,rectCount,bufferImageCopyBuffer.data());
520 
521 	//create in transfer stage, use in fragment shader stage
522 	imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
523 	imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
524 	imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
525 	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
526 	vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_TRANSFER_BIT,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,0,
527 		0,0,0,0,1,&imageMemoryBarrier);
528 
529 	imageLayout = imageMemoryBarrier.newLayout;
530 }
531 
532 //Texture::Texture(uint _w, uint _h, const CompositorInterface *_pcomp) : TextureBase(_w,_h,VK_FORMAT_R8G8B8A8_UNORM,_pcomp), TextureStaged(_w,_h,VK_FORMAT_R8G8B8A8_UNORM,_pcomp), TexturePixmap(_w,_h,_pcomp){
Texture(uint _w,uint _h,const VkComponentMapping * _pcomponentMapping,uint _flags,const CompositorInterface * _pcomp)533 Texture::Texture(uint _w, uint _h, const VkComponentMapping *_pcomponentMapping, uint _flags, const CompositorInterface *_pcomp) : TextureBase(_w,_h,VK_FORMAT_R8G8B8A8_UNORM,_pcomponentMapping,_flags,_pcomp), TextureStaged(_w,_h,VK_FORMAT_R8G8B8A8_UNORM,_pcomponentMapping,_flags,_pcomp), TextureHostPointer(_w,_h,_pcomponentMapping,_flags,_pcomp){
534 	//
535 }
536 
~Texture()537 Texture::~Texture(){
538 	//
539 }
540 
Buffer(uint _size,VkBufferUsageFlagBits usage,const CompositorInterface * _pcomp)541 Buffer::Buffer(uint _size, VkBufferUsageFlagBits usage, const CompositorInterface *_pcomp) : pcomp(_pcomp), size(_size){
542 	//
543 	VkBufferCreateInfo bufferCreateInfo = {};
544 	bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
545 	bufferCreateInfo.size = size;
546 	bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
547 	bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
548 	if(vkCreateBuffer(pcomp->logicalDev,&bufferCreateInfo,0,&stagingBuffer) != VK_SUCCESS)
549 		throw Exception("Failed to create a staging buffer.");
550 
551 	VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProps;
552 	vkGetPhysicalDeviceMemoryProperties(pcomp->physicalDev,&physicalDeviceMemoryProps);
553 
554 	VkMemoryRequirements memoryRequirements;
555 	vkGetBufferMemoryRequirements(pcomp->logicalDev,stagingBuffer,&memoryRequirements);
556 
557 	VkMemoryAllocateInfo memoryAllocateInfo = {};
558 	memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
559 	memoryAllocateInfo.allocationSize = memoryRequirements.size;
560 	for(memoryAllocateInfo.memoryTypeIndex = 0; memoryAllocateInfo.memoryTypeIndex < physicalDeviceMemoryProps.memoryTypeCount; memoryAllocateInfo.memoryTypeIndex++){
561 		if(memoryRequirements.memoryTypeBits & (1<<memoryAllocateInfo.memoryTypeIndex) && physicalDeviceMemoryProps.memoryTypes[memoryAllocateInfo.memoryTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
562 			break;
563 	}
564 	if(vkAllocateMemory(pcomp->logicalDev,&memoryAllocateInfo,0,&stagingMemory) != VK_SUCCESS)
565 		throw Exception("Failed to allocate staging buffer memory.");
566 	if(vkBindBufferMemory(pcomp->logicalDev,stagingBuffer,stagingMemory,0) != VK_SUCCESS)
567 		throw Exception("Failed to bind staging buffer memory.");
568 
569 	stagingMemorySize = memoryRequirements.size;
570 	bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
571 	bufferCreateInfo.size = size;
572 	bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT|usage;//VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
573 	bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
574 	if(vkCreateBuffer(pcomp->logicalDev,&bufferCreateInfo,0,&buffer) != VK_SUCCESS)
575 		throw Exception("Failed to create a buffer.");
576 
577 	vkGetBufferMemoryRequirements(pcomp->logicalDev,buffer,&memoryRequirements);
578 
579 	memoryAllocateInfo.allocationSize = memoryRequirements.size;
580 	for(memoryAllocateInfo.memoryTypeIndex = 0; memoryAllocateInfo.memoryTypeIndex < physicalDeviceMemoryProps.memoryTypeCount; memoryAllocateInfo.memoryTypeIndex++){
581 		if(memoryRequirements.memoryTypeBits & (1<<memoryAllocateInfo.memoryTypeIndex) && physicalDeviceMemoryProps.memoryTypes[memoryAllocateInfo.memoryTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
582 			break;
583 	}
584 
585 	if(vkAllocateMemory(pcomp->logicalDev,&memoryAllocateInfo,0,&deviceMemory) != VK_SUCCESS)
586 		throw Exception("Failed to allocate buffer memory.");
587 	if(vkBindBufferMemory(pcomp->logicalDev,buffer,deviceMemory,0) != VK_SUCCESS)
588 		throw Exception("Failed to bind buffer memory.");
589 }
590 
~Buffer()591 Buffer::~Buffer(){
592 	vkFreeMemory(pcomp->logicalDev,deviceMemory,0);
593 	vkDestroyBuffer(pcomp->logicalDev,buffer,0);
594 
595 	vkFreeMemory(pcomp->logicalDev,stagingMemory,0);
596 	vkDestroyBuffer(pcomp->logicalDev,stagingBuffer,0);
597 }
598 
Map() const599 const void * Buffer::Map() const{
600 	void *pdata;
601 	if(vkMapMemory(pcomp->logicalDev,stagingMemory,0,stagingMemorySize,0,&pdata) != VK_SUCCESS)
602 		return 0;
603 	return pdata;
604 }
605 
Unmap(const VkCommandBuffer * pcommandBuffer)606 void Buffer::Unmap(const VkCommandBuffer *pcommandBuffer){
607 	vkUnmapMemory(pcomp->logicalDev,stagingMemory);
608 
609 	VkBufferMemoryBarrier bufferMemoryBarrier = {};
610 	bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
611 	bufferMemoryBarrier.buffer = buffer;
612 	bufferMemoryBarrier.offset = 0;
613 	bufferMemoryBarrier.size = size;//VK_WHOLE_SIZE;
614 	/*bufferMemoryBarrier.srcAccessMask = 0;
615 	bufferMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
616 	vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_HOST_BIT,VK_PIPELINE_STAGE_TRANSFER_BIT,0,
617 		0,0,1,&bufferMemoryBarrier,0,0);*/
618 	//not needed
619 	//https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-submission-host-writes
620 
621 	VkBufferCopy bufferCopy = {};
622 	bufferCopy.srcOffset = 0;
623 	bufferCopy.dstOffset = 0;
624 	bufferCopy.size = size;
625 	vkCmdCopyBuffer(*pcommandBuffer,stagingBuffer,buffer,1,&bufferCopy);
626 
627 	bufferMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
628 	bufferMemoryBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;//VK_ACCESS_SHADER_READ_BIT;
629 	//vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_TRANSFER_BIT,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,0,
630 	vkCmdPipelineBarrier(*pcommandBuffer,VK_PIPELINE_STAGE_TRANSFER_BIT,VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,0,
631 		0,0,1,&bufferMemoryBarrier,0,0);
632 }
633 
ShaderModule(const char * _pname,const Blob * pblob,const CompositorInterface * _pcomp)634 ShaderModule::ShaderModule(const char *_pname, const Blob *pblob, const CompositorInterface *_pcomp) : pcomp(_pcomp), pname(mstrdup(_pname)){
635 	VkShaderModuleCreateInfo shaderModuleCreateInfo = {};
636 	shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
637 	shaderModuleCreateInfo.pCode = reinterpret_cast<const uint32_t *>(pblob->GetBufferPointer());
638 	shaderModuleCreateInfo.codeSize = pblob->GetBufferLength();
639 
640 	if(vkCreateShaderModule(pcomp->logicalDev,&shaderModuleCreateInfo,0,&shaderModule) != VK_SUCCESS)
641 		throw Exception("Failed to create a shader module.");
642 
643 	SpvReflectShaderModule reflectShaderModule;
644 	if(spvReflectCreateShaderModule(shaderModuleCreateInfo.codeSize,shaderModuleCreateInfo.pCode,&reflectShaderModule) != SPV_REFLECT_RESULT_SUCCESS)
645 		throw Exception("Failed to reflect shader module.");
646 
647 	uint inputCount;
648 	if(spvReflectEnumerateInputVariables(&reflectShaderModule,&inputCount,0) != SPV_REFLECT_RESULT_SUCCESS)
649 		throw Exception("Failed to enumerate input variables.");
650 
651 	//input variables
652 	SpvReflectInterfaceVariable **preflectInputVars = new SpvReflectInterfaceVariable*[inputCount];
653 	spvReflectEnumerateInputVariables(&reflectShaderModule,&inputCount,preflectInputVars);
654 
655 	for(uint i = 0; i < inputCount; ++i){
656 		if(!preflectInputVars[i]->semantic){
657 			if(preflectInputVars[i]->location != ~0u)
658 				DebugPrintf(stdout,"warning: unsemantic vertex attribute in %s at location %u.\n",_pname,preflectInputVars[i]->location);
659 			continue;
660 		}
661 		auto m = std::find_if(semanticMap.begin(),semanticMap.end(),[&](auto &r)->bool{
662 			return strcasecmp(std::get<0>(r),preflectInputVars[i]->semantic) == 0
663 				&& std::get<1>(r) == (VkFormat)preflectInputVars[i]->format;
664 		});
665 		if(m == semanticMap.end()){
666 			if((VkShaderStageFlagBits)reflectShaderModule.shader_stage == VK_SHADER_STAGE_VERTEX_BIT && preflectInputVars[i]->location != ~0u)
667 				DebugPrintf(stdout,"warning: unrecognized semantic %s in %s at location %u.\n",preflectInputVars[i]->semantic,_pname,preflectInputVars[i]->location);
668 			continue;
669 		}
670 		Input &in = inputs.emplace_back();
671 		in.location = preflectInputVars[i]->location;
672 		in.binding = 0; //one vertex buffer bound, per vertex
673 		in.semanticMapIndex = m-semanticMap.begin();
674 	}
675 	/*std::sort(inputs.begin(),inputs.end(),[](const Input &a, const Input &b){
676 		return a.location < b.location;
677 	});
678 	inputStride = 0;
679 	for(auto &m : inputs){
680 		m.offset = inputStride;
681 		inputStride += std::get<2>(semanticMap[m.semanticMapIndex]);
682 	}*/
683 
684 	delete []preflectInputVars;
685 
686 	//push constants
687 	if(spvReflectEnumeratePushConstantBlocks(&reflectShaderModule,&pushConstantBlockCount,0) != SPV_REFLECT_RESULT_SUCCESS)
688 		throw Exception("Failed to enumerate push constant blocks.");
689 
690 	SpvReflectBlockVariable **preflectBlockVars = new SpvReflectBlockVariable*[pushConstantBlockCount];
691 	spvReflectEnumeratePushConstantBlocks(&reflectShaderModule,&pushConstantBlockCount,preflectBlockVars);
692 
693 	pPushConstantRanges = new VkPushConstantRange[pushConstantBlockCount];
694 	for(uint i = 0; i < pushConstantBlockCount; ++i){
695 		pPushConstantRanges[i].stageFlags = (VkShaderStageFlagBits)reflectShaderModule.shader_stage;
696 		pPushConstantRanges[i].offset = preflectBlockVars[i]->offset;
697 		pPushConstantRanges[i].size = preflectBlockVars[i]->size;
698 
699 		for(uint j = 0; j < preflectBlockVars[i]->member_count; ++j){
700 			auto m = std::find_if(variableMap.begin(),variableMap.end(),[&](auto &r)->bool{
701 				return strcmp(std::get<0>(r),preflectBlockVars[i]->members[j].name) == 0;
702 			});
703 			if(m == variableMap.end()){
704 				DebugPrintf(stdout,"warning: unrecognized variable %s in %s with offset %u.\n",preflectBlockVars[i]->members[j].name,_pname,preflectBlockVars[i]->members[j].offset);
705 				continue;
706 			}
707 			//printf("---%u: %s\n",j,preflectBlockVars[i]->members[j].name);
708 			Variable &var = variables.emplace_back();
709 			var.offset = preflectBlockVars[i]->members[j].offset;
710 			var.variableMapIndex = m-variableMap.begin();
711 		}
712 	}
713 	//alt: one range allowed only
714 	/*pushConstantRange.stageFlags = (VkShaderStageFlagBits)reflectShaderModule.shader_stage;
715 	pushConstantRange.offset = preflectBlockVars[0]->offset;
716 	pushConstantRange.size = preflectBlockVars[0]->size;*/
717 
718 	delete []preflectBlockVars;
719 
720 	if(spvReflectEnumerateDescriptorSets(&reflectShaderModule,&setCount,0) != SPV_REFLECT_RESULT_SUCCESS)
721 		throw Exception("Failed to enumerate descriptor sets.");
722 
723 	//descriptor sets
724 	SpvReflectDescriptorSet **preflectDescSets = new SpvReflectDescriptorSet*[setCount];
725 	spvReflectEnumerateDescriptorSets(&reflectShaderModule,&setCount,preflectDescSets);
726 
727 	pdescSetLayouts = new VkDescriptorSetLayout[setCount];
728 	for(uint i = 0; i < setCount; ++i){
729 		VkDescriptorSetLayoutBinding *pbindings = new VkDescriptorSetLayoutBinding[preflectDescSets[i]->binding_count];
730 		for(uint j = 0; j < preflectDescSets[i]->binding_count; ++j){
731 			pbindings[j] = (VkDescriptorSetLayoutBinding){};
732 			pbindings[j].binding = preflectDescSets[i]->bindings[j]->binding;
733 			pbindings[j].descriptorType = (VkDescriptorType)preflectDescSets[i]->bindings[j]->descriptor_type;
734 			pbindings[j].descriptorCount = 1; //one binding can have multiple descriptors (combined image samplers)
735 			for(uint k = 0; k < preflectDescSets[i]->bindings[j]->array.dims_count; ++k)
736 				pbindings[j].descriptorCount *= preflectDescSets[i]->bindings[j]->array.dims[k];
737 			pbindings[j].stageFlags = (VkShaderStageFlagBits)reflectShaderModule.shader_stage;
738 			pbindings[j].pImmutableSamplers = &pcomp->pointSampler;
739 
740 			Binding &b = bindings.emplace_back();
741 			b.pname = preflectDescSets[i]->bindings[j]->name?mstrdup(preflectDescSets[i]->bindings[j]->name):mstrdup("content"); //hack: name might be null in optimized shader builds
742 			b.type = pbindings[j].descriptorType;
743 			b.setIndex = i;
744 			b.binding = pbindings[j].binding;
745 		}
746 
747 		VkDescriptorSetLayoutCreateInfo descSetLayoutCreateInfo = {};
748 		descSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
749 		descSetLayoutCreateInfo.bindingCount = preflectDescSets[i]->binding_count;
750 		descSetLayoutCreateInfo.pBindings = pbindings;
751 		if(vkCreateDescriptorSetLayout(pcomp->logicalDev,&descSetLayoutCreateInfo,0,&pdescSetLayouts[i]) != VK_SUCCESS)
752 			throw Exception("Failed to create a descriptor set layout.");
753 
754 		delete []pbindings;
755 	}
756 
757 	delete []preflectDescSets;
758 	spvReflectDestroyShaderModule(&reflectShaderModule);
759 }
760 
~ShaderModule()761 ShaderModule::~ShaderModule(){
762 	mstrfree(pname);
763 	for(Binding &b : bindings)
764 		mstrfree(b.pname);
765 	delete []pPushConstantRanges;
766 	for(uint i = 0; i < setCount; ++i)
767 		vkDestroyDescriptorSetLayout(pcomp->logicalDev,pdescSetLayouts[i],0);
768 	delete []pdescSetLayouts;
769 	vkDestroyShaderModule(pcomp->logicalDev,shaderModule,0);
770 }
771 
772 const std::vector<std::tuple<const char *, VkFormat, uint>> ShaderModule::semanticMap = {
773 	{"POSITION",VK_FORMAT_R32G32_SFLOAT,8},
774 	{"POSITION",VK_FORMAT_R32G32_UINT,8},
775 	{"TEXCOORD",VK_FORMAT_R32G32_SFLOAT,8}, //R16G16?
776 	{"TEXCOORD",VK_FORMAT_R32G32_UINT,8} //R16G16?
777 };
778 
779 const std::vector<std::tuple<const char *, uint>> ShaderModule::variableMap = {
780 	{"xy0",8},
781 	{"xy1",8},
782 	{"transform",16},
783 	{"screen",8},
784 	{"margin",8},
785 	{"titlePad",8},
786 	{"titleSpan",8},
787 	{"stackIndex",4},
788 	{"flags",4},
789 	{"time",4}
790 };
791 
Pipeline(ShaderModule * _pvertexShader,ShaderModule * _pgeometryShader,ShaderModule * _pfragmentShader,const std::vector<std::pair<ShaderModule::INPUT,uint>> * pvertexBufferLayout,const VkPipelineInputAssemblyStateCreateInfo * pinputAssemblyStateCreateInfo,const VkPipelineRasterizationStateCreateInfo * prasterizationStateCreateInfo,const VkPipelineDepthStencilStateCreateInfo * pdepthStencilStateCreateInfo,const VkPipelineColorBlendStateCreateInfo * pcolorBlendStateCreateInfo,const VkPipelineDynamicStateCreateInfo * pdynamicStateCreateInfo,const CompositorInterface * _pcomp)792 Pipeline::Pipeline(ShaderModule *_pvertexShader, ShaderModule *_pgeometryShader, ShaderModule *_pfragmentShader, const std::vector<std::pair<ShaderModule::INPUT, uint>> *pvertexBufferLayout, const VkPipelineInputAssemblyStateCreateInfo *pinputAssemblyStateCreateInfo, const VkPipelineRasterizationStateCreateInfo *prasterizationStateCreateInfo, const VkPipelineDepthStencilStateCreateInfo *pdepthStencilStateCreateInfo, const VkPipelineColorBlendStateCreateInfo *pcolorBlendStateCreateInfo, const VkPipelineDynamicStateCreateInfo *pdynamicStateCreateInfo, const CompositorInterface *_pcomp) : pshaderModule{_pvertexShader,_pgeometryShader,_pfragmentShader}, pcomp(_pcomp){
793 	VkVertexInputAttributeDescription *pvertexInputAttributeDescs = new VkVertexInputAttributeDescription[_pvertexShader->inputs.size()];
794 	uint vertexAttributeDescCount = 0;
795 	uint inputStride = 0;
796 	if(pvertexBufferLayout){
797 		for(uint i = 0, n = _pvertexShader->inputs.size(); i < n; ++i){
__anon657309dc0602(auto &r)798 			auto m = std::find_if(pvertexBufferLayout->begin(),pvertexBufferLayout->end(),[&](auto &r)->bool{
799 				return (uint)r.first == _pvertexShader->inputs[i].semanticMapIndex;
800 			});
801 			if(m == pvertexBufferLayout->end()){
802 				DebugPrintf(stdout,"warning: semantic %s in %s at location %u not supported by the input buffer.\n",std::get<0>(ShaderModule::semanticMap[_pvertexShader->inputs[i].semanticMapIndex]),_pvertexShader->pname,_pvertexShader->inputs[i].location);
803 				continue;
804 			}
805 			pvertexInputAttributeDescs[vertexAttributeDescCount].offset = m->second;
806 			pvertexInputAttributeDescs[vertexAttributeDescCount].location = _pvertexShader->inputs[i].location;
807 			pvertexInputAttributeDescs[vertexAttributeDescCount].binding = _pvertexShader->inputs[i].binding;
808 			pvertexInputAttributeDescs[vertexAttributeDescCount].format = std::get<1>(ShaderModule::semanticMap[_pvertexShader->inputs[i].semanticMapIndex]);
809 			pvertexInputAttributeDescs[vertexAttributeDescCount].offset = m->second;
810 
811 			inputStride += std::get<2>(ShaderModule::semanticMap[_pvertexShader->inputs[i].semanticMapIndex]);
812 
813 			++vertexAttributeDescCount;
814 		}
815 	}
816 
817 	//per-vertex data only, instancing not used
818 	VkVertexInputBindingDescription vertexInputBindingDesc = {};
819 	vertexInputBindingDesc.binding = 0;
820 	vertexInputBindingDesc.stride = inputStride;//_pvertexShader->inputStride;
821 	vertexInputBindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
822 
823 	VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {};
824 	vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
825 	vertexInputStateCreateInfo.vertexBindingDescriptionCount = (uint)(vertexAttributeDescCount > 0);
826 	vertexInputStateCreateInfo.pVertexBindingDescriptions = &vertexInputBindingDesc;
827 	vertexInputStateCreateInfo.vertexAttributeDescriptionCount = vertexAttributeDescCount;
828 	vertexInputStateCreateInfo.pVertexAttributeDescriptions = pvertexInputAttributeDescs;
829 
830 	VkPipelineShaderStageCreateInfo shaderStageCreateInfo[3];
831 
832 	uint stageCount = 0;
833 	uint setCount = 0;
834 	for(uint i = 0, stageBit[] = {VK_SHADER_STAGE_VERTEX_BIT,VK_SHADER_STAGE_GEOMETRY_BIT,VK_SHADER_STAGE_FRAGMENT_BIT}; i < SHADER_MODULE_COUNT; ++i){
835 		if(!pshaderModule[i])
836 			continue;
837 		setCount += pshaderModule[i]->setCount;
838 
839 		shaderStageCreateInfo[stageCount] = (VkPipelineShaderStageCreateInfo){};
840 		shaderStageCreateInfo[stageCount].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
841 		shaderStageCreateInfo[stageCount].stage = (VkShaderStageFlagBits)stageBit[i];
842 		shaderStageCreateInfo[stageCount].module = pshaderModule[i]->shaderModule;
843 		shaderStageCreateInfo[stageCount].pName = "main";
844 
845 		++stageCount;
846 	}
847 
848 	VkViewport viewport = {};
849 	viewport.x = 0.0f;
850 	viewport.y = 0.0f;
851 	viewport.width = (float)pcomp->imageExtent.width;
852 	viewport.height = (float)pcomp->imageExtent.height;
853 	viewport.minDepth = 0.0f;
854 	viewport.maxDepth = 1.0f;
855 
856 	VkRect2D scissor = {};
857 	scissor.offset = {0,0};
858 	scissor.extent = pcomp->imageExtent;
859 
860 	VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {};
861 	viewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
862 	viewportStateCreateInfo.viewportCount = 1;
863 	viewportStateCreateInfo.pViewports = &viewport;
864 	viewportStateCreateInfo.scissorCount = 1;
865 	viewportStateCreateInfo.pScissors = &scissor;
866 
867 	VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {};
868 	multisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
869 	multisampleStateCreateInfo.sampleShadingEnable = VK_FALSE;
870 	multisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
871 
872 	pushConstantRange.stageFlags = 0;
873 	pushConstantRange.offset = ~0u;
874 	pushConstantRange.size = 0;
875 	for(uint i = 0; i < SHADER_MODULE_COUNT; ++i){
876 		if(!pshaderModule[i])
877 			continue;
878 		if(pshaderModule[i]->pushConstantBlockCount > 0){
879 			pushConstantRange.stageFlags |= pshaderModule[i]->pPushConstantRanges[0].stageFlags;
880 			pushConstantRange.offset = std::min(pushConstantRange.offset,pshaderModule[i]->pPushConstantRanges[0].offset);
881 			pushConstantRange.size = std::max(pushConstantRange.size,pshaderModule[i]->pPushConstantRanges[0].size);
882 		}
883 	}
884 
885 	VkDescriptorSetLayout *pcombinedSets = new VkDescriptorSetLayout[setCount];
886 
887 	for(uint i = 0, p = 0; i < SHADER_MODULE_COUNT; ++i){
888 		if(!pshaderModule[i])
889 			continue;
890 		std::copy(pshaderModule[i]->pdescSetLayouts,pshaderModule[i]->pdescSetLayouts+pshaderModule[i]->setCount,pcombinedSets+p);
891 		p += pshaderModule[i]->setCount;
892 	}
893 
894 	VkPipelineLayoutCreateInfo layoutCreateInfo = {};
895 	layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
896 	layoutCreateInfo.setLayoutCount = setCount;
897 	layoutCreateInfo.pSetLayouts = pcombinedSets;
898 	layoutCreateInfo.pushConstantRangeCount = (bool)(pushConstantRange.stageFlags != 0);
899 	layoutCreateInfo.pPushConstantRanges = &pushConstantRange;
900 	if(vkCreatePipelineLayout(pcomp->logicalDev,&layoutCreateInfo,0,&pipelineLayout) != VK_SUCCESS)
901 		throw Exception("Failed to create a pipeline layout.");
902 
903 	delete []pcombinedSets;
904 
905 	/*VkDynamicState dynamicStates[1] = {VK_DYNAMIC_STATE_SCISSOR};
906 
907 	VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {};
908 	dynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
909 	dynamicStateCreateInfo.pNext = 0;
910 	if(pcomp->scissoring){
911 		dynamicStateCreateInfo.pDynamicStates = dynamicStates;
912 		dynamicStateCreateInfo.dynamicStateCount = 1;
913 	}else{
914 		dynamicStateCreateInfo.pDynamicStates = 0;
915 		dynamicStateCreateInfo.dynamicStateCount = 0;
916 	}*/
917 
918 	VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {};
919 	graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
920 	graphicsPipelineCreateInfo.stageCount = stageCount;
921 	graphicsPipelineCreateInfo.pStages = shaderStageCreateInfo;
922 	graphicsPipelineCreateInfo.pVertexInputState = &vertexInputStateCreateInfo;
923 	graphicsPipelineCreateInfo.pInputAssemblyState = pinputAssemblyStateCreateInfo;
924 	graphicsPipelineCreateInfo.pViewportState = &viewportStateCreateInfo;
925 	graphicsPipelineCreateInfo.pRasterizationState = prasterizationStateCreateInfo;
926 	graphicsPipelineCreateInfo.pMultisampleState = &multisampleStateCreateInfo;
927 	graphicsPipelineCreateInfo.pDepthStencilState = pdepthStencilStateCreateInfo;
928 	graphicsPipelineCreateInfo.pColorBlendState = pcolorBlendStateCreateInfo;
929 	//graphicsPipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo;
930 	graphicsPipelineCreateInfo.pDynamicState = pdynamicStateCreateInfo;
931 	graphicsPipelineCreateInfo.layout = pipelineLayout;
932 	graphicsPipelineCreateInfo.renderPass = pcomp->renderPass;
933 	graphicsPipelineCreateInfo.subpass = 0;
934 	graphicsPipelineCreateInfo.basePipelineHandle = 0;
935 	graphicsPipelineCreateInfo.basePipelineIndex = -1;
936 
937 	if(vkCreateGraphicsPipelines(pcomp->logicalDev,0,1,&graphicsPipelineCreateInfo,0,&pipeline) != VK_SUCCESS)
938 		throw Exception("Failed to create a graphics pipeline.");
939 
940 	delete []pvertexInputAttributeDescs;
941 }
942 
~Pipeline()943 Pipeline::~Pipeline(){
944 	vkDestroyPipeline(pcomp->logicalDev,pipeline,0);
945 	vkDestroyPipelineLayout(pcomp->logicalDev,pipelineLayout,0);
946 }
947 
ClientPipeline(ShaderModule * _pvertexShader,ShaderModule * _pgeometryShader,ShaderModule * _pfragmentShader,const std::vector<std::pair<ShaderModule::INPUT,uint>> * pvertexBufferLayout,const CompositorInterface * _pcomp)948 ClientPipeline::ClientPipeline(ShaderModule *_pvertexShader, ShaderModule *_pgeometryShader, ShaderModule *_pfragmentShader, const std::vector<std::pair<ShaderModule::INPUT, uint>> *pvertexBufferLayout, const CompositorInterface *_pcomp) : Pipeline(_pvertexShader,_pgeometryShader,_pfragmentShader,pvertexBufferLayout,&inputAssemblyStateCreateInfo,&rasterizationStateCreateInfo,0,&colorBlendStateCreateInfo,_pcomp->scissoring?&dynamicStateCreateInfoScissoring:&dynamicStateCreateInfo,_pcomp){
949 	//
950 }
951 
~ClientPipeline()952 ClientPipeline::~ClientPipeline(){
953 	//
954 }
955 
956 const VkPipelineInputAssemblyStateCreateInfo ClientPipeline::inputAssemblyStateCreateInfo = {
957 	.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
958 	.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST,//VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
959 	.primitiveRestartEnable = VK_FALSE
960 };
961 
962 const VkPipelineRasterizationStateCreateInfo ClientPipeline::rasterizationStateCreateInfo = {
963 	.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
964 	.depthClampEnable = VK_FALSE,
965 	.rasterizerDiscardEnable = VK_FALSE,
966 	.polygonMode = VK_POLYGON_MODE_FILL,
967 	.cullMode = VK_CULL_MODE_NONE,
968 	.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
969 	.depthBiasEnable = VK_FALSE,
970 	.depthBiasConstantFactor = 0.0f,
971 	.depthBiasClamp = 0.0f,
972 	.depthBiasSlopeFactor = 0.0f,
973 	.lineWidth = 1.0f
974 };
975 
976 const VkPipelineColorBlendAttachmentState ClientPipeline::colorBlendAttachmentState = {
977 	.blendEnable = VK_TRUE,
978 	//premultiplied alpha blending
979 	.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
980 	.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
981 	.colorBlendOp = VK_BLEND_OP_ADD,
982 	.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
983 	.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
984 	.alphaBlendOp = VK_BLEND_OP_ADD,
985 	.colorWriteMask = VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
986 };
987 
988 const VkDynamicState ClientPipeline::dynamicStatesScissoring[1] = {VK_DYNAMIC_STATE_SCISSOR};
989 
990 const VkPipelineDynamicStateCreateInfo ClientPipeline::dynamicStateCreateInfo = {
991 	.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
992 	.pNext = 0,
993 	.flags = 0,
994 	.dynamicStateCount = 0,
995 	.pDynamicStates = 0
996 };
997 
998 const VkPipelineDynamicStateCreateInfo ClientPipeline::dynamicStateCreateInfoScissoring = {
999 	.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1000 	.pNext = 0,
1001 	.flags = 0,
1002 	.dynamicStateCount = 1,
1003 	.pDynamicStates = dynamicStatesScissoring
1004 };
1005 
1006 const VkPipelineColorBlendStateCreateInfo ClientPipeline::colorBlendStateCreateInfo = {
1007 	.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1008 	.logicOpEnable = VK_FALSE,
1009 	.logicOp = VK_LOGIC_OP_COPY,
1010 	.attachmentCount = 1,
1011 	.pAttachments = &colorBlendAttachmentState,
1012 	.blendConstants = {0.0f,0.0f,0.0f,0.0f}
1013 };
1014 
TextPipeline(ShaderModule * _pvertexShader,ShaderModule * _pgeometryShader,ShaderModule * _pfragmentShader,const std::vector<std::pair<ShaderModule::INPUT,uint>> * pvertexBufferLayout,const CompositorInterface * _pcomp)1015 TextPipeline::TextPipeline(ShaderModule *_pvertexShader, ShaderModule *_pgeometryShader, ShaderModule *_pfragmentShader, const std::vector<std::pair<ShaderModule::INPUT, uint>> *pvertexBufferLayout, const CompositorInterface *_pcomp) : Pipeline(_pvertexShader,_pgeometryShader,_pfragmentShader,pvertexBufferLayout,&inputAssemblyStateCreateInfo,&rasterizationStateCreateInfo,0,&colorBlendStateCreateInfo,&ClientPipeline::dynamicStateCreateInfoScissoring,_pcomp){
1016 	//
1017 }
1018 
~TextPipeline()1019 TextPipeline::~TextPipeline(){
1020 	//
1021 }
1022 
1023 const VkPipelineInputAssemblyStateCreateInfo TextPipeline::inputAssemblyStateCreateInfo = {
1024 	.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1025 	.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1026 	.primitiveRestartEnable = VK_FALSE
1027 };
1028 
1029 const VkPipelineRasterizationStateCreateInfo TextPipeline::rasterizationStateCreateInfo = {
1030 	.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1031 	.depthClampEnable = VK_FALSE,
1032 	.rasterizerDiscardEnable = VK_FALSE,
1033 	.polygonMode = VK_POLYGON_MODE_FILL,
1034 	//.polygonMode = VK_POLYGON_MODE_LINE,
1035 	.cullMode = VK_CULL_MODE_NONE,
1036 	.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
1037 	.depthBiasEnable = VK_FALSE,
1038 	.depthBiasConstantFactor = 0.0f,
1039 	.depthBiasClamp = 0.0f,
1040 	.depthBiasSlopeFactor = 0.0f,
1041 	.lineWidth = 1.0f
1042 };
1043 
1044 const VkPipelineColorBlendAttachmentState TextPipeline::colorBlendAttachmentState = {
1045 	.blendEnable = VK_TRUE,
1046 	//alpha blending
1047 	.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
1048 	.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1049 	.colorBlendOp = VK_BLEND_OP_ADD,
1050 	.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
1051 	.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1052 	.alphaBlendOp = VK_BLEND_OP_ADD,
1053 	.colorWriteMask = VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
1054 };
1055 
1056 const VkPipelineColorBlendStateCreateInfo TextPipeline::colorBlendStateCreateInfo = {
1057 	.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1058 	.logicOpEnable = VK_FALSE,
1059 	.logicOp = VK_LOGIC_OP_COPY,
1060 	.attachmentCount = 1,
1061 	.pAttachments = &colorBlendAttachmentState,
1062 	.blendConstants = {0.0f,0.0f,0.0f,0.0f}
1063 };
1064 
1065 }
1066 
1067