From 1e3711ee666b9c89dae7d438bb2ead75fd5129f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Oct 2019 21:15:01 +0200 Subject: [PATCH] Vulkan blend factor: Bugfix and minor optimization --- GPU/Vulkan/PipelineManagerVulkan.cpp | 10 +++++++++- GPU/Vulkan/StateMappingVulkan.cpp | 4 +--- ext/native/math/dataconv.h | 15 +++++++++++++++ ext/native/thin3d/VulkanQueueRunner.cpp | 8 ++++++-- ext/native/thin3d/VulkanQueueRunner.h | 2 +- ext/native/thin3d/VulkanRenderManager.h | 4 ++-- ext/native/thin3d/thin3d_vulkan.cpp | 3 ++- 7 files changed, 36 insertions(+), 10 deletions(-) diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 9b253c1acc..d655404c5c 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -126,7 +126,15 @@ static int SetupVertexAttribsPretransformed(VkVertexInputAttributeDescription at } static bool UsesBlendConstant(int factor) { - return factor == VK_BLEND_FACTOR_CONSTANT_ALPHA || factor == VK_BLEND_FACTOR_CONSTANT_COLOR; + switch (factor) { + case VK_BLEND_FACTOR_CONSTANT_ALPHA: + case VK_BLEND_FACTOR_CONSTANT_COLOR: + case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: + case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: + return true; + default: + return false; + } } static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pipelineCache, diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 7249cce10e..65c5d03631 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -413,8 +413,6 @@ void DrawEngineVulkan::ApplyDrawStateLate(VulkanRenderManager *renderManager, bo renderManager->SetStencilParams(dynState_.stencilWriteMask, dynState_.stencilCompareMask, applyStencilRef ? stencilRef : dynState_.stencilRef); } if (gstate_c.IsDirty(DIRTY_BLEND_STATE) && useBlendConstant) { - float bc[4]; - Uint8x4ToFloat4(bc, dynState_.blendColor); - renderManager->SetBlendFactor(bc); + renderManager->SetBlendFactor(dynState_.blendColor); } } diff --git a/ext/native/math/dataconv.h b/ext/native/math/dataconv.h index 8852d9d4c5..502cb9a0a6 100644 --- a/ext/native/math/dataconv.h +++ b/ext/native/math/dataconv.h @@ -46,6 +46,21 @@ inline void Uint8x4ToFloat4(float f[4], uint32_t u) { #endif } +// Could be SSE optimized. +inline uint32_t Float4ToUint8x4(const float f[4]) { + int i4[4]; + for (int i = 0; i < 4; i++) { + if (f[i] > 1.0f) { + i4[i] = 255; + } else if (f[i] < 0.0f) { + i4[i] = 0; + } else { + i4[i] = (int)(f[i] * 255.0f); + } + } + return i4[0] | (i4[1] << 8) | (i4[2] << 16) | (i4[3] << 24); +} + inline void Uint8x3ToFloat4_AlphaUint8(float f[4], uint32_t u, uint8_t alpha) { #if defined(_M_SSE) || PPSSPP_PLATFORM(ARM_NEON) Uint8x4ToFloat4(f, (u & 0xFFFFFF) | (alpha << 24)); diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 19b9e1c6a3..c76712f68b 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -851,7 +851,7 @@ void VulkanQueueRunner::LogRenderPass(const VKRStep &pass) { ILOG(" BindPipeline(%x)", (int)(intptr_t)cmd.pipeline.pipeline); break; case VKRRenderCommand::BLEND: - ILOG(" Blend(%f, %f, %f, %f)", cmd.blendColor.color[0], cmd.blendColor.color[1], cmd.blendColor.color[2], cmd.blendColor.color[3]); + ILOG(" BlendColor(%08x)", cmd.blendColor.color); break; case VKRRenderCommand::CLEAR: ILOG(" Clear"); @@ -1015,8 +1015,12 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c break; case VKRRenderCommand::BLEND: - vkCmdSetBlendConstants(cmd, c.blendColor.color); + { + float bc[4]; + Uint8x4ToFloat4(bc, c.blendColor.color); + vkCmdSetBlendConstants(cmd, bc); break; + } case VKRRenderCommand::PUSH_CONSTANTS: vkCmdPushConstants(cmd, c.push.pipelineLayout, c.push.stages, c.push.offset, c.push.size, c.push.data); diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index 8bb1adfbdf..19a29bf243 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -141,7 +141,7 @@ struct VkRenderData { uint8_t stencilRef; } stencil; struct { - float color[4]; + uint32_t color; } blendColor; struct { VkPipelineLayout pipelineLayout; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index d0b0d74793..0015640b9d 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -164,10 +164,10 @@ public: curRenderStep_->commands.push_back(data); } - void SetBlendFactor(float color[4]) { + void SetBlendFactor(uint32_t color) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); VkRenderData data{ VKRRenderCommand::BLEND }; - CopyFloat4(data.blendColor.color, color); + data.blendColor.color = color; curRenderStep_->commands.push_back(data); } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index bb1a9aa93f..27f1c4fcc4 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1055,7 +1055,8 @@ void VKContext::SetViewports(int count, Viewport *viewports) { } void VKContext::SetBlendFactor(float color[4]) { - renderManager_.SetBlendFactor(color); + uint32_t col = Float4ToUint8x4(color); + renderManager_.SetBlendFactor(col); } void VKContext::SetStencilRef(uint8_t stencilRef) {