mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix] (MG_Util/ShaderTranspiler): rename "sampler" in parameter name to avoid driver compiler issues
This commit is contained in:
@@ -185,6 +185,7 @@ set(SOURCE_FILES
|
||||
MobileGL/MG_Util/ShaderTranspiler/glslang/TMglGlslIoResolver.cpp
|
||||
MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenInterfaceStructPass.cpp
|
||||
MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/EliminateFloatEqualsZeroPass.cpp
|
||||
MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/RenameSamplerFunctionParameterPass.cpp
|
||||
|
||||
MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp
|
||||
MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.cpp
|
||||
|
||||
@@ -9,6 +9,91 @@
|
||||
#include "PipelineFactory.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
static const char* PrimitiveTopologyToString(VkPrimitiveTopology topology) {
|
||||
switch (topology) {
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY)
|
||||
ENUM_STR_CASE(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST)
|
||||
default:
|
||||
return "VK_PRIMITIVE_TOPOLOGY_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* SampleCountToString(VkSampleCountFlagBits sampleCount) {
|
||||
switch (sampleCount) {
|
||||
ENUM_STR_CASE(VK_SAMPLE_COUNT_1_BIT)
|
||||
ENUM_STR_CASE(VK_SAMPLE_COUNT_2_BIT)
|
||||
ENUM_STR_CASE(VK_SAMPLE_COUNT_4_BIT)
|
||||
ENUM_STR_CASE(VK_SAMPLE_COUNT_8_BIT)
|
||||
ENUM_STR_CASE(VK_SAMPLE_COUNT_16_BIT)
|
||||
ENUM_STR_CASE(VK_SAMPLE_COUNT_32_BIT)
|
||||
ENUM_STR_CASE(VK_SAMPLE_COUNT_64_BIT)
|
||||
default:
|
||||
return "VK_SAMPLE_COUNT_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* CullModeToString(VkCullModeFlags cullMode) {
|
||||
switch (cullMode) {
|
||||
case VK_CULL_MODE_NONE:
|
||||
return "VK_CULL_MODE_NONE";
|
||||
case VK_CULL_MODE_FRONT_BIT:
|
||||
return "VK_CULL_MODE_FRONT_BIT";
|
||||
case VK_CULL_MODE_BACK_BIT:
|
||||
return "VK_CULL_MODE_BACK_BIT";
|
||||
case VK_CULL_MODE_FRONT_AND_BACK:
|
||||
return "VK_CULL_MODE_FRONT_AND_BACK";
|
||||
default:
|
||||
return "VK_CULL_MODE_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* CompareOpToString(VkCompareOp compareOp) {
|
||||
switch (compareOp) {
|
||||
ENUM_STR_CASE(VK_COMPARE_OP_NEVER)
|
||||
ENUM_STR_CASE(VK_COMPARE_OP_LESS)
|
||||
ENUM_STR_CASE(VK_COMPARE_OP_EQUAL)
|
||||
ENUM_STR_CASE(VK_COMPARE_OP_LESS_OR_EQUAL)
|
||||
ENUM_STR_CASE(VK_COMPARE_OP_GREATER)
|
||||
ENUM_STR_CASE(VK_COMPARE_OP_NOT_EQUAL)
|
||||
ENUM_STR_CASE(VK_COMPARE_OP_GREATER_OR_EQUAL)
|
||||
ENUM_STR_CASE(VK_COMPARE_OP_ALWAYS)
|
||||
default:
|
||||
return "VK_COMPARE_OP_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* LogicOpToString(VkLogicOp logicOp) {
|
||||
switch (logicOp) {
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_CLEAR)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_AND)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_AND_REVERSE)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_COPY)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_AND_INVERTED)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_NO_OP)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_XOR)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_OR)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_NOR)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_EQUIVALENT)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_INVERT)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_OR_REVERSE)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_COPY_INVERTED)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_OR_INVERTED)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_NAND)
|
||||
ENUM_STR_CASE(VK_LOGIC_OP_SET)
|
||||
default:
|
||||
return "VK_LOGIC_OP_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
PipelineFactory::PipelineFactory(VkDevice device, const VulkanRendererConfig& config):
|
||||
m_device(device), m_config(config) {
|
||||
MOBILEGL_ASSERT(m_device != VK_NULL_HANDLE, "PipelineFactory: device is null");
|
||||
@@ -191,8 +276,52 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
gpi.subpass = payload.subpass;
|
||||
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
VK_VERIFY(vkCreateGraphicsPipelines(m_device, m_pipelineCache, 1, &gpi, nullptr, &pipeline),
|
||||
"vkCreateGraphicsPipelines");
|
||||
const VkResult result = vkCreateGraphicsPipelines(m_device, m_pipelineCache, 1, &gpi, nullptr, &pipeline);
|
||||
if (result != VK_SUCCESS) {
|
||||
MGLOG_F("PipelineFactory::CreatePipeline failed: result=%s (%d) programHash=0x%llx vertexInputHash=0x%llx stageCount=%u topology=%s(%d) colorAttachmentCount=%u samples=%s(%d) subpass=%u",
|
||||
VkResultToString(result),
|
||||
result,
|
||||
static_cast<unsigned long long>(payload.programHash),
|
||||
static_cast<unsigned long long>(payload.vertexInputHash),
|
||||
gpi.stageCount,
|
||||
PrimitiveTopologyToString(payload.topology),
|
||||
payload.topology,
|
||||
payload.colorAttachmentCount,
|
||||
SampleCountToString(payload.rasterizationSamples),
|
||||
payload.rasterizationSamples,
|
||||
payload.subpass);
|
||||
MGLOG_F("PipelineFactory::CreatePipeline state: cullMode=%s(0x%x) frontFace=%d depthTest=%d depthWrite=%d depthCompare=%s(%d) depthBias=%d rasterizerDiscard=%d stencilTest=%d logicOpEnable=%d logicOp=%s(%d)",
|
||||
CullModeToString(payload.cullMode),
|
||||
static_cast<Uint32>(payload.cullMode),
|
||||
payload.frontFace,
|
||||
payload.depthTestEnable ? 1 : 0,
|
||||
payload.depthWriteEnable ? 1 : 0,
|
||||
CompareOpToString(payload.depthCompareOp),
|
||||
payload.depthCompareOp,
|
||||
payload.depthBiasEnable ? 1 : 0,
|
||||
payload.rasterizerDiscardEnable ? 1 : 0,
|
||||
payload.stencilTestEnable ? 1 : 0,
|
||||
payload.logicOpEnable ? 1 : 0,
|
||||
LogicOpToString(payload.logicOp),
|
||||
payload.logicOp);
|
||||
MGLOG_F("PipelineFactory::CreatePipeline vertex input: bindingCount=%u attributeCount=%u",
|
||||
payload.vertexInputState->vertexBindingDescriptionCount,
|
||||
payload.vertexInputState->vertexAttributeDescriptionCount);
|
||||
for (Uint32 i = 0; i < payload.colorAttachmentCount; ++i) {
|
||||
const auto& attachment = payload.colorBlendAttachments[i];
|
||||
MGLOG_F("PipelineFactory::CreatePipeline colorAttachment[%u]: blend=%d colorWriteMask=0x%x srcColor=%d dstColor=%d colorOp=%d srcAlpha=%d dstAlpha=%d alphaOp=%d",
|
||||
i,
|
||||
attachment.blendEnable == VK_TRUE ? 1 : 0,
|
||||
static_cast<Uint32>(attachment.colorWriteMask),
|
||||
attachment.srcColorBlendFactor,
|
||||
attachment.dstColorBlendFactor,
|
||||
attachment.colorBlendOp,
|
||||
attachment.srcAlphaBlendFactor,
|
||||
attachment.dstAlphaBlendFactor,
|
||||
attachment.alphaBlendOp);
|
||||
}
|
||||
}
|
||||
VK_VERIFY(result, "vkCreateGraphicsPipelines");
|
||||
return pipeline;
|
||||
}
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
|
||||
@@ -10,16 +10,61 @@
|
||||
|
||||
#include "VulkanRendererConfig.h"
|
||||
|
||||
#define ENUM_STR_CASE(c) case c: return #c;
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
inline const char* VkResultToString(VkResult result) {
|
||||
switch (result) {
|
||||
ENUM_STR_CASE(VK_SUCCESS)
|
||||
ENUM_STR_CASE(VK_NOT_READY)
|
||||
ENUM_STR_CASE(VK_TIMEOUT)
|
||||
ENUM_STR_CASE(VK_EVENT_SET)
|
||||
ENUM_STR_CASE(VK_EVENT_RESET)
|
||||
ENUM_STR_CASE(VK_INCOMPLETE)
|
||||
ENUM_STR_CASE(VK_ERROR_OUT_OF_HOST_MEMORY)
|
||||
ENUM_STR_CASE(VK_ERROR_OUT_OF_DEVICE_MEMORY)
|
||||
ENUM_STR_CASE(VK_ERROR_INITIALIZATION_FAILED)
|
||||
ENUM_STR_CASE(VK_ERROR_DEVICE_LOST)
|
||||
ENUM_STR_CASE(VK_ERROR_MEMORY_MAP_FAILED)
|
||||
ENUM_STR_CASE(VK_ERROR_LAYER_NOT_PRESENT)
|
||||
ENUM_STR_CASE(VK_ERROR_EXTENSION_NOT_PRESENT)
|
||||
ENUM_STR_CASE(VK_ERROR_FEATURE_NOT_PRESENT)
|
||||
ENUM_STR_CASE(VK_ERROR_INCOMPATIBLE_DRIVER)
|
||||
ENUM_STR_CASE(VK_ERROR_TOO_MANY_OBJECTS)
|
||||
ENUM_STR_CASE(VK_ERROR_FORMAT_NOT_SUPPORTED)
|
||||
ENUM_STR_CASE(VK_ERROR_FRAGMENTED_POOL)
|
||||
ENUM_STR_CASE(VK_ERROR_UNKNOWN)
|
||||
ENUM_STR_CASE(VK_ERROR_OUT_OF_POOL_MEMORY)
|
||||
ENUM_STR_CASE(VK_ERROR_INVALID_EXTERNAL_HANDLE)
|
||||
ENUM_STR_CASE(VK_ERROR_FRAGMENTATION)
|
||||
ENUM_STR_CASE(VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS)
|
||||
ENUM_STR_CASE(VK_PIPELINE_COMPILE_REQUIRED)
|
||||
ENUM_STR_CASE(VK_ERROR_SURFACE_LOST_KHR)
|
||||
ENUM_STR_CASE(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR)
|
||||
ENUM_STR_CASE(VK_SUBOPTIMAL_KHR)
|
||||
ENUM_STR_CASE(VK_ERROR_OUT_OF_DATE_KHR)
|
||||
ENUM_STR_CASE(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR)
|
||||
ENUM_STR_CASE(VK_ERROR_VALIDATION_FAILED_EXT)
|
||||
ENUM_STR_CASE(VK_ERROR_INVALID_SHADER_NV)
|
||||
default:
|
||||
return "VK_RESULT_UNKNOWN";
|
||||
}
|
||||
}
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
|
||||
#define VK_VERIFY(expr, ...) \
|
||||
do { \
|
||||
VkResult _vk_verify_result = (expr); \
|
||||
MOBILEGL_ASSERT(_vk_verify_result == VK_SUCCESS, "Vulkan error %d at %s:%d" __VA_OPT__(" - ") __VA_ARGS__, _vk_verify_result, __FILE__, __LINE__); \
|
||||
if (_vk_verify_result != VK_SUCCESS) { \
|
||||
MGLOG_F("Vulkan error %s (%d) at %s:%d" __VA_OPT__(" - ") __VA_ARGS__, \
|
||||
MobileGL::MG_Backend::DirectVulkan::VkResultToString(_vk_verify_result), \
|
||||
_vk_verify_result, __FILE__, __LINE__); \
|
||||
} \
|
||||
MOBILEGL_ASSERT(_vk_verify_result == VK_SUCCESS, "Vulkan error %s (%d) at %s:%d" __VA_OPT__(" - ") __VA_ARGS__, MobileGL::MG_Backend::DirectVulkan::VkResultToString(_vk_verify_result), _vk_verify_result, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define ENUM_STR_CASE(c) case c: return #c;
|
||||
|
||||
#define XXHASH_VERIFY(expr, ...) \
|
||||
do { \
|
||||
XXH_errorcode _xxh_verify_result = (expr); \
|
||||
MOBILEGL_ASSERT(_xxh_verify_result == XXH_OK, "XXHash error %d at %s:%d" __VA_OPT__(" - ") __VA_ARGS__, _xxh_verify_result, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
@@ -43,7 +43,7 @@ endif()
|
||||
target_compile_definitions(DirectVulkanSanityTest PRIVATE -DNOMINMAX)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(DirectVulkanSanityTest)
|
||||
gtest_discover_tests(DirectVulkanSanityTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
add_executable(
|
||||
DirectVulkanTestExec
|
||||
|
||||
@@ -24,4 +24,4 @@ if (MSVC)
|
||||
endif()
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(BufferTest)
|
||||
gtest_discover_tests(BufferTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
@@ -62,7 +62,7 @@ set(LINK_LIBRARIES
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(SanityTest)
|
||||
gtest_discover_tests(SanityTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
add_subdirectory(Buffer)
|
||||
add_subdirectory(EGLState)
|
||||
|
||||
@@ -17,4 +17,4 @@ target_link_libraries(
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(EGLStateTest)
|
||||
gtest_discover_tests(EGLStateTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
@@ -17,4 +17,4 @@ target_link_libraries(
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(FramebufferTest)
|
||||
gtest_discover_tests(FramebufferTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
@@ -39,5 +39,5 @@ target_link_libraries(
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(ProgramUtilTest)
|
||||
gtest_discover_tests(ProgramTest)
|
||||
gtest_discover_tests(ProgramUtilTest DISCOVERY_TIMEOUT 30)
|
||||
gtest_discover_tests(ProgramTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
|
||||
#include <MG_Util/ShaderTranspiler/ShaderCompiler.h>
|
||||
#include <MG_Util/ShaderTranspiler/ShaderSourceProcessor.h>
|
||||
#include <MG_Util/ShaderTranspiler/SpirvPasses/RenameSamplerFunctionParameterPass.h>
|
||||
#include <MG_Util/ShaderTranspiler/Types.h>
|
||||
#include <MG_Util/ShaderTranspiler/glslang/UniformTraverser.h>
|
||||
#include <spirv-tools/libspirv.hpp>
|
||||
#include <spirv-tools/optimizer.hpp>
|
||||
|
||||
using namespace MobileGL;
|
||||
|
||||
@@ -31,6 +34,64 @@ TEST_F(ProgramUtilTest, Sanity) {
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
|
||||
TEST_F(ProgramUtilTest, RenameSamplerFunctionParameterInSpirvPass) {
|
||||
using namespace MG_Util::ShaderTranspiler;
|
||||
|
||||
const String spirvText = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %outColor
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpName %globalSampler "sampler"
|
||||
OpName %paramSampler "sampler"
|
||||
OpName %main "main"
|
||||
OpDecorate %outColor Location 0
|
||||
%void = OpTypeVoid
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%mainFn = OpTypeFunction %void
|
||||
%paramFn = OpTypeFunction %void %float
|
||||
%outV4Ptr = OpTypePointer Output %v4float
|
||||
%privatePtr = OpTypePointer Private %float
|
||||
%outColor = OpVariable %outV4Ptr Output
|
||||
%globalSampler = OpVariable %privatePtr Private
|
||||
%helper = OpFunction %void None %paramFn
|
||||
%paramSampler = OpFunctionParameter %float
|
||||
%helperBody = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%main = OpFunction %void None %mainFn
|
||||
%mainBody = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);
|
||||
Vector<uint32_t> inputBinary;
|
||||
ASSERT_TRUE(tools.Assemble(spirvText, &inputBinary));
|
||||
|
||||
spvtools::Optimizer optimizer(SPV_ENV_VULKAN_1_1);
|
||||
spvtools::OptimizerOptions options;
|
||||
options.set_run_validator(false);
|
||||
optimizer.RegisterPass(RenameSamplerFunctionParameterPass::CreateRenameSamplerFunctionParameterPass());
|
||||
|
||||
Vector<uint32_t> outputBinary;
|
||||
ASSERT_TRUE(optimizer.Run(inputBinary.data(), inputBinary.size(), &outputBinary, options));
|
||||
|
||||
String outputText;
|
||||
ASSERT_TRUE(tools.Disassemble(outputBinary, &outputText));
|
||||
|
||||
EXPECT_NE(outputText.find("\"MGL_COMPAT_sampler\""), String::npos);
|
||||
|
||||
SizeT exactSamplerNameCount = 0;
|
||||
SizeT searchOffset = 0;
|
||||
while ((searchOffset = outputText.find("\"sampler\"", searchOffset)) != String::npos) {
|
||||
++exactSamplerNameCount;
|
||||
searchOffset += std::strlen("\"sampler\"");
|
||||
}
|
||||
EXPECT_EQ(exactSamplerNameCount, 1u);
|
||||
}
|
||||
|
||||
TEST_F(ProgramUtilTest, PreprocessLegacyVertexShaderModernizesGlmarkStyleSource) {
|
||||
using namespace MG_Util::ShaderTranspiler;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ target_link_libraries(
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(TextureTest)
|
||||
gtest_discover_tests(TextureTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
add_executable(
|
||||
VkClearManagerTest
|
||||
@@ -35,4 +35,4 @@ target_link_libraries(
|
||||
${LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
gtest_discover_tests(VkClearManagerTest)
|
||||
gtest_discover_tests(VkClearManagerTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
@@ -17,4 +17,4 @@ target_link_libraries(
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(VertexArrayTest)
|
||||
gtest_discover_tests(VertexArrayTest DISCOVERY_TIMEOUT 30)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "SpirvPasses/EliminateFloatEqualsZeroPass.h"
|
||||
#include "SpirvPasses/FlattenInterfaceStructPass.h"
|
||||
#include "SpirvPasses/RenameSamplerFunctionParameterPass.h"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
#include "spirv-tools/optimizer.hpp"
|
||||
|
||||
@@ -240,6 +241,7 @@ namespace MobileGL {
|
||||
optimizer.RegisterPass(CreateAggressiveDCEPass(false));
|
||||
optimizer.RegisterPass(CreateRemoveUnusedInterfaceVariablesPass());
|
||||
optimizer.RegisterPass(FlattenInterfaceStructPass::CreateFlattenInterfaceStructPass());
|
||||
optimizer.RegisterPass(RenameSamplerFunctionParameterPass::CreateRenameSamplerFunctionParameterPass());
|
||||
optimizer.RegisterPass(EliminateFloatEqualsZeroPass::CreateEliminateFloatEqualsZeroPass());
|
||||
|
||||
return optimizer.Run(inputBinary.data(), inputBinary.size(), &outputBinary, options);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// MobileGL - MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/RenameSamplerFunctionParameterPass.cpp
|
||||
// Copyright (c) 2025-2026 MobileGL-Dev
|
||||
// Licensed under the GNU Lesser General Public License v3.0:
|
||||
// https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
// End of Source File Header
|
||||
|
||||
#include "RenameSamplerFunctionParameterPass.h"
|
||||
|
||||
#include "spirv.hpp"
|
||||
#include "source/opt/def_use_manager.h"
|
||||
#include "source/opt/instruction.h"
|
||||
#include "source/opt/ir_context.h"
|
||||
#include "source/opt/module.h"
|
||||
#include "source/util/make_unique.h"
|
||||
|
||||
namespace MobileGL {
|
||||
namespace MG_Util {
|
||||
namespace ShaderTranspiler {
|
||||
namespace {
|
||||
constexpr const char* kConflictingName = "sampler";
|
||||
constexpr const char* kCompatName = "MGL_COMPAT_sampler";
|
||||
|
||||
Bool IsNamedSamplerFunctionParameter(spvtools::opt::IRContext* context,
|
||||
spvtools::opt::Instruction& nameInst) {
|
||||
if (nameInst.opcode() != spv::Op::OpName || nameInst.NumInOperands() < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nameInst.GetInOperand(1).AsString() != kConflictingName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* defUseMgr = context->get_def_use_mgr();
|
||||
const Uint32 targetId = nameInst.GetSingleWordInOperand(0);
|
||||
const auto* target = defUseMgr->GetDef(targetId);
|
||||
return target != nullptr && target->opcode() == spv::Op::OpFunctionParameter;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
spvtools::opt::Pass::Status RenameSamplerFunctionParameterPass::Process() {
|
||||
Bool modified = false;
|
||||
auto* irContext = context();
|
||||
|
||||
for (auto& debugInst : irContext->debugs2()) {
|
||||
if (!IsNamedSamplerFunctionParameter(irContext, debugInst)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
debugInst.SetInOperand(
|
||||
1, spvtools::utils::MakeVector<spvtools::opt::Operand::OperandData>(kCompatName));
|
||||
modified = true;
|
||||
}
|
||||
|
||||
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
|
||||
}
|
||||
|
||||
spvtools::Optimizer::PassToken RenameSamplerFunctionParameterPass::CreateRenameSamplerFunctionParameterPass() {
|
||||
return spvtools::Optimizer::PassToken(MakeUnique<RenameSamplerFunctionParameterPass>());
|
||||
}
|
||||
} // namespace ShaderTranspiler
|
||||
} // namespace MG_Util
|
||||
} // namespace MobileGL
|
||||
@@ -0,0 +1,27 @@
|
||||
// MobileGL - MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/RenameSamplerFunctionParameterPass.h
|
||||
// Copyright (c) 2025-2026 MobileGL-Dev
|
||||
// Licensed under the GNU Lesser General Public License v3.0:
|
||||
// https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
// End of Source File Header
|
||||
|
||||
#pragma once
|
||||
#include "source/opt/pass.h"
|
||||
#include "spirv-tools/optimizer.hpp"
|
||||
|
||||
#include <Includes.h>
|
||||
|
||||
namespace MobileGL {
|
||||
namespace MG_Util {
|
||||
namespace ShaderTranspiler {
|
||||
class RenameSamplerFunctionParameterPass : public spvtools::opt::Pass {
|
||||
public:
|
||||
const char* name() const override { return "rename-sampler-function-parameter"; }
|
||||
Status Process() override;
|
||||
|
||||
static spvtools::Optimizer::PassToken CreateRenameSamplerFunctionParameterPass();
|
||||
};
|
||||
} // namespace ShaderTranspiler
|
||||
} // namespace MG_Util
|
||||
} // namespace MobileGL
|
||||
Reference in New Issue
Block a user