Plumb steamcompmgr window painting to Vulkan compute.
This commit is contained in:
parent
622f198549
commit
ec34dad8a9
4 changed files with 163 additions and 124 deletions
|
@ -1,12 +1,37 @@
|
|||
[[vk::binding(0, 0)]] RWTexture2D<float4> outImage;
|
||||
[[vk::binding(1, 0)]] Texture2D inLayerTex0;
|
||||
[[vk::binding(2, 0)]] SamplerState sampler0;
|
||||
[[vk::binding(3, 0)]] Texture2D inLayerTex1;
|
||||
[[vk::binding(4, 0)]] SamplerState sampler1;
|
||||
[[vk::binding(5, 0)]] Texture2D inLayerTex2;
|
||||
[[vk::binding(6, 0)]] SamplerState sampler2;
|
||||
[[vk::binding(7, 0)]] Texture2D inLayerTex3;
|
||||
[[vk::binding(8, 0)]] SamplerState sampler3;
|
||||
|
||||
[[vk::binding(1, 0)]] cbuffer compositeDesc
|
||||
{
|
||||
float flLayerCount;
|
||||
|
||||
float2 flScale0;
|
||||
float2 flOffset0;
|
||||
float flOpacity0;
|
||||
|
||||
float2 flScale1;
|
||||
float2 flOffset1;
|
||||
float flOpacity1;
|
||||
|
||||
float2 flScale2;
|
||||
float2 flOffset2;
|
||||
float flOpacity2;
|
||||
|
||||
float2 flScale3;
|
||||
float2 flOffset3;
|
||||
float flOpacity3;
|
||||
}
|
||||
|
||||
[[vk::binding(2, 0)]] Texture2D inLayerTex0;
|
||||
[[vk::binding(3, 0)]] SamplerState sampler0;
|
||||
|
||||
[[vk::binding(4, 0)]] Texture2D inLayerTex1;
|
||||
[[vk::binding(5, 0)]] SamplerState sampler1;
|
||||
|
||||
[[vk::binding(6, 0)]] Texture2D inLayerTex2;
|
||||
[[vk::binding(7, 0)]] SamplerState sampler2;
|
||||
|
||||
[[vk::binding(8, 0)]] Texture2D inLayerTex3;
|
||||
[[vk::binding(9, 0)]] SamplerState sampler3;
|
||||
|
||||
[numthreads(16, 16, 1)]
|
||||
void main(
|
||||
|
@ -17,7 +42,19 @@ void main(
|
|||
{
|
||||
uint2 index = uint2(dispatchThreadId.x, dispatchThreadId.y);
|
||||
|
||||
float4 outputValue = inLayerTex0.Sample( sampler0, float2( index ) );
|
||||
float4 outputValue;
|
||||
|
||||
if ( flLayerCount >= 1.0f )
|
||||
{
|
||||
outputValue = inLayerTex0.Sample( sampler0, float2( index ) * flScale0 + flOffset0 );
|
||||
}
|
||||
|
||||
if ( flLayerCount >= 2.0f )
|
||||
{
|
||||
float4 layerSample = inLayerTex1.Sample( sampler1, float2( index ) * flScale1 + flOffset1 );
|
||||
float layerAlpha = flOpacity1 * layerSample.a;
|
||||
outputValue = layerSample * layerAlpha + outputValue * ( 1 - layerAlpha );
|
||||
}
|
||||
|
||||
outImage [index] = outputValue;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,10 @@ struct VkPhysicalDeviceMemoryProperties memoryProperties;
|
|||
int g_nOutImage; // ping/pong between two RTs
|
||||
CVulkanTexture outputImage[2];
|
||||
|
||||
VkBuffer constantBuffer;
|
||||
VkDeviceMemory bufferMemory;
|
||||
Composite_t *g_pCompositeBuffer;
|
||||
|
||||
std::unordered_map<VulkanTexture_t, CVulkanTexture *> g_mapVulkanTextures;
|
||||
std::atomic<VulkanTexture_t> g_nMaxVulkanTexHandle;
|
||||
|
||||
|
@ -443,13 +447,17 @@ int init_device()
|
|||
// probably hard to hit that even with 3 overlays, and a bunch of tracked windows
|
||||
// famous last words
|
||||
//#define k_nMaxSets 20
|
||||
#define k_nMaxSets 2000 // don't have time to cache or free stuff
|
||||
#define k_nMaxSets 20000 // don't have time to cache or free stuff
|
||||
|
||||
VkDescriptorPoolSize descriptorPoolSize[] = {
|
||||
{
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
k_nMaxSets * 1,
|
||||
},
|
||||
{
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
k_nMaxSets * 1,
|
||||
},
|
||||
{
|
||||
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
k_nMaxSets * k_nMaxLayers,
|
||||
|
@ -476,7 +484,43 @@ int init_device()
|
|||
return false;
|
||||
}
|
||||
|
||||
VkBufferCreateInfo bufferCreateInfo = {};
|
||||
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufferCreateInfo.pNext = nullptr;
|
||||
bufferCreateInfo.size = sizeof( Composite_t );
|
||||
bufferCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||
|
||||
res = vkCreateBuffer( device, &bufferCreateInfo, nullptr, &constantBuffer );
|
||||
|
||||
if ( res != VK_SUCCESS )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
VkMemoryRequirements memRequirements;
|
||||
vkGetBufferMemoryRequirements(device, constantBuffer, &memRequirements);
|
||||
|
||||
int memTypeIndex = findMemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memRequirements.memoryTypeBits );
|
||||
|
||||
if ( memTypeIndex == -1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
VkMemoryAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocInfo.allocationSize = memRequirements.size;
|
||||
allocInfo.memoryTypeIndex = memTypeIndex;
|
||||
|
||||
vkAllocateMemory( device, &allocInfo, nullptr, &bufferMemory );
|
||||
|
||||
vkBindBufferMemory( device, constantBuffer, bufferMemory, 0 );
|
||||
vkMapMemory( device, bufferMemory, 0, VK_WHOLE_SIZE, 0, (void**)&g_pCompositeBuffer );
|
||||
|
||||
if ( g_pCompositeBuffer == nullptr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -687,8 +731,11 @@ void vulkan_free_texture( VulkanTexture_t vulkanTex )
|
|||
// actually free something at some point
|
||||
}
|
||||
|
||||
bool vulkan_composite( struct VulkanPipeline_t *pPipeline )
|
||||
bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline )
|
||||
{
|
||||
*g_pCompositeBuffer = *pComposite;
|
||||
// XXX maybe flush something?
|
||||
|
||||
CVulkanTexture *pTex[ k_nMaxLayers ] = {};
|
||||
uint32_t nTexCount = 0;
|
||||
|
||||
|
@ -714,14 +761,21 @@ bool vulkan_composite( struct VulkanPipeline_t *pPipeline )
|
|||
|
||||
vecLayoutBindings.push_back( descriptorSetLayoutBindings ); // first binding is target storage image
|
||||
|
||||
descriptorSetLayoutBindings.binding = 1;
|
||||
descriptorSetLayoutBindings.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
|
||||
vecLayoutBindings.push_back( descriptorSetLayoutBindings ); // second binding is composite description buffer
|
||||
|
||||
for ( uint32_t i = 0; i < nTexCount; i++ )
|
||||
{
|
||||
descriptorSetLayoutBindings.binding = 2 + ( i * 2 );
|
||||
descriptorSetLayoutBindings.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
descriptorSetLayoutBindings.binding = 1 + ( i * 2 );
|
||||
|
||||
vecLayoutBindings.push_back( descriptorSetLayoutBindings );
|
||||
|
||||
descriptorSetLayoutBindings.binding = 2 + ( i * 2 ) + 1;
|
||||
descriptorSetLayoutBindings.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
descriptorSetLayoutBindings.binding = 1 + ( i * 2 ) + 1;
|
||||
|
||||
vecLayoutBindings.push_back( descriptorSetLayoutBindings );
|
||||
}
|
||||
|
||||
|
@ -730,7 +784,7 @@ bool vulkan_composite( struct VulkanPipeline_t *pPipeline )
|
|||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.bindingCount = 1 + ( nTexCount * 2 ),
|
||||
.bindingCount = 2 + ( nTexCount * 2 ),
|
||||
vecLayoutBindings.data()
|
||||
};
|
||||
|
||||
|
@ -808,6 +862,12 @@ bool vulkan_composite( struct VulkanPipeline_t *pPipeline )
|
|||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
|
||||
};
|
||||
|
||||
VkDescriptorBufferInfo bufferInfo = {
|
||||
.buffer = constantBuffer,
|
||||
.offset = 0,
|
||||
.range = VK_WHOLE_SIZE
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet writeDescriptorSet = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
|
@ -822,6 +882,13 @@ bool vulkan_composite( struct VulkanPipeline_t *pPipeline )
|
|||
};
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
|
||||
writeDescriptorSet.dstBinding = 1;
|
||||
writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
writeDescriptorSet.pImageInfo = nullptr;
|
||||
writeDescriptorSet.pBufferInfo = &bufferInfo;
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < nTexCount; i++ )
|
||||
|
@ -857,7 +924,7 @@ bool vulkan_composite( struct VulkanPipeline_t *pPipeline )
|
|||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = descriptorSet,
|
||||
.dstBinding = 1 + (i * 2),
|
||||
.dstBinding = 2 + (i * 2),
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
|
@ -878,7 +945,7 @@ bool vulkan_composite( struct VulkanPipeline_t *pPipeline )
|
|||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = descriptorSet,
|
||||
.dstBinding = 1 + (i * 2) + 1,
|
||||
.dstBinding = 2 + (i * 2) + 1,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
|
|
|
@ -52,12 +52,24 @@ struct VulkanPipeline_t
|
|||
} layerBindings[ k_nMaxLayers ];
|
||||
};
|
||||
|
||||
struct Composite_t
|
||||
{
|
||||
float flLayerCount;
|
||||
|
||||
struct
|
||||
{
|
||||
float flScaleX, flScaleY;
|
||||
float flOffsetX, flOffsetY;
|
||||
float flOpacity;
|
||||
} layers[ k_nMaxLayers ];
|
||||
};
|
||||
|
||||
int vulkan_init(void);
|
||||
|
||||
VulkanTexture_t vulkan_create_texture_from_dmabuf( struct wlr_dmabuf_attributes *pDMA );
|
||||
void vulkan_free_texture( VulkanTexture_t vulkanTex );
|
||||
|
||||
bool vulkan_composite( struct VulkanPipeline_t *pPipeline );
|
||||
bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline );
|
||||
uint32_t vulkan_get_last_composite_fbid( void );
|
||||
|
||||
void vulkan_present_to_window( void );
|
||||
|
|
|
@ -510,11 +510,10 @@ paint_fake_cursor (Display *dpy, win *w)
|
|||
}
|
||||
|
||||
static void
|
||||
paint_window (Display *dpy, win *w, Bool doBlend, Bool notificationMode)
|
||||
paint_window (Display *dpy, win *w, struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline, Bool notificationMode)
|
||||
{
|
||||
int sourceWidth, sourceHeight;
|
||||
int drawXOffset = 0, drawYOffset = 0;
|
||||
Bool isScaling = False;
|
||||
float currentScaleRatio = 1.0;
|
||||
|
||||
if (!w)
|
||||
|
@ -539,122 +538,57 @@ paint_window (Display *dpy, win *w, Bool doBlend, Bool notificationMode)
|
|||
sourceHeight = w->a.height;
|
||||
}
|
||||
|
||||
// glBindTexture (GL_TEXTURE_2D, w->texName);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (sourceWidth != root_width || sourceHeight != root_height || globalScaleRatio != 1.0f)
|
||||
if (sourceWidth != g_nOutputWidth || sourceHeight != g_nOutputHeight || globalScaleRatio != 1.0f)
|
||||
{
|
||||
float XRatio = (float)root_width / sourceWidth;
|
||||
float YRatio = (float)root_height / sourceHeight;
|
||||
float XRatio = (float)g_nOutputWidth / sourceWidth;
|
||||
float YRatio = (float)g_nOutputHeight / sourceHeight;
|
||||
|
||||
currentScaleRatio = (XRatio < YRatio) ? XRatio : YRatio;
|
||||
currentScaleRatio *= globalScaleRatio;
|
||||
|
||||
drawXOffset = (root_width - sourceWidth * currentScaleRatio) / 2.0f;
|
||||
drawYOffset = (root_height - sourceHeight * currentScaleRatio) / 2.0f;
|
||||
drawXOffset = (g_nOutputWidth - sourceWidth * currentScaleRatio) / 2.0f;
|
||||
drawYOffset = (g_nOutputHeight - sourceHeight * currentScaleRatio) / 2.0f;
|
||||
|
||||
if ( zoomScaleRatio != 1.0 )
|
||||
{
|
||||
drawXOffset += ((sourceWidth / 2) - cursorX) * currentScaleRatio;
|
||||
drawYOffset += ((sourceHeight / 2) - cursorY) * currentScaleRatio;
|
||||
}
|
||||
|
||||
isScaling = True;
|
||||
}
|
||||
|
||||
if (doBlend)
|
||||
glEnable(GL_BLEND);
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
int curLayer = (int)pComposite->flLayerCount;
|
||||
|
||||
// If scaling and blending, we need to draw our letterbox black border with
|
||||
// the right opacity instead of relying on the clear color
|
||||
if (isScaling && doBlend && !notificationMode)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glColor4f(0.0f, 0.0f, 0.0f, (float)w->opacity / OPAQUE);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
// We can't overdraw because we're blending
|
||||
|
||||
// Top and bottom stripes, including sides
|
||||
if (drawYOffset)
|
||||
{
|
||||
glVertex2d (0.0f, 0.0f);
|
||||
glVertex2d (root_width, 0.0f);
|
||||
glVertex2d (root_width, drawYOffset);
|
||||
glVertex2d (0.0f, drawYOffset);
|
||||
|
||||
glVertex2d (0.0f, root_height - drawYOffset);
|
||||
glVertex2d (root_width, root_height - drawYOffset);
|
||||
glVertex2d (root_width, root_height);
|
||||
glVertex2d (0.0f, root_height);
|
||||
}
|
||||
|
||||
// Side stripes, excluding any top and bottom areas
|
||||
if (drawXOffset)
|
||||
{
|
||||
glVertex2d (0.0f, drawYOffset);
|
||||
glVertex2d (drawXOffset, drawYOffset);
|
||||
glVertex2d (drawXOffset, root_height - drawYOffset);
|
||||
glVertex2d (0.0f, root_height - drawYOffset);
|
||||
|
||||
glVertex2d (root_width - drawXOffset, drawYOffset);
|
||||
glVertex2d (root_width, drawYOffset);
|
||||
glVertex2d (root_width, root_height - drawYOffset);
|
||||
glVertex2d (root_width - drawXOffset, root_height - drawYOffset);
|
||||
}
|
||||
|
||||
glEnd ();
|
||||
}
|
||||
pComposite->layers[ curLayer ].flOpacity = (float)w->opacity / OPAQUE;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (w->isOverlay)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
|
||||
else
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, (float)w->opacity / OPAQUE);
|
||||
|
||||
int originX, originY, width, height;
|
||||
pComposite->layers[ curLayer ].flScaleX = 1.0 / currentScaleRatio;
|
||||
pComposite->layers[ curLayer ].flScaleY = 1.0 / currentScaleRatio;
|
||||
|
||||
if (notificationMode)
|
||||
{
|
||||
int xOffset = 0, yOffset = 0;
|
||||
|
||||
width = w->a.width * currentScaleRatio;
|
||||
height = w->a.height * currentScaleRatio;
|
||||
int width = w->a.width * currentScaleRatio;
|
||||
int height = w->a.height * currentScaleRatio;
|
||||
|
||||
if (globalScaleRatio != 1.0f)
|
||||
{
|
||||
xOffset = (root_width - root_width * globalScaleRatio) / 2.0;
|
||||
yOffset = (root_height - root_height * globalScaleRatio) / 2.0;
|
||||
xOffset = (g_nOutputWidth - g_nOutputWidth * globalScaleRatio) / 2.0;
|
||||
yOffset = (g_nOutputHeight - g_nOutputHeight * globalScaleRatio) / 2.0;
|
||||
}
|
||||
|
||||
originX = root_width - xOffset - width;
|
||||
originY = root_height - yOffset - height;
|
||||
pComposite->layers[ curLayer ].flOffsetX = (g_nOutputWidth - xOffset - width) * -1.0f;
|
||||
pComposite->layers[ curLayer ].flOffsetY = (g_nOutputHeight - yOffset - height) * -1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
originX = drawXOffset;
|
||||
originY = drawYOffset;
|
||||
|
||||
width = sourceWidth * currentScaleRatio;
|
||||
height = sourceHeight * currentScaleRatio;
|
||||
pComposite->layers[ curLayer ].flOffsetX = -drawXOffset;
|
||||
pComposite->layers[ curLayer ].flOffsetY = -drawYOffset;
|
||||
}
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2d (0.0f, 0.0f);
|
||||
glVertex2d (originX, originY);
|
||||
glTexCoord2d (1.0f, 0.0f);
|
||||
glVertex2d (originX + width, originY);
|
||||
glTexCoord2d (1.0f, 1.0f);
|
||||
glVertex2d (originX + width, originY + height);
|
||||
glTexCoord2d (0.0f, 1.0f);
|
||||
glVertex2d (originX, originY + height);
|
||||
glEnd ();
|
||||
pPipeline->layerBindings[ curLayer ].tex = w->vulkanTex;
|
||||
pPipeline->layerBindings[ curLayer ].bFilter = w->isOverlay ? true : false;
|
||||
|
||||
pComposite->flLayerCount += 1.0f;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -768,14 +702,8 @@ paint_all (Display *dpy)
|
|||
ensure_win_resources(dpy, overlay);
|
||||
ensure_win_resources(dpy, notification);
|
||||
|
||||
glViewport(0, 0, root_width, root_height);
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, root_width, root_height, 0.0f, -1.0f, 1.0f);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
struct Composite_t composite = {};
|
||||
struct VulkanPipeline_t pipeline = {};
|
||||
|
||||
// Fading out from previous window?
|
||||
if (fadingOut)
|
||||
|
@ -784,7 +712,7 @@ paint_all (Display *dpy)
|
|||
|
||||
// Draw it in the background
|
||||
fadeOutWindow.opacity = (1.0d - newOpacity) * OPAQUE;
|
||||
paint_window(dpy, &fadeOutWindow, True, False);
|
||||
paint_window(dpy, &fadeOutWindow, &composite, &pipeline, False);
|
||||
|
||||
w = find_win(dpy, currentFocusWindow);
|
||||
ensure_win_resources(dpy, w);
|
||||
|
@ -792,14 +720,14 @@ paint_all (Display *dpy)
|
|||
// Blend new window on top with linear crossfade
|
||||
w->opacity = newOpacity * OPAQUE;
|
||||
|
||||
paint_window(dpy, w, True, False);
|
||||
paint_window(dpy, w, &composite, &pipeline, False);
|
||||
}
|
||||
else
|
||||
{
|
||||
w = find_win(dpy, currentFocusWindow);
|
||||
ensure_win_resources(dpy, w);
|
||||
// Just draw focused window as normal, be it Steam or the game
|
||||
paint_window(dpy, w, False, False);
|
||||
paint_window(dpy, w, &composite, &pipeline, False);
|
||||
|
||||
if (fadeOutWindow.id) {
|
||||
|
||||
|
@ -820,7 +748,7 @@ paint_all (Display *dpy)
|
|||
{
|
||||
if (overlay->opacity)
|
||||
{
|
||||
paint_window(dpy, overlay, True, False);
|
||||
paint_window(dpy, overlay, &composite, &pipeline, False);
|
||||
}
|
||||
overlay->damaged = 0;
|
||||
}
|
||||
|
@ -829,7 +757,7 @@ paint_all (Display *dpy)
|
|||
{
|
||||
if (notification->opacity)
|
||||
{
|
||||
paint_window(dpy, notification, True, True);
|
||||
paint_window(dpy, notification, &composite, &pipeline, True);
|
||||
}
|
||||
notification->damaged = 0;
|
||||
}
|
||||
|
@ -843,13 +771,8 @@ paint_all (Display *dpy)
|
|||
|
||||
if (drawDebugInfo)
|
||||
paint_debug_info(dpy);
|
||||
|
||||
struct VulkanPipeline_t pipeline = {};
|
||||
|
||||
pipeline.layerBindings[0].tex = w->vulkanTex;
|
||||
pipeline.layerBindings[0].bFilter = false;
|
||||
|
||||
bool bResult = vulkan_composite( &pipeline );
|
||||
bool bResult = vulkan_composite( &composite, &pipeline );
|
||||
|
||||
if ( bResult != true )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue