Fixing command resource binding
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -95,6 +95,7 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
||||
{"precomputeBRDF", "EnvironmentMapping"},
|
||||
},
|
||||
.rootSignature = cubePipelineLayout,
|
||||
.dumpIntermediate = true,
|
||||
});
|
||||
cubePipelineLayout->create();
|
||||
|
||||
|
||||
+2
-2
@@ -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__
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ){}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
@@ -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 = {
|
||||
cascades[s].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.sourceData =
|
||||
{
|
||||
.size = sizeof(Matrix4),
|
||||
.data = nullptr,
|
||||
},
|
||||
.name = "LightSpaceBuffer"
|
||||
});
|
||||
.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 = {
|
||||
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
|
||||
{
|
||||
.size = sizeof(float) * NUM_CASCADES,
|
||||
.data = nullptr,
|
||||
},
|
||||
.name = "CASCADE_SPLITS"
|
||||
});
|
||||
.name = "CASCADE_SPLITS"});
|
||||
resources->registerUniformOutput("SHADOWMAP_CASCADESPLITS", cascadeSplitsBuffer);
|
||||
viewport = shadowViewport;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ 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");
|
||||
|
||||
Reference in New Issue
Block a user