2020-12-05 13:08:24 +01:00
|
|
|
#include "stdafx.h"
|
2016-02-21 16:50:49 +01:00
|
|
|
#include "VKCommonDecompiler.h"
|
2019-12-03 23:34:23 +01:00
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
#pragma warning(push, 0)
|
|
|
|
|
#else
|
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wall"
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wextra"
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
2021-02-15 16:45:54 +01:00
|
|
|
#pragma GCC diagnostic ignored "-Wsuggest-override"
|
|
|
|
|
#ifdef __clang__
|
|
|
|
|
#pragma clang diagnostic ignored "-Winconsistent-missing-override"
|
|
|
|
|
#endif
|
2019-12-03 23:34:23 +01:00
|
|
|
#endif
|
Fixes from FreeBSD package (#3765)
* Thread: unbreak on BSDs after dbc9bdfe02ae
Utilities/Thread.cpp:1920:2: error: unknown type name 'cpu_set_t'; did you mean 'cpusetid_t'?
cpu_set_t cs;
^~~~~~~~~
cpusetid_t
/usr/include/sys/types.h:84:22: note: 'cpusetid_t' declared here
typedef __cpusetid_t cpusetid_t;
^
Utilities/Thread.cpp:1921:2: error: use of undeclared identifier 'CPU_ZERO'
CPU_ZERO(&cs);
^
Utilities/Thread.cpp:1922:2: error: use of undeclared identifier 'CPU_SET'
CPU_SET(core, &cs);
^
Utilities/Thread.cpp:1923:48: error: unknown type name 'cpu_set_t'; did you mean 'cpusetid_t'?
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs);
^~~~~~~~~
cpusetid_t
* JIT: use MAP_32BIT on Linux and FreeBSD
Unless RLIMIT_DATA is low enough FreeBSD by default reserves lower 2Gb
for brk(2) style heap, ignoring mmap(2) address hint requested by RPCS3.
Passing MAP_32BIT fixes the following crash
Assertion failed: ((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) || (Type == ELF::R_X86_64_32S && ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN))), function resolveX86_64Relocation, file /usr/ports/devel/llvm40/work/llvm-4.0.1.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp, line 287.
* build: unbreak -DVULKAN_PREBUILT with system glslang on Unix
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:4:10: fatal error: '../../../../Vulkan/glslang/SPIRV/GlslangToSpv.h' file not found
#include "../../../../Vulkan/glslang/SPIRV/GlslangToSpv.h"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rpcs3/CMakeFiles/rpcs3.dir/Emu/RSX/VK/VKCommonDecompiler.cpp.o: In function `vk::compile_glsl_to_spv(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, glsl::program_domain, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&)':
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x50e): undefined reference to `glslang::TProgram::TProgram()'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x51d): undefined reference to `glslang::TShader::TShader(EShLanguage)'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x542): undefined reference to `glslang::TShader::setStrings(char const* const*, int)'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x581): undefined reference to `glslang::TShader::parse(TBuiltInResource const*, int, EProfile, bool, bool, EShMessages, glslang::TShader::Includer&)'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x5d6): undefined reference to `glslang::TProgram::link(EShMessages)'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x5f1): undefined reference to `glslang::GlslangToSpv(glslang::TIntermediate const&, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&, glslang::SpvOptions*)'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x5ff): undefined reference to `glslang::TShader::getInfoLog()'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x61a): undefined reference to `glslang::TShader::getInfoDebugLog()'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x630): undefined reference to `glslang::TShader::~TShader()'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x63c): undefined reference to `glslang::TProgram::~TProgram()'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x6d2): undefined reference to `glslang::TShader::~TShader()'
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x6de): undefined reference to `glslang::TProgram::~TProgram()'
rpcs3/CMakeFiles/rpcs3.dir/Emu/RSX/VK/VKCommonDecompiler.cpp.o: In function `vk::initialize_compiler_context()':
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x6f5): undefined reference to `glslang::InitializeProcess()'
rpcs3/CMakeFiles/rpcs3.dir/Emu/RSX/VK/VKCommonDecompiler.cpp.o: In function `vk::finalize_compiler_context()':
rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp:(.text+0x856): undefined reference to `glslang::FinalizeProcess()'
* build/msvc: add missing glslang include directory after 6bb3f1b4d75c
"c:\projects\rpcs3\rpcs3\VKGSRender.vcxproj" (default target) (15) ->
(ClCompile target) ->
Emu\RSX\VK\VKCommonDecompiler.cpp(4): fatal error C1083: Cannot open include file: 'SPIRV/GlslangToSpv.h': No such file or directory [c:\projects\rpcs3\rpcs3\VKGSRender.vcxproj]
2017-11-20 22:56:25 +01:00
|
|
|
#include "SPIRV/GlslangToSpv.h"
|
2020-05-03 14:18:54 +02:00
|
|
|
#include "spirv-tools/optimizer.hpp"
|
2019-12-03 23:34:23 +01:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
#pragma warning(pop)
|
|
|
|
|
#else
|
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
|
#endif
|
2016-02-21 16:50:49 +01:00
|
|
|
|
|
|
|
|
namespace vk
|
|
|
|
|
{
|
2017-06-15 01:33:50 +02:00
|
|
|
static TBuiltInResource g_default_config;
|
|
|
|
|
|
2016-02-21 16:50:49 +01:00
|
|
|
void init_default_resources(TBuiltInResource &rsc)
|
|
|
|
|
{
|
|
|
|
|
rsc.maxLights = 32;
|
|
|
|
|
rsc.maxClipPlanes = 6;
|
|
|
|
|
rsc.maxTextureUnits = 32;
|
|
|
|
|
rsc.maxTextureCoords = 32;
|
|
|
|
|
rsc.maxVertexAttribs = 64;
|
|
|
|
|
rsc.maxVertexUniformComponents = 4096;
|
|
|
|
|
rsc.maxVaryingFloats = 64;
|
|
|
|
|
rsc.maxVertexTextureImageUnits = 32;
|
|
|
|
|
rsc.maxCombinedTextureImageUnits = 80;
|
|
|
|
|
rsc.maxTextureImageUnits = 32;
|
|
|
|
|
rsc.maxFragmentUniformComponents = 4096;
|
|
|
|
|
rsc.maxDrawBuffers = 32;
|
|
|
|
|
rsc.maxVertexUniformVectors = 128;
|
|
|
|
|
rsc.maxVaryingVectors = 8;
|
|
|
|
|
rsc.maxFragmentUniformVectors = 16;
|
|
|
|
|
rsc.maxVertexOutputVectors = 16;
|
|
|
|
|
rsc.maxFragmentInputVectors = 15;
|
2017-08-01 19:22:33 +02:00
|
|
|
rsc.minProgramTexelOffset = -8;
|
2016-02-21 16:50:49 +01:00
|
|
|
rsc.maxProgramTexelOffset = 7;
|
|
|
|
|
rsc.maxClipDistances = 8;
|
|
|
|
|
rsc.maxComputeWorkGroupCountX = 65535;
|
|
|
|
|
rsc.maxComputeWorkGroupCountY = 65535;
|
|
|
|
|
rsc.maxComputeWorkGroupCountZ = 65535;
|
|
|
|
|
rsc.maxComputeWorkGroupSizeX = 1024;
|
|
|
|
|
rsc.maxComputeWorkGroupSizeY = 1024;
|
|
|
|
|
rsc.maxComputeWorkGroupSizeZ = 64;
|
|
|
|
|
rsc.maxComputeUniformComponents = 1024;
|
|
|
|
|
rsc.maxComputeTextureImageUnits = 16;
|
|
|
|
|
rsc.maxComputeImageUniforms = 8;
|
|
|
|
|
rsc.maxComputeAtomicCounters = 8;
|
|
|
|
|
rsc.maxComputeAtomicCounterBuffers = 1;
|
|
|
|
|
rsc.maxVaryingComponents = 60;
|
|
|
|
|
rsc.maxVertexOutputComponents = 64;
|
|
|
|
|
rsc.maxGeometryInputComponents = 64;
|
|
|
|
|
rsc.maxGeometryOutputComponents = 128;
|
|
|
|
|
rsc.maxFragmentInputComponents = 128;
|
|
|
|
|
rsc.maxImageUnits = 8;
|
|
|
|
|
rsc.maxCombinedImageUnitsAndFragmentOutputs = 8;
|
|
|
|
|
rsc.maxCombinedShaderOutputResources = 8;
|
|
|
|
|
rsc.maxImageSamples = 0;
|
|
|
|
|
rsc.maxVertexImageUniforms = 0;
|
|
|
|
|
rsc.maxTessControlImageUniforms = 0;
|
|
|
|
|
rsc.maxTessEvaluationImageUniforms = 0;
|
|
|
|
|
rsc.maxGeometryImageUniforms = 0;
|
|
|
|
|
rsc.maxFragmentImageUniforms = 8;
|
|
|
|
|
rsc.maxCombinedImageUniforms = 8;
|
|
|
|
|
rsc.maxGeometryTextureImageUnits = 16;
|
|
|
|
|
rsc.maxGeometryOutputVertices = 256;
|
|
|
|
|
rsc.maxGeometryTotalOutputComponents = 1024;
|
|
|
|
|
rsc.maxGeometryUniformComponents = 1024;
|
|
|
|
|
rsc.maxGeometryVaryingComponents = 64;
|
|
|
|
|
rsc.maxTessControlInputComponents = 128;
|
|
|
|
|
rsc.maxTessControlOutputComponents = 128;
|
|
|
|
|
rsc.maxTessControlTextureImageUnits = 16;
|
|
|
|
|
rsc.maxTessControlUniformComponents = 1024;
|
|
|
|
|
rsc.maxTessControlTotalOutputComponents = 4096;
|
|
|
|
|
rsc.maxTessEvaluationInputComponents = 128;
|
|
|
|
|
rsc.maxTessEvaluationOutputComponents = 128;
|
|
|
|
|
rsc.maxTessEvaluationTextureImageUnits = 16;
|
|
|
|
|
rsc.maxTessEvaluationUniformComponents = 1024;
|
|
|
|
|
rsc.maxTessPatchComponents = 120;
|
|
|
|
|
rsc.maxPatchVertices = 32;
|
|
|
|
|
rsc.maxTessGenLevel = 64;
|
|
|
|
|
rsc.maxViewports = 16;
|
|
|
|
|
rsc.maxVertexAtomicCounters = 0;
|
|
|
|
|
rsc.maxTessControlAtomicCounters = 0;
|
|
|
|
|
rsc.maxTessEvaluationAtomicCounters = 0;
|
|
|
|
|
rsc.maxGeometryAtomicCounters = 0;
|
|
|
|
|
rsc.maxFragmentAtomicCounters = 8;
|
|
|
|
|
rsc.maxCombinedAtomicCounters = 8;
|
|
|
|
|
rsc.maxAtomicCounterBindings = 1;
|
|
|
|
|
rsc.maxVertexAtomicCounterBuffers = 0;
|
|
|
|
|
rsc.maxTessControlAtomicCounterBuffers = 0;
|
|
|
|
|
rsc.maxTessEvaluationAtomicCounterBuffers = 0;
|
|
|
|
|
rsc.maxGeometryAtomicCounterBuffers = 0;
|
|
|
|
|
rsc.maxFragmentAtomicCounterBuffers = 1;
|
|
|
|
|
rsc.maxCombinedAtomicCounterBuffers = 1;
|
|
|
|
|
rsc.maxAtomicCounterBufferSize = 16384;
|
|
|
|
|
rsc.maxTransformFeedbackBuffers = 4;
|
|
|
|
|
rsc.maxTransformFeedbackInterleavedComponents = 64;
|
|
|
|
|
rsc.maxCullDistances = 8;
|
|
|
|
|
rsc.maxCombinedClipAndCullDistances = 8;
|
|
|
|
|
rsc.maxSamples = 4;
|
|
|
|
|
|
2019-06-08 08:32:09 +02:00
|
|
|
rsc.limits.nonInductiveForLoops = true;
|
|
|
|
|
rsc.limits.whileLoops = true;
|
|
|
|
|
rsc.limits.doWhileLoops = true;
|
|
|
|
|
rsc.limits.generalUniformIndexing = true;
|
|
|
|
|
rsc.limits.generalAttributeMatrixVectorIndexing = true;
|
|
|
|
|
rsc.limits.generalVaryingIndexing = true;
|
|
|
|
|
rsc.limits.generalSamplerIndexing = true;
|
|
|
|
|
rsc.limits.generalVariableIndexing = true;
|
|
|
|
|
rsc.limits.generalConstantMatrixVectorIndexing = true;
|
2016-02-21 16:50:49 +01:00
|
|
|
}
|
|
|
|
|
|
2019-06-09 09:03:27 +02:00
|
|
|
static constexpr std::array<std::pair<std::string_view, int>, 18> varying_registers =
|
|
|
|
|
{{
|
2016-07-17 18:57:50 +02:00
|
|
|
{ "tc0", 0 },
|
|
|
|
|
{ "tc1", 1 },
|
|
|
|
|
{ "tc2", 2 },
|
|
|
|
|
{ "tc3", 3 },
|
|
|
|
|
{ "tc4", 4 },
|
|
|
|
|
{ "tc5", 5 },
|
|
|
|
|
{ "tc6", 6 },
|
|
|
|
|
{ "tc7", 7 },
|
|
|
|
|
{ "tc8", 8 },
|
|
|
|
|
{ "tc9", 9 },
|
|
|
|
|
{ "diff_color", 10 },
|
2019-08-23 18:36:01 +02:00
|
|
|
{ "diff_color1", 11 },
|
2016-07-17 18:57:50 +02:00
|
|
|
{ "spec_color", 12 },
|
2019-08-23 18:36:01 +02:00
|
|
|
{ "spec_color1", 13 },
|
2016-02-21 16:50:49 +01:00
|
|
|
{ "fog_c", 14 },
|
|
|
|
|
{ "fogc", 14 }
|
2019-06-09 09:03:27 +02:00
|
|
|
}};
|
2016-02-21 16:50:49 +01:00
|
|
|
|
2019-06-09 09:03:27 +02:00
|
|
|
int get_varying_register_location(std::string_view varying_register_name)
|
2016-02-21 16:50:49 +01:00
|
|
|
{
|
2019-06-09 09:03:27 +02:00
|
|
|
for (const auto& varying_register : varying_registers)
|
2016-02-21 16:50:49 +01:00
|
|
|
{
|
2019-06-09 09:03:27 +02:00
|
|
|
if (varying_register.first == varying_register_name)
|
|
|
|
|
{
|
|
|
|
|
return varying_register.second;
|
|
|
|
|
}
|
2016-02-21 16:50:49 +01:00
|
|
|
}
|
|
|
|
|
|
2020-12-09 16:04:52 +01:00
|
|
|
fmt::throw_exception("Unknown register name: %s", varying_register_name);
|
2016-02-21 16:50:49 +01:00
|
|
|
}
|
|
|
|
|
|
2017-08-04 16:11:39 +02:00
|
|
|
bool compile_glsl_to_spv(std::string& shader, program_domain domain, std::vector<u32>& spv)
|
2016-02-21 16:50:49 +01:00
|
|
|
{
|
2018-06-12 17:46:59 +02:00
|
|
|
EShLanguage lang = (domain == glsl_fragment_program) ? EShLangFragment :
|
|
|
|
|
(domain == glsl_vertex_program)? EShLangVertex : EShLangCompute;
|
2016-02-21 16:50:49 +01:00
|
|
|
|
|
|
|
|
glslang::TProgram program;
|
|
|
|
|
glslang::TShader shader_object(lang);
|
2018-01-24 18:26:17 +01:00
|
|
|
|
|
|
|
|
shader_object.setEnvInput(glslang::EShSourceGlsl, lang, glslang::EShClientVulkan, 100);
|
2018-06-24 09:52:17 +02:00
|
|
|
shader_object.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetClientVersion::EShTargetVulkan_1_0);
|
|
|
|
|
shader_object.setEnvTarget(glslang::EshTargetSpv, glslang::EShTargetLanguageVersion::EShTargetSpv_1_0);
|
2019-04-12 23:25:44 +02:00
|
|
|
|
2016-02-21 16:50:49 +01:00
|
|
|
bool success = false;
|
|
|
|
|
const char *shader_text = shader.data();
|
|
|
|
|
|
|
|
|
|
shader_object.setStrings(&shader_text, 1);
|
|
|
|
|
|
2019-12-03 23:34:23 +01:00
|
|
|
EShMessages msg = static_cast<EShMessages>(EShMsgVulkanRules | EShMsgSpvRules);
|
2017-06-15 01:33:50 +02:00
|
|
|
if (shader_object.parse(&g_default_config, 400, EProfile::ECoreProfile, false, true, msg))
|
2016-02-21 16:50:49 +01:00
|
|
|
{
|
|
|
|
|
program.addShader(&shader_object);
|
2018-01-24 18:26:17 +01:00
|
|
|
success = program.link(msg);
|
2016-02-21 16:50:49 +01:00
|
|
|
if (success)
|
|
|
|
|
{
|
2018-01-24 18:26:17 +01:00
|
|
|
glslang::SpvOptions options;
|
2020-05-03 14:18:54 +02:00
|
|
|
options.disableOptimizer = true;
|
2018-01-24 18:26:17 +01:00
|
|
|
options.optimizeSize = true;
|
|
|
|
|
glslang::GlslangToSpv(*program.getIntermediate(lang), spv, &options);
|
2020-05-03 14:18:54 +02:00
|
|
|
|
|
|
|
|
// Now we optimize
|
2020-09-24 20:58:34 +02:00
|
|
|
//spvtools::Optimizer optimizer(SPV_ENV_VULKAN_1_0);
|
|
|
|
|
//optimizer.RegisterPass(spvtools::CreateUnifyConstantPass()); // Remove duplicate constants
|
|
|
|
|
//optimizer.RegisterPass(spvtools::CreateMergeReturnPass()); // Huge savings in vertex interpreter and likely normal vertex shaders
|
|
|
|
|
//optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); // Remove dead code
|
|
|
|
|
//optimizer.Run(spv.data(), spv.size(), &spv);
|
2016-02-21 16:50:49 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-02-01 09:07:25 +01:00
|
|
|
rsx_log.error("%s", shader_object.getInfoLog());
|
|
|
|
|
rsx_log.error("%s", shader_object.getInfoDebugLog());
|
2016-02-21 16:50:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
2017-06-15 01:33:50 +02:00
|
|
|
|
|
|
|
|
void initialize_compiler_context()
|
|
|
|
|
{
|
|
|
|
|
glslang::InitializeProcess();
|
|
|
|
|
init_default_resources(g_default_config);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void finalize_compiler_context()
|
|
|
|
|
{
|
|
|
|
|
glslang::FinalizeProcess();
|
|
|
|
|
}
|
2016-02-21 16:50:49 +01:00
|
|
|
}
|