mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-11 05:26:24 +02:00
Initial work on shader translation using glslang+spirv-cross
This commit is contained in:
1 parent
55beec3e89
commit
dfc71f32cb
5 files changed
+191
-2
No files matched your search
+1
-2
@@ -5,12 +5,11 @@
|
||||
|
||||
#include <crtdbg.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#if defined(_DEBUG)
|
||||
#define USE_CRT_DBG
|
||||
#ifndef DBG_NEW
|
||||
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
|
||||
#define new DBG_NEW
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _DEBUG
|
||||
@@ -0,0 +1,147 @@
|
||||
// Copyright (c) 2017- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#ifndef ANDROID
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
// DbgNew is not compatible with Glslang
|
||||
#ifdef DBG_NEW
|
||||
#undef new
|
||||
#endif
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "ShaderTranslation.h"
|
||||
#include "ext/glslang/SPIRV/GlslangToSpv.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "ext/SPIRV-Cross/spirv.hpp"
|
||||
#include "ext/SPIRV-Cross/spirv_common.hpp"
|
||||
#include "ext/SPIRV-Cross/spirv_cross.hpp"
|
||||
#include "ext/SPIRV-Cross/spirv_glsl.hpp"
|
||||
#ifdef _WIN32
|
||||
#include "ext/SPIRV-Cross/spirv_hlsl.hpp"
|
||||
#endif
|
||||
|
||||
extern void init_resources(TBuiltInResource &Resources);
|
||||
|
||||
static EShLanguage GetLanguage(const Draw::ShaderStage stage) {
|
||||
switch (stage) {
|
||||
case Draw::ShaderStage::VERTEX: return EShLangVertex;
|
||||
case Draw::ShaderStage::CONTROL: return EShLangTessControl;
|
||||
case Draw::ShaderStage::EVALUATION: return EShLangTessEvaluation;
|
||||
case Draw::ShaderStage::GEOMETRY: return EShLangGeometry;
|
||||
case Draw::ShaderStage::FRAGMENT: return EShLangFragment;
|
||||
case Draw::ShaderStage::COMPUTE: return EShLangCompute;
|
||||
default: return EShLangVertex;
|
||||
}
|
||||
}
|
||||
|
||||
bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShaderMetadata *destMetadata, std::string src, ShaderLanguage srcLang, Draw::ShaderStage stage, std::string *errorMessage) {
|
||||
if (srcLang != GLSL_300)
|
||||
return false;
|
||||
|
||||
glslang::TProgram program;
|
||||
const char *shaderStrings[1];
|
||||
|
||||
TBuiltInResource Resources;
|
||||
init_resources(Resources);
|
||||
|
||||
// Enable SPIR-V and Vulkan rules when parsing GLSL
|
||||
EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
|
||||
|
||||
EShLanguage shaderStage = GetLanguage(stage);
|
||||
glslang::TShader shader(shaderStage);
|
||||
|
||||
shaderStrings[0] = src.c_str();
|
||||
shader.setStrings(shaderStrings, 1);
|
||||
|
||||
if (!shader.parse(&Resources, 100, false, messages)) {
|
||||
ELOG("%s", shader.getInfoLog());
|
||||
ELOG("%s", shader.getInfoDebugLog());
|
||||
if (errorMessage) {
|
||||
*errorMessage = shader.getInfoLog();
|
||||
(*errorMessage) += shader.getInfoDebugLog();
|
||||
}
|
||||
return false; // something didn't work
|
||||
}
|
||||
|
||||
// Note that program does not take ownership of &shader, so this is fine.
|
||||
program.addShader(&shader);
|
||||
|
||||
if (!program.link(messages)) {
|
||||
ELOG("%s", shader.getInfoLog());
|
||||
ELOG("%s", shader.getInfoDebugLog());
|
||||
if (errorMessage) {
|
||||
*errorMessage = shader.getInfoLog();
|
||||
(*errorMessage) += shader.getInfoDebugLog();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> spirv;
|
||||
// Can't fail, parsing worked, "linking" worked.
|
||||
glslang::GlslangToSpv(*program.getIntermediate(shaderStage), spirv);
|
||||
|
||||
// Alright, step 1 done. Now let's takes this SPIR-V shader and output in our desired format.
|
||||
|
||||
switch (destLang) {
|
||||
case GLSL_VULKAN:
|
||||
return false; // TODO
|
||||
#ifdef _WIN32
|
||||
case HLSL_D3D11:
|
||||
{
|
||||
spirv_cross::CompilerHLSL hlsl(spirv);
|
||||
spirv_cross::CompilerHLSL::Options options{};
|
||||
options.fixup_clipspace = true;
|
||||
options.shader_model = 30;
|
||||
hlsl.set_options(options);
|
||||
*dest = hlsl.compile();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
case GLSL_140:
|
||||
{
|
||||
spirv_cross::CompilerGLSL glsl(std::move(spirv));
|
||||
// The SPIR-V is now parsed, and we can perform reflection on it.
|
||||
spirv_cross::ShaderResources resources = glsl.get_shader_resources();
|
||||
// Get all sampled images in the shader.
|
||||
for (auto &resource : resources.sampled_images) {
|
||||
unsigned set = glsl.get_decoration(resource.id, spv::DecorationDescriptorSet);
|
||||
unsigned binding = glsl.get_decoration(resource.id, spv::DecorationBinding);
|
||||
printf("Image %s at set = %u, binding = %u\n", resource.name.c_str(), set, binding);
|
||||
// Modify the decoration to prepare it for GLSL.
|
||||
glsl.unset_decoration(resource.id, spv::DecorationDescriptorSet);
|
||||
// Some arbitrary remapping if we want.
|
||||
glsl.set_decoration(resource.id, spv::DecorationBinding, set * 16 + binding);
|
||||
}
|
||||
// Set some options.
|
||||
spirv_cross::CompilerGLSL::Options options;
|
||||
options.version = 140;
|
||||
options.es = true;
|
||||
glsl.set_options(options);
|
||||
|
||||
// Compile to GLSL, ready to give to GL driver.
|
||||
*dest = glsl.compile();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2017- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "GPU/Common/ShaderCommon.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
|
||||
#ifndef ANDROID
|
||||
|
||||
struct TranslatedShaderMetadata {
|
||||
|
||||
};
|
||||
|
||||
bool TranslateShader(std::string *dst, ShaderLanguage destLang, TranslatedShaderMetadata *destMetadata, std::string src, ShaderLanguage srcLang, Draw::ShaderStage stage, std::string *errorMessage);
|
||||
|
||||
#endif
|
||||
@@ -190,6 +190,7 @@
|
||||
<ClInclude Include="Common\PostShader.h" />
|
||||
<ClInclude Include="Common\ShaderCommon.h" />
|
||||
<ClInclude Include="Common\ShaderId.h" />
|
||||
<ClInclude Include="Common\ShaderTranslation.h" />
|
||||
<ClInclude Include="Common\ShaderUniforms.h" />
|
||||
<ClInclude Include="Common\SoftwareTransformCommon.h" />
|
||||
<ClInclude Include="Common\SplineCommon.h" />
|
||||
@@ -273,6 +274,7 @@
|
||||
<ClCompile Include="Common\IndexGenerator.cpp" />
|
||||
<ClCompile Include="Common\PostShader.cpp" />
|
||||
<ClCompile Include="Common\ShaderId.cpp" />
|
||||
<ClCompile Include="Common\ShaderTranslation.cpp" />
|
||||
<ClCompile Include="Common\ShaderUniforms.cpp" />
|
||||
<ClCompile Include="Common\SplineCommon.cpp" />
|
||||
<ClCompile Include="Common\TextureDecoderNEON.cpp">
|
||||
@@ -365,6 +367,9 @@
|
||||
<ProjectReference Include="..\Common\Common.vcxproj">
|
||||
<Project>{3fcdbae2-5103-4350-9a8e-848ce9c73195}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ext\SPIRV-Cross.vcxproj">
|
||||
<Project>{4328a62c-f1e9-47ed-b816-a1a81daf4363}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -256,6 +256,9 @@
|
||||
<Filter>D3D11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3D11\StateMappingD3D11.h" />
|
||||
<ClInclude Include="Common\ShaderTranslation.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Math3D.cpp">
|
||||
@@ -501,5 +504,8 @@
|
||||
<ClCompile Include="D3D11\StencilBufferD3D11.cpp">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\ShaderTranslation.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in new issue
Block a user