mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
vulkan: uniforms in custom shaders
things like `uniform float time;` or `uniform sampler2D tex` now work
This commit is contained in:
@@ -322,6 +322,20 @@ int Shader::getVertexAttributeIndex(const std::string& name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Shader::UniformInfo* Shader::getUniformInfo(const std::string& name) const {
|
||||||
|
return &uniformInfos.at(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Shader::UniformInfo* Shader::getUniformInfo(BuiltinUniform builtin) const {
|
||||||
|
return builtinUniformInfo[builtin];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::sendTextures(const UniformInfo* info, graphics::Texture** textures, int count) {
|
||||||
|
for (unsigned i = 0; i < count; i++) {
|
||||||
|
info->textures[i] = textures[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Shader::calculateUniformBufferSizeAligned() {
|
void Shader::calculateUniformBufferSizeAligned() {
|
||||||
gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
|
gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
|
||||||
auto vgfx = (Graphics*)gfx;
|
auto vgfx = (Graphics*)gfx;
|
||||||
@@ -341,7 +355,7 @@ void Shader::buildLocalUniforms(spirv_cross::Compiler& comp, const spirv_cross::
|
|||||||
|
|
||||||
const auto& membertypes = type.member_types;
|
const auto& membertypes = type.member_types;
|
||||||
|
|
||||||
for (size_t uindex = 0; uindex < membertypes.size(); uindex) {
|
for (size_t uindex = 0; uindex < membertypes.size(); uindex++) {
|
||||||
const auto& memberType = comp.get_type(membertypes[uindex]);
|
const auto& memberType = comp.get_type(membertypes[uindex]);
|
||||||
size_t memberSize = comp.get_declared_struct_member_size(type, uindex);
|
size_t memberSize = comp.get_declared_struct_member_size(type, uindex);
|
||||||
size_t offset = baseoff + comp.type_struct_member_offset(type, uindex);
|
size_t offset = baseoff + comp.type_struct_member_offset(type, uindex);
|
||||||
@@ -361,7 +375,7 @@ void Shader::buildLocalUniforms(spirv_cross::Compiler& comp, const spirv_cross::
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformInfo u = {};
|
UniformInfo u{};
|
||||||
u.name = name;
|
u.name = name;
|
||||||
u.dataSize = memberSize;
|
u.dataSize = memberSize;
|
||||||
u.count = memberType.array.empty() ? 1 : memberType.array[0];
|
u.count = memberType.array.empty() ? 1 : memberType.array[0];
|
||||||
@@ -397,8 +411,6 @@ void Shader::buildLocalUniforms(spirv_cross::Compiler& comp, const spirv_cross::
|
|||||||
}
|
}
|
||||||
builtinUniformInfo[builtin] = &uniformInfos[u.name];
|
builtinUniformInfo[builtin] = &uniformInfos[u.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// update uniform.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,59 +521,18 @@ void Shader::compileShaders() {
|
|||||||
auto shaderResources = comp.get_shader_resources(active);
|
auto shaderResources = comp.get_shader_resources(active);
|
||||||
comp.set_enabled_interface_variables(std::move(active));
|
comp.set_enabled_interface_variables(std::move(active));
|
||||||
|
|
||||||
std::string builtinUniformName = "love_UniformsPerDraw";
|
|
||||||
|
|
||||||
for (const auto& resource : shaderResources.uniform_buffers) {
|
for (const auto& resource : shaderResources.uniform_buffers) {
|
||||||
size_t uniformBufferObjectSize = comp.get_declared_struct_size(comp.get_type(resource.base_type_id));
|
if (resource.name == "gl_DefaultUniformBlock") {
|
||||||
|
const auto& type = comp.get_type(resource.base_type_id);
|
||||||
const auto& resourceType = comp.get_type(resource.type_id);
|
size_t uniformBufferObjectSize = comp.get_declared_struct_size(type);
|
||||||
unsigned memberCount = resourceType.member_types.size();
|
|
||||||
for (unsigned i = 0; i < memberCount; i++) {
|
|
||||||
auto& type = comp.get_type(resourceType.member_types[i]);
|
|
||||||
auto baseType = type.basetype;
|
|
||||||
const std::string& name = comp.get_member_name(resourceType.self, i);
|
|
||||||
|
|
||||||
if (name == "gl_DefaultUniformBlock") {
|
|
||||||
auto defaultUniformBlockSize = comp.get_declared_struct_size(type);
|
auto defaultUniformBlockSize = comp.get_declared_struct_size(type);
|
||||||
localUniformStagingData.resize(defaultUniformBlockSize);
|
localUniformStagingData.resize(defaultUniformBlockSize);
|
||||||
|
|
||||||
|
memset(localUniformStagingData.data(), 0, defaultUniformBlockSize);
|
||||||
|
|
||||||
std::string basename("");
|
std::string basename("");
|
||||||
buildLocalUniforms(comp, type, 0, basename);
|
buildLocalUniforms(comp, type, 0, basename);
|
||||||
}
|
}
|
||||||
else if (name == builtinUniformName) {
|
|
||||||
UniformInfo u{};
|
|
||||||
u.name = name;
|
|
||||||
u.dataSize = sizeof(BuiltinUniformData);
|
|
||||||
|
|
||||||
localUniformStagingData.resize(u.dataSize);
|
|
||||||
builtinUniformDataOffset = 0;
|
|
||||||
|
|
||||||
u.count = type.array.empty() ? 1 : type.array[0];
|
|
||||||
u.components = 1;
|
|
||||||
u.data = localUniformStagingData.data();
|
|
||||||
|
|
||||||
if (type.columns == 1) {
|
|
||||||
if (type.basetype == SPIRType::Int) {
|
|
||||||
u.baseType = UNIFORM_INT;
|
|
||||||
}
|
|
||||||
else if (type.basetype == SPIRType::UInt) {
|
|
||||||
u.baseType = UNIFORM_UINT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
u.baseType = UNIFORM_FLOAT;
|
|
||||||
}
|
|
||||||
u.components = type.vecsize;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
u.baseType = UNIFORM_MATRIX;
|
|
||||||
u.matrix.rows = type.vecsize;
|
|
||||||
u.matrix.columns = type.columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
uniformInfos[u.name] = u;
|
|
||||||
|
|
||||||
builtinUniformInfo[BUILTIN_UNIFORMS_PER_DRAW] = &uniformInfos[u.name];
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
throw love::Exception("unimplemented: non default uniform blocks.");
|
throw love::Exception("unimplemented: non default uniform blocks.");
|
||||||
}
|
}
|
||||||
@@ -634,7 +605,6 @@ void Shader::compileShaders() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
delete program;
|
delete program;
|
||||||
for (auto shader : glslangShaders) {
|
for (auto shader : glslangShaders) {
|
||||||
@@ -704,6 +674,10 @@ void Shader::setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Shader::hasUniform(const std::string& name) const {
|
||||||
|
return uniformInfos.find(name) != uniformInfos.end();
|
||||||
|
}
|
||||||
|
|
||||||
void Shader::setUniformData(BuiltinUniformData& data) {
|
void Shader::setUniformData(BuiltinUniformData& data) {
|
||||||
char* ptr = (char*) builtinUniformInfo[BUILTIN_UNIFORMS_PER_DRAW]->data + builtinUniformDataOffset;
|
char* ptr = (char*) builtinUniformInfo[BUILTIN_UNIFORMS_PER_DRAW]->data + builtinUniformDataOffset;
|
||||||
memcpy(ptr, &data, sizeof(BuiltinUniformData));
|
memcpy(ptr, &data, sizeof(BuiltinUniformData));
|
||||||
|
|||||||
@@ -39,18 +39,18 @@ public:
|
|||||||
|
|
||||||
int getVertexAttributeIndex(const std::string& name) override;
|
int getVertexAttributeIndex(const std::string& name) override;
|
||||||
|
|
||||||
const UniformInfo* getUniformInfo(const std::string& name) const override { return nullptr; }
|
const UniformInfo* getUniformInfo(const std::string& name) const override;
|
||||||
const UniformInfo* getUniformInfo(BuiltinUniform builtin) const override { return nullptr; }
|
const UniformInfo* getUniformInfo(BuiltinUniform builtin) const override;
|
||||||
|
|
||||||
// Not needed right now, since the logic that links the values of the uniforms to the shader is done in cmdPushDescriptorSets
|
// Not needed right now, since the logic that links the values of the uniforms to the shader is done in cmdPushDescriptorSets
|
||||||
// which gets called from the vulkan::Graphics class whenever a draw call happens.
|
// which gets called from the vulkan::Graphics class whenever a draw call happens.
|
||||||
// I'll have to reevaluate the use of this function in the future though.
|
// I'll have to reevaluate the use of this function in the future though.
|
||||||
void updateUniform(const UniformInfo* info, int count) override {}
|
void updateUniform(const UniformInfo* info, int count) override {}
|
||||||
|
|
||||||
void sendTextures(const UniformInfo* info, graphics::Texture** textures, int count) override {}
|
void sendTextures(const UniformInfo* info, graphics::Texture** textures, int count) override;
|
||||||
void sendBuffers(const UniformInfo* info, love::graphics::Buffer** buffers, int count) override {}
|
void sendBuffers(const UniformInfo* info, love::graphics::Buffer** buffers, int count) override {}
|
||||||
|
|
||||||
bool hasUniform(const std::string& name) const override { return false; }
|
bool hasUniform(const std::string& name) const override;
|
||||||
|
|
||||||
void setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cbtexture, graphics::Texture* crtexture) override;
|
void setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cbtexture, graphics::Texture* crtexture) override;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user