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