mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-23 06:05:45 +00:00
Allow building SPIR-V with debug info and check debug info in reflection
This commit is contained in:
@@ -196,6 +196,11 @@ void main() {
|
||||
ShaderBindpointMapping mapping;
|
||||
compile(ShaderStage::Fragment, source, "main", refl, mapping);
|
||||
|
||||
if(testType == ShaderType::eShaderGLSPIRV)
|
||||
CHECK(refl.encoding == ShaderEncoding::SPIRV);
|
||||
else
|
||||
CHECK(refl.encoding == ShaderEncoding::GLSL);
|
||||
|
||||
REQUIRE_ARRAY_SIZE(refl.constantBlocks.size(), 1);
|
||||
{
|
||||
CHECK(refl.constantBlocks[0].name == "$Globals");
|
||||
@@ -308,6 +313,8 @@ void main() {
|
||||
ShaderBindpointMapping mapping;
|
||||
compile(ShaderStage::Fragment, source, "main", refl, mapping);
|
||||
|
||||
CHECK(refl.encoding == ShaderEncoding::SPIRV);
|
||||
|
||||
REQUIRE_ARRAY_SIZE(refl.samplers.size(), 1);
|
||||
{
|
||||
CHECK(refl.samplers[0].name == "S");
|
||||
@@ -526,6 +533,61 @@ void main() {
|
||||
RDCFATAL("Unexpected test type");
|
||||
}
|
||||
|
||||
SECTION("Debug information")
|
||||
{
|
||||
std::string source = R"(
|
||||
#version 450 core
|
||||
|
||||
layout(location = 3) in vec2 a_input;
|
||||
layout(location = 6) flat in uvec3 z_input;
|
||||
|
||||
layout(location = 0) out vec4 a_output;
|
||||
layout(location = 1) out vec3 z_output;
|
||||
layout(location = 2) out int b_output;
|
||||
|
||||
void main() {
|
||||
a_output = vec4(a_input.y + gl_FragCoord.x, 0, 0, 1);
|
||||
z_output = vec3(a_output.xy, a_output.z);
|
||||
b_output = int(z_input.x);
|
||||
gl_FragDepth = float(z_output.y);
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
ShaderReflection refl;
|
||||
ShaderBindpointMapping mapping;
|
||||
compile(ShaderStage::Fragment, source, "main", refl, mapping);
|
||||
|
||||
CHECK(refl.entryPoint == "main");
|
||||
CHECK(refl.stage == ShaderStage::Fragment);
|
||||
|
||||
CHECK(refl.debugInfo.encoding == ShaderEncoding::GLSL);
|
||||
|
||||
REQUIRE(refl.debugInfo.files.size() == 1);
|
||||
|
||||
CHECK(refl.debugInfo.files[0].contents == source);
|
||||
|
||||
if(testType == eShaderGLSL)
|
||||
{
|
||||
CHECK(refl.debugInfo.files[0].filename == "main.glsl");
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(refl.debugInfo.files[0].filename == "source0.glsl");
|
||||
|
||||
REQUIRE(refl.debugInfo.compileFlags.flags.size() == 1);
|
||||
|
||||
CHECK(refl.debugInfo.compileFlags.flags[0].name == "@cmdline");
|
||||
|
||||
if(testType == eShaderGLSPIRV)
|
||||
CHECK(refl.debugInfo.compileFlags.flags[0].value ==
|
||||
" --client opengl100 --target-env opengl --entry-point main");
|
||||
else
|
||||
CHECK(refl.debugInfo.compileFlags.flags[0].value ==
|
||||
" --client vulkan100 --target-env vulkan1.0 --entry-point main");
|
||||
}
|
||||
};
|
||||
|
||||
SECTION("Input and output signatures")
|
||||
{
|
||||
std::string source = R"(
|
||||
|
||||
@@ -1103,6 +1103,11 @@ static void AddSigParameter(std::vector<SigParameter> &sigs, uint32_t ®Index,
|
||||
void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &refl,
|
||||
const FixedFunctionVertexOutputs &outputUsage)
|
||||
{
|
||||
refl.stage = MakeShaderStage(shadType);
|
||||
refl.entryPoint = "main";
|
||||
refl.encoding = ShaderEncoding::GLSL;
|
||||
refl.debugInfo.encoding = ShaderEncoding::GLSL;
|
||||
|
||||
if(shadType == eGL_COMPUTE_SHADER)
|
||||
{
|
||||
GL.glGetProgramiv(sepProg, eGL_COMPUTE_WORK_GROUP_SIZE, (GLint *)refl.dispatchThreadsDimension);
|
||||
|
||||
@@ -3469,6 +3469,10 @@ void MakeOfflineShaderReflection(ShaderStage stage, const std::string &source,
|
||||
|
||||
MakeShaderReflection(ShaderEnum((size_t)stage), fakeProg, refl, outputUsage);
|
||||
|
||||
refl.debugInfo.files.resize(1);
|
||||
refl.debugInfo.files[0].filename = "main.glsl";
|
||||
refl.debugInfo.files[0].contents = source;
|
||||
|
||||
// implement some stubs for testing
|
||||
GL.glGetUniformLocation = &_testStub_GetUniformLocation;
|
||||
GL.glGetUniformiv = &_testStub_GetUniformiv;
|
||||
@@ -3488,8 +3492,6 @@ void MakeOfflineShaderReflection(ShaderStage stage, const std::string &source,
|
||||
// helper function that uses the replay proxy system to compile and reflect the shader using the
|
||||
// current driver. Unused by default but you can change the unit test below to call this function
|
||||
// instead of MakeOfflineShaderReflection.
|
||||
//
|
||||
// Note that we can't fill out ShaderBindpointMapping easily on the actual driver
|
||||
void MakeOnlineShaderReflection(ShaderStage stage, const std::string &source,
|
||||
const std::string &entryPoint, ShaderReflection &refl,
|
||||
ShaderBindpointMapping &mapping)
|
||||
@@ -3526,6 +3528,10 @@ void MakeOnlineShaderReflection(ShaderStage stage, const std::string &source,
|
||||
|
||||
refl = *driver->GetShader(id, ShaderEntryPoint("main", ShaderStage::Fragment));
|
||||
|
||||
// Note that we can't fill out ShaderBindpointMapping easily on the actual driver through the
|
||||
// replay interface
|
||||
WARN("Using online reflection - all checks with ShaderBindpointMapping will fail");
|
||||
|
||||
driver->FreeCustomShader(id);
|
||||
|
||||
driver->Shutdown();
|
||||
|
||||
@@ -272,15 +272,9 @@ void WrappedOpenGL::ShaderData::ProcessCompilation(WrappedOpenGL &drv, ResourceI
|
||||
disassembly = s;
|
||||
|
||||
reflection.resourceId = id;
|
||||
reflection.entryPoint = "main";
|
||||
|
||||
reflection.stage = MakeShaderStage(type);
|
||||
|
||||
reflection.encoding = ShaderEncoding::GLSL;
|
||||
reflection.rawBytes.assign((byte *)concatenated.c_str(), concatenated.size());
|
||||
|
||||
reflection.debugInfo.encoding = ShaderEncoding::GLSL;
|
||||
|
||||
reflection.debugInfo.files.resize(1);
|
||||
reflection.debugInfo.files[0].filename = "main.glsl";
|
||||
reflection.debugInfo.files[0].contents = concatenated;
|
||||
|
||||
@@ -41,9 +41,16 @@ std::string rdcspv::Compile(const rdcspv::CompilationSettings &settings,
|
||||
std::string errors = "";
|
||||
|
||||
const char **strs = new const char *[sources.size()];
|
||||
const char **names = new const char *[sources.size()];
|
||||
std::vector<std::string> names_str;
|
||||
names_str.resize(sources.size());
|
||||
|
||||
for(size_t i = 0; i < sources.size(); i++)
|
||||
{
|
||||
strs[i] = sources[i].c_str();
|
||||
names_str[i] = StringFormat::Fmt("source%d.glsl", i);
|
||||
names[i] = names_str[i].c_str();
|
||||
}
|
||||
|
||||
RDCCOMPILE_ASSERT((int)EShLangVertex == (int)rdcspv::ShaderStage::Vertex &&
|
||||
(int)EShLangTessControl == (int)rdcspv::ShaderStage::TessControl &&
|
||||
@@ -58,7 +65,7 @@ std::string rdcspv::Compile(const rdcspv::CompilationSettings &settings,
|
||||
|
||||
glslang::TShader *shader = new glslang::TShader(lang);
|
||||
|
||||
shader->setStrings(strs, (int)sources.size());
|
||||
shader->setStringsWithLengthsAndNames(strs, NULL, names, (int)sources.size());
|
||||
|
||||
if(!settings.entryPoint.empty())
|
||||
shader->setEntryPoint(settings.entryPoint.c_str());
|
||||
@@ -70,6 +77,9 @@ std::string rdcspv::Compile(const rdcspv::CompilationSettings &settings,
|
||||
if(settings.lang == rdcspv::InputLanguage::VulkanHLSL)
|
||||
flags = EShMessages(flags | EShMsgVulkanRules | EShMsgReadHlsl);
|
||||
|
||||
if(settings.debugInfo)
|
||||
flags = EShMessages(flags | EShMsgDebugInfo);
|
||||
|
||||
bool success = shader->parse(GetDefaultResources(), 110, false, flags);
|
||||
|
||||
if(!success)
|
||||
@@ -101,7 +111,11 @@ std::string rdcspv::Compile(const rdcspv::CompilationSettings &settings,
|
||||
// if we successfully compiled and linked, we must have the stage we started with
|
||||
RDCASSERT(intermediate);
|
||||
|
||||
glslang::GlslangToSpv(*intermediate, spirv);
|
||||
glslang::SpvOptions opts;
|
||||
if(settings.debugInfo)
|
||||
opts.generateDebugInfo = true;
|
||||
|
||||
glslang::GlslangToSpv(*intermediate, spirv, &opts);
|
||||
}
|
||||
|
||||
delete program;
|
||||
@@ -111,6 +125,7 @@ std::string rdcspv::Compile(const rdcspv::CompilationSettings &settings,
|
||||
}
|
||||
|
||||
delete[] strs;
|
||||
delete[] names;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ struct CompilationSettings
|
||||
|
||||
ShaderStage stage = ShaderStage::Invalid;
|
||||
InputLanguage lang = InputLanguage::Unknown;
|
||||
bool debugInfo = false;
|
||||
std::string entryPoint;
|
||||
};
|
||||
|
||||
|
||||
@@ -4209,6 +4209,7 @@ void SPVModule::MakeReflection(GraphicsAPI sourceAPI, ShaderStage stage,
|
||||
// VKTODOLOW filter to only functions/resources used by entryPoint
|
||||
reflection.entryPoint = entryPoint;
|
||||
reflection.stage = stage;
|
||||
reflection.encoding = ShaderEncoding::SPIRV;
|
||||
|
||||
// TODO sort these so that the entry point is in the first file
|
||||
if(!sourceFiles.empty())
|
||||
|
||||
@@ -218,6 +218,7 @@ TEST_CASE("Validate SPIR-V reflection", "[spirv][reflection]")
|
||||
? rdcspv::InputLanguage::VulkanGLSL
|
||||
: rdcspv::InputLanguage::OpenGLGLSL,
|
||||
rdcspv::ShaderStage(stage));
|
||||
settings.debugInfo = true;
|
||||
std::string errors = rdcspv::Compile(settings, {source}, spirv);
|
||||
|
||||
INFO("SPIR-V compile output: " << errors);
|
||||
|
||||
Reference in New Issue
Block a user