Skip to content

Commit

Permalink
rendervulkan: Eliminate blur radius spec constant
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua-Ashton committed Nov 10, 2022
1 parent c61db3c commit c10eb7d
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 51 deletions.
77 changes: 34 additions & 43 deletions src/rendervulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,12 @@ struct PipelineInfo_t

uint32_t layerCount;
uint32_t ycbcrMask;
uint32_t blurRadius;
uint32_t blurLayerCount;

bool compositeDebug;

bool operator==(const PipelineInfo_t& o) const {
return shaderType == o.shaderType && layerCount == o.layerCount && ycbcrMask == o.ycbcrMask && blurRadius == o.blurRadius && blurLayerCount == o.blurLayerCount && compositeDebug == o.compositeDebug;
return shaderType == o.shaderType && layerCount == o.layerCount && ycbcrMask == o.ycbcrMask && blurLayerCount == o.blurLayerCount && compositeDebug == o.compositeDebug;
}
};

Expand All @@ -155,7 +154,6 @@ namespace std
uint32_t hash = k.shaderType;
hash = hash_combine(hash, k.layerCount);
hash = hash_combine(hash, k.ycbcrMask);
hash = hash_combine(hash, k.blurRadius);
hash = hash_combine(hash, k.blurLayerCount);
hash = hash_combine(hash, k.compositeDebug);
return hash;
Expand Down Expand Up @@ -449,7 +447,7 @@ class CVulkanDevice
bool BInit();

VkSampler sampler(SamplerState key);
VkPipeline pipeline(ShaderType type, uint32_t layerCount = 1, uint32_t ycbcrMask = 0, uint32_t radius = 0, uint32_t blur_layers = 0);
VkPipeline pipeline(ShaderType type, uint32_t layerCount = 1, uint32_t ycbcrMask = 0, uint32_t blur_layers = 0);
int32_t findMemoryType( VkMemoryPropertyFlags properties, uint32_t requiredTypeBits );
std::unique_ptr<CVulkanCmdBuffer> commandBuffer();
uint64_t submit( std::unique_ptr<CVulkanCmdBuffer> cmdBuf);
Expand Down Expand Up @@ -495,7 +493,7 @@ class CVulkanDevice
bool createPools();
bool createShaders();
bool createScratchResources();
VkPipeline compilePipeline(uint32_t layerCount, uint32_t ycbcrMask, uint32_t radius, ShaderType type, uint32_t blur_layer_count, bool composite_debug);
VkPipeline compilePipeline(uint32_t layerCount, uint32_t ycbcrMask, ShaderType type, uint32_t blur_layer_count, bool composite_debug);
void compileAllPipelines();
void resetCmdBuffers(uint64_t sequence);

Expand Down Expand Up @@ -1198,9 +1196,9 @@ VkSampler CVulkanDevice::sampler( SamplerState key )
return ret;
}

