lot of metal changes, but no idea how this stuff works
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ set(METAL_ROOT ${EXTERNAL_ROOT}/metal-cpp)
|
|||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(VCPKG_BASE_FOLDER ${VCPKG_INSTALLED_DIR}/x64-windows/)
|
set(VCPKG_BASE_FOLDER ${VCPKG_INSTALLED_DIR}/x64-windows/)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
set(VCPKG_BASE_FOLDER ${VCPKG_INSTALLED_DIR}/arm64-osx/)
|
set(VCPKG_BASE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/build/vcpkg_installed/arm64-osx/)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(Boost_NO_WARN_NEW_VERSIONS 1)
|
set(Boost_NO_WARN_NEW_VERSIONS 1)
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ void cullLights(ComputeShaderInput in)
|
|||||||
float maxDepthWS = clipToWorld(float4(0, 0, fMaxDepth, 1)).z;
|
float maxDepthWS = clipToWorld(float4(0, 0, fMaxDepth, 1)).z;
|
||||||
float nearClipWS = clipToWorld(float4(0, 0, 0, 1)).z;
|
float nearClipWS = clipToWorld(float4(0, 0, 0, 1)).z;
|
||||||
|
|
||||||
Plane maxPlane = {float3(0, 0, -1), -maxDepthWS};
|
Plane maxPlane = {float4(0, 0, -1, -maxDepthWS)};
|
||||||
|
|
||||||
for ( uint i = in.groupIndex; i < pLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
|
for ( uint i = in.groupIndex; i < pLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct BoundingSphere
|
|||||||
bool result = true;
|
bool result = true;
|
||||||
for(int i = 0; i < 4 && result; ++i)
|
for(int i = 0; i < 4 && result; ++i)
|
||||||
{
|
{
|
||||||
if(dot(frustum.sides[i].n, getCenter()) - frustum.sides[i].d < -getRadius())
|
if(dot(frustum.sides[i].getNormal(), getCenter()) - frustum.sides[i].getDistance() < -getRadius())
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
@@ -39,11 +39,11 @@ struct AABB
|
|||||||
bool result = true;
|
bool result = true;
|
||||||
for(int i = 0; i < 4 && result; ++i)
|
for(int i = 0; i < 4 && result; ++i)
|
||||||
{
|
{
|
||||||
const float r = extents.x * abs(frustum.sides[i].n.x)
|
const float r = extents.x * abs(frustum.sides[i].getNormal().x)
|
||||||
+ extents.y * abs(frustum.sides[i].n.y)
|
+ extents.y * abs(frustum.sides[i].getNormal().y)
|
||||||
+ extents.z * abs(frustum.sides[i].n.z);
|
+ extents.z * abs(frustum.sides[i].getNormal().z);
|
||||||
|
|
||||||
const float signedDistance = dot(frustum.sides[i].n, center) - frustum.sides[i].d;
|
const float signedDistance = dot(frustum.sides[i].getNormal(), center) - frustum.sides[i].getDistance();
|
||||||
if(signedDistance < -r)
|
if(signedDistance < -r)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
|
|||||||
@@ -101,11 +101,18 @@ float4 clipToScreen(float4 clip)
|
|||||||
|
|
||||||
struct Plane
|
struct Plane
|
||||||
{
|
{
|
||||||
float3 n;
|
float4 nd;
|
||||||
float d;
|
float3 getNormal()
|
||||||
|
{
|
||||||
|
return nd.xyz;
|
||||||
|
}
|
||||||
|
float getDistance()
|
||||||
|
{
|
||||||
|
return nd.w;
|
||||||
|
}
|
||||||
bool pointInside(float3 point)
|
bool pointInside(float3 point)
|
||||||
{
|
{
|
||||||
return dot(n, point) - d > 0.0f;
|
return dot(getNormal(), point) - getDistance() > 0.0f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -131,9 +138,11 @@ Plane computePlane(float3 p0, float3 p1, float3 p2)
|
|||||||
float3 v0 = p1 - p0;
|
float3 v0 = p1 - p0;
|
||||||
float3 v2 = p2 - p0;
|
float3 v2 = p2 - p0;
|
||||||
|
|
||||||
plane.n = normalize(cross(v0, v2));
|
float3 n = normalize(cross(v0, v2));
|
||||||
|
|
||||||
plane.d = dot(plane.n, p0);
|
float d = dot(n, p0);
|
||||||
|
|
||||||
|
plane.nd = float4(n, d);
|
||||||
|
|
||||||
return plane;
|
return plane;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ import Common;
|
|||||||
|
|
||||||
struct DispatchParams
|
struct DispatchParams
|
||||||
{
|
{
|
||||||
uint3 numThreadGroups;
|
uint4 numThreadGroups;
|
||||||
uint pad0;
|
uint4 numThreads;
|
||||||
uint3 numThreads;
|
|
||||||
uint pad1;
|
|
||||||
RWStructuredBuffer<Frustum> frustums;
|
RWStructuredBuffer<Frustum> frustums;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ struct PointLight : ILightEnv
|
|||||||
|
|
||||||
bool insidePlane(Plane plane, float3 position)
|
bool insidePlane(Plane plane, float3 position)
|
||||||
{
|
{
|
||||||
return dot(plane.n, position) - plane.d < -colorRange.w;
|
return dot(plane.getNormal(), position) - plane.getDistance() < -colorRange.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insideFrustum(Frustum frustum, float3 position, float minDepth, float maxDepth)
|
bool insideFrustum(Frustum frustum, float3 position, float minDepth, float maxDepth)
|
||||||
|
|||||||
+12
-12
@@ -116,18 +116,18 @@ int main() {
|
|||||||
// .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
// .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
||||||
// .importPath = "Whitechapel",
|
// .importPath = "Whitechapel",
|
||||||
//});
|
//});
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath = sourcePath / "import/models/box.glb",
|
// .filePath = sourcePath / "import/models/box.glb",
|
||||||
.importPath = "",
|
// .importPath = "",
|
||||||
});
|
//});
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath = sourcePath / "import/models/rttest.glb",
|
// .filePath = sourcePath / "import/models/rttest.glb",
|
||||||
.importPath = "",
|
// .importPath = "",
|
||||||
});
|
//});
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath = sourcePath / "import/models/town_hall.glb",
|
// .filePath = sourcePath / "import/models/town_hall.glb",
|
||||||
.importPath = "",
|
// .importPath = "",
|
||||||
});
|
//});
|
||||||
getThreadPool().waitIdle();
|
getThreadPool().waitIdle();
|
||||||
vd->commitMeshes();
|
vd->commitMeshes();
|
||||||
WindowCreateInfo mainWindowInfo = {
|
WindowCreateInfo mainWindowInfo = {
|
||||||
|
|||||||
@@ -299,6 +299,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
|||||||
constexpr void remove(value_type&& element, bool keepOrder = true) { erase(find(element), keepOrder); }
|
constexpr void remove(value_type&& element, bool keepOrder = true) { erase(find(element), keepOrder); }
|
||||||
constexpr void erase(iterator it, bool keepOrder = true) { removeAt(it - begin(), keepOrder); }
|
constexpr void erase(iterator it, bool keepOrder = true) { removeAt(it - begin(), keepOrder); }
|
||||||
constexpr void erase(const_iterator it, bool keepOrder = true) { removeAt(it - cbegin(), keepOrder); }
|
constexpr void erase(const_iterator it, bool keepOrder = true) { removeAt(it - cbegin(), keepOrder); }
|
||||||
|
constexpr bool contains(const T& value) const { return find(value) != end(); }
|
||||||
constexpr void removeAt(size_type index, bool keepOrder = true) {
|
constexpr void removeAt(size_type index, bool keepOrder = true) {
|
||||||
if (keepOrder) {
|
if (keepOrder) {
|
||||||
for (size_type i = index; i < arraySize - 1; ++i) {
|
for (size_type i = index; i < arraySize - 1; ++i) {
|
||||||
@@ -385,7 +386,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
|||||||
assert(result != nullptr);
|
assert(result != nullptr);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
void deallocateArray(T* ptr, size_type size) { allocator.deallocate(ptr, size); }
|
void deallocateArray(T* ptr, size_type size) { if(ptr == nullptr) return; allocator.deallocate(ptr, size); }
|
||||||
template <typename Type> T& addInternal(Type&& t) noexcept {
|
template <typename Type> T& addInternal(Type&& t) noexcept {
|
||||||
if (arraySize == allocated) {
|
if (arraySize == allocated) {
|
||||||
size_type newSize = arraySize + 1;
|
size_type newSize = arraySize + 1;
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> c
|
|||||||
std::allocator_traits<NodeAllocator>::construct(allocator, node, node->prev, node->next, std::forward<Type>(data));
|
std::allocator_traits<NodeAllocator>::construct(allocator, node, node->prev, node->next, std::forward<Type>(data));
|
||||||
}
|
}
|
||||||
constexpr void destroyNode(Node* node) { std::allocator_traits<NodeAllocator>::destroy(allocator, node); }
|
constexpr void destroyNode(Node* node) { std::allocator_traits<NodeAllocator>::destroy(allocator, node); }
|
||||||
constexpr void deallocateNode(Node* node) { allocator.deallocate(node, 1); }
|
constexpr void deallocateNode(Node* node) { if(node == nullptr) return; allocator.deallocate(node, 1); }
|
||||||
template <typename ValueType> constexpr iterator addInternal(ValueType&& value) {
|
template <typename ValueType> constexpr iterator addInternal(ValueType&& value) {
|
||||||
initializeNode(tail, std::forward<ValueType>(value));
|
initializeNode(tail, std::forward<ValueType>(value));
|
||||||
Node* newTail = allocateNode();
|
Node* newTail = allocateNode();
|
||||||
@@ -308,4 +308,4 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> c
|
|||||||
const_iterator cendIt;
|
const_iterator cendIt;
|
||||||
size_type _size;
|
size_type _size;
|
||||||
};
|
};
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Pair.h"
|
#include "Pair.h"
|
||||||
|
#include "Array.h"
|
||||||
#include <memory_resource>
|
#include <memory_resource>
|
||||||
|
|
||||||
|
|
||||||
@@ -226,13 +227,13 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void verifyTree() {
|
/*void verifyTree() {
|
||||||
size_t numElems = 0;
|
size_t numElems = 0;
|
||||||
for (const auto& it : *this) {
|
for (const auto& it : *this) {
|
||||||
numElems++;
|
numElems++;
|
||||||
}
|
}
|
||||||
assert(numElems == _size);
|
assert(numElems == _size);
|
||||||
}
|
}*/
|
||||||
void markIteratorsDirty() { iteratorsDirty = true; }
|
void markIteratorsDirty() { iteratorsDirty = true; }
|
||||||
void refreshIterators() {
|
void refreshIterators() {
|
||||||
beginIt = calcBeginIterator();
|
beginIt = calcBeginIterator();
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ class Graphics {
|
|||||||
virtual void endRenderPass() = 0;
|
virtual void endRenderPass() = 0;
|
||||||
virtual void waitDeviceIdle() = 0;
|
virtual void waitDeviceIdle() = 0;
|
||||||
|
|
||||||
|
virtual void executeCommands(ORenderCommand commands) = 0;
|
||||||
virtual void executeCommands(Array<ORenderCommand> commands) = 0;
|
virtual void executeCommands(Array<ORenderCommand> commands) = 0;
|
||||||
virtual void executeCommands(OComputeCommand commands) = 0;
|
virtual void executeCommands(OComputeCommand commands) = 0;
|
||||||
virtual void executeCommands(Array<OComputeCommand> commands) = 0;
|
virtual void executeCommands(Array<OComputeCommand> commands) = 0;
|
||||||
|
|||||||
@@ -96,8 +96,7 @@ class UniformBuffer : public Gfx::UniformBuffer {
|
|||||||
virtual ~UniformBuffer();
|
virtual ~UniformBuffer();
|
||||||
virtual void updateContents(uint64 offset, uint64 size, void* data) override;
|
virtual void updateContents(uint64 offset, uint64 size, void* data) override;
|
||||||
virtual void rotateBuffer(uint64 size) override;
|
virtual void rotateBuffer(uint64 size) override;
|
||||||
void* getContents() const { return contents.data(); }
|
Array<uint8> getContents() const { return contents; }
|
||||||
size_t getSize() const { return contents.size(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
|
|||||||
@@ -3,12 +3,14 @@
|
|||||||
#include "Containers/Array.h"
|
#include "Containers/Array.h"
|
||||||
#include "Descriptor.h"
|
#include "Descriptor.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "Graphics/Graphics.h"
|
|
||||||
#include "Graphics/Command.h"
|
#include "Graphics/Command.h"
|
||||||
#include "Graphics/Enums.h"
|
#include "Graphics/Enums.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Graphics/Resources.h"
|
#include "Graphics/Resources.h"
|
||||||
|
#include "Metal/MTLArgumentEncoder.hpp"
|
||||||
#include "Metal/MTLCaptureManager.hpp"
|
#include "Metal/MTLCaptureManager.hpp"
|
||||||
|
#include "Metal/MTLLibrary.hpp"
|
||||||
|
#include "Metal/MTLRenderCommandEncoder.hpp"
|
||||||
#include "Pipeline.h"
|
#include "Pipeline.h"
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
@@ -40,8 +42,7 @@ void Command::present(MTL::Drawable* drawable) { cmdBuffer->presentDrawable(draw
|
|||||||
|
|
||||||
void Command::end(PEvent signal) {
|
void Command::end(PEvent signal) {
|
||||||
assert(!parallelEncoder);
|
assert(!parallelEncoder);
|
||||||
if(blitEncoder)
|
if (blitEncoder) {
|
||||||
{
|
|
||||||
blitEncoder->endEncoding();
|
blitEncoder->endEncoding();
|
||||||
}
|
}
|
||||||
if (signal != nullptr) {
|
if (signal != nullptr) {
|
||||||
@@ -51,9 +52,7 @@ void Command::end(PEvent signal) {
|
|||||||
cmdBuffer->commit();
|
cmdBuffer->commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command::waitDeviceIdle() {
|
void Command::waitDeviceIdle() { cmdBuffer->waitUntilCompleted(); }
|
||||||
cmdBuffer->waitUntilCompleted();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Command::signalEvent(PEvent event) { cmdBuffer->encodeSignalEvent(event->getHandle(), 1); }
|
void Command::signalEvent(PEvent event) { cmdBuffer->encodeSignalEvent(event->getHandle(), 1); }
|
||||||
|
|
||||||
@@ -80,7 +79,7 @@ void RenderCommand::setViewport(Gfx::PViewport viewport) {
|
|||||||
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
|
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
|
||||||
boundPipeline = pipeline.cast<GraphicsPipeline>();
|
boundPipeline = pipeline.cast<GraphicsPipeline>();
|
||||||
encoder->setRenderPipelineState(boundPipeline->getHandle());
|
encoder->setRenderPipelineState(boundPipeline->getHandle());
|
||||||
if(boundPipeline->getPipelineLayout()->hasPushConstants()) {
|
if (boundPipeline->getPipelineLayout()->hasPushConstants()) {
|
||||||
constantsBuffer = boundPipeline->graphics->getDevice()->newBuffer(boundPipeline->getPipelineLayout()->getPushConstantsSize(), 0);
|
constantsBuffer = boundPipeline->graphics->getDevice()->newBuffer(boundPipeline->getPipelineLayout()->getPushConstantsSize(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,10 +90,46 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
|||||||
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
||||||
metalSet->bind();
|
metalSet->bind();
|
||||||
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
||||||
encoder->setVertexBuffer(metalSet->getArgumentBuffer(), 0, descriptorIndex);
|
|
||||||
encoder->setFragmentBuffer(metalSet->getArgumentBuffer(), 0, descriptorIndex);
|
auto createEncoder = [&metalSet, descriptorIndex](MTL::Function* function, const Array<uint32>& usedSets) {
|
||||||
encoder->setObjectBuffer(metalSet->getArgumentBuffer(), 0, descriptorIndex);
|
if(metalSet->encoder == nullptr) {
|
||||||
encoder->setMeshBuffer(metalSet->getArgumentBuffer(), 0, descriptorIndex);
|
if (metalSet->isPlainDescriptor()) {
|
||||||
|
metalSet->encoder = metalSet->createEncoder();
|
||||||
|
} else if (function != nullptr && usedSets.contains(descriptorIndex)) {
|
||||||
|
metalSet->encoder = function->newArgumentEncoder(descriptorIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
createEncoder(boundPipeline->taskFunction, boundPipeline->taskSets);
|
||||||
|
createEncoder(boundPipeline->meshFunction, boundPipeline->meshSets);
|
||||||
|
createEncoder(boundPipeline->vertexFunction, boundPipeline->vertexSets);
|
||||||
|
createEncoder(boundPipeline->fragmentFunction, boundPipeline->fragmentSets);
|
||||||
|
if(metalSet->argumentBuffer == nullptr) {
|
||||||
|
metalSet->argumentBuffer = metalSet->graphics->getDevice()->newBuffer(metalSet->encoder->encodedLength(), MTL::ResourceOptionCPUCacheModeDefault);
|
||||||
|
metalSet->encoder->setArgumentBuffer(metalSet->argumentBuffer, 0);
|
||||||
|
}
|
||||||
|
for (const auto& write : metalSet->uniformWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
for (const auto& write : metalSet->bufferWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& write : metalSet->samplerWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& write : metalSet->textureWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& write : metalSet->accelerationWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
encoder->setObjectBuffer(metalSet->argumentBuffer, 0, descriptorIndex);
|
||||||
|
encoder->setMeshBuffer(metalSet->argumentBuffer, 0, descriptorIndex);
|
||||||
|
encoder->setVertexBuffer(metalSet->argumentBuffer, 0, descriptorIndex);
|
||||||
|
encoder->setFragmentBuffer(metalSet->argumentBuffer, 0, descriptorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) {
|
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) {
|
||||||
@@ -163,7 +198,7 @@ void ComputeCommand::end() {
|
|||||||
void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
||||||
boundPipeline = pipeline.cast<ComputePipeline>();
|
boundPipeline = pipeline.cast<ComputePipeline>();
|
||||||
encoder->setComputePipelineState(boundPipeline->getHandle());
|
encoder->setComputePipelineState(boundPipeline->getHandle());
|
||||||
if(boundPipeline->getPipelineLayout()->hasPushConstants()) {
|
if (boundPipeline->getPipelineLayout()->hasPushConstants()) {
|
||||||
constantsBuffer = boundPipeline->graphics->getDevice()->newBuffer(boundPipeline->getPipelineLayout()->getPushConstantsSize(), 0);
|
constantsBuffer = boundPipeline->graphics->getDevice()->newBuffer(boundPipeline->getPipelineLayout()->getPushConstantsSize(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,7 +207,34 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) {
|
|||||||
auto metalSet = set.cast<DescriptorSet>();
|
auto metalSet = set.cast<DescriptorSet>();
|
||||||
metalSet->bind();
|
metalSet->bind();
|
||||||
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
||||||
encoder->setBuffer(metalSet->getArgumentBuffer(), 0, descriptorIndex);
|
if(metalSet->encoder == nullptr) {
|
||||||
|
if (metalSet->isPlainDescriptor()) {
|
||||||
|
metalSet->encoder = metalSet->createEncoder();
|
||||||
|
} else {
|
||||||
|
metalSet->encoder = boundPipeline->computeFunction->newArgumentEncoder(descriptorIndex);
|
||||||
|
}
|
||||||
|
metalSet->argumentBuffer = metalSet->graphics->getDevice()->newBuffer(metalSet->encoder->encodedLength(), MTL::ResourceOptionCPUCacheModeDefault);
|
||||||
|
metalSet->encoder->setArgumentBuffer(metalSet->argumentBuffer, 0);
|
||||||
|
}
|
||||||
|
for (const auto& write : metalSet->uniformWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
for (const auto& write : metalSet->bufferWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& write : metalSet->samplerWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& write : metalSet->textureWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& write : metalSet->accelerationWrites) {
|
||||||
|
write.apply(metalSet->encoder);
|
||||||
|
}
|
||||||
|
encoder->setBuffer(metalSet->argumentBuffer, 0, descriptorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
|
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
|
||||||
@@ -192,7 +254,7 @@ void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
|
|||||||
encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ), MTL::Size(32, 32, 1));
|
encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ), MTL::Size(32, 32, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeCommand::dispatchIndirect(Gfx::PShaderBuffer buffer, uint32 offset){
|
void ComputeCommand::dispatchIndirect(Gfx::PShaderBuffer buffer, uint32 offset) {
|
||||||
encoder->dispatchThreadgroups(buffer.cast<ShaderBuffer>()->getHandle(), offset, MTL::Size(32, 32, 1));
|
encoder->dispatchThreadgroups(buffer.cast<ShaderBuffer>()->getHandle(), offset, MTL::Size(32, 32, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,14 +302,11 @@ void CommandQueue::submitCommands(PEvent signalSemaphore) {
|
|||||||
activeCommand->waitDeviceIdle();
|
activeCommand->waitDeviceIdle();
|
||||||
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
|
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
|
||||||
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());
|
||||||
readyCommands.removeAt(0);
|
readyCommands.removeAt(0);
|
||||||
activeCommand->waitForEvent(prevCmdEvent);
|
activeCommand->waitForEvent(prevCmdEvent);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
|
MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
|
||||||
descriptor->setErrorOptions(MTL::CommandBufferErrorOptionEncoderExecutionStatus);
|
descriptor->setErrorOptions(MTL::CommandBufferErrorOptionEncoderExecutionStatus);
|
||||||
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
|
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
#include "Foundation/NSObject.hpp"
|
#include "Foundation/NSObject.hpp"
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
|
#include "Graphics/Metal/Command.h"
|
||||||
#include "Graphics/Metal/Resources.h"
|
#include "Graphics/Metal/Resources.h"
|
||||||
|
#include "Metal/MTLAccelerationStructure.hpp"
|
||||||
#include "Metal/MTLArgumentEncoder.hpp"
|
#include "Metal/MTLArgumentEncoder.hpp"
|
||||||
#include "Metal/MTLLibrary.hpp"
|
#include "Metal/MTLLibrary.hpp"
|
||||||
#include "Metal/MTLResource.hpp"
|
#include "Metal/MTLResource.hpp"
|
||||||
@@ -21,6 +23,7 @@ class DescriptorLayout : public Gfx::DescriptorLayout {
|
|||||||
MTL::ArgumentEncoder* createEncoder();
|
MTL::ArgumentEncoder* createEncoder();
|
||||||
uint32 getFlattenedIndex(uint32 binding, uint32 arrayIndex) const { return flattenMap.at(flattenIndex(binding, arrayIndex)); }
|
uint32 getFlattenedIndex(uint32 binding, uint32 arrayIndex) const { return flattenMap.at(flattenIndex(binding, arrayIndex)); }
|
||||||
constexpr uint32 getTotalBindingCount() const { return flattenedBindingCount; }
|
constexpr uint32 getTotalBindingCount() const { return flattenedBindingCount; }
|
||||||
|
constexpr bool isPlainDescriptor() const { return plainDescriptor; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr uint64 flattenIndex(uint32 binding, uint32 arrayIndex) const { return uint64(arrayIndex) << 32 | binding; }
|
constexpr uint64 flattenIndex(uint32 binding, uint32 arrayIndex) const { return uint64(arrayIndex) << 32 | binding; }
|
||||||
@@ -28,6 +31,9 @@ class DescriptorLayout : public Gfx::DescriptorLayout {
|
|||||||
NS::Array* arguments;
|
NS::Array* arguments;
|
||||||
Map<uint64, uint32> flattenMap;
|
Map<uint64, uint32> flattenMap;
|
||||||
uint32 flattenedBindingCount = 0;
|
uint32 flattenedBindingCount = 0;
|
||||||
|
// descriptor sets containing only uniform data are not actually argument buffers, so they need to be
|
||||||
|
// handled separately
|
||||||
|
bool plainDescriptor = true;
|
||||||
};
|
};
|
||||||
DEFINE_REF(DescriptorLayout)
|
DEFINE_REF(DescriptorLayout)
|
||||||
|
|
||||||
@@ -62,15 +68,54 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
|||||||
virtual void updateAccelerationStructure(uint32 binding, uint32 index, Gfx::PTopLevelAS as) override;
|
virtual void updateAccelerationStructure(uint32 binding, uint32 index, Gfx::PTopLevelAS as) override;
|
||||||
|
|
||||||
constexpr const Array<MTL::Resource*>& getBoundResources() const { return boundResources; }
|
constexpr const Array<MTL::Resource*>& getBoundResources() const { return boundResources; }
|
||||||
|
constexpr bool isPlainDescriptor() const { return owner->getLayout()->isPlainDescriptor(); }
|
||||||
MTL::Buffer* getArgumentBuffer() const { return argumentBuffer; }
|
constexpr MTL::ArgumentEncoder* createEncoder() const { return owner->getLayout()->createEncoder(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
PDescriptorPool owner;
|
PDescriptorPool owner;
|
||||||
Array<MTL::Resource*> boundResources;
|
Array<MTL::Resource*> boundResources;
|
||||||
MTL::ArgumentEncoder* encoder;
|
|
||||||
MTL::Buffer* argumentBuffer = nullptr;
|
MTL::Buffer* argumentBuffer = nullptr;
|
||||||
|
MTL::ArgumentEncoder* encoder = nullptr;
|
||||||
|
|
||||||
|
struct UniformWriteInfo
|
||||||
|
{
|
||||||
|
uint32 index;
|
||||||
|
Array<uint8> content;
|
||||||
|
void apply(MTL::ArgumentEncoder* encoder) const { std::memcpy(encoder->constantData(index), content.data(), content.size()); }
|
||||||
|
};
|
||||||
|
Array<UniformWriteInfo> uniformWrites;
|
||||||
|
struct BufferWriteInfo
|
||||||
|
{
|
||||||
|
uint32 index;
|
||||||
|
MTL::Buffer* buffer;
|
||||||
|
void apply(MTL::ArgumentEncoder* encoder) const { encoder->setBuffer(buffer, 0, 2); }
|
||||||
|
};
|
||||||
|
Array<BufferWriteInfo> bufferWrites;
|
||||||
|
struct TextureWriteInfo
|
||||||
|
{
|
||||||
|
uint32 index;
|
||||||
|
MTL::Texture* texture;
|
||||||
|
void apply(MTL::ArgumentEncoder* encoder) const { encoder->setTexture(texture, index); }
|
||||||
|
};
|
||||||
|
Array<TextureWriteInfo> textureWrites;
|
||||||
|
struct SamplerWriteInfo
|
||||||
|
{
|
||||||
|
uint32 index;
|
||||||
|
MTL::SamplerState* sampler;
|
||||||
|
void apply(MTL::ArgumentEncoder* encoder) const { encoder->setSamplerState(sampler, index); }
|
||||||
|
};
|
||||||
|
Array<SamplerWriteInfo> samplerWrites;
|
||||||
|
struct AccelerationStructureWriteInfo
|
||||||
|
{
|
||||||
|
uint32 index;
|
||||||
|
MTL::AccelerationStructure* accelerationStructure;
|
||||||
|
void apply(MTL::ArgumentEncoder* encoder) const { encoder->setAccelerationStructure(accelerationStructure, index); }
|
||||||
|
};
|
||||||
|
Array<AccelerationStructureWriteInfo> accelerationWrites;
|
||||||
|
|
||||||
|
friend class RenderCommand;
|
||||||
|
friend class ComputeCommand;
|
||||||
};
|
};
|
||||||
DEFINE_REF(DescriptorSet)
|
DEFINE_REF(DescriptorSet)
|
||||||
|
|
||||||
|
|||||||
@@ -34,65 +34,16 @@ void DescriptorLayout::create() {
|
|||||||
MTL::ArgumentDescriptor** objects = new MTL::ArgumentDescriptor*[descriptorBindings.size()];
|
MTL::ArgumentDescriptor** objects = new MTL::ArgumentDescriptor*[descriptorBindings.size()];
|
||||||
flattenedBindingCount = 0;
|
flattenedBindingCount = 0;
|
||||||
for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
|
for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
|
||||||
objects[i] = MTL::ArgumentDescriptor::alloc()->init();
|
if(descriptorBindings[i].descriptorType != Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
|
||||||
objects[i]->setIndex(flattenedBindingCount);
|
plainDescriptor = false;
|
||||||
objects[i]->setAccess(cast(descriptorBindings[i].access));
|
} else {
|
||||||
objects[i]->setArrayLength(descriptorBindings[i].descriptorCount);
|
objects[i] = MTL::ArgumentDescriptor::alloc()->init();
|
||||||
MTL::DataType dataType;
|
objects[i]->setIndex(flattenedBindingCount);
|
||||||
switch (descriptorBindings[i].descriptorType) {
|
objects[i]->setAccess(cast(descriptorBindings[i].access));
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
objects[i]->setArrayLength(descriptorBindings[i].descriptorCount);
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
objects[i]->setDataType(MTL::DataTypeChar);
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
|
||||||
dataType = MTL::DataTypeTexture;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
|
||||||
dataType = MTL::DataTypePointer;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
|
|
||||||
dataType = MTL::DataTypeChar;
|
|
||||||
objects[i]->setArrayLength(descriptorBindings[i].uniformLength);
|
objects[i]->setArrayLength(descriptorBindings[i].uniformLength);
|
||||||
break;
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_SAMPLER:
|
|
||||||
dataType = MTL::DataTypeSampler;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
|
|
||||||
dataType = MTL::DataTypeInstanceAccelerationStructure;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new std::logic_error("unknown descriptor type");
|
|
||||||
}
|
}
|
||||||
objects[i]->setDataType(dataType);
|
|
||||||
MTL::TextureType textureType;
|
|
||||||
switch (descriptorBindings[i].textureType) {
|
|
||||||
case Gfx::SE_IMAGE_VIEW_TYPE_1D:
|
|
||||||
textureType = MTL::TextureType1D;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_IMAGE_VIEW_TYPE_2D:
|
|
||||||
textureType = MTL::TextureType2D;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_IMAGE_VIEW_TYPE_3D:
|
|
||||||
textureType = MTL::TextureType3D;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_IMAGE_VIEW_TYPE_CUBE:
|
|
||||||
textureType = MTL::TextureTypeCube;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_IMAGE_VIEW_TYPE_1D_ARRAY:
|
|
||||||
textureType = MTL::TextureType1DArray;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY:
|
|
||||||
textureType = MTL::TextureType2DArray;
|
|
||||||
break;
|
|
||||||
case Gfx::SE_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
|
||||||
textureType = MTL::TextureTypeCubeArray;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
objects[i]->setTextureType(textureType);
|
|
||||||
for(uint32 j = 0; j < descriptorBindings[i].descriptorCount; ++j) {
|
for(uint32 j = 0; j < descriptorBindings[i].descriptorCount; ++j) {
|
||||||
flattenMap[flattenIndex(i, j)] = flattenedBindingCount++;
|
flattenMap[flattenIndex(i, j)] = flattenedBindingCount++;
|
||||||
}
|
}
|
||||||
@@ -124,10 +75,6 @@ void DescriptorPool::reset() {}
|
|||||||
|
|
||||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
||||||
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), graphics(graphics), owner(owner) {
|
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), graphics(graphics), owner(owner) {
|
||||||
encoder = owner->getLayout()->createEncoder();
|
|
||||||
argumentBuffer = graphics->getDevice()->newBuffer(encoder->encodedLength(), 0);
|
|
||||||
std::cout << owner->getLayout()->getName() << ": " << encoder->encodedLength() << std::endl;
|
|
||||||
encoder->setArgumentBuffer(argumentBuffer, 0);
|
|
||||||
boundResources.resize(owner->getLayout()->getTotalBindingCount());
|
boundResources.resize(owner->getLayout()->getTotalBindingCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,56 +85,82 @@ void DescriptorSet::writeChanges() {}
|
|||||||
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PUniformBuffer uniformBuffer) {
|
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PUniformBuffer uniformBuffer) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
||||||
PUniformBuffer buffer = uniformBuffer.cast<UniformBuffer>();
|
PUniformBuffer buffer = uniformBuffer.cast<UniformBuffer>();
|
||||||
std::memcpy(encoder->constantData(flattenedIndex), buffer->getContents(), buffer->getSize());
|
|
||||||
boundResources[flattenedIndex] = nullptr;
|
boundResources[flattenedIndex] = nullptr;
|
||||||
|
uniformWrites.add(UniformWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.content = buffer->getContents(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) {
|
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
||||||
PShaderBuffer buffer = uniformBuffer.cast<ShaderBuffer>();
|
PShaderBuffer buffer = uniformBuffer.cast<ShaderBuffer>();
|
||||||
encoder->setBuffer(buffer->getHandle(), 0, flattenedIndex);
|
|
||||||
boundResources[flattenedIndex] = buffer->getHandle();
|
boundResources[flattenedIndex] = buffer->getHandle();
|
||||||
|
bufferWrites.add(BufferWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.buffer = buffer->getHandle(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PVertexBuffer uniformBuffer) {
|
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PVertexBuffer uniformBuffer) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
||||||
PVertexBuffer buffer = uniformBuffer.cast<VertexBuffer>();
|
PVertexBuffer buffer = uniformBuffer.cast<VertexBuffer>();
|
||||||
encoder->setBuffer(buffer->getHandle(), 0, flattenedIndex);
|
|
||||||
boundResources[flattenedIndex] = buffer->getHandle();
|
boundResources[flattenedIndex] = buffer->getHandle();
|
||||||
|
bufferWrites.add(BufferWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.buffer = buffer->getHandle(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PIndexBuffer uniformBuffer) {
|
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PIndexBuffer uniformBuffer) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
||||||
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
||||||
encoder->setBuffer(buffer->getHandle(), 0, flattenedIndex);
|
|
||||||
boundResources[flattenedIndex] = buffer->getHandle();
|
boundResources[flattenedIndex] = buffer->getHandle();
|
||||||
|
bufferWrites.add(BufferWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.buffer = buffer->getHandle(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateSampler(uint32 binding, uint32 index, Gfx::PSampler samplerState) {
|
void DescriptorSet::updateSampler(uint32 binding, uint32 index, Gfx::PSampler samplerState) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
||||||
PSampler sampler = samplerState.cast<Sampler>();
|
PSampler sampler = samplerState.cast<Sampler>();
|
||||||
encoder->setSamplerState(sampler->getHandle(), flattenedIndex);
|
boundResources[flattenedIndex] = nullptr;
|
||||||
|
samplerWrites.add(SamplerWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.sampler = sampler->getHandle(),
|
||||||
|
});
|
||||||
boundResources[flattenedIndex] = nullptr; // Samplers are not resources??????
|
boundResources[flattenedIndex] = nullptr; // Samplers are not resources??????
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateTexture(uint32 binding, uint32 index, Gfx::PTexture2D texture) {
|
void DescriptorSet::updateTexture(uint32 binding, uint32 index, Gfx::PTexture2D texture) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
||||||
PTextureBase tex = texture.cast<TextureBase>();
|
PTextureBase tex = texture.cast<TextureBase>();
|
||||||
encoder->setTexture(tex->getImage(), flattenedIndex);
|
|
||||||
boundResources[flattenedIndex] = tex->getImage();
|
boundResources[flattenedIndex] = tex->getImage();
|
||||||
|
textureWrites.add(TextureWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.texture = tex->getImage(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateTexture(uint32 binding, uint32 index, Gfx::PTexture3D texture) {
|
void DescriptorSet::updateTexture(uint32 binding, uint32 index, Gfx::PTexture3D texture) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
||||||
PTextureBase tex = texture.cast<TextureBase>();
|
PTextureBase tex = texture.cast<TextureBase>();
|
||||||
encoder->setTexture(tex->getImage(), flattenedIndex);
|
|
||||||
boundResources[flattenedIndex] = tex->getImage();
|
boundResources[flattenedIndex] = tex->getImage();
|
||||||
|
textureWrites.add(TextureWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.texture = tex->getImage(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateTexture(uint32 binding, uint32 index, Gfx::PTextureCube texture) {
|
void DescriptorSet::updateTexture(uint32 binding, uint32 index, Gfx::PTextureCube texture) {
|
||||||
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
uint32 flattenedIndex = owner->getLayout()->getFlattenedIndex(binding, index);
|
||||||
PTextureBase tex = texture.cast<TextureBase>();
|
PTextureBase tex = texture.cast<TextureBase>();
|
||||||
encoder->setTexture(tex->getImage(), flattenedIndex);
|
|
||||||
boundResources[flattenedIndex] = tex->getImage();
|
boundResources[flattenedIndex] = tex->getImage();
|
||||||
|
textureWrites.add(TextureWriteInfo{
|
||||||
|
.index = flattenedIndex,
|
||||||
|
.texture = tex->getImage(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateAccelerationStructure(uint32 binding, uint32 index, Gfx::PTopLevelAS as) { assert(false && "TODO"); }
|
void DescriptorSet::updateAccelerationStructure(uint32 binding, uint32 index, Gfx::PTopLevelAS as) { assert(false && "TODO"); }
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class Graphics : public Gfx::Graphics {
|
|||||||
virtual void endRenderPass() override;
|
virtual void endRenderPass() override;
|
||||||
virtual void waitDeviceIdle() override;
|
virtual void waitDeviceIdle() override;
|
||||||
|
|
||||||
|
virtual void executeCommands(Gfx::ORenderCommand commands) override;
|
||||||
virtual void executeCommands(Array<Gfx::ORenderCommand> commands) override;
|
virtual void executeCommands(Array<Gfx::ORenderCommand> commands) override;
|
||||||
virtual void executeCommands(Gfx::OComputeCommand commands) override;
|
virtual void executeCommands(Gfx::OComputeCommand commands) override;
|
||||||
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ void Graphics::waitDeviceIdle() {
|
|||||||
queue->submitCommands();
|
queue->submitCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::executeCommands(Gfx::ORenderCommand commands) {
|
||||||
|
Array<Gfx::ORenderCommand> command;
|
||||||
|
command.add(std::move(commands));
|
||||||
|
queue->executeCommands(std::move(command));
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands) { queue->executeCommands(std::move(commands)); }
|
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands) { queue->executeCommands(std::move(commands)); }
|
||||||
|
|
||||||
void Graphics::executeCommands(Gfx::OComputeCommand commands) {
|
void Graphics::executeCommands(Gfx::OComputeCommand commands) {
|
||||||
|
|||||||
@@ -22,6 +22,14 @@ class GraphicsPipeline : public Gfx::GraphicsPipeline {
|
|||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
MTL::RenderPipelineState* state;
|
MTL::RenderPipelineState* state;
|
||||||
MTL::PrimitiveType primitiveType;
|
MTL::PrimitiveType primitiveType;
|
||||||
|
MTL::Function* taskFunction = nullptr;
|
||||||
|
Array<uint32> taskSets;
|
||||||
|
MTL::Function* meshFunction = nullptr;
|
||||||
|
Array<uint32> meshSets;
|
||||||
|
MTL::Function* vertexFunction = nullptr;
|
||||||
|
Array<uint32> vertexSets;
|
||||||
|
MTL::Function* fragmentFunction = nullptr;
|
||||||
|
Array<uint32> fragmentSets;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
@@ -33,6 +41,7 @@ class ComputePipeline : public Gfx::ComputePipeline {
|
|||||||
constexpr MTL::ComputePipelineState* getHandle() const { return state; }
|
constexpr MTL::ComputePipelineState* getHandle() const { return state; }
|
||||||
|
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
|
MTL::Function* computeFunction;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MTL::ComputePipelineState* state;
|
MTL::ComputePipelineState* state;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "PipelineCache.h"
|
#include "PipelineCache.h"
|
||||||
#include "Descriptor.h"
|
#include "Descriptor.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
|
#include "Metal/MTLLibrary.hpp"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
#include "Foundation/NSError.hpp"
|
#include "Foundation/NSError.hpp"
|
||||||
#include "Foundation/NSString.hpp"
|
#include "Foundation/NSString.hpp"
|
||||||
@@ -62,10 +63,17 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pipelineDescriptor->setVertexDescriptor(vertexDescriptor);
|
pipelineDescriptor->setVertexDescriptor(vertexDescriptor);
|
||||||
|
auto vertShader = createInfo.vertexShader.cast<VertexShader>();
|
||||||
pipelineDescriptor->setVertexFunction(createInfo.vertexShader.cast<VertexShader>()->getFunction());
|
Array<uint32> vertexSets = vertShader->usedDescriptors;
|
||||||
|
MTL::Function* vertexFunction = vertShader->getFunction();
|
||||||
|
Array<uint32> fragmentSets;
|
||||||
|
MTL::Function* fragmentFunction = nullptr;
|
||||||
|
pipelineDescriptor->setVertexFunction(vertexFunction);
|
||||||
if (createInfo.fragmentShader != nullptr) {
|
if (createInfo.fragmentShader != nullptr) {
|
||||||
pipelineDescriptor->setFragmentFunction(createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
auto fragShader = createInfo.fragmentShader.cast<FragmentShader>();
|
||||||
|
fragmentSets = fragShader->usedDescriptors;
|
||||||
|
fragmentFunction = fragShader->getFunction();
|
||||||
|
pipelineDescriptor->setFragmentFunction(fragmentFunction);
|
||||||
}
|
}
|
||||||
pipelineDescriptor->setInputPrimitiveTopology(cast(createInfo.topology));
|
pipelineDescriptor->setInputPrimitiveTopology(cast(createInfo.topology));
|
||||||
for(uint c = 0; c < renderPass->getLayout().colorAttachments.size(); ++c) {
|
for(uint c = 0; c < renderPass->getLayout().colorAttachments.size(); ++c) {
|
||||||
@@ -137,6 +145,10 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
|||||||
}
|
}
|
||||||
|
|
||||||
pipelineDescriptor->release();
|
pipelineDescriptor->release();
|
||||||
|
graphicsPipelines[hash]->vertexSets = vertexSets;
|
||||||
|
graphicsPipelines[hash]->vertexFunction = vertexFunction;
|
||||||
|
graphicsPipelines[hash]->fragmentSets = fragmentSets;
|
||||||
|
graphicsPipelines[hash]->fragmentFunction = fragmentFunction;
|
||||||
return graphicsPipelines[hash];
|
return graphicsPipelines[hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,12 +156,25 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo crea
|
|||||||
PRenderPass renderPass = createInfo.renderPass.cast<RenderPass>();
|
PRenderPass renderPass = createInfo.renderPass.cast<RenderPass>();
|
||||||
MTL::MeshRenderPipelineDescriptor* pipelineDescriptor = MTL::MeshRenderPipelineDescriptor::alloc()->init();
|
MTL::MeshRenderPipelineDescriptor* pipelineDescriptor = MTL::MeshRenderPipelineDescriptor::alloc()->init();
|
||||||
|
|
||||||
pipelineDescriptor->setMeshFunction(createInfo.meshShader.cast<MeshShader>()->getFunction());
|
auto meshShader = createInfo.meshShader.cast<MeshShader>();
|
||||||
|
Array<uint32> meshSets = meshShader->usedDescriptors;
|
||||||
|
MTL::Function* meshFunction = meshShader->getFunction();
|
||||||
|
Array<uint32> taskSets;
|
||||||
|
MTL::Function* taskFunction = nullptr;
|
||||||
|
Array<uint32> fragmentSets;
|
||||||
|
MTL::Function* fragmentFunction = nullptr;
|
||||||
|
pipelineDescriptor->setMeshFunction(meshFunction);
|
||||||
if (createInfo.taskShader != nullptr) {
|
if (createInfo.taskShader != nullptr) {
|
||||||
pipelineDescriptor->setObjectFunction(createInfo.taskShader.cast<TaskShader>()->getFunction());
|
auto taskShader = createInfo.taskShader.cast<TaskShader>();
|
||||||
|
taskSets = taskShader->usedDescriptors;
|
||||||
|
taskFunction = taskShader->getFunction();
|
||||||
|
pipelineDescriptor->setObjectFunction(taskFunction);
|
||||||
}
|
}
|
||||||
if (createInfo.fragmentShader != nullptr) {
|
if (createInfo.fragmentShader != nullptr) {
|
||||||
pipelineDescriptor->setFragmentFunction(createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
auto fragShader = createInfo.fragmentShader.cast<FragmentShader>();
|
||||||
|
fragmentSets = fragShader->usedDescriptors;
|
||||||
|
fragmentFunction = fragShader->getFunction();
|
||||||
|
pipelineDescriptor->setFragmentFunction(fragmentFunction);
|
||||||
}
|
}
|
||||||
for(uint c = 0; c < renderPass->getLayout().colorAttachments.size(); ++c) {
|
for(uint c = 0; c < renderPass->getLayout().colorAttachments.size(); ++c) {
|
||||||
const auto& color = renderPass->getLayout().colorAttachments[c];
|
const auto& color = renderPass->getLayout().colorAttachments[c];
|
||||||
@@ -187,6 +212,13 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo crea
|
|||||||
}
|
}
|
||||||
|
|
||||||
pipelineDescriptor->release();
|
pipelineDescriptor->release();
|
||||||
|
|
||||||
|
graphicsPipelines[hash]->taskSets = taskSets;
|
||||||
|
graphicsPipelines[hash]->taskFunction = taskFunction;
|
||||||
|
graphicsPipelines[hash]->meshSets = meshSets;
|
||||||
|
graphicsPipelines[hash]->meshFunction = meshFunction;
|
||||||
|
graphicsPipelines[hash]->fragmentSets = fragmentSets;
|
||||||
|
graphicsPipelines[hash]->fragmentFunction = fragmentFunction;
|
||||||
return graphicsPipelines[hash];
|
return graphicsPipelines[hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,5 +233,6 @@ PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo cr
|
|||||||
computePipelines[hash] = new ComputePipeline(graphics, graphics->getDevice()->newComputePipelineState(shader->getFunction(), &error),
|
computePipelines[hash] = new ComputePipeline(graphics, graphics->getDevice()->newComputePipelineState(shader->getFunction(), &error),
|
||||||
std::move(createInfo.pipelineLayout));
|
std::move(createInfo.pipelineLayout));
|
||||||
assert(!error);
|
assert(!error);
|
||||||
|
computePipelines[hash]->computeFunction = shader->getFunction();
|
||||||
return computePipelines[hash];
|
return computePipelines[hash];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,14 @@ class Shader {
|
|||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
MTL::Library* library;
|
MTL::Library* library;
|
||||||
MTL::Function* function;
|
MTL::Function* function;
|
||||||
|
// since metal is stupid and doesnt let us create argument encoders for
|
||||||
|
// descriptors of stages that dont use them, we have to track
|
||||||
|
// which stage uses what descriptors, which makes sense since functions are independent
|
||||||
|
// but since metal ALSO doesnt provide any way to find out we have to
|
||||||
|
// literally manually string search the generated code to find out
|
||||||
|
Array<uint32> usedDescriptors;
|
||||||
uint32 hash;
|
uint32 hash;
|
||||||
|
friend class PipelineCache;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Shader)
|
DEFINE_REF(Shader)
|
||||||
|
|
||||||
@@ -60,4 +67,4 @@ DEFINE_REF(AnyHitShader)
|
|||||||
DEFINE_REF(MissShader)
|
DEFINE_REF(MissShader)
|
||||||
DEFINE_REF(CallableShader)
|
DEFINE_REF(CallableShader)
|
||||||
} // namespace Metal
|
} // namespace Metal
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <slang.h>
|
#include <slang.h>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Metal;
|
using namespace Seele::Metal;
|
||||||
@@ -26,9 +27,16 @@ Shader::~Shader() {
|
|||||||
void Shader::create(const ShaderCreateInfo& createInfo) {
|
void Shader::create(const ShaderCreateInfo& createInfo) {
|
||||||
auto [kernelBlob, entryPoint] = generateShader(createInfo);
|
auto [kernelBlob, entryPoint] = generateShader(createInfo);
|
||||||
hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32());
|
hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32());
|
||||||
std::ofstream test("test.metal");
|
std::regex pattern("\\[\\[buffer\\(\\d+\\)\\]\\]");
|
||||||
test.write((const char*)kernelBlob->getBufferPointer(), kernelBlob->getBufferSize());
|
|
||||||
test.close();
|
std::string codeStr = std::string((const char*)kernelBlob->getBufferPointer());
|
||||||
|
auto matches_begin = std::sregex_iterator(codeStr.begin(), codeStr.end(), pattern);
|
||||||
|
auto matches_end = std::sregex_iterator();
|
||||||
|
|
||||||
|
for (auto it = matches_begin; it != matches_end; ++it) {
|
||||||
|
usedDescriptors.add(std::atoi((*it).str().c_str()+9)); // [[buffer( is 9 characters
|
||||||
|
}
|
||||||
|
|
||||||
NS::Error* error;
|
NS::Error* error;
|
||||||
MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init();
|
MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init();
|
||||||
library = graphics->getDevice()->newLibrary(NS::String::string((char*)kernelBlob->getBufferPointer(), NS::ASCIIStringEncoding), options,
|
library = graphics->getDevice()->newLibrary(NS::String::string((char*)kernelBlob->getBufferPointer(), NS::ASCIIStringEncoding), options,
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ void BasePass::beginFrame(const Component::Camera& cam) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BasePass::render() {
|
void BasePass::render() {
|
||||||
opaqueCulling->updateBuffer(0, 0, oLightIndexList);
|
/*opaqueCulling->updateBuffer(0, 0, oLightIndexList);
|
||||||
opaqueCulling->updateTexture(1, 0, oLightGrid);
|
opaqueCulling->updateTexture(1, 0, oLightGrid);
|
||||||
transparentCulling->updateBuffer(0, 0, tLightIndexList);
|
transparentCulling->updateBuffer(0, 0, tLightIndexList);
|
||||||
transparentCulling->updateTexture(1, 0, tLightGrid);
|
transparentCulling->updateTexture(1, 0, tLightGrid);
|
||||||
@@ -250,16 +250,21 @@ void BasePass::render() {
|
|||||||
|
|
||||||
//commands.add(waterRenderer->render(viewParamsSet));
|
//commands.add(waterRenderer->render(viewParamsSet));
|
||||||
//commands.add(terrainRenderer->render(viewParamsSet));
|
//commands.add(terrainRenderer->render(viewParamsSet));
|
||||||
|
*/
|
||||||
// Skybox
|
// Skybox
|
||||||
|
graphics->waitDeviceIdle();
|
||||||
|
graphics->beginRenderPass(renderPass);
|
||||||
{
|
{
|
||||||
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
||||||
skyboxCommand->setViewport(viewport);
|
skyboxCommand->setViewport(viewport);
|
||||||
skyboxCommand->bindPipeline(pipeline);
|
skyboxCommand->bindPipeline(pipeline);
|
||||||
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
||||||
skyboxCommand->draw(36, 1, 0, 0);
|
skyboxCommand->draw(36, 1, 0, 0);
|
||||||
commands.add(std::move(skyboxCommand));
|
graphics->executeCommands(std::move(skyboxCommand));
|
||||||
}
|
}
|
||||||
|
graphics->endRenderPass();
|
||||||
|
graphics->waitDeviceIdle();
|
||||||
|
/*
|
||||||
// Transparent rendering
|
// Transparent rendering
|
||||||
{
|
{
|
||||||
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
||||||
@@ -376,6 +381,7 @@ void BasePass::render() {
|
|||||||
query->endQuery();
|
query->endQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd");
|
||||||
gDebugVertices.clear();
|
gDebugVertices.clear();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePass::endFrame() {}
|
void BasePass::endFrame() {}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ CachedDepthPass::~CachedDepthPass() {}
|
|||||||
void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
||||||
|
|
||||||
void CachedDepthPass::render() {
|
void CachedDepthPass::render() {
|
||||||
query->beginQuery();
|
/* query->beginQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin");
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
@@ -136,7 +136,7 @@ void CachedDepthPass::render() {
|
|||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
graphics->waitDeviceIdle();
|
graphics->waitDeviceIdle();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd");
|
||||||
query->endQuery();
|
query->endQuery();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void CachedDepthPass::endFrame() {}
|
void CachedDepthPass::endFrame() {}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ DepthCullingPass::~DepthCullingPass() {}
|
|||||||
void DepthCullingPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
void DepthCullingPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
||||||
|
|
||||||
void DepthCullingPass::render() {
|
void DepthCullingPass::render() {
|
||||||
query->beginQuery();
|
/*query->beginQuery();
|
||||||
depthAttachment.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
depthAttachment.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
@@ -217,7 +217,7 @@ void DepthCullingPass::render() {
|
|||||||
// Sync visibility write with compute read
|
// Sync visibility write with compute read
|
||||||
visibilityAttachment.getTexture()->pipelineBarrier(Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
visibilityAttachment.getTexture()->pipelineBarrier(Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthCullingPass::endFrame() {}
|
void DepthCullingPass::endFrame() {}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "RenderGraph.h"
|
#include "RenderGraph.h"
|
||||||
#include "Scene/Scene.h"
|
#include "Scene/Scene.h"
|
||||||
|
#include "Graphics/Metal/Descriptor.h"
|
||||||
|
#include "Graphics/Metal/Shader.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ void LightCullingPass::beginFrame(const Component::Camera& cam) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::render() {
|
void LightCullingPass::render() {
|
||||||
query->beginQuery();
|
/*query->beginQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LightCullBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LightCullBegin");
|
||||||
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
@@ -71,7 +73,7 @@ void LightCullingPass::render() {
|
|||||||
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::endFrame() {}
|
void LightCullingPass::endFrame() {}
|
||||||
@@ -248,7 +250,7 @@ void LightCullingPass::setupFrustums() {
|
|||||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
.uniformLength = 56,//sizeof(DispatchParams),
|
.uniformLength = sizeof(DispatchParams),
|
||||||
});
|
});
|
||||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.binding = 1,
|
.binding = 1,
|
||||||
@@ -269,6 +271,8 @@ void LightCullingPass::setupFrustums() {
|
|||||||
graphics->beginShaderCompilation(createInfo);
|
graphics->beginShaderCompilation(createInfo);
|
||||||
frustumShader = graphics->createComputeShader({0});
|
frustumShader = graphics->createComputeShader({0});
|
||||||
// Have to compile shader before finalizing layout as parameters get mapped later
|
// Have to compile shader before finalizing layout as parameters get mapped later
|
||||||
|
Metal::ComputeShader* shader = (Metal::ComputeShader*)(*frustumShader);
|
||||||
|
std::cout << shader->getFunction()->newArgumentEncoder(1)->debugDescription()->cString(NS::ASCIIStringEncoding) << std::endl;
|
||||||
frustumLayout->create();
|
frustumLayout->create();
|
||||||
|
|
||||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||||
@@ -315,7 +319,7 @@ void LightCullingPass::setupFrustums() {
|
|||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
graphics->waitDeviceIdle();
|
|
||||||
Frustum* frustums = (Frustum*)frustumBuffer->map();
|
Frustum* frustums = (Frustum*)frustumBuffer->map();
|
||||||
std::cout << frustums << std::endl;
|
graphics->waitDeviceIdle();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ void VisibilityPass::beginFrame(const Component::Camera& cam) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VisibilityPass::render() {
|
void VisibilityPass::render() {
|
||||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
/*cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
||||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||||
cullingBuffer->clear();
|
cullingBuffer->clear();
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ void VisibilityPass::render() {
|
|||||||
query->endQuery();
|
query->endQuery();
|
||||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);
|
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibilityPass::endFrame() {}
|
void VisibilityPass::endFrame() {}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ void ShaderCompiler::compile() {
|
|||||||
if (pass.useMaterial) {
|
if (pass.useMaterial) {
|
||||||
for (const auto& [matName, mat] : materials) {
|
for (const auto& [matName, mat] : materials) {
|
||||||
for (int y = 0; y < 2; y++) {
|
for (int y = 0; y < 2; y++) {
|
||||||
work.add([=]() {
|
work.add([=, this]() {
|
||||||
ShaderPermutation permutation = getTemplate(name);
|
ShaderPermutation permutation = getTemplate(name);
|
||||||
permutation.setPositionOnly(false);
|
permutation.setPositionOnly(false);
|
||||||
permutation.setDepthCulling(y);
|
permutation.setDepthCulling(y);
|
||||||
|
|||||||
@@ -38,6 +38,20 @@ std::ostream& operator<<(std::ostream& stream, const Vector4& vector) {
|
|||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& stream, const UVector2& vector) {
|
||||||
|
stream << "UVec2(" << vector.x << ", " << vector.y << ")";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
std::ostream& operator<<(std::ostream& stream, const UVector& vector) {
|
||||||
|
stream << "UVec3(" << vector.x << ", " << vector.y << ", " << vector.z << ")";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
std::ostream& operator<<(std::ostream& stream, const UVector4& vector) {
|
||||||
|
stream << "UVec4(" << vector.x << ", " << vector.y << ", " << vector.z << ", " << vector.w << ")";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& stream, const Quaternion& vector) {
|
std::ostream& operator<<(std::ostream& stream, const Quaternion& vector) {
|
||||||
stream << "Quat(" << vector.w << ", " << vector.x << ", " << vector.y << ", " << vector.z << ")";
|
stream << "Quat(" << vector.w << ", " << vector.x << ", " << vector.y << ", " << vector.z << ")";
|
||||||
return stream;
|
return stream;
|
||||||
@@ -53,4 +67,4 @@ Vector Seele::parseVector(const char* str) {
|
|||||||
float y = std::stof(base_match[2].str());
|
float y = std::stof(base_match[2].str());
|
||||||
float z = std::stof(base_match[3].str());
|
float z = std::stof(base_match[3].str());
|
||||||
return Vector(x, y, z);
|
return Vector(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,4 +45,9 @@ void from_json(nlohmann::json& j, Vector& vec);
|
|||||||
std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector);
|
std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector);
|
||||||
std::ostream& operator<<(std::ostream& stream, const Seele::Vector& vector);
|
std::ostream& operator<<(std::ostream& stream, const Seele::Vector& vector);
|
||||||
std::ostream& operator<<(std::ostream& stream, const Seele::Vector4& vector);
|
std::ostream& operator<<(std::ostream& stream, const Seele::Vector4& vector);
|
||||||
std::ostream& operator<<(std::ostream& stream, const Seele::Quaternion& vector);
|
|
||||||
|
std::ostream& operator<<(std::ostream& stream, const Seele::UVector2& vector);
|
||||||
|
std::ostream& operator<<(std::ostream& stream, const Seele::UVector& vector);
|
||||||
|
std::ostream& operator<<(std::ostream& stream, const Seele::UVector4& vector);
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& stream, const Seele::Quaternion& vector);
|
||||||
|
|||||||
@@ -15,13 +15,11 @@
|
|||||||
#include "System/LightGather.h"
|
#include "System/LightGather.h"
|
||||||
#include "System/MeshUpdater.h"
|
#include "System/MeshUpdater.h"
|
||||||
#include "Window/Window.h"
|
#include "Window/Window.h"
|
||||||
#include <fstream>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath)
|
GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath)
|
||||||
: View(graphics, window, createInfo, "Game"), scene(new Scene(graphics)), gameInterface(dllPath) {
|
: View(graphics, window, createInfo, "Game"), graphics(graphics), scene(new Scene(graphics)), gameInterface(dllPath) {
|
||||||
reloadGame();
|
reloadGame();
|
||||||
renderGraph.addPass(new CachedDepthPass(graphics, scene));
|
renderGraph.addPass(new CachedDepthPass(graphics, scene));
|
||||||
renderGraph.addPass(new DepthCullingPass(graphics, scene));
|
renderGraph.addPass(new DepthCullingPass(graphics, scene));
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class GameView : public View {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void applyArea(URect rect) override;
|
virtual void applyArea(URect rect) override;
|
||||||
|
Gfx::PGraphics graphics;
|
||||||
OScene scene;
|
OScene scene;
|
||||||
GameInterface gameInterface;
|
GameInterface gameInterface;
|
||||||
RenderGraph renderGraph;
|
RenderGraph renderGraph;
|
||||||
|
|||||||
Reference in New Issue
Block a user