Move to combined samplers and rewrite composite shader in GLSL
Cleans up the composite shader significantly as well as it uses arrays of descriptors/samplers now. This all gets unrolled as the loop is spec-constant sized.
This commit is contained in:
parent
f537a40483
commit
e818aec744
4 changed files with 86 additions and 152 deletions
|
@ -61,7 +61,7 @@ shadercompiler = find_program('glslangValidator')
|
|||
|
||||
spirv_shader = custom_target('shader_target',
|
||||
output : 'composite.h',
|
||||
input : 'src/composite.comp.hlsl',
|
||||
input : 'src/composite.comp',
|
||||
command : [
|
||||
shadercompiler, '-V', '-e', 'main', '--vn',
|
||||
'composite_spv', '@INPUT@', '-o', '@OUTPUT@'
|
||||
|
|
58
src/composite.comp
Normal file
58
src/composite.comp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#version 450
|
||||
|
||||
#extension GL_EXT_scalar_block_layout : require
|
||||
|
||||
layout(
|
||||
local_size_x = 8,
|
||||
local_size_y = 8,
|
||||
local_size_z = 1) in;
|
||||
|
||||
const int MaxLayers = 4;
|
||||
|
||||
layout(constant_id = 0) const int c_layerCount = 1;
|
||||
layout(constant_id = 1) const bool c_swapChannels = false;
|
||||
|
||||
layout(binding = 0, rgba8) writeonly uniform image2D dst;
|
||||
|
||||
layout(std430, binding = 1)
|
||||
uniform layers_t {
|
||||
vec2 u_scale[MaxLayers];
|
||||
vec2 u_offset[MaxLayers];
|
||||
float u_opacity[MaxLayers];
|
||||
};
|
||||
|
||||
layout(binding = 2) uniform sampler2D s_samplers[MaxLayers];
|
||||
|
||||
vec4 sampleLayer(uint layerIdx, vec2 uv) {
|
||||
vec2 coord = (uv + u_offset[layerIdx]) * u_scale[layerIdx];
|
||||
return texture(s_samplers[layerIdx], coord);
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec2 coord = uvec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
|
||||
uvec2 outSize = imageSize(dst);
|
||||
|
||||
if (coord.x >= outSize.x || coord.y >= outSize.y)
|
||||
return;
|
||||
|
||||
vec2 uv = vec2(coord);
|
||||
vec4 outputValue = vec4(0.0f);
|
||||
|
||||
if (c_layerCount > 0)
|
||||
outputValue = sampleLayer(0, uv);
|
||||
|
||||
for (int i = 1; i < c_layerCount; i++) {
|
||||
vec4 layerColor = sampleLayer(i, uv);
|
||||
float layerAlpha = u_opacity[i] * layerColor.a;
|
||||
outputValue = layerColor * layerAlpha + outputValue * (1.0f - layerAlpha);
|
||||
}
|
||||
|
||||
if (c_swapChannels)
|
||||
outputValue = outputValue.bgra;
|
||||
|
||||
imageStore(dst, ivec2(coord), outputValue);
|
||||
|
||||
// Indicator to quickly tell if we're in the compositing path or not.
|
||||
if (false && coord.x > 50 && coord.x < 100 && coord.y > 50 && coord.y < 100)
|
||||
imageStore(dst, ivec2(coord), vec4(1.0f, 0.0f, 1.0f, 1.0f));
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
[[vk::binding(0, 0)]] RWTexture2D<float4> outImage;
|
||||
|
||||
[[vk::binding(1, 0)]] cbuffer compositeDesc
|
||||
{
|
||||
float flScale0X;
|
||||
float flScale0Y;
|
||||
float flScale1X;
|
||||
float flScale1Y;
|
||||
float flScale2X;
|
||||
float flScale2Y;
|
||||
float flScale3X;
|
||||
float flScale3Y;
|
||||
|
||||
float flOffset0X;
|
||||
float flOffset0Y;
|
||||
float flOffset1X;
|
||||
float flOffset1Y;
|
||||
float flOffset2X;
|
||||
float flOffset2Y;
|
||||
float flOffset3X;
|
||||
float flOffset3Y;
|
||||
|
||||
float flOpacity0;
|
||||
float flOpacity1;
|
||||
float flOpacity2;
|
||||
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;
|
||||
|
||||
[[vk::constant_id(0)]] const int nLayerCount = 1;
|
||||
[[vk::constant_id(1)]] const bool bSwapChannels = false;
|
||||
|
||||
[numthreads(8, 8, 1)]
|
||||
void main(
|
||||
uint3 groupId : SV_GroupID,
|
||||
uint3 groupThreadId : SV_GroupThreadID,
|
||||
uint3 dispatchThreadId : SV_DispatchThreadID,
|
||||
uint groupIndex : SV_GroupIndex)
|
||||
{
|
||||
uint2 index = uint2(dispatchThreadId.x, dispatchThreadId.y);
|
||||
|
||||
uint2 outSize;
|
||||
outImage.GetDimensions( outSize.x, outSize.y );
|
||||
|
||||
if ( index.x >= outSize.x || index.y >= outSize.y )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float4 outputValue;
|
||||
|
||||
if ( nLayerCount >= 1 )
|
||||
{
|
||||
outputValue = inLayerTex0.Sample( sampler0, ( float2( index ) + float2( flOffset0X, flOffset0Y ) ) * float2( flScale0X, flScale0Y ) );
|
||||
}
|
||||
|
||||
if ( nLayerCount >= 2 )
|
||||
{
|
||||
float4 layerSample = inLayerTex1.Sample( sampler1, ( float2( index ) + float2( flOffset1X, flOffset1Y ) ) * float2( flScale1X, flScale1Y ) );
|
||||
float layerAlpha = flOpacity1 * layerSample.a;
|
||||
outputValue = layerSample * layerAlpha + outputValue * ( 1.0 - layerAlpha );
|
||||
}
|
||||
|
||||
if ( nLayerCount >= 3 )
|
||||
{
|
||||
float4 layerSample = inLayerTex2.Sample( sampler2, ( float2( index ) + float2( flOffset2X, flOffset2Y ) ) * float2( flScale2X, flScale2Y ) );
|
||||
float layerAlpha = flOpacity2 * layerSample.a;
|
||||
outputValue = layerSample * layerAlpha + outputValue * ( 1.0 - layerAlpha );
|
||||
}
|
||||
|
||||
if ( bSwapChannels )
|
||||
{
|
||||
outImage [index] = outputValue.bgra;
|
||||
}
|
||||
else
|
||||
{
|
||||
outImage [index] = outputValue;
|
||||
}
|
||||
|
||||
// indicator to quickly tell if we're in the compositing path or not
|
||||
if ( 0 && index.x > 50 && index.x < 100 && index.y > 50 && index.y < 100 )
|
||||
{
|
||||
outImage [index] = float4(1.0,0.0,1.0,1.0);
|
||||
}
|
||||
}
|
|
@ -980,11 +980,7 @@ retry:
|
|||
k_nMaxSets * 1,
|
||||
},
|
||||
{
|
||||
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
k_nMaxSets * k_nMaxLayers,
|
||||
},
|
||||
{
|
||||
VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
k_nMaxSets * k_nMaxLayers,
|
||||
},
|
||||
};
|
||||
|
@ -1017,29 +1013,23 @@ retry:
|
|||
vecLayoutBindings.push_back( descriptorSetLayoutBindings ); // first binding is target storage image
|
||||
|
||||
descriptorSetLayoutBindings.binding = 1;
|
||||
descriptorSetLayoutBindings.descriptorCount = 1;
|
||||
descriptorSetLayoutBindings.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
|
||||
vecLayoutBindings.push_back( descriptorSetLayoutBindings ); // second binding is composite description buffer
|
||||
|
||||
for ( uint32_t i = 0; i < k_nMaxLayers; i++ )
|
||||
{
|
||||
descriptorSetLayoutBindings.binding = 2 + ( i * 2 );
|
||||
descriptorSetLayoutBindings.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
|
||||
vecLayoutBindings.push_back( descriptorSetLayoutBindings );
|
||||
|
||||
descriptorSetLayoutBindings.binding = 2 + ( i * 2 ) + 1;
|
||||
descriptorSetLayoutBindings.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
|
||||
vecLayoutBindings.push_back( descriptorSetLayoutBindings );
|
||||
}
|
||||
descriptorSetLayoutBindings.binding = 2;
|
||||
descriptorSetLayoutBindings.descriptorCount = k_nMaxLayers;
|
||||
descriptorSetLayoutBindings.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
|
||||
vecLayoutBindings.push_back( descriptorSetLayoutBindings );
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.bindingCount = 2 + ( k_nMaxLayers * 2 ),
|
||||
.bindingCount = (uint32_t)vecLayoutBindings.size(),
|
||||
.pBindings = vecLayoutBindings.data()
|
||||
};
|
||||
|
||||
|
@ -1832,6 +1822,7 @@ void vulkan_update_descriptor( struct VulkanPipeline_t *pPipeline )
|
|||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
std::array< VkDescriptorImageInfo, k_nMaxLayers > imageDescriptors;
|
||||
for ( uint32_t i = 0; i < k_nMaxLayers; i++ )
|
||||
{
|
||||
VkSampler sampler = VK_NULL_HANDLE;
|
||||
|
@ -1871,48 +1862,29 @@ void vulkan_update_descriptor( struct VulkanPipeline_t *pPipeline )
|
|||
|
||||
{
|
||||
VkDescriptorImageInfo imageInfo = {
|
||||
.sampler = sampler,
|
||||
.imageView = pTex->m_vkImageView,
|
||||
// TODO figure out what it is exactly for the wayland surfaces
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet writeDescriptorSet = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = descriptorSet,
|
||||
.dstBinding = 2 + (i * 2),
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.pImageInfo = &imageInfo,
|
||||
.pBufferInfo = nullptr,
|
||||
.pTexelBufferView = nullptr,
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
VkDescriptorImageInfo imageInfo = {
|
||||
.sampler = sampler,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet writeDescriptorSet = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = descriptorSet,
|
||||
.dstBinding = 2 + (i * 2) + 1,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.pImageInfo = &imageInfo,
|
||||
.pBufferInfo = nullptr,
|
||||
.pTexelBufferView = nullptr,
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
|
||||
imageDescriptors[ i ] = imageInfo;
|
||||
}
|
||||
}
|
||||
|
||||
VkWriteDescriptorSet writeDescriptorSet = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = descriptorSet,
|
||||
.dstBinding = 2,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = imageDescriptors.size(),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = imageDescriptors.data(),
|
||||
.pBufferInfo = nullptr,
|
||||
.pTexelBufferView = nullptr,
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline, bool bScreenshot )
|
||||
|
|
Loading…
Reference in a new issue