GPU: Add command line option to output shader source
This command line outputs only shaders whose name matches the argument string. Metal is missing as it waits until #147010 lands. Pull Request: https://projects.blender.org/blender/blender/pulls/147970
This commit is contained in:
committed by
Clément Foucault
parent
304461e761
commit
139fa532c1
@@ -170,7 +170,13 @@ struct Global {
|
||||
* Triggers a GPU capture if the name matches a DebugScope.
|
||||
* Set using `--debug-gpu-scope-capture "debug_scope"`.
|
||||
*/
|
||||
char gpu_debug_scope_name[200];
|
||||
char gpu_debug_scope_name[100];
|
||||
|
||||
/**
|
||||
* Save final shader string to disk.
|
||||
* Set using `--debug-gpu-shader-source "shader_name"`.
|
||||
*/
|
||||
char gpu_debug_shader_source_name[100];
|
||||
|
||||
bool profile_gpu;
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -1218,6 +1219,21 @@ StringRefNull GLShader::glsl_patch_get(GLenum gl_stage)
|
||||
return "";
|
||||
}
|
||||
|
||||
static StringRefNull stage_name_get(GLenum gl_stage)
|
||||
{
|
||||
switch (gl_stage) {
|
||||
case GL_VERTEX_SHADER:
|
||||
return "vertex";
|
||||
case GL_GEOMETRY_SHADER:
|
||||
return "geometry";
|
||||
case GL_FRAGMENT_SHADER:
|
||||
return "fragment";
|
||||
case GL_COMPUTE_SHADER:
|
||||
return "compute";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
GLuint GLShader::create_shader_stage(GLenum gl_stage,
|
||||
MutableSpan<StringRefNull> sources,
|
||||
GLSources &gl_sources,
|
||||
@@ -1246,21 +1262,7 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage,
|
||||
|
||||
if (DEBUG_LOG_SHADER_SRC_ON_ERROR) {
|
||||
/* Store the generated source for printing in case the link fails. */
|
||||
StringRefNull source_type;
|
||||
switch (gl_stage) {
|
||||
case GL_VERTEX_SHADER:
|
||||
source_type = "VertShader";
|
||||
break;
|
||||
case GL_GEOMETRY_SHADER:
|
||||
source_type = "GeomShader";
|
||||
break;
|
||||
case GL_FRAGMENT_SHADER:
|
||||
source_type = "FragShader";
|
||||
break;
|
||||
case GL_COMPUTE_SHADER:
|
||||
source_type = "ComputeShader";
|
||||
break;
|
||||
}
|
||||
StringRefNull source_type = stage_name_get(gl_stage);
|
||||
|
||||
debug_source += "\n\n----------" + source_type + "----------\n\n";
|
||||
for (StringRefNull source : sources) {
|
||||
@@ -1281,6 +1283,24 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage,
|
||||
|
||||
std::string concat_source = fmt::to_string(fmt::join(sources, ""));
|
||||
|
||||
std::string full_name = this->name_get() + "_" + stage_name_get(gl_stage);
|
||||
|
||||
if (this->name_get() == G.gpu_debug_shader_source_name) {
|
||||
namespace fs = std::filesystem;
|
||||
fs::path shader_dir = fs::current_path() / "Shaders";
|
||||
fs::create_directories(shader_dir);
|
||||
fs::path file_path = shader_dir / (full_name + ".glsl");
|
||||
|
||||
std::ofstream output_source_file(file_path);
|
||||
if (output_source_file) {
|
||||
output_source_file << concat_source;
|
||||
output_source_file.close();
|
||||
}
|
||||
else {
|
||||
std::cerr << "Shader Source Debug: Failed to open file: " << file_path << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* Patch line directives so that we can make error reporting consistent. */
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = concat_source.find("#line ", start_pos)) != std::string::npos) {
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
#include "vk_shader.hh"
|
||||
#include "vk_shader_compiler.hh"
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
static std::optional<std::string> cache_dir_get()
|
||||
@@ -212,10 +217,27 @@ static bool compile_ex(shaderc::Compiler &compiler,
|
||||
options.SetGenerateDebugInfo();
|
||||
}
|
||||
|
||||
std::string full_name = shader.name_get() + "_" + to_stage_name(stage);
|
||||
|
||||
if (shader.name_get() == G.gpu_debug_shader_source_name) {
|
||||
namespace fs = std::filesystem;
|
||||
fs::path shader_dir = fs::current_path() / "Shaders";
|
||||
fs::create_directories(shader_dir);
|
||||
fs::path file_path = shader_dir / (full_name + ".glsl");
|
||||
|
||||
std::ofstream output_source_file(file_path);
|
||||
if (output_source_file) {
|
||||
output_source_file << shader_module.combined_sources;
|
||||
output_source_file.close();
|
||||
}
|
||||
else {
|
||||
std::cerr << "Shader Source Debug: Failed to open file: " << file_path << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* Removes line directive. */
|
||||
std::string sources = patch_line_directives(shader_module.combined_sources);
|
||||
|
||||
std::string full_name = shader.name_get() + "_" + to_stage_name(stage);
|
||||
shader_module.compilation_result = compiler.CompileGlslToSpv(
|
||||
sources, stage, full_name.c_str(), options);
|
||||
bool compilation_succeeded = shader_module.compilation_result.GetCompilationStatus() ==
|
||||
|
||||
@@ -763,6 +763,7 @@ static void print_help(bArgs *ba, bool all)
|
||||
BLI_args_print_arg_doc(ba, "--debug-gpu-force-workarounds");
|
||||
BLI_args_print_arg_doc(ba, "--debug-gpu-compile-shaders");
|
||||
BLI_args_print_arg_doc(ba, "--debug-gpu-shader-debug-info");
|
||||
BLI_args_print_arg_doc(ba, "--debug-gpu-shader-source");
|
||||
if (defs.with_renderdoc) {
|
||||
BLI_args_print_arg_doc(ba, "--debug-gpu-scope-capture");
|
||||
BLI_args_print_arg_doc(ba, "--debug-gpu-renderdoc");
|
||||
@@ -1545,6 +1546,20 @@ static int arg_handle_debug_gpu_scope_capture_set(int argc, const char **argv, v
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char arg_handle_debug_gpu_shader_source_doc[] =
|
||||
"\n"
|
||||
"\tCapture the GPU commands issued inside the give scope name."
|
||||
"\tFiles are saved in the current working directory inside a folder named \"Shaders\".";
|
||||
static int arg_handle_debug_gpu_shader_source(int argc, const char **argv, void * /*data*/)
|
||||
{
|
||||
if (argc > 1) {
|
||||
STRNCPY(G.gpu_debug_scope_name, argv[1]);
|
||||
return 1;
|
||||
}
|
||||
fprintf(stderr, "\nError: you must specify a shader name to capture.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char arg_handle_debug_gpu_renderdoc_set_doc[] =
|
||||
"\n"
|
||||
"\tEnable RenderDoc integration for GPU frame grabbing and debugging.";
|
||||
@@ -3014,6 +3029,8 @@ void main_args_setup(bContext *C, bArgs *ba, bool all)
|
||||
"--debug-gpu-compile-shaders",
|
||||
CB(arg_handle_debug_gpu_compile_shaders_set),
|
||||
nullptr);
|
||||
BLI_args_add(
|
||||
ba, nullptr, "--debug-gpu-shader-source", CB(arg_handle_debug_gpu_shader_source), nullptr);
|
||||
if (defs.with_renderdoc) {
|
||||
BLI_args_add(ba,
|
||||
nullptr,
|
||||
|
||||
Reference in New Issue
Block a user