VkPipeline CVulkanDevice::compilePipeline(uint32_t layerCount, uint32_t ycbcrMask, uint32_t radius, ShaderType type, uint32_t blur_layer_count, bool composite_debug)
VkPipeline CVulkanDevice::compilePipeline(uint32_t layerCount, uint32_t ycbcrMask, ShaderType type, uint32_t blur_layer_count, bool composite_debug)
{
const std::array<VkSpecializationMapEntry, 5> specializationEntries = {{
const std::array<VkSpecializationMapEntry, 4> specializationEntries = {{
{
.constantID = 0,
.offset = sizeof(uint32_t) * 0,
Expand All @@ -1221,24 +1219,17 @@ VkPipeline CVulkanDevice::compilePipeline(uint32_t layerCount, uint32_t ycbcrMas
.offset = sizeof(uint32_t) * 3,
.size = sizeof(uint32_t)
},
{
.constantID = 4,
.offset = sizeof(uint32_t) * 4,
.size = sizeof(uint32_t)
},
}};

struct {
uint32_t layerCount;
uint32_t ycbcrMask;
uint32_t debug;
uint32_t radius;
uint32_t blur_layer_count;
} specializationData = {
.layerCount = layerCount,
.ycbcrMask = ycbcrMask,
.debug = composite_debug,
.radius = radius ? (radius * 2) - 1 : 0,
.blur_layer_count = blur_layer_count,
};

Expand Down Expand Up @@ -1277,49 +1268,47 @@ void CVulkanDevice::compileAllPipelines()
pthread_setname_np( pthread_self(), "gamescope-shdr" );

std::array<PipelineInfo_t, SHADER_TYPE_COUNT> pipelineInfos;
#define SHADER(type, layer_count, max_ycbcr, max_radius, blur_layers) pipelineInfos[SHADER_TYPE_##type] = {SHADER_TYPE_##type, layer_count, max_ycbcr, max_radius, blur_layers, false}
SHADER(BLIT, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, 1, 1);
SHADER(BLUR, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, kMaxBlurRadius, k_nMaxBlurLayers);
SHADER(BLUR_COND, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, kMaxBlurRadius, k_nMaxBlurLayers);
SHADER(BLUR_FIRST_PASS, 1, 2, kMaxBlurRadius, 1);
SHADER(RCAS, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, 1, 1);
SHADER(EASU, 1, 1, 1, 1);
SHADER(NIS, 1, 1, 1, 1);
#define SHADER(type, layer_count, max_ycbcr, blur_layers) pipelineInfos[SHADER_TYPE_##type] = {SHADER_TYPE_##type, layer_count, max_ycbcr, blur_layers, false}
SHADER(BLIT, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, 1);
SHADER(BLUR, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, k_nMaxBlurLayers);
SHADER(BLUR_COND, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, k_nMaxBlurLayers);
SHADER(BLUR_FIRST_PASS, 1, 2, 1);
SHADER(RCAS, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, 1);
SHADER(EASU, 1, 1, 1);
SHADER(NIS, 1, 1, 1);
#undef SHADER

for (auto& info : pipelineInfos) {
for (uint32_t layerCount = 1; layerCount <= info.layerCount; layerCount++) {
for (uint32_t ycbcrMask = 0; ycbcrMask < info.ycbcrMask; ycbcrMask++) {
for (uint32_t radius = 0; radius < info.blurRadius; radius++) {
for (uint32_t blur_layers = 1; blur_layers <= info.blurLayerCount; blur_layers++) {
if (ycbcrMask >= (1u << (layerCount + 1)))
continue;
if (blur_layers > layerCount)
continue;

VkPipeline newPipeline = compilePipeline(layerCount, ycbcrMask, radius, info.shaderType, blur_layers, info.compositeDebug);
{
std::lock_guard<std::mutex> lock(m_pipelineMutex);
PipelineInfo_t key = {info.shaderType, layerCount, ycbcrMask, radius, blur_layers, info.compositeDebug};
auto result = m_pipelineMap.emplace(std::make_pair(key, newPipeline));
if (!result.second)
vk.DestroyPipeline(device(), newPipeline, nullptr);
}
for (uint32_t blur_layers = 1; blur_layers <= info.blurLayerCount; blur_layers++) {
if (ycbcrMask >= (1u << (layerCount + 1)))
continue;
if (blur_layers > layerCount)
continue;

VkPipeline newPipeline = compilePipeline(layerCount, ycbcrMask, info.shaderType, blur_layers, info.compositeDebug);
{
std::lock_guard<std::mutex> lock(m_pipelineMutex);
PipelineInfo_t key = {info.shaderType, layerCount, ycbcrMask, blur_layers, info.compositeDebug};
auto result = m_pipelineMap.emplace(std::make_pair(key, newPipeline));
if (!result.second)
vk.DestroyPipeline(device(), newPipeline, nullptr);
}
}
}
}
}
}

VkPipeline CVulkanDevice::pipeline(ShaderType type, uint32_t layerCount, uint32_t ycbcrMask, uint32_t radius, uint32_t blur_layers)
VkPipeline CVulkanDevice::pipeline(ShaderType type, uint32_t layerCount, uint32_t ycbcrMask, uint32_t blur_layers)
{
std::lock_guard<std::mutex> lock(m_pipelineMutex);
PipelineInfo_t key = {type, layerCount, ycbcrMask, radius, blur_layers, g_bIsCompositeDebug};
PipelineInfo_t key = {type, layerCount, ycbcrMask, blur_layers, g_bIsCompositeDebug};
auto search = m_pipelineMap.find(key);
if (search == m_pipelineMap.end())
{
VkPipeline result = compilePipeline(layerCount, ycbcrMask, radius, type, blur_layers, g_bIsCompositeDebug);
VkPipeline result = compilePipeline(layerCount, ycbcrMask, type, blur_layers, g_bIsCompositeDebug);
m_pipelineMap[key] = result;
return result;
}
Expand Down Expand Up @@ -1548,7 +1537,7 @@ void CVulkanCmdBuffer::clearState()
template<class PushData, class... Args>
void CVulkanCmdBuffer::pushConstants(Args&&... args)
{
static_assert(sizeof(PushData) <= 128, "Only 128 bytes push constants.");
// static_assert(sizeof(PushData) <= 128, "Only 128 bytes push constants.");
PushData data(std::forward<Args>(args)...);
m_device->vk.CmdPushConstants(m_cmdBuffer, m_device->pipelineLayout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(data), &data);
}
Expand Down Expand Up @@ -2953,6 +2942,7 @@ struct BlitPushData_t
float opacity[k_nMaxLayers];
uint32_t borderMask;
uint32_t frameId;
uint32_t blurRadius;

explicit BlitPushData_t(const struct FrameInfo_t *frameInfo)
{
Expand All @@ -2964,6 +2954,7 @@ struct BlitPushData_t
}
borderMask = frameInfo->borderMask();
frameId = s_frameId++;
blurRadius = frameInfo->blurRadius ? ( frameInfo->blurRadius * 2 ) - 1 : 0;
}

explicit BlitPushData_t(float blit_scale) {
Expand Down Expand Up @@ -3165,7 +3156,7 @@ bool vulkan_composite( const struct FrameInfo_t *frameInfo, std::shared_ptr<CVul
if (frameInfo->layerCount >= 2 && frameInfo->layers[1].zpos == g_zposOverride)
blur_layer_count++;

cmdBuffer->bindPipeline(g_device.pipeline(type, blur_layer_count, frameInfo->ycbcrMask() & 0x3u, frameInfo->blurRadius));
cmdBuffer->bindPipeline(g_device.pipeline(type, blur_layer_count, frameInfo->ycbcrMask() & 0x3u));
cmdBuffer->bindTarget(g_output.tmpOutput);
for (uint32_t i = 0; i < blur_layer_count; i++)
{
Expand All @@ -3181,7 +3172,7 @@ bool vulkan_composite( const struct FrameInfo_t *frameInfo, std::shared_ptr<CVul
cmdBuffer->dispatch(div_roundup(currentOutputWidth, pixelsPerGroup), div_roundup(currentOutputHeight, pixelsPerGroup));

type = frameInfo->blurLayer0 == BLUR_MODE_COND ? SHADER_TYPE_BLUR_COND : SHADER_TYPE_BLUR;
cmdBuffer->bindPipeline(g_device.pipeline(type, frameInfo->layerCount, frameInfo->ycbcrMask(), frameInfo->blurRadius, blur_layer_count));
cmdBuffer->bindPipeline(g_device.pipeline(type, frameInfo->layerCount, frameInfo->ycbcrMask(), blur_layer_count));
bind_all_layers(cmdBuffer.get(), frameInfo);
cmdBuffer->bindTarget(compositeImage);
cmdBuffer->bindTexture(VKR_BLUR_EXTRA_SLOT, g_output.tmpOutput);
Expand Down
3 changes: 2 additions & 1 deletion src/shaders/cs_composite_blur.comp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ uniform layers_t {
float u_opacity[VKR_MAX_LAYERS];
uint u_borderMask;
uint u_frameId;
uint u_blur_radius;
};

#define BLUR_DONT_SCALE 1
Expand All @@ -42,7 +43,7 @@ void main() {
outputValue = vec3(1.0f, 0.0f, 0.0f);

if (c_layerCount > 0)
outputValue = gaussian_blur(s_samplers[VKR_BLUR_EXTRA_SLOT], 0, vec2(coord), c_blur_radius, true, true).rgb;
outputValue = gaussian_blur(s_samplers[VKR_BLUR_EXTRA_SLOT], 0, vec2(coord), u_blur_radius, true, true).rgb;

for (int i = c_blur_layer_count; i < c_layerCount; i++) {
vec4 layerColor = sampleLayer(i, uv);
Expand Down
3 changes: 2 additions & 1 deletion src/shaders/cs_composite_blur_cond.comp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ uniform layers_t {
float u_opacity[VKR_MAX_LAYERS];
uint u_borderMask;
uint u_frameId;
uint u_blur_radius;
};
#define BLUR_DONT_SCALE 1
#include "composite.h"
Expand Down Expand Up @@ -53,7 +54,7 @@ void main() {

if (c_layerCount > 0) {
if (finalRevAlpha < 0.95) {
outputValue += gaussian_blur(s_samplers[VKR_BLUR_EXTRA_SLOT], 0, vec2(coord), c_blur_radius, true, true).rgb * finalRevAlpha;
outputValue += gaussian_blur(s_samplers[VKR_BLUR_EXTRA_SLOT], 0, vec2(coord), u_blur_radius, true, true).rgb * finalRevAlpha;
} else {
outputValue = sampleLayer(0, uv).rgb * u_opacity[0];
for (int i = 1; i < c_blur_layer_count; i++) {
Expand Down
9 changes: 5 additions & 4 deletions src/shaders/cs_gaussian_blur_horizontal.comp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ uniform layers_t {
float u_opacity[VKR_MAX_LAYERS];
uint u_borderMask;
uint u_frameId;
uint u_blur_radius;
};

#include "composite.h"
Expand All @@ -30,18 +31,18 @@ void main()

if (c_layerCount > 0) {
if ((c_ycbcrMask & 1) != 0)
outputValue = gaussian_blur(s_ycbcr_samplers[0], 0, pos, c_blur_radius, false, false).rgb * u_opacity[0];
outputValue = gaussian_blur(s_ycbcr_samplers[0], 0, pos, u_blur_radius, false, false).rgb * u_opacity[0];
else
outputValue = gaussian_blur(s_samplers[0], 0, pos, c_blur_radius, false, true).rgb * u_opacity[0];
outputValue = gaussian_blur(s_samplers[0], 0, pos, u_blur_radius, false, true).rgb * u_opacity[0];
}

for (int i = 1; i < c_layerCount; i++) {
vec4 layerColor;
// YCBCR technically has incorrect blending here but... meh.
if ((c_ycbcrMask & (1 << i)) != 0)
layerColor = srgbToLinear(gaussian_blur(s_ycbcr_samplers[i], i, pos, c_blur_radius, false, false));
layerColor = srgbToLinear(gaussian_blur(s_ycbcr_samplers[i], i, pos, u_blur_radius, false, false));
else
layerColor = gaussian_blur(s_samplers[i], i, pos, c_blur_radius, false, true);
layerColor = gaussian_blur(s_samplers[i], i, pos, u_blur_radius, false, true);

float opacity = u_opacity[i];
float layerAlpha = opacity * layerColor.a;
Expand Down
3 changes: 1 addition & 2 deletions src/shaders/descriptor_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
layout(constant_id = 0) const int c_layerCount = 1;
layout(constant_id = 1) const uint c_ycbcrMask = 0;
layout(constant_id = 2) const bool c_compositing_debug = false;
layout(constant_id = 3) const uint c_blur_radius = 11;
layout(constant_id = 4) const int c_blur_layer_count = 0;
layout(constant_id = 3) const int c_blur_layer_count = 0;

layout(binding = 0, rgba8) writeonly uniform image2D dst;
layout(binding = 1) uniform sampler2D s_samplers[VKR_SAMPLER_SLOTS];
Expand Down

0 comments on commit c10eb7d

Please sign in to comment.