Fixing command resource binding

This commit is contained in:
Dynamitos
2025-09-05 07:10:27 +02:00
parent 5be15b4929
commit e97beda2bc
13 changed files with 73 additions and 57 deletions
+1 -1
View File
@@ -253,7 +253,7 @@ float2 integrateBRDF(float nDotV, float roughness) {
} }
[shader("pixel")] [shader("pixel")]
float2 precomputeBRDF(float2 texCoords) : SV_Target float2 precomputeBRDF(float2 texCoords : UV) : SV_Target
{ {
return integrateBRDF(texCoords.x, texCoords.y); return integrateBRDF(texCoords.x, texCoords.y);
} }
+1
View File
@@ -95,6 +95,7 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
{"precomputeBRDF", "EnvironmentMapping"}, {"precomputeBRDF", "EnvironmentMapping"},
}, },
.rootSignature = cubePipelineLayout, .rootSignature = cubePipelineLayout,
.dumpIntermediate = true,
}); });
cubePipelineLayout->create(); cubePipelineLayout->create();
+2 -2
View File
@@ -24,8 +24,8 @@ static Gfx::OGraphics graphics;
int main() { int main() {
std::string gameName = "MeshShadingDemo"; std::string gameName = "MeshShadingDemo";
std::filesystem::path outputPath = fmt::format("/home/dynamitos/{0}Game/", gameName); std::filesystem::path outputPath = fmt::format("/Users/dynamitos/{0}Game/", gameName);
std::filesystem::path sourcePath = fmt::format("/home/dynamitos/{0}/", gameName); std::filesystem::path sourcePath = fmt::format("/Users/dynamitos/{0}/", gameName);
#ifdef WIN32 #ifdef WIN32
std::string libraryEnding = "dll"; std::string libraryEnding = "dll";
#elif __APPLE__ #elif __APPLE__
+8 -1
View File
@@ -62,7 +62,7 @@ class DescriptorSet {
virtual void updateConstants(const std::string& name, uint32 offset, void* data) = 0; virtual void updateConstants(const std::string& name, uint32 offset, void* data) = 0;
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) = 0; virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) = 0;
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer vertexBuffer) = 0; virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer vertexBuffer) = 0;
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0;\ virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0;
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) = 0; virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) = 0;
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0; virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0;
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) = 0; virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) = 0;
@@ -93,6 +93,13 @@ class PipelineLayout {
constexpr std::string getName() const { return name; }; constexpr std::string getName() const { return name; };
constexpr bool hasPushConstants() const { return !pushConstants.empty(); } constexpr bool hasPushConstants() const { return !pushConstants.empty(); }
constexpr uint64 getPushConstantsSize() const { return pushConstants[0].size; } constexpr uint64 getPushConstantsSize() const { return pushConstants[0].size; }
constexpr const std::string& getPushConstantName(uint64 offset) {
for (uint32 i = 0; i < pushConstants.size(); ++i) {
if (offset == pushConstants[i].offset)
return pushConstants[i].name;
}
throw std::logic_error("unknown push constant offset");
}
protected: protected:
uint32 layoutHash = 0; uint32 layoutHash = 0;
+1 -1
View File
@@ -12,7 +12,7 @@ using namespace Seele;
using namespace Seele::Metal; using namespace Seele::Metal;
BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, uint64 size, MTL::ResourceOptions options) BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, uint64 size, MTL::ResourceOptions options)
: CommandBoundResource(graphics) { : CommandBoundResource(graphics, name) {
buffer = graphics->getDevice()->newBuffer(size, options); buffer = graphics->getDevice()->newBuffer(size, options);
buffer->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding)); buffer->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
} }
+8 -8
View File
@@ -147,7 +147,7 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
createEncoder(boundPipeline->vertexFunction, boundPipeline->vertexSets); createEncoder(boundPipeline->vertexFunction, boundPipeline->vertexSets);
createEncoder(boundPipeline->fragmentFunction, boundPipeline->fragmentSets); createEncoder(boundPipeline->fragmentFunction, boundPipeline->fragmentSets);
if(setHandle->argumentBuffer == nullptr) { if(setHandle->argumentBuffer == nullptr) {
setHandle->argumentBuffer = new BufferAllocation(setHandle->graphics, "ArgumentBuffer", setHandle->encoder->encodedLength()); setHandle->argumentBuffer = new BufferAllocation(metalSet->graphics, "ArgumentBuffer", setHandle->encoder->encodedLength());
setHandle->encoder->setArgumentBuffer(setHandle->argumentBuffer->buffer, 0); setHandle->encoder->setArgumentBuffer(setHandle->argumentBuffer->buffer, 0);
} }
setHandle->argumentBuffer->bind(); setHandle->argumentBuffer->bind();
@@ -198,18 +198,18 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) {
} }
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) { void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) {
uint pushIndex = boundPipeline->getPipelineLayout()->findParameter("pOffsets"); uint pushIndex = boundPipeline->getPipelineLayout()->findParameter(boundPipeline->getPipelineLayout()->getPushConstantName(offset));
if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) { if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) {
encoder->setVertexBytes(data, size, pushIndex); // TODO: hardcoded encoder->setVertexBytes(data, size, pushIndex);
} }
if (stage & Gfx::SE_SHADER_STAGE_FRAGMENT_BIT) { if (stage & Gfx::SE_SHADER_STAGE_FRAGMENT_BIT) {
encoder->setFragmentBytes(data, size, pushIndex); // TODO: hardcoded encoder->setFragmentBytes(data, size, pushIndex);
} }
if (stage & Gfx::SE_SHADER_STAGE_TASK_BIT_EXT) { if (stage & Gfx::SE_SHADER_STAGE_TASK_BIT_EXT) {
encoder->setObjectBytes(data, size, pushIndex); // TODO: hardcoded encoder->setObjectBytes(data, size, pushIndex);
} }
if (stage & Gfx::SE_SHADER_STAGE_MESH_BIT_EXT) { if (stage & Gfx::SE_SHADER_STAGE_MESH_BIT_EXT) {
encoder->setMeshBytes(data, size, pushIndex); // TODO: hardcoded encoder->setMeshBytes(data, size, pushIndex);
} }
} }
@@ -271,7 +271,7 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
}; };
createEncoder(boundPipeline->computeFunction); createEncoder(boundPipeline->computeFunction);
if(setHandle->argumentBuffer == nullptr) { if(setHandle->argumentBuffer == nullptr) {
setHandle->argumentBuffer = new BufferAllocation(setHandle->graphics, "ArgumentBuffer", setHandle->encoder->encodedLength()); setHandle->argumentBuffer = new BufferAllocation(metalSet->graphics, "ArgumentBuffer", setHandle->encoder->encodedLength());
setHandle->encoder->setArgumentBuffer(setHandle->argumentBuffer->buffer, 0); setHandle->encoder->setArgumentBuffer(setHandle->argumentBuffer->buffer, 0);
} }
setHandle->argumentBuffer->bind(); setHandle->argumentBuffer->bind();
@@ -366,6 +366,7 @@ void CommandQueue::submitCommands(PEvent signalSemaphore) {
for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) { for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) {
if ((*it)->getHandle() == cmdBuffer) { if ((*it)->getHandle() == cmdBuffer) {
auto& cmd = *it; auto& cmd = *it;
std::cout << "Command completed" << std::endl;
cmd->reset(); cmd->reset();
readyCommands.add(std::move(*it)); readyCommands.add(std::move(*it));
pendingCommands.erase(it); pendingCommands.erase(it);
@@ -375,7 +376,6 @@ void CommandQueue::submitCommands(PEvent signalSemaphore) {
})); }));
PEvent prevCmdEvent = activeCommand->getCompletedEvent(); PEvent prevCmdEvent = activeCommand->getCompletedEvent();
activeCommand->end(signalSemaphore); activeCommand->end(signalSemaphore);
activeCommand->waitDeviceIdle();
pendingCommands.add(std::move(activeCommand)); pendingCommands.add(std::move(activeCommand));
if (!readyCommands.empty()) { if (!readyCommands.empty()) {
activeCommand = std::move(readyCommands.front()); activeCommand = std::move(readyCommands.front());
-1
View File
@@ -58,7 +58,6 @@ public:
void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture); void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture);
void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as); void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as);
PGraphics graphics;
PDescriptorPool owner; PDescriptorPool owner;
OBufferAllocation argumentBuffer = nullptr; OBufferAllocation argumentBuffer = nullptr;
MTL::ArgumentEncoder* encoder = nullptr; MTL::ArgumentEncoder* encoder = nullptr;
+2 -1
View File
@@ -59,7 +59,7 @@ void DescriptorLayout::create() {
MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); } MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); }
DescriptorSetHandle::DescriptorSetHandle(PGraphics graphics, PDescriptorPool owner, const std::string& name) DescriptorSetHandle::DescriptorSetHandle(PGraphics graphics, PDescriptorPool owner, const std::string& name)
: CommandBoundResource(graphics), owner(owner) : CommandBoundResource(graphics, name), owner(owner)
{ {
} }
@@ -143,6 +143,7 @@ void DescriptorSetHandle::updateTexture(const std::string& name, uint32 index, G
.access = owner->getLayout()->variableMapping[name].access, .access = owner->getLayout()->variableMapping[name].access,
}); });
boundResources.add(tex); boundResources.add(tex);
boundResources.add(tex->getSource());
} }
void DescriptorSetHandle::updateAccelerationStructure(const std::string& , uint32 , Gfx::PTopLevelAS ){} void DescriptorSetHandle::updateAccelerationStructure(const std::string& , uint32 , Gfx::PTopLevelAS ){}
+4 -4
View File
@@ -56,17 +56,17 @@ void RenderPass::updateRenderPass() {
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) { for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
const auto& color = layout.colorAttachments[i]; const auto& color = layout.colorAttachments[i];
auto desc = renderPass->colorAttachments()->object(i); auto desc = renderPass->colorAttachments()->object(i);
desc->setTexture(color.getTextureView().cast<TextureBase>()->getImage()); desc->setTexture(color.getTextureView().cast<TextureView>()->getHandle());
if (!layout.resolveAttachments.empty()) { if (!layout.resolveAttachments.empty()) {
const auto& resolve = layout.resolveAttachments[i]; const auto& resolve = layout.resolveAttachments[i];
desc->setResolveTexture(resolve.getTextureView().cast<TextureBase>()->getImage()); desc->setResolveTexture(resolve.getTextureView().cast<TextureView>()->getHandle());
} }
} }
if (layout.depthAttachment.getTextureView() != nullptr) { if (layout.depthAttachment.getTextureView() != nullptr) {
auto depth = renderPass->depthAttachment(); auto depth = renderPass->depthAttachment();
depth->setTexture(layout.depthAttachment.getTextureView().cast<TextureBase>()->getImage()); depth->setTexture(layout.depthAttachment.getTextureView().cast<TextureView>()->getHandle());
if (layout.depthResolveAttachment.getTextureView() != nullptr) { if (layout.depthResolveAttachment.getTextureView() != nullptr) {
depth->setResolveTexture(layout.depthResolveAttachment.getTextureView().cast<TextureBase>()->getImage()); depth->setResolveTexture(layout.depthResolveAttachment.getTextureView().cast<TextureView>()->getHandle());
} }
} }
} }
+12 -3
View File
@@ -5,6 +5,7 @@
#include <Foundation/Foundation.hpp> #include <Foundation/Foundation.hpp>
#include <Metal/Metal.hpp> #include <Metal/Metal.hpp>
#include <QuartzCore/QuartzCore.hpp> #include <QuartzCore/QuartzCore.hpp>
#include <iostream>
namespace Seele { namespace Seele {
namespace Metal { namespace Metal {
@@ -26,17 +27,25 @@ DEFINE_REF(DestructionManager)
class CommandBoundResource { class CommandBoundResource {
public: public:
CommandBoundResource(PGraphics graphics) : graphics(graphics) {} CommandBoundResource(PGraphics graphics, const std::string& name) : graphics(graphics), name(name) {}
virtual ~CommandBoundResource() { virtual ~CommandBoundResource() {
if (isCurrentlyBound()) if (isCurrentlyBound())
abort(); abort();
} }
constexpr bool isCurrentlyBound() const { return bindCount > 0; } constexpr bool isCurrentlyBound() const { return bindCount > 0; }
constexpr void bind() { bindCount++; } void bind() { bindCount++;
constexpr void unbind() { bindCount--; } std::cout << "Bind " << bindCount << " " << name << std::endl;
}
void unbind() { bindCount--;
std::cout << "Unbind " << bindCount << " " << name << std::endl;
}
const std::string& getName() const {
return name;
}
protected: protected:
PGraphics graphics; PGraphics graphics;
std::string name;
uint64 bindCount = 0; uint64 bindCount = 0;
}; };
DEFINE_REF(CommandBoundResource) DEFINE_REF(CommandBoundResource)
+11 -4
View File
@@ -13,7 +13,7 @@ using namespace Seele;
using namespace Seele::Metal; using namespace Seele::Metal;
TextureView::TextureView(PGraphics graphics, PTextureHandle source, uint32 width, uint32 height, uint32 numLayers, uint32 numMipLevels, MTL::Texture* view) TextureView::TextureView(PGraphics graphics, PTextureHandle source, uint32 width, uint32 height, uint32 numLayers, uint32 numMipLevels, MTL::Texture* view)
: CommandBoundResource(graphics), width(width), height(height), numLayers(numLayers), numMipLevels(numMipLevels), source(source), view(view) {} : CommandBoundResource(graphics, source->getName()), width(width), height(height), numLayers(numLayers), numMipLevels(numMipLevels), source(source), view(view) {}
TextureView::~TextureView() {} TextureView::~TextureView() {}
@@ -43,15 +43,22 @@ void TextureView::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags
Gfx::OTextureView TextureHandle::createTextureView(uint32 baseMipLevel, uint32 viewLevelCount, uint32 baseArrayLayer, Gfx::OTextureView TextureHandle::createTextureView(uint32 baseMipLevel, uint32 viewLevelCount, uint32 baseArrayLayer,
uint32 viewLayerCount) { uint32 viewLayerCount) {
MTL::Texture* viewTexture = MTL::Texture* viewTexture;
texture->newTextureView(cast(format), type, NS::Range(baseMipLevel, viewLevelCount), NS::Range(baseArrayLayer, viewLayerCount)); if(viewLevelCount > 1)
{
viewTexture = texture->newTextureView(cast(format), type, NS::Range(baseMipLevel, viewLevelCount), NS::Range(baseArrayLayer, viewLayerCount));
}
else
{
viewTexture = texture->newTextureView(cast(format));
}
uint32 viewWidth = width * std::pow(0.5, baseMipLevel); uint32 viewWidth = width * std::pow(0.5, baseMipLevel);
uint32 viewHeight = height * std::pow(0.5, baseMipLevel); uint32 viewHeight = height * std::pow(0.5, baseMipLevel);
return new TextureView(graphics, this, viewWidth, viewHeight, viewLayerCount, viewLevelCount, viewTexture); return new TextureView(graphics, this, viewWidth, viewHeight, viewLayerCount, viewLevelCount, viewTexture);
} }
TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage) TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
: CommandBoundResource(graphics), texture(existingImage), type(type), width(createInfo.width), height(createInfo.height), : CommandBoundResource(graphics, createInfo.name), texture(existingImage), type(type), width(createInfo.width), height(createInfo.height),
depth(createInfo.depth), arrayCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format), depth(createInfo.depth), arrayCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format),
usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), ownsImage(existingImage == nullptr) { usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), ownsImage(existingImage == nullptr) {
if (createInfo.useMip) { if (createInfo.useMip) {
+8 -16
View File
@@ -78,14 +78,8 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
float splitDist = cascadeSplits[i]; float splitDist = cascadeSplits[i];
Array<Vector> frustumCorners = { Array<Vector> frustumCorners = {
Vector(-1.0f, 1.0f, 1.0f), Vector(-1.0f, 1.0f, 1.0f), Vector(1.0f, 1.0f, 1.0f), Vector(1.0f, -1.0f, 1.0f), Vector(-1.0f, -1.0f, 1.0f),
Vector(1.0f, 1.0f, 1.0f), Vector(-1.0f, 1.0f, 0.0f), Vector(1.0f, 1.0f, 0.0f), Vector(1.0f, -1.0f, 0.0f), Vector(-1.0f, -1.0f, 0.0f),
Vector(1.0f, -1.0f, 1.0f),
Vector(-1.0f, -1.0f, 1.0f),
Vector(-1.0f, 1.0f, 0.0f),
Vector(1.0f, 1.0f, 0.0f),
Vector(1.0f, -1.0f, 0.0f),
Vector(-1.0f, -1.0f, 0.0f),
}; };
for (auto& c : frustumCorners) { for (auto& c : frustumCorners) {
@@ -287,13 +281,12 @@ void ShadowPass::publishOutputs() {
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT, .usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
.name = "ShadowMapCascade", .name = "ShadowMapCascade",
}); });
cascades[s].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ cascades[s].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.sourceData =
.sourceData = { {
.size = sizeof(Matrix4), .size = sizeof(Matrix4),
.data = nullptr, .data = nullptr,
}, },
.name = "LightSpaceBuffer" .name = "LightSpaceBuffer"});
});
cascades[s].views.clear(); cascades[s].views.clear();
for (uint32 j = 0; j < cascades[s].shadowMaps->getNumLayers(); ++j) { for (uint32 j = 0; j < cascades[s].shadowMaps->getNumLayers(); ++j) {
cascades[s].views.add(cascades[s].shadowMaps->createTextureView(0, 1, j, 1)); cascades[s].views.add(cascades[s].shadowMaps->createTextureView(0, 1, j, 1));
@@ -302,13 +295,12 @@ void ShadowPass::publishOutputs() {
resources->registerTextureOutput(fmt::format("SHADOWMAP_TEXTURE{0}", s), Gfx::PTexture2DArray(cascades[s].shadowMaps)); resources->registerTextureOutput(fmt::format("SHADOWMAP_TEXTURE{0}", s), Gfx::PTexture2DArray(cascades[s].shadowMaps));
resources->registerBufferOutput(fmt::format("SHADOWMAP_LIGHTSPACE{0}", s), cascades[s].lightSpaceBuffer); resources->registerBufferOutput(fmt::format("SHADOWMAP_LIGHTSPACE{0}", s), cascades[s].lightSpaceBuffer);
} }
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
.sourceData = { {
.size = sizeof(float) * NUM_CASCADES, .size = sizeof(float) * NUM_CASCADES,
.data = nullptr, .data = nullptr,
}, },
.name = "CASCADE_SPLITS" .name = "CASCADE_SPLITS"});
});
resources->registerUniformOutput("SHADOWMAP_CASCADESPLITS", cascadeSplitsBuffer); resources->registerUniformOutput("SHADOWMAP_CASCADESPLITS", cascadeSplitsBuffer);
viewport = shadowViewport; viewport = shadowViewport;
} }
+1 -1
View File
@@ -15,7 +15,7 @@ void GameInterface::reload() {
destroyInstance(game); destroyInstance(game);
dlclose(lib); dlclose(lib);
} }
std::filesystem::copy(soPath.parent_path().parent_path() / "res" / "shaders", "shaders/game", std::filesystem::copy_options::overwrite_existing); //std::filesystem::copy(soPath.parent_path().parent_path() / "res" / "shaders", "shaders/game", std::filesystem::copy_options::overwrite_existing);
lib = dlopen(soPath.c_str(), RTLD_NOW); lib = dlopen(soPath.c_str(), RTLD_NOW);
createInstance = (decltype(createInstance))dlsym(lib, "createInstance"); createInstance = (decltype(createInstance))dlsym(lib, "createInstance");
destroyInstance = (decltype(destroyInstance))dlsym(lib, "destroyInstance"); destroyInstance = (decltype(destroyInstance))dlsym(lib, "destroyInstance");