fix: alot of stuff changed. Mostly bugfixxes / architechture changes

This commit is contained in:
2026-08-09 02:24:17 +02:00
parent 4b6f773c0c
commit 05384debbf
98 changed files with 5461 additions and 1751 deletions
+80 -15
View File
@@ -4,36 +4,58 @@
#include <destrum/Graphics/Util.h>
#include "spdlog/spdlog.h"
#include <algorithm>
#include <string>
#include <stdexcept>
void MaterialCache::init(
GfxDevice& gfxDevice,
MaterialDefaultTextures defaults)
{
defaultTextures = defaults;
try {
defaultTextures = defaults;
device = &gfxDevice;
materialDataBuffer = gfxDevice.createBuffer(
MAX_MATERIALS * sizeof(MaterialData),
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
materialDataBuffer = gfxDevice.createBuffer(
MAX_MATERIALS * sizeof(MaterialData),
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_CPU_TO_GPU);
vkutil::addDebugLabel(
gfxDevice.getDevice(),
materialDataBuffer.buffer,
"material data");
vkutil::addDebugLabel(
gfxDevice.getDevice(),
materialDataBuffer.buffer,
"material data");
Material placeholderMaterial{};
placeholderMaterial.name = "PLACEHOLDER_MATERIAL";
placeholderMaterial.diffuseTexture = defaultTextures.white;
Material placeholderMaterial{};
placeholderMaterial.name = "PLACEHOLDER_MATERIAL";
placeholderMaterial.diffuseTexture = defaultTextures.white;
placeholderMaterialId = addMaterial(placeholderMaterial);
placeholderMaterialId = addMaterial(placeholderMaterial);
gfxDevice.getMemoryManager().flushAllocation(materialDataBuffer);
} catch (...) {
cleanup(gfxDevice);
throw;
}
}
void MaterialCache::cleanup(GfxDevice& gfxDevice)
{
gfxDevice.destroyBuffer(materialDataBuffer);
materialDataBuffer = {};
materials.clear();
materialKeys.clear();
placeholderMaterialId = NULL_MATERIAL_ID;
device = nullptr;
}
MaterialID MaterialCache::addMaterial(Material material)
{
if (!materials.empty() && device != nullptr) {
// The material buffer is shared by all in-flight frames. A newly
// appended entry may be written while an older frame is reading it.
device->waitIdle();
}
const auto getTextureOrElse = [](ImageID imageId, ImageID placeholder)
{
return imageId != NULL_IMAGE_ID ? imageId : placeholder;
@@ -42,7 +64,12 @@ MaterialID MaterialCache::addMaterial(Material material)
MaterialData* data = static_cast<MaterialData*>(materialDataBuffer.info.pMappedData);
const auto id = getFreeMaterialId();
assert(id < MAX_MATERIALS);
if (id >= MAX_MATERIALS) {
throw std::runtime_error("MaterialCache capacity exhausted");
}
if (data == nullptr) {
throw std::runtime_error("MaterialCache material buffer is not mapped");
}
data[id] = MaterialData{
.baseColor = glm::vec4(material.baseColor, 1.0f),
@@ -66,10 +93,30 @@ MaterialID MaterialCache::addMaterial(Material material)
.emissiveTex = defaultTextures.emissive,
};
device->getMemoryManager().flushAllocation(
materialDataBuffer,
static_cast<VkDeviceSize>(id) * sizeof(MaterialData),
sizeof(MaterialData));
// The caller may update multiple materials in one frame; the range flush is
// cheap for coherent allocations and required for non-coherent memory.
// The cache does not own a device reference, so the renderer flushes the
// exact range after batching updates.
const auto materialId = static_cast<MaterialID>(materials.size());
std::string key = material.name.empty()
? "material:" + std::to_string(materialId)
: material.name;
const std::string baseKey = key;
std::size_t suffix = 1;
while (std::find(materialKeys.begin(), materialKeys.end(), key) != materialKeys.end()) {
key = baseKey + "#" + std::to_string(suffix++);
}
materials.push_back(std::move(material));
materialKeys.push_back(std::move(key));
return id;
return materialId;
}
MaterialID MaterialCache::addSimpleTextureMaterial(ImageID textureID)
@@ -88,9 +135,23 @@ const Material& MaterialCache::getMaterial(MaterialID id) const
return materials.at(id);
}
const std::string& MaterialCache::getMaterialKey(MaterialID id) const
{
return materialKeys.at(id);
}
std::optional<MaterialID> MaterialCache::findMaterialByKey(std::string_view key) const
{
const auto it = std::find(materialKeys.begin(), materialKeys.end(), key);
if (it == materialKeys.end()) {
return std::nullopt;
}
return static_cast<MaterialID>(std::distance(materialKeys.begin(), it));
}
MaterialID MaterialCache::getFreeMaterialId() const
{
return materials.size();
return static_cast<MaterialID>(materials.size());
}
MaterialID MaterialCache::getPlaceholderMaterialId() const
@@ -136,4 +197,8 @@ void MaterialCache::updateMaterialGPU(MaterialID id)
.metallicRoughnessTex = defaultTextures.metallicRoughness,
.emissiveTex = defaultTextures.emissive,
};
device->getMemoryManager().flushAllocation(
materialDataBuffer,
static_cast<VkDeviceSize>(id) * sizeof(MaterialData),
sizeof(MaterialData));
}