mirror of
https://github.com/love2d/love.git
synced 2026-08-12 16:40:57 +02:00
Add debugname field to shader options table.
This commit is contained in:
@@ -402,7 +402,7 @@ Shader *Graphics::newShader(const std::vector<std::string> &stagessource, const
|
||||
|
||||
}
|
||||
|
||||
return newShaderInternal(stages);
|
||||
return newShaderInternal(stages, options);
|
||||
}
|
||||
|
||||
Shader *Graphics::newComputeShader(const std::string &source, const Shader::CompileOptions &options)
|
||||
@@ -418,7 +418,7 @@ Shader *Graphics::newComputeShader(const std::string &source, const Shader::Comp
|
||||
// shouldn't be much reuse.
|
||||
stages[SHADERSTAGE_COMPUTE].set(newShaderStage(SHADERSTAGE_COMPUTE, source, options, info, false));
|
||||
|
||||
return newShaderInternal(stages);
|
||||
return newShaderInternal(stages, options);
|
||||
}
|
||||
|
||||
Buffer *Graphics::newBuffer(const Buffer::Settings &settings, DataFormat format, const void *data, size_t size, size_t arraylength)
|
||||
|
||||
@@ -1020,7 +1020,7 @@ protected:
|
||||
|
||||
ShaderStage *newShaderStage(ShaderStageType stage, const std::string &source, const Shader::CompileOptions &options, const Shader::SourceInfo &info, bool cache);
|
||||
virtual ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) = 0;
|
||||
virtual Shader *newShaderInternal(StrongRef<ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) = 0;
|
||||
virtual Shader *newShaderInternal(StrongRef<ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options) = 0;
|
||||
virtual StreamBuffer *newStreamBuffer(BufferUsage type, size_t size) = 0;
|
||||
|
||||
virtual GraphicsReadback *newReadbackInternal(ReadbackMethod method, Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) = 0;
|
||||
|
||||
@@ -686,8 +686,9 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
Shader::Shader(StrongRef<ShaderStage> _stages[])
|
||||
Shader::Shader(StrongRef<ShaderStage> _stages[], const CompileOptions &options)
|
||||
: stages()
|
||||
, debugName(options.debugName)
|
||||
{
|
||||
std::string err;
|
||||
if (!validateInternal(_stages, err, validationReflection))
|
||||
@@ -1250,6 +1251,20 @@ bool Shader::fillUniformReflectionData(UniformInfo &u)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Shader::getShaderStageDebugName(ShaderStageType stage) const
|
||||
{
|
||||
std::string name = debugName;
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
const char *stagename = "unknown";
|
||||
ShaderStage::getConstant(stage, stagename);
|
||||
name += " (" + std::string(stagename) + ")";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
bool Shader::initialize()
|
||||
{
|
||||
return glslang::InitializeProcess();
|
||||
|
||||
@@ -111,6 +111,7 @@ public:
|
||||
struct CompileOptions
|
||||
{
|
||||
std::map<std::string, std::string> defines;
|
||||
std::string debugName;
|
||||
};
|
||||
|
||||
struct SourceInfo
|
||||
@@ -189,7 +190,7 @@ public:
|
||||
// Pointer to the default Shader.
|
||||
static Shader *standardShaders[STANDARD_MAX_ENUM];
|
||||
|
||||
Shader(StrongRef<ShaderStage> stages[]);
|
||||
Shader(StrongRef<ShaderStage> stages[], const CompileOptions &options);
|
||||
virtual ~Shader();
|
||||
|
||||
/**
|
||||
@@ -217,6 +218,8 @@ public:
|
||||
**/
|
||||
virtual std::string getWarnings() const = 0;
|
||||
|
||||
const std::string &getDebugName() const { return debugName; }
|
||||
|
||||
virtual int getVertexAttributeIndex(const std::string &name) = 0;
|
||||
|
||||
virtual const UniformInfo *getUniformInfo(const std::string &name) const = 0;
|
||||
@@ -291,6 +294,8 @@ protected:
|
||||
|
||||
bool fillUniformReflectionData(UniformInfo &u);
|
||||
|
||||
std::string getShaderStageDebugName(ShaderStageType stage) const;
|
||||
|
||||
static bool validateInternal(StrongRef<ShaderStage> stages[], std::string& err, ValidationReflection &reflection);
|
||||
static DataBaseType getDataBaseType(PixelFormat format);
|
||||
static bool isResourceBaseTypeCompatible(DataBaseType a, DataBaseType b);
|
||||
@@ -302,6 +307,8 @@ protected:
|
||||
|
||||
ValidationReflection validationReflection;
|
||||
|
||||
std::string debugName;
|
||||
|
||||
}; // Shader
|
||||
|
||||
} // graphics
|
||||
|
||||
@@ -196,7 +196,7 @@ private:
|
||||
};
|
||||
|
||||
love::graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
|
||||
love::graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
|
||||
love::graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options) override;
|
||||
love::graphics::StreamBuffer *newStreamBuffer(BufferUsage usage, size_t size) override;
|
||||
|
||||
love::graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) override;
|
||||
|
||||
@@ -438,9 +438,9 @@ love::graphics::ShaderStage *Graphics::newShaderStageInternal(ShaderStageType st
|
||||
return new ShaderStage(this, stage, source, gles, cachekey);
|
||||
}
|
||||
|
||||
love::graphics::Shader *Graphics::newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
|
||||
love::graphics::Shader *Graphics::newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options)
|
||||
{
|
||||
return new Shader(device, stages);
|
||||
return new Shader(device, stages, options);
|
||||
}
|
||||
|
||||
love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
Access access;
|
||||
};
|
||||
|
||||
Shader(id<MTLDevice> device, StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]);
|
||||
Shader(id<MTLDevice> device, StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const CompileOptions &options);
|
||||
virtual ~Shader();
|
||||
|
||||
// Implements Shader.
|
||||
|
||||
@@ -249,8 +249,8 @@ static EShLanguage getGLSLangStage(ShaderStageType stage)
|
||||
return EShLangCount;
|
||||
}
|
||||
|
||||
Shader::Shader(id<MTLDevice> device, StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
|
||||
: love::graphics::Shader(stages)
|
||||
Shader::Shader(id<MTLDevice> device, StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const CompileOptions &options)
|
||||
: love::graphics::Shader(stages, options)
|
||||
, functions()
|
||||
, builtinUniformInfo()
|
||||
, localUniformStagingData(nullptr)
|
||||
@@ -759,6 +759,10 @@ void Shader::compileFromGLSLang(id<MTLDevice> device, const glslang::TProgram &p
|
||||
|
||||
functions[stageindex] = [library newFunctionWithName:library.functionNames[0]];
|
||||
|
||||
std::string debugname = getShaderStageDebugName((ShaderStageType)stageindex);
|
||||
if (!debugname.empty())
|
||||
functions[stageindex].label = @(debugname.c_str());
|
||||
|
||||
auto setTextureBinding = [this](CompilerMSL &msl, int stageindex, const spirv_cross::Resource &resource) -> void
|
||||
{
|
||||
auto it = uniforms.find(resource.name);
|
||||
|
||||
@@ -168,9 +168,9 @@ love::graphics::ShaderStage *Graphics::newShaderStageInternal(ShaderStageType st
|
||||
return new ShaderStage(this, stage, source, gles, cachekey);
|
||||
}
|
||||
|
||||
love::graphics::Shader *Graphics::newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
|
||||
love::graphics::Shader *Graphics::newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options)
|
||||
{
|
||||
return new Shader(stages);
|
||||
return new Shader(stages, options);
|
||||
}
|
||||
|
||||
love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
|
||||
|
||||
@@ -139,7 +139,7 @@ private:
|
||||
};
|
||||
|
||||
love::graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
|
||||
love::graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
|
||||
love::graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options) override;
|
||||
love::graphics::StreamBuffer *newStreamBuffer(BufferUsage type, size_t size) override;
|
||||
|
||||
love::graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) override;
|
||||
|
||||
@@ -43,8 +43,8 @@ static bool isBuffer(Shader::UniformType utype)
|
||||
return utype == Shader::UNIFORM_TEXELBUFFER || utype == Shader::UNIFORM_STORAGEBUFFER;
|
||||
}
|
||||
|
||||
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
|
||||
: love::graphics::Shader(stages)
|
||||
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const CompileOptions &options)
|
||||
: love::graphics::Shader(stages, options)
|
||||
, program(0)
|
||||
, splitUniformsPerDraw(false)
|
||||
, builtinUniforms()
|
||||
@@ -512,6 +512,9 @@ bool Shader::loadVolatile()
|
||||
if (program == 0)
|
||||
throw love::Exception("Cannot create shader program object.");
|
||||
|
||||
if (!debugName.empty() && (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_2))
|
||||
glObjectLabel(GL_PROGRAM, program, -1, debugName.c_str());
|
||||
|
||||
for (const auto &stage : stages)
|
||||
{
|
||||
if (stage.get() != nullptr)
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
GLenum internalFormat;
|
||||
};
|
||||
|
||||
Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]);
|
||||
Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const CompileOptions &options);
|
||||
virtual ~Shader();
|
||||
|
||||
// Implements Volatile
|
||||
|
||||
@@ -1150,9 +1150,9 @@ graphics::ShaderStage *Graphics::newShaderStageInternal(ShaderStageType stage, c
|
||||
return new ShaderStage(this, stage, source, gles, cachekey);
|
||||
}
|
||||
|
||||
graphics::Shader *Graphics::newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
|
||||
graphics::Shader *Graphics::newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options)
|
||||
{
|
||||
return new Shader(stages);
|
||||
return new Shader(stages, options);
|
||||
}
|
||||
|
||||
graphics::StreamBuffer *Graphics::newStreamBuffer(BufferUsage type, size_t size)
|
||||
|
||||
@@ -328,7 +328,7 @@ public:
|
||||
|
||||
protected:
|
||||
graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
|
||||
graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
|
||||
graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options) override;
|
||||
graphics::StreamBuffer *newStreamBuffer(BufferUsage type, size_t size) override;
|
||||
bool dispatch(love::graphics::Shader *shader, int x, int y, int z) override;
|
||||
bool dispatch(love::graphics::Shader *shader, love::graphics::Buffer *indirectargs, size_t argsoffset) override;
|
||||
|
||||
@@ -241,8 +241,8 @@ static bool usesLocalUniformData(const graphics::Shader::UniformInfo *info)
|
||||
info->baseType == graphics::Shader::UNIFORM_UINT;
|
||||
}
|
||||
|
||||
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[])
|
||||
: graphics::Shader(stages)
|
||||
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[], const CompileOptions &options)
|
||||
: graphics::Shader(stages, options)
|
||||
{
|
||||
auto gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
|
||||
vgfx = dynamic_cast<Graphics*>(gfx);
|
||||
@@ -949,6 +949,19 @@ void Shader::compileShaders()
|
||||
if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS)
|
||||
throw love::Exception("failed to create shader module");
|
||||
|
||||
std::string debugname = getShaderStageDebugName(shaderStage);
|
||||
if (!debugname.empty() && vgfx->getEnabledOptionalInstanceExtensions().debugInfo)
|
||||
{
|
||||
auto device = vgfx->getDevice();
|
||||
|
||||
VkDebugUtilsObjectNameInfoEXT nameInfo{};
|
||||
nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
|
||||
nameInfo.objectType = VK_OBJECT_TYPE_SHADER_MODULE;
|
||||
nameInfo.objectHandle = (uint64_t)shaderModule;
|
||||
nameInfo.pObjectName = debugname.c_str();
|
||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||
}
|
||||
|
||||
shaderModules.push_back(shaderModule);
|
||||
|
||||
VkPipelineShaderStageCreateInfo shaderStageInfo{};
|
||||
|
||||
@@ -52,7 +52,7 @@ class Shader final
|
||||
, public Volatile
|
||||
{
|
||||
public:
|
||||
Shader(StrongRef<love::graphics::ShaderStage> stages[]);
|
||||
Shader(StrongRef<love::graphics::ShaderStage> stages[], const CompileOptions &options);
|
||||
virtual ~Shader();
|
||||
|
||||
bool loadVolatile() override;
|
||||
|
||||
@@ -1463,6 +1463,11 @@ static int w_getShaderSource(lua_State *L, int startidx, std::vector<std::string
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, optionsidx, "debugname");
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
options.debugName = luax_checkstring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -517,6 +517,17 @@ int w_Shader_getLocalThreadgroupSize(lua_State* L)
|
||||
return 3;
|
||||
}
|
||||
|
||||
int w_Shader_getDebugName(lua_State *L)
|
||||
{
|
||||
Shader *shader = luax_checkshader(L, 1);
|
||||
const std::string &debugName = shader->getDebugName();
|
||||
if (debugName.empty())
|
||||
lua_pushnil(L);
|
||||
else
|
||||
luax_pushstring(L, debugName);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg w_Shader_functions[] =
|
||||
{
|
||||
{ "getWarnings", w_Shader_getWarnings },
|
||||
@@ -525,6 +536,7 @@ static const luaL_Reg w_Shader_functions[] =
|
||||
{ "hasUniform", w_Shader_hasUniform },
|
||||
{ "hasStage", w_Shader_hasStage },
|
||||
{ "getLocalThreadgroupSize", w_Shader_getLocalThreadgroupSize },
|
||||
{ "getDebugName", w_Shader_getDebugName },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -710,11 +710,12 @@ love.test.graphics.Shader = function(test)
|
||||
return transform_projection * vertex_position;
|
||||
}
|
||||
]]
|
||||
local shader1 = love.graphics.newShader(pixelcode1, vertexcode1)
|
||||
local shader1 = love.graphics.newShader(pixelcode1, vertexcode1, {debugname = 'testshader'})
|
||||
test:assertObject(shader1)
|
||||
test:assertEquals('vertex shader:\npixel shader:\n', shader1:getWarnings(), 'check shader valid')
|
||||
test:assertFalse(shader1:hasUniform('tex1'), 'check invalid uniform')
|
||||
test:assertTrue(shader1:hasUniform('tex2'), 'check valid uniform')
|
||||
test:assertEquals('testshader', shader1:getDebugName())
|
||||
|
||||
-- check invalid shader
|
||||
local pixelcode2 = [[
|
||||
|
||||
Reference in New Issue
Block a user