Adding bindless material descriptors

This commit is contained in:
Dynamitos
2024-06-18 19:19:05 +02:00
parent cff14981ff
commit f6ebbc2067
23 changed files with 387 additions and 274 deletions
+10 -42
View File
@@ -44,14 +44,13 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) {
json j;
jsonstream >> j;
std::string materialName = j["name"].get<std::string>() + "Material";
Gfx::ODescriptorLayout layout = graphics->createDescriptorLayout("pMaterial");
// Shader file needs to conform to the slang standard, which prohibits _
materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end());
materialName.erase(std::remove(materialName.begin(), materialName.end(), '-'), materialName.end());
uint32 uniformBufferOffset = 0;
uint32 bindingCounter = 0; // Uniform buffers are always binding 0
int32 uniformBinding = -1;
uint32 numTextures = 0;
uint32 numSamplers = 0;
uint32 numFloats = 0;
Array<OShaderExpression> expressions;
uint32 key = 0;
uint32 auxKey = 0;
@@ -59,39 +58,22 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) {
for (auto& param : j["params"].items()) {
std::string type = param.value()["type"].get<std::string>();
auto defaultValue = param.value().find("default");
// TODO: ALIGNMENT RULES
if (type.compare("float") == 0) {
float defaultData = 0.f;
if (defaultValue != param.value().end()) {
defaultData = std::stof(defaultValue.value().get<std::string>());
}
OFloatParameter p = new FloatParameter(param.key(), defaultData, uniformBufferOffset, uniformBinding);
if (uniformBinding == -1) {
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = bindingCounter,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
});
uniformBinding = bindingCounter++;
}
uniformBufferOffset += 4;
OFloatParameter p = new FloatParameter(param.key(), defaultData, numFloats++);
parameters.add(p->key);
expressions.add(std::move(p));
}
// TODO: ALIGNMENT RULES
else if (type.compare("float3") == 0) {
Vector defaultData = Vector(0, 0, 0);
if (defaultValue != param.value().end()) {
defaultData = parseVector(defaultValue.value().get<std::string>().c_str());
}
OVectorParameter p = new VectorParameter(param.key(), defaultData, uniformBufferOffset, uniformBinding);
if (uniformBinding == -1) {
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = bindingCounter,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
});
uniformBinding = bindingCounter++;
}
uniformBufferOffset += 16;
OVectorParameter p = new VectorParameter(param.key(), defaultData, numFloats);
numFloats += 3;
parameters.add(p->key);
expressions.add(std::move(p));
} else if (type.compare("Texture2D") == 0) {
@@ -110,19 +92,11 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) {
if (texture == nullptr) {
texture = AssetRegistry::findTexture("", ""); // this will return placeholder texture
}
OTextureParameter p = new TextureParameter(param.key(), texture, bindingCounter);
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = bindingCounter++,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
});
OTextureParameter p = new TextureParameter(param.key(), texture, numTextures++);
parameters.add(p->key);
expressions.add(std::move(p));
} else if (type.compare("Sampler") == 0) {
OSamplerParameter p = new SamplerParameter(param.key(), graphics->createSampler({}), bindingCounter);
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = bindingCounter++,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
});
OSamplerParameter p = new SamplerParameter(param.key(), graphics->createSampler({}), numSamplers++);
parameters.add(p->key);
expressions.add(std::move(p));
} else if (type.compare("Sampler2D") == 0) {
@@ -141,18 +115,13 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) {
if (texture == nullptr) {
texture = AssetRegistry::findTexture("", ""); // this will return placeholder texture
}
OCombinedTextureParameter p = new CombinedTextureParameter(param.key(), texture, graphics->createSampler({}), bindingCounter);
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = bindingCounter++,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
});
OCombinedTextureParameter p = new CombinedTextureParameter(param.key(), texture, graphics->createSampler({}), numTextures++);
parameters.add(p->key);
expressions.add(std::move(p));
} else {
std::cout << "Error unsupported parameter type" << std::endl;
}
}
uint32 uniformDataSize = uniformBufferOffset;
auto referenceExpression = [&parameters, &auxKey, &expressions](json obj) -> std::string {
if (obj.is_string()) {
std::string str = obj.get<std::string>();
@@ -233,8 +202,7 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) {
}
}
}
layout->create();
asset->material = new Material(graphics, std::move(layout), uniformDataSize, uniformBinding, materialName, std::move(expressions),
asset->material = new Material(graphics, numTextures, numSamplers, numFloats, materialName, std::move(expressions),
std::move(parameters), std::move(mat));
asset->material->compile();
+10 -35
View File
@@ -111,32 +111,23 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
materialName.end()); // dots break adding the .asset extension later
materialName.erase(std::remove(materialName.begin(), materialName.end(), ')'),
materialName.end()); // dots break adding the .asset extension later
Gfx::ODescriptorLayout materialLayout = graphics->createDescriptorLayout("pMaterial");
Array<OShaderExpression> expressions;
Array<std::string> parameters;
materialLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = 0,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.shaderStages = Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
});
size_t uniformSize = 0;
uint32 bindingCounter = 1;
uint32 numTextures = 0;
uint32 numSamplers = 0;
uint32 numFloats = 0;
auto addScalarParameter = [&](std::string paramKey, const char* matKey, int type, int index) {
float scalar;
material->Get(matKey, type, index, scalar);
expressions.add(new FloatParameter(paramKey, scalar, uniformSize, 0));
uniformSize += sizeof(float);
expressions.add(new FloatParameter(paramKey, scalar, numFloats++));
parameters.add(paramKey);
};
auto addVectorParameter = [&](std::string paramKey, const char* matKey, int type, int index) {
aiColor3D color;
material->Get(matKey, type, index, color);
uniformSize = (uniformSize + sizeof(Vector4) - 1) / sizeof(Vector4) * sizeof(Vector4);
expressions.add(new VectorParameter(paramKey, Vector(color.r, color.g, color.b), uniformSize, 0));
uniformSize += sizeof(Vector);
expressions.add(new VectorParameter(paramKey, Vector(color.r, color.g, color.b), numFloats));
numFloats += 3;
parameters.add(paramKey);
};
@@ -181,15 +172,8 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
std::cout << "couldnt find " << texPath.C_Str() << std::endl;
return;
}
expressions.add(new TextureParameter(textureKey, texture, bindingCounter));
materialLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = bindingCounter,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D,
.shaderStages = Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
});
expressions.add(new TextureParameter(textureKey, texture, numTextures++));
parameters.add(textureKey);
bindingCounter++;
std::string samplerKey = fmt::format("{0}Sampler{1}", paramKey, index);
SamplerCreateInfo samplerInfo = {};
@@ -215,14 +199,8 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
samplerInfo.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
break;
}
expressions.add(new SamplerParameter(samplerKey, graphics->createSampler(samplerInfo), bindingCounter));
materialLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = bindingCounter,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
.shaderStages = Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
});
expressions.add(new SamplerParameter(samplerKey, graphics->createSampler(samplerInfo), numSamplers++));
parameters.add(samplerKey);
bindingCounter++;
std::string sampleKey = fmt::format("{0}Sample{1}", paramKey, index);
expressions.add(new SampleExpression());
@@ -242,8 +220,7 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
return;
}
std::string blendFactorKey = fmt::format("{0}BlendFactor{1}", paramKey, index);
expressions.add(new FloatParameter(blendFactorKey, blend, uniformSize, 0));
uniformSize += sizeof(float);
expressions.add(new FloatParameter(blendFactorKey, blend, numFloats++));
parameters.add(blendFactorKey);
std::string strengthKey = fmt::format("{0}Strength{1}", paramKey, index);
@@ -396,10 +373,8 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
break;
};
materialLayout->create();
OMaterialAsset baseMat = new MaterialAsset(importPath, materialName);
baseMat->material = new Material(graphics, std::move(materialLayout), uniformSize, 0, materialName, std::move(expressions),
baseMat->material = new Material(graphics, numTextures, numSamplers, numFloats, materialName, std::move(expressions),
std::move(parameters), std::move(brdf));
baseMat->material->compile();
graphics->getShaderCompiler()->registerMaterial(baseMat->material);