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")]
float2 precomputeBRDF(float2 texCoords) : SV_Target
float2 precomputeBRDF(float2 texCoords : UV) : SV_Target
{
return integrateBRDF(texCoords.x, texCoords.y);
}
+1
View File
@@ -95,6 +95,7 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
{"precomputeBRDF", "EnvironmentMapping"},
},
.rootSignature = cubePipelineLayout,
.dumpIntermediate = true,
});
cubePipelineLayout->create();
+2 -2
View File
@@ -24,8 +24,8 @@ static Gfx::OGraphics graphics;
int main() {
std::string gameName = "MeshShadingDemo";
std::filesystem::path outputPath = fmt::format("/home/dynamitos/{0}Game/", gameName);
std::filesystem::path sourcePath = fmt::format("/home/dynamitos/{0}/", gameName);
std::filesystem::path outputPath = fmt::format("/Users/dynamitos/{0}Game/", gameName);
std::filesystem::path sourcePath = fmt::format("/Users/dynamitos/{0}/", gameName);
#ifdef WIN32
std::string libraryEnding = "dll";
#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 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::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 updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 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 bool hasPushConstants() const { return !pushConstants.empty(); }
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:
uint32 layoutHash = 0;
+1 -1
View File
@@ -12,7 +12,7 @@ using namespace Seele;
using namespace Seele::Metal;
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->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->fragmentFunction, boundPipeline->fragmentSets);
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->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) {
uint pushIndex = boundPipeline->getPipelineLayout()->findParameter("pOffsets");
uint pushIndex = boundPipeline->getPipelineLayout()->findParameter(boundPipeline->getPipelineLayout()->getPushConstantName(offset));
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) {
encoder->setFragmentBytes(data, size, pushIndex); // TODO: hardcoded
encoder->setFragmentBytes(data, size, pushIndex);
}
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) {
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);
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->argumentBuffer->bind();
@@ -366,6 +366,7 @@ void CommandQueue::submitCommands(PEvent signalSemaphore) {
for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) {
if ((*it)->getHandle() == cmdBuffer) {
auto& cmd = *it;
std::cout << "Command completed" << std::endl;
cmd->reset();
readyCommands.add(std::move(*it));
pendingCommands.erase(it);
@@ -375,7 +376,6 @@ void CommandQueue::submitCommands(PEvent signalSemaphore) {
}));
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
activeCommand->end(signalSemaphore);
activeCommand->waitDeviceIdle();
pendingCommands.add(std::move(activeCommand));
if (!readyCommands.empty()) {
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 updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as);
PGraphics graphics;
PDescriptorPool owner;
OBufferAllocation argumentBuffer = 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); }
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,
});
boundResources.add(tex);
boundResources.add(tex->getSource());
}
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) {
const auto& color = layout.colorAttachments[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()) {
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) {
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) {
depth->setResolveTexture(layout.depthResolveAttachment.getTextureView().cast<TextureBase>()->getImage());
depth->setResolveTexture(layout.depthResolveAttachment.getTextureView().cast<TextureView>()->getHandle());
}
}
}
+13 -4
View File
@@ -5,6 +5,7 @@
#include <Foundation/Foundation.hpp>
#include <Metal/Metal.hpp>
#include <QuartzCore/QuartzCore.hpp>
#include <iostream>
namespace Seele {
namespace Metal {
@@ -25,18 +26,26 @@ class DestructionManager {
DEFINE_REF(DestructionManager)
class CommandBoundResource {
public:
CommandBoundResource(PGraphics graphics) : graphics(graphics) {}
public:
CommandBoundResource(PGraphics graphics, const std::string& name) : graphics(graphics), name(name) {}
virtual ~CommandBoundResource() {
if (isCurrentlyBound())
abort();
}
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
constexpr void bind() { bindCount++; }
constexpr void unbind() { bindCount--; }
void bind() { 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:
PGraphics graphics;
std::string name;
uint64 bindCount = 0;
};
DEFINE_REF(CommandBoundResource)
+11 -4
View File
@@ -13,7 +13,7 @@ using namespace Seele;
using namespace Seele::Metal;
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() {}
@@ -43,15 +43,22 @@ void TextureView::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags
Gfx::OTextureView TextureHandle::createTextureView(uint32 baseMipLevel, uint32 viewLevelCount, uint32 baseArrayLayer,
uint32 viewLayerCount) {
MTL::Texture* viewTexture =
texture->newTextureView(cast(format), type, NS::Range(baseMipLevel, viewLevelCount), NS::Range(baseArrayLayer, viewLayerCount));
MTL::Texture* viewTexture;
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 viewHeight = height * std::pow(0.5, baseMipLevel);
return new TextureView(graphics, this, viewWidth, viewHeight, viewLayerCount, viewLevelCount, viewTexture);
}
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),
usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), ownsImage(existingImage == nullptr) {
if (createInfo.useMip) {
+20 -28
View File
@@ -78,14 +78,8 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
float splitDist = cascadeSplits[i];
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, 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, 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) {
@@ -127,7 +121,7 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
viewParams.viewProjectionMatrix = viewProjectionMatrix;
viewParams.inverseViewProjectionMatrix = glm::inverse(viewProjectionMatrix);
viewParams.cameraPosition_WS = Vector4(cameraPos, 1);
viewParams.cameraForward_WS = Vector4(frustumCenter - cameraPos, 0);
viewParams.cameraForward_WS = Vector4(frustumCenter - cameraPos, 0);
viewParams.screenDimensions = Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y);
viewParams.invScreenDimensions = 1.0f / viewParams.screenDimensions;
cascades[i].viewParams.add(createViewParamsSet());
@@ -262,11 +256,11 @@ void ShadowPass::endFrame() {}
void ShadowPass::publishOutputs() {
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
{
.size = sizeof(float) * NUM_CASCADES,
.data = nullptr,
},
.name = "CascadeSplits"});
{
.size = sizeof(float) * NUM_CASCADES,
.data = nullptr,
},
.name = "CascadeSplits"});
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
{
.size = {SHADOW_MAP_SIZE, SHADOW_MAP_SIZE},
@@ -287,13 +281,12 @@ void ShadowPass::publishOutputs() {
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
.name = "ShadowMapCascade",
});
cascades[s].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = sizeof(Matrix4),
.data = nullptr,
},
.name = "LightSpaceBuffer"
});
cascades[s].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.sourceData =
{
.size = sizeof(Matrix4),
.data = nullptr,
},
.name = "LightSpaceBuffer"});
cascades[s].views.clear();
for (uint32 j = 0; j < cascades[s].shadowMaps->getNumLayers(); ++j) {
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->registerBufferOutput(fmt::format("SHADOWMAP_LIGHTSPACE{0}", s), cascades[s].lightSpaceBuffer);
}
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
.sourceData = {
.size = sizeof(float) * NUM_CASCADES,
.data = nullptr,
},
.name = "CASCADE_SPLITS"
});
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
{
.size = sizeof(float) * NUM_CASCADES,
.data = nullptr,
},
.name = "CASCADE_SPLITS"});
resources->registerUniformOutput("SHADOWMAP_CASCADESPLITS", cascadeSplitsBuffer);
viewport = shadowViewport;
}
+2 -2
View File
@@ -15,9 +15,9 @@ void GameInterface::reload() {
destroyInstance(game);
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);
createInstance = (decltype(createInstance))dlsym(lib, "createInstance");
destroyInstance = (decltype(destroyInstance))dlsym(lib, "destroyInstance");
game = createInstance();
}
}