Metal changes
This commit is contained in:
@@ -19,7 +19,7 @@ if(WIN32)
|
||||
${SLANG_ROOT}lib/slang.lib
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
elseif(APPLE)
|
||||
set(BINARY_ROOT ${SLANG_ROOT}/build/Debug/)
|
||||
set(BINARY_ROOT ${SOURCE_DIR}../../slang/build/Debug/)
|
||||
set_target_properties(slang PROPERTIES IMPORTED_LOCATION ${BINARY_ROOT}/lib/libslang.dylib)
|
||||
install(FILES
|
||||
${BINARY_ROOT}/lib/libslang.dylib
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Common;
|
||||
import VertexData;
|
||||
import StaticMeshVertexData;
|
||||
import MaterialParameter;
|
||||
import Scene;
|
||||
|
||||
|
||||
@@ -27,16 +27,23 @@ struct FragmentParameter
|
||||
float3 biTangent_WS : TANGENT1;
|
||||
float3 position_WS : POSITION2;
|
||||
float3 vertexColor : COLOR0;
|
||||
float2 texCoords[MAX_TEXCOORDS] : TEXCOORD0;
|
||||
float4 texCoords0 : TEXCOORD0;
|
||||
float4 texCoords1 : TEXCOORD1;
|
||||
float4 texCoords2 : TEXCOORD2;
|
||||
float4 texCoords3 : TEXCOORD3;
|
||||
MaterialParameter getMaterialParameter()
|
||||
{
|
||||
MaterialParameter result;
|
||||
result.position_WS = position_WS;
|
||||
result.vertexColor = vertexColor;
|
||||
for(uint i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
result.texCoords[i] = texCoords[i];
|
||||
}
|
||||
result.texCoords[0] = texCoords0.xy;
|
||||
result.texCoords[1] = texCoords0.zw;
|
||||
result.texCoords[2] = texCoords1.xy;
|
||||
result.texCoords[3] = texCoords1.zw;
|
||||
result.texCoords[4] = texCoords2.xy;
|
||||
result.texCoords[5] = texCoords2.zw;
|
||||
result.texCoords[6] = texCoords3.xy;
|
||||
result.texCoords[7] = texCoords3.zw;
|
||||
return result;
|
||||
}
|
||||
LightingParameter getLightingParameter()
|
||||
@@ -66,10 +73,10 @@ struct FragmentParameter
|
||||
result.biTangent_WS = f0.biTangent_WS * barycentricCoords.x + f1.biTangent_WS * barycentricCoords.y + f2.biTangent_WS * barycentricCoords.z;
|
||||
result.position_WS = f0.position_WS * barycentricCoords.x + f1.position_WS * barycentricCoords.y + f2.position_WS * barycentricCoords.z;
|
||||
result.vertexColor = f0.vertexColor * barycentricCoords.x + f1.vertexColor * barycentricCoords.y + f2.vertexColor * barycentricCoords.z;
|
||||
for(uint i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
result.texCoords[i] = f0.texCoords[i] * barycentricCoords.x + f1.texCoords[i] * barycentricCoords.y + f2.texCoords[i] * barycentricCoords.z;
|
||||
}
|
||||
//for(uint i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
//{
|
||||
// result.texCoords[i] = f0.texCoords[i] * barycentricCoords.x + f1.texCoords[i] * barycentricCoords.y + f2.texCoords[i] * barycentricCoords.z;
|
||||
//}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
@@ -112,10 +119,10 @@ struct VertexAttributes
|
||||
result.biTangent_WS = B;
|
||||
result.position_WS = worldPos.xyz;
|
||||
result.vertexColor = vertexColor;
|
||||
for(uint i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
result.texCoords[i] = texCoords[i];
|
||||
}
|
||||
result.texCoords0 = float4(texCoords[0], texCoords[1]);
|
||||
result.texCoords1 = float4(texCoords[2], texCoords[3]);
|
||||
result.texCoords2 = float4(texCoords[4], texCoords[5]);
|
||||
result.texCoords3 = float4(texCoords[6], texCoords[7]);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import Common;
|
||||
import VertexData;
|
||||
import MaterialParameter;
|
||||
|
||||
struct StaticMeshVertexData : IVertexData
|
||||
struct StaticMeshVertexData
|
||||
{
|
||||
VertexAttributes getAttributes(uint index)
|
||||
{
|
||||
@@ -27,3 +27,5 @@ struct StaticMeshVertexData : IVertexData
|
||||
StructuredBuffer<float4> color;
|
||||
StructuredBuffer<float2> texCoords[MAX_TEXCOORDS];
|
||||
};
|
||||
layout(set=1)
|
||||
ParameterBlock<StaticMeshVertexData> pVertexData;
|
||||
|
||||
@@ -10,6 +10,3 @@ interface IVertexData
|
||||
{
|
||||
VertexAttributes getAttributes(uint index);
|
||||
};
|
||||
|
||||
layout(set=1)
|
||||
ParameterBlock<IVertexData> pVertexData;
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Metal/MTLResource.hpp"
|
||||
#include "Metal/MTLTypes.hpp"
|
||||
#include "MinimalEngine.h"
|
||||
#include "Resources.h"
|
||||
@@ -11,31 +12,47 @@ namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class BufferAllocation : public CommandBoundResource {
|
||||
public:
|
||||
BufferAllocation(PGraphics graphics);
|
||||
BufferAllocation(PGraphics graphics, const std::string& name, uint64 size, MTL::ResourceOptions options = MTL::ResourceOptionCPUCacheModeDefault);
|
||||
virtual ~BufferAllocation();
|
||||
void pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void transferOwnership(Gfx::QueueType newOwner);
|
||||
void updateContents(uint64 regionOffset, uint64 regionSize, void* ptr);
|
||||
void readContents(uint64 regionOffset, uint64 regionSize, void* ptr);
|
||||
void* map();
|
||||
void unmap();
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64 size = 0;
|
||||
};
|
||||
DECLARE_REF(BufferAllocation)
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic, const std::string& name);
|
||||
Buffer(PGraphics graphics, uint64 size, Gfx::SeBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name,
|
||||
bool createCleared = false, uint32 clearValue = 0);
|
||||
virtual ~Buffer();
|
||||
MTL::Buffer* getHandle() const { return buffers[currentBuffer]->buffer; }
|
||||
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return buffers[currentBuffer]->size; }
|
||||
void* map(bool writeOnly = true);
|
||||
void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly);
|
||||
void unmap();
|
||||
void updateContents(uint64 regionOffset, uint64 regionSize, void* ptr);
|
||||
void readContents(uint64 regionOffset, uint64 regionSize, void* ptr);
|
||||
|
||||
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer = 0;
|
||||
uint32 currentBuffer;
|
||||
Gfx::QueueType initialOwner;
|
||||
Array<OBufferAllocation> buffers;
|
||||
Gfx::SeBufferUsageFlags usage;
|
||||
bool dynamic;
|
||||
bool createCleared;
|
||||
std::string name;
|
||||
void rotateBuffer(uint64 size);
|
||||
void createBuffer(uint64 size, void* data);
|
||||
uint32 clearValue;
|
||||
void rotateBuffer(uint64 size, bool preserveContents = false);
|
||||
void createBuffer(uint64 size, uint32 destIndex);
|
||||
void copyBuffer(uint64 src, uint64 dest);
|
||||
|
||||
void transferOwnership(Gfx::QueueType newOwner);
|
||||
void pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
|
||||
};
|
||||
DEFINE_REF(Buffer)
|
||||
|
||||
@@ -73,7 +90,8 @@ class UniformBuffer : public Gfx::UniformBuffer, public Buffer {
|
||||
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo);
|
||||
virtual ~UniformBuffer();
|
||||
|
||||
virtual bool updateContents(const DataSource& sourceData) override;
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
virtual void updateContents(const DataSource& sourceData) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
@@ -86,10 +104,10 @@ class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer {
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& createInfo);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
virtual void readContents(Array<uint8>& data) override;
|
||||
virtual void rotateBuffer(uint64 size, bool preserveContents = false) override;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo& sourceData) override;
|
||||
virtual void* mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||
virtual void unmap() override;
|
||||
virtual void clear() override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Buffer.h"
|
||||
#include "Foundation/NSString.hpp"
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/Enums.h"
|
||||
@@ -10,8 +11,11 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
BufferAllocation::BufferAllocation(PGraphics graphics)
|
||||
: CommandBoundResource(graphics) {}
|
||||
BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, uint64 size, MTL::ResourceOptions options)
|
||||
: CommandBoundResource(graphics) {
|
||||
buffer = graphics->getDevice()->newBuffer(size, options);
|
||||
buffer->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
BufferAllocation::~BufferAllocation() {
|
||||
if (buffer != nullptr) {
|
||||
@@ -19,10 +23,42 @@ BufferAllocation::~BufferAllocation() {
|
||||
}
|
||||
}
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic,
|
||||
const std::string &name)
|
||||
: graphics(graphics), dynamic(dynamic), name(name) {
|
||||
createBuffer(size, data);
|
||||
void BufferAllocation::pipelineBarrier(Gfx::SeAccessFlags, Gfx::SePipelineStageFlags , Gfx::SeAccessFlags, Gfx::SePipelineStageFlags)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BufferAllocation::transferOwnership(Gfx::QueueType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, void* ptr)
|
||||
{
|
||||
std::memcpy((uint8*)buffer->contents() + regionOffset, ptr, regionSize);
|
||||
}
|
||||
|
||||
void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void* ptr)
|
||||
{
|
||||
std::memcpy(ptr, (uint8*)buffer->contents() + regionOffset, regionSize);
|
||||
}
|
||||
|
||||
void* BufferAllocation::map()
|
||||
{
|
||||
return buffer->contents();
|
||||
}
|
||||
|
||||
void BufferAllocation::unmap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, Gfx::SeBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name,
|
||||
bool createCleared, uint32 clearValue)
|
||||
: graphics(graphics), currentBuffer(0), dynamic(dynamic), createCleared(createCleared), name(name), clearValue(clearValue) {
|
||||
buffers.add(nullptr);
|
||||
createBuffer(size, 0);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
@@ -31,52 +67,76 @@ Buffer::~Buffer() {
|
||||
}
|
||||
}
|
||||
|
||||
void *Buffer::map(bool) { return getHandle()->contents(); }
|
||||
|
||||
void *Buffer::mapRegion(uint64 regionOffset, uint64, bool) {
|
||||
return (char *)getHandle()->contents() + regionOffset;
|
||||
void Buffer::updateContents(uint64 regionOffset, uint64 regionSize, void* ptr)
|
||||
{
|
||||
getAlloc()->updateContents(regionOffset, regionSize, ptr);
|
||||
}
|
||||
|
||||
void Buffer::unmap() {}
|
||||
|
||||
void Buffer::rotateBuffer(uint64 size) {
|
||||
size = std::max(getSize(), size);
|
||||
for (size_t i = 0; i < buffers.size(); ++i) {
|
||||
if (buffers[i]->isCurrentlyBound()) {
|
||||
continue;
|
||||
}
|
||||
if (buffers[i]->size < size) {
|
||||
buffers[i]->buffer->release();
|
||||
buffers[i]->buffer =
|
||||
graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
buffers[i]->size = size;
|
||||
}
|
||||
currentBuffer = i;
|
||||
return;
|
||||
}
|
||||
createBuffer(size, nullptr);
|
||||
currentBuffer = buffers.size() - 1;
|
||||
void Buffer::readContents(uint64 regionOffset, uint64 regionSize, void* ptr)
|
||||
{
|
||||
getAlloc()->readContents(regionOffset, regionSize, ptr);
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(uint64 size, void *data) {
|
||||
buffers.add(new BufferAllocation(graphics));
|
||||
if (data != nullptr) {
|
||||
buffers.back()->buffer =
|
||||
graphics->getDevice()->newBuffer(data, size, MTL::StorageModeShared);
|
||||
} else {
|
||||
buffers.back()->buffer =
|
||||
graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
}
|
||||
buffers.back()->buffer->setLabel(
|
||||
NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
void Buffer::rotateBuffer(uint64 size, bool preserveContents)
|
||||
{
|
||||
if(size == 0)
|
||||
return;
|
||||
assert(dynamic);
|
||||
for(uint32 i = 0; i < buffers.size(); ++i) {
|
||||
if(buffers[i]->isCurrentlyBound()) {
|
||||
continue;
|
||||
}
|
||||
if(buffers[i]->size < size) {
|
||||
createBuffer(size, i);
|
||||
}
|
||||
if(preserveContents) {
|
||||
copyBuffer(currentBuffer, i);
|
||||
}
|
||||
currentBuffer = i;
|
||||
return;
|
||||
}
|
||||
buffers.add(nullptr);
|
||||
createBuffer(size, buffers.size() - 1);
|
||||
if(preserveContents) {
|
||||
copyBuffer(currentBuffer, buffers.size() - 1);
|
||||
}
|
||||
currentBuffer = buffers.size() - 1;
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(uint64 size, uint32 destIndex)
|
||||
{
|
||||
buffers[destIndex] = new BufferAllocation(graphics, name, size);
|
||||
if(createCleared) {
|
||||
std::memset(buffers[destIndex]->map(), clearValue, buffers[destIndex]->size);
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::copyBuffer(uint64 src, uint64 dest)
|
||||
{
|
||||
if(src == dest) {
|
||||
return;
|
||||
}
|
||||
std::memcpy(buffers[dest]->map(), buffers[src]->map(), buffers[src]->size);
|
||||
}
|
||||
|
||||
void Buffer::transferOwnership(Gfx::QueueType newOwner)
|
||||
{
|
||||
getAlloc()->transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
void Buffer::pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
getAlloc()->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics,
|
||||
const VertexBufferCreateInfo &createInfo)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo.numVertices,
|
||||
createInfo.vertexSize, createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, false, createInfo.name) {
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo),
|
||||
Metal::Buffer(graphics, createInfo.sourceData.size, Gfx::SE_BUFFER_USAGE_VERTEX_BUFFER_BIT, createInfo.sourceData.owner, false,
|
||||
createInfo.name) {
|
||||
if(createInfo.sourceData.size > 0 && createInfo.sourceData.data != nullptr) {
|
||||
getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data);
|
||||
}
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer() {}
|
||||
@@ -93,20 +153,22 @@ void VertexBuffer::download(Array<uint8> &buffer) {
|
||||
}
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
Metal::Buffer::transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
void VertexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
Metal::Buffer::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics,
|
||||
const IndexBufferCreateInfo &createInfo)
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size,
|
||||
createInfo.indexType, createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, false, createInfo.name) {
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo),
|
||||
Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
Gfx::SE_BUFFER_USAGE_INDEX_BUFFER_BIT | Gfx::SE_BUFFER_USAGE_TRANSFER_DST_BIT | Gfx::SE_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
createInfo.sourceData.owner, false, createInfo.name) {
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer() {}
|
||||
@@ -117,76 +179,90 @@ void IndexBuffer::download(Array<uint8> &buffer) {
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
}
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
Metal::Buffer::transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
void IndexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
Metal::Buffer::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics,
|
||||
const UniformBufferCreateInfo &createInfo)
|
||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, createInfo.dynamic,
|
||||
createInfo.name) {}
|
||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo),
|
||||
Metal::Buffer(graphics, createInfo.sourceData.size, Gfx::SE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, createInfo.sourceData.owner,
|
||||
createInfo.dynamic, createInfo.name) {
|
||||
getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data);
|
||||
}
|
||||
|
||||
UniformBuffer::~UniformBuffer() {}
|
||||
|
||||
bool UniformBuffer::updateContents(const DataSource &sourceData) {
|
||||
void *data = getHandle()->contents();
|
||||
std::memcpy((char *)data + sourceData.offset, sourceData.data,
|
||||
sourceData.size);
|
||||
return true;
|
||||
void UniformBuffer::rotateBuffer(uint64 size) {
|
||||
Metal::Buffer::rotateBuffer(size);
|
||||
}
|
||||
|
||||
void UniformBuffer::updateContents(const DataSource &sourceData) {
|
||||
if (sourceData.size > 0 && sourceData.data != nullptr) {
|
||||
Metal::Buffer::rotateBuffer(sourceData.size);
|
||||
getAlloc()->updateContents(sourceData.offset, sourceData.size, sourceData.data);
|
||||
}
|
||||
}
|
||||
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
Metal::Buffer::transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
void UniformBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
Metal::Buffer::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics,
|
||||
const ShaderBufferCreateInfo &createInfo)
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo.numElements,
|
||||
createInfo.sourceData),
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, createInfo.dynamic,
|
||||
createInfo.name) {}
|
||||
Gfx::SE_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
createInfo.sourceData.owner, createInfo.dynamic, createInfo.name, createInfo.createCleared, createInfo.clearValue) {}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer() {}
|
||||
|
||||
void ShaderBuffer::rotateBuffer(uint64 size) {
|
||||
Metal::Buffer::rotateBuffer(size);
|
||||
void ShaderBuffer::readContents(Array<uint8>& data) {
|
||||
data.resize(getSize());
|
||||
getAlloc()->readContents(0, data.size(), data.data());
|
||||
}
|
||||
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) {
|
||||
Gfx::ShaderBuffer::updateContents(createInfo);
|
||||
if (createInfo.sourceData.data == nullptr) {
|
||||
return;
|
||||
}
|
||||
void *data = map();
|
||||
std::memcpy((char *)data + createInfo.sourceData.offset,
|
||||
createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unmap();
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) {
|
||||
if (createInfo.sourceData.data == nullptr) {
|
||||
return;
|
||||
}
|
||||
// We always want to update, as the contents could be different on the GPU
|
||||
if (createInfo.sourceData.size > 0 && createInfo.sourceData.data != nullptr) {
|
||||
getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) {
|
||||
return Metal::Buffer::mapRegion(offset, size, writeOnly);
|
||||
void ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) {
|
||||
assert(dynamic);
|
||||
Metal::Buffer::rotateBuffer(size, preserveContents);
|
||||
}
|
||||
|
||||
void ShaderBuffer::unmap() { Metal::Buffer::unmap(); }
|
||||
|
||||
void ShaderBuffer::clear() {
|
||||
std::memset(getAlloc()->map(), 0, getSize());
|
||||
}
|
||||
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
Metal::Buffer::transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
void ShaderBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
Metal::Buffer::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "Buffer.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Metal/MTLArgumentEncoder.hpp"
|
||||
#include "Metal/MTLBlitCommandEncoder.hpp"
|
||||
#include "Metal/MTLCaptureManager.hpp"
|
||||
#include "Metal/MTLCommandBuffer.hpp"
|
||||
@@ -55,6 +56,7 @@ class RenderCommand : public Gfx::RenderCommand {
|
||||
void end();
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindPipeline(Gfx::PRayTracingPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
|
||||
@@ -64,10 +66,12 @@ class RenderCommand : public Gfx::RenderCommand {
|
||||
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override;
|
||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
|
||||
virtual void traceRays(uint32 width, uint32 height, uint32 depth) override;
|
||||
|
||||
private:
|
||||
PGraphicsPipeline boundPipeline;
|
||||
PIndexBuffer boundIndexBuffer;
|
||||
MTL::ArgumentEncoder* argumentEncoder;
|
||||
MTL::Buffer* argumentBuffer;
|
||||
MTL::RenderCommandEncoder* encoder;
|
||||
std::string name;
|
||||
|
||||
@@ -84,15 +84,10 @@ void RenderCommand::setViewport(Gfx::PViewport viewport) {
|
||||
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
|
||||
boundPipeline = pipeline.cast<GraphicsPipeline>();
|
||||
encoder->setRenderPipelineState(boundPipeline->getHandle());
|
||||
uint64 argBufferSize = 0;
|
||||
for (auto [_, layout] : boundPipeline->getPipelineLayout()->getLayouts()) {
|
||||
argBufferSize += 3 * sizeof(uint64) * layout->getBindings().size();
|
||||
}
|
||||
argumentBuffer = boundPipeline->graphics->getDevice()->newBuffer(
|
||||
argBufferSize, MTL::ResourceStorageModeShared);
|
||||
argumentBuffer->setLabel(
|
||||
NS::String::string(boundPipeline->getPipelineLayout()->getName().c_str(),
|
||||
NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
void RenderCommand::bindPipeline(Gfx::PRayTracingPipeline pipeline) {
|
||||
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet,
|
||||
@@ -126,7 +121,10 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet,
|
||||
usage = MTL::ResourceUsageWrite;
|
||||
break;
|
||||
}
|
||||
encoder->useResource(metalSet->getBoundResources()[i], usage);
|
||||
for(size_t x = 0; x < metalSet->getBoundResources()[i].size(); ++x)
|
||||
{
|
||||
encoder->useResource(metalSet->getBoundResources()[i][x], usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,6 +186,10 @@ void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset,
|
||||
// encoder->drawMeshThreadgroups()
|
||||
}
|
||||
|
||||
void RenderCommand::traceRays(uint32 width, uint32 height, uint32 depth){
|
||||
|
||||
}
|
||||
|
||||
ComputeCommand::ComputeCommand(MTL::CommandBuffer *cmdBuffer,
|
||||
const std::string &name)
|
||||
: commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()),
|
||||
@@ -244,7 +246,10 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set,
|
||||
usage = MTL::ResourceUsageWrite;
|
||||
break;
|
||||
}
|
||||
encoder->useResource(metalSet->getBoundResources()[i], usage);
|
||||
for(size_t x = 0; x < metalSet->getBoundResources()[i].size(); ++x)
|
||||
{
|
||||
encoder->useResource(metalSet->getBoundResources()[i][x], usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
#include "Buffer.h"
|
||||
#include "Foundation/NSArray.hpp"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Resources.h"
|
||||
#include "Metal/MTLArgumentEncoder.hpp"
|
||||
#include "Metal/MTLLibrary.hpp"
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
namespace Seele {
|
||||
@@ -13,9 +16,13 @@ class DescriptorLayout : public Gfx::DescriptorLayout {
|
||||
DescriptorLayout(PGraphics graphics, const std::string& name);
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create() override;
|
||||
void setFunction(MTL::Function* func, uint64 ind) { function = func; index = ind; }
|
||||
MTL::ArgumentEncoder* createEncoder() { return function->newArgumentEncoder(index); }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::Function* function;
|
||||
uint64 index;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout)
|
||||
|
||||
@@ -40,27 +47,27 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
|
||||
|
||||
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
|
||||
constexpr void allocate() { currentlyInUse = true; }
|
||||
constexpr void free() { currentlyInUse = false; }
|
||||
virtual void updateBuffer(uint32 binding, Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32 binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32 binding, Gfx::PIndexBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32 binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32 binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateSampler(uint32 binding, uint32 dstArrayIndex, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32 binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTexture(uint32 binding, uint32 dstArrayIndex, Gfx::PTexture texture) override;
|
||||
virtual void updateTextureArray(uint32 binding, Array<Gfx::PTexture2D> texture) override;
|
||||
virtual void updateSamplerArray(uint32 binding, Array<Gfx::PSampler> samplers) override;
|
||||
virtual void updateAccelerationStructure(uint32 binding, Gfx::PTopLevelAS as) override;
|
||||
|
||||
constexpr MTL::Buffer* getBuffer() const { return buffer; }
|
||||
constexpr const Array<MTL::Resource*>& getBoundResources() const { return boundResources; }
|
||||
constexpr const Array<Array<MTL::Resource*>>& getBoundResources() const { return boundResources; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
MTL::ArgumentEncoder* encoder;
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64* argumentBuffer = nullptr;
|
||||
Array<MTL::Resource*> boundResources;
|
||||
bool currentlyInUse;
|
||||
Array<Array<MTL::Resource*>> boundResources;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "Descriptor.h"
|
||||
#include "Buffer.h"
|
||||
#include "Enums.h"
|
||||
#include "Foundation/NSObject.hpp"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Resources.h"
|
||||
@@ -10,6 +11,7 @@
|
||||
#include "Metal/MTLTexture.hpp"
|
||||
#include "Texture.h"
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <CRC.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele;
|
||||
@@ -21,11 +23,11 @@ DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string &name)
|
||||
DescriptorLayout::~DescriptorLayout() {}
|
||||
|
||||
void DescriptorLayout::create() {
|
||||
pool = new DescriptorPool(graphics, this);
|
||||
hash =
|
||||
CRC::Calculate(descriptorBindings.data(),
|
||||
sizeof(Gfx::DescriptorBinding) * descriptorBindings.size(),
|
||||
CRC::CRC_32());
|
||||
pool = new DescriptorPool(graphics, this);
|
||||
hash =
|
||||
CRC::Calculate(descriptorBindings.data(),
|
||||
sizeof(Gfx::DescriptorBinding) * descriptorBindings.size(),
|
||||
CRC::CRC_32());
|
||||
}
|
||||
|
||||
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
|
||||
@@ -35,36 +37,30 @@ DescriptorPool::~DescriptorPool() {}
|
||||
|
||||
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
||||
for (uint32 setIndex = 0; setIndex < allocatedSets.size(); ++setIndex) {
|
||||
if (allocatedSets[setIndex]->isCurrentlyBound() ||
|
||||
allocatedSets[setIndex]->isCurrentlyInUse()) {
|
||||
if (allocatedSets[setIndex]->isCurrentlyBound()) {
|
||||
// Currently in use, skip
|
||||
continue;
|
||||
}
|
||||
allocatedSets[setIndex]->allocate();
|
||||
|
||||
// Found set, stop searching
|
||||
return PDescriptorSet(allocatedSets[setIndex]);
|
||||
}
|
||||
allocatedSets.add(new DescriptorSet(graphics, this));
|
||||
allocatedSets.back()->allocate();
|
||||
return PDescriptorSet(allocatedSets.back());
|
||||
}
|
||||
|
||||
void DescriptorPool::reset() {
|
||||
for (auto &set : allocatedSets) {
|
||||
set->free();
|
||||
}
|
||||
}
|
||||
|
||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
||||
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics),
|
||||
graphics(graphics), owner(owner), currentlyInUse(false) {
|
||||
graphics(graphics), owner(owner) {
|
||||
boundResources.resize(owner->getLayout()->getBindings().size());
|
||||
buffer = graphics->getDevice()->newBuffer(
|
||||
std::max<size_t>(8, sizeof(uint64_t) * 3 *
|
||||
owner->getLayout()->getBindings().size()),
|
||||
MTL::ResourceStorageModeShared);
|
||||
argumentBuffer = (uint64 *)buffer->contents();
|
||||
for(uint32 i = 0; i < boundResources.size(); ++i) {
|
||||
boundResources[i].resize(owner->getLayout()->getBindings()[i].descriptorCount);
|
||||
}
|
||||
encoder = owner->getLayout()->createEncoder();
|
||||
buffer = graphics->getDevice()->newBuffer(encoder->encodedLength(), MTL::ResourceOptionCPUCacheModeDefault);
|
||||
buffer->setLabel(NS::String::string(owner->getLayout()->getName().c_str(),
|
||||
NS::ASCIIStringEncoding));
|
||||
}
|
||||
@@ -73,68 +69,41 @@ DescriptorSet::~DescriptorSet() { buffer->release(); }
|
||||
|
||||
void DescriptorSet::writeChanges() {}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding,
|
||||
Gfx::PUniformBuffer uniformBuffer) {
|
||||
PUniformBuffer metalBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = metalBuffer->getHandle()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] =
|
||||
(uint32)metalBuffer->getSize(); // TODO: buffer texture view, typed??
|
||||
boundResources[binding] = metalBuffer->getHandle();
|
||||
}
|
||||
void DescriptorSet::updateBuffer(uint32_t binding,
|
||||
Gfx::PShaderBuffer uniformBuffer) {
|
||||
PShaderBuffer metalBuffer = uniformBuffer.cast<ShaderBuffer>();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = metalBuffer->getHandle()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] =
|
||||
(uint32)metalBuffer->getSize(); // TODO: buffer texture view, typed??
|
||||
boundResources[binding] = metalBuffer->getHandle();
|
||||
void DescriptorSet::updateBuffer(uint32 binding, Gfx::PUniformBuffer uniformBuffer)
|
||||
{
|
||||
encoder->setBuffer(uniformBuffer.cast<UniformBuffer>()->getHandle(), 0, binding);
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index,
|
||||
Gfx::PShaderBuffer uniformBuffer) {}
|
||||
|
||||
void DescriptorSet::updateSampler(uint32_t binding,
|
||||
Gfx::PSampler samplerState) {
|
||||
PSampler sampler = samplerState.cast<Sampler>();
|
||||
MTL::ResourceID resourceId = sampler->getHandle()->gpuResourceID();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = 0;
|
||||
argumentBuffer[offset + 1] = *(uint64 *)&resourceId;
|
||||
argumentBuffer[offset + 2] = 0; // LOD bias
|
||||
}
|
||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture,
|
||||
Gfx::PSampler samplerState) {
|
||||
PTextureBase base = texture.cast<TextureBase>();
|
||||
if (layout->getBindings()[binding].access ==
|
||||
Gfx::SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT) {
|
||||
MTL::ResourceID resourceId = base->getTexture()->gpuResourceID();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = 0;
|
||||
argumentBuffer[offset + 1] = *(uint64 *)&resourceId;
|
||||
argumentBuffer[offset + 2] = 0; // min LOD clamp
|
||||
} else {
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = base->getTexture()->buffer()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] =
|
||||
(uint32)base->getTexture()
|
||||
->buffer()
|
||||
->length(); // TODO: buffer texture view, typed??
|
||||
}
|
||||
boundResources[binding] = base->getTexture();
|
||||
void DescriptorSet::updateBuffer(uint32 binding, Gfx::PShaderBuffer uniformBuffer)
|
||||
{
|
||||
encoder->setBuffer(uniformBuffer.cast<ShaderBuffer>()->getHandle(), 0, binding);
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTextureArray(uint32_t binding,
|
||||
Array<Gfx::PTexture> array) {
|
||||
for (auto &t : array) {
|
||||
updateTexture(binding++, t);
|
||||
}
|
||||
void DescriptorSet::updateBuffer(uint32 binding, Gfx::PIndexBuffer uniformBuffer)
|
||||
{
|
||||
encoder->setBuffer(uniformBuffer.cast<IndexBuffer>()->getHandle(), 0, binding);
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32 binding, uint32 index, Gfx::PShaderBuffer uniformBuffer)
|
||||
{
|
||||
encoder->setBuffer(uniformBuffer.cast<ShaderBuffer>()->getHandle(), 0, binding);
|
||||
}
|
||||
|
||||
void DescriptorSet::updateSampler(uint32 binding, Gfx::PSampler samplerState)
|
||||
{}
|
||||
void DescriptorSet::updateSampler(uint32 binding, uint32 dstArrayIndex, Gfx::PSampler samplerState)
|
||||
{}
|
||||
void DescriptorSet::updateTexture(uint32 binding, Gfx::PTexture texture, Gfx::PSampler sampler)
|
||||
{}
|
||||
void DescriptorSet::updateTexture(uint32 binding, uint32 dstArrayIndex, Gfx::PTexture texture)
|
||||
{}
|
||||
void DescriptorSet::updateTextureArray(uint32 binding, Array<Gfx::PTexture2D> texture)
|
||||
{}
|
||||
void DescriptorSet::updateSamplerArray(uint32 binding, Array<Gfx::PSampler> samplers)
|
||||
{}
|
||||
void DescriptorSet::updateAccelerationStructure(uint32 binding, Gfx::PTopLevelAS as)
|
||||
{}
|
||||
|
||||
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string &name,
|
||||
Gfx::PPipelineLayout baseLayout)
|
||||
: Gfx::PipelineLayout(name, baseLayout), graphics(graphics) {}
|
||||
|
||||
@@ -18,7 +18,7 @@ class Graphics : public Gfx::Graphics {
|
||||
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea) override;
|
||||
Gfx::PViewport renderArea, std::string name = "") override;
|
||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||
virtual void endRenderPass() override;
|
||||
virtual void waitDeviceIdle() override;
|
||||
@@ -37,6 +37,7 @@ class Graphics : public Gfx::Graphics {
|
||||
virtual Gfx::ORenderCommand createRenderCommand(const std::string& name = "") override;
|
||||
virtual Gfx::OComputeCommand createComputeCommand(const std::string& name = "") override;
|
||||
|
||||
virtual void beginShaderCompilation(const ShaderCompilationInfo& compileInfo) override;
|
||||
virtual Gfx::OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
|
||||
@@ -45,6 +46,7 @@ class Graphics : public Gfx::Graphics {
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::PRayTracingPipeline createRayTracingPipeline(Gfx::RayTracingPipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::OSampler createSampler(const SamplerCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
@@ -52,7 +54,24 @@ class Graphics : public Gfx::Graphics {
|
||||
|
||||
virtual Gfx::OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) override;
|
||||
|
||||
virtual Gfx::OOcclusionQuery createOcclusionQuery(const std::string& name = "") override;
|
||||
virtual Gfx::OPipelineStatisticsQuery createPipelineStatisticsQuery(const std::string& name = "") override;
|
||||
virtual Gfx::OTimestampQuery createTimestampQuery(uint64 numTimestamps, const std::string& name = "") override;
|
||||
|
||||
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override;
|
||||
virtual void copyTexture(Gfx::PTexture src, Gfx::PTexture dst) override;
|
||||
|
||||
// Ray Tracing
|
||||
virtual Gfx::OBottomLevelAS createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTopLevelAS createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo) override;
|
||||
virtual void buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS> data) override;
|
||||
|
||||
virtual Gfx::ORayGenShader createRayGenShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OAnyHitShader createAnyHitShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OClosestHitShader createClosestHitShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OMissShader createMissShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OIntersectionShader createIntersectionShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OCallableShader createCallableShader(const ShaderCreateInfo& createInfo) override;
|
||||
|
||||
MTL::Device* getDevice() const { return device; }
|
||||
PCommandQueue getQueue() const { return queue; }
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
#include "Resources.h"
|
||||
#include "Shader.h"
|
||||
#include "Window.h"
|
||||
|
||||
#include <slang.h>
|
||||
#include "Graphics/slang-compile.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
@@ -40,8 +41,8 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner,
|
||||
Gfx::ORenderPass
|
||||
Graphics::createRenderPass(Gfx::RenderTargetLayout layout,
|
||||
Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea) {
|
||||
return new RenderPass(this, layout, dependencies, renderArea);
|
||||
Gfx::PViewport renderArea, std::string name) {
|
||||
return new RenderPass(this, layout, dependencies, renderArea, name);
|
||||
}
|
||||
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
|
||||
@@ -102,6 +103,10 @@ Gfx::OComputeCommand Graphics::createComputeCommand(const std::string &name) {
|
||||
return queue->getComputeCommand(name);
|
||||
}
|
||||
|
||||
void Graphics::beginShaderCompilation(const ShaderCompilationInfo &compileInfo) {
|
||||
beginCompilation(compileInfo, SLANG_METAL, compileInfo.rootSignature);
|
||||
}
|
||||
|
||||
Gfx::OVertexShader
|
||||
Graphics::createVertexShader(const ShaderCreateInfo &createInfo) {
|
||||
OVertexShader result = new VertexShader(this);
|
||||
@@ -151,6 +156,9 @@ Gfx::PComputePipeline
|
||||
Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) {
|
||||
return cache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
Gfx::PRayTracingPipeline Graphics::createRayTracingPipeline(Gfx::RayTracingPipelineCreateInfo createInfo) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo &createInfo) {
|
||||
return new Sampler(this, createInfo);
|
||||
@@ -172,5 +180,68 @@ Graphics::createVertexInput(VertexInputStateCreateInfo createInfo) {
|
||||
return new VertexInput(createInfo);
|
||||
}
|
||||
|
||||
|
||||
Gfx::OOcclusionQuery Graphics::createOcclusionQuery(const std::string& name) {
|
||||
|
||||
}
|
||||
|
||||
Gfx::OPipelineStatisticsQuery Graphics::createPipelineStatisticsQuery(const std::string& name) {
|
||||
|
||||
}
|
||||
|
||||
Gfx::OTimestampQuery Graphics::createTimestampQuery(uint64 numTimestamps, const std::string& name) {
|
||||
|
||||
}
|
||||
|
||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
||||
}
|
||||
|
||||
void Graphics::copyTexture(Gfx::PTexture src, Gfx::PTexture dst) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Ray Tracing
|
||||
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Graphics::buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS> data) {
|
||||
|
||||
}
|
||||
|
||||
Gfx::ORayGenShader Graphics::createRayGenShader(const ShaderCreateInfo& createInfo) {
|
||||
ORayGenShader shader = new RayGenShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OAnyHitShader Graphics::createAnyHitShader(const ShaderCreateInfo& createInfo) {
|
||||
OAnyHitShader shader = new AnyHitShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OClosestHitShader Graphics::createClosestHitShader(const ShaderCreateInfo& createInfo) {
|
||||
OClosestHitShader shader = new ClosestHitShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OMissShader Graphics::createMissShader(const ShaderCreateInfo& createInfo) {
|
||||
OMissShader shader = new MissShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OIntersectionShader Graphics::createIntersectionShader(const ShaderCreateInfo& createInfo) {
|
||||
OIntersectionShader shader = new IntersectionShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OCallableShader Graphics::createCallableShader(const ShaderCreateInfo& createInfo) {
|
||||
OCallableShader shader = new CallableShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class RenderPass : public Gfx::RenderPass {
|
||||
public:
|
||||
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport viewport);
|
||||
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport viewport, const std::string& name = "");
|
||||
virtual ~RenderPass();
|
||||
void updateRenderPass();
|
||||
MTL::RenderPassDescriptor* getDescriptor() const { return renderPass; }
|
||||
|
||||
@@ -9,7 +9,7 @@ using namespace Seele::Metal;
|
||||
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout,
|
||||
Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport viewport)
|
||||
Gfx::PViewport viewport, const std::string& name)
|
||||
: Gfx::RenderPass(layout, dependencies), graphics(graphics),
|
||||
viewport(viewport) {
|
||||
renderPass = MTL::RenderPassDescriptor::renderPassDescriptor();
|
||||
@@ -33,7 +33,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout,
|
||||
desc->setResolveLevel(0);
|
||||
desc->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
||||
desc->setResolveTexture(
|
||||
resolve.getTexture().cast<TextureBase>()->getTexture());
|
||||
resolve.getTexture().cast<TextureBase>()->getImage());
|
||||
}
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
@@ -45,7 +45,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout,
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
depth->setResolveTexture(layout.depthResolveAttachment.getTexture()
|
||||
.cast<TextureBase>()
|
||||
->getTexture());
|
||||
->getImage());
|
||||
depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
||||
}
|
||||
}
|
||||
@@ -57,11 +57,11 @@ 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.getTexture().cast<TextureBase>()->getTexture());
|
||||
desc->setTexture(color.getTexture().cast<TextureBase>()->getImage());
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
auto depth = renderPass->depthAttachment();
|
||||
depth->setTexture(
|
||||
layout.depthAttachment.getTexture().cast<TextureBase>()->getTexture());
|
||||
layout.depthAttachment.getTexture().cast<TextureBase>()->getImage());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Metal/MTLSampler.hpp"
|
||||
#include <Foundation/Foundation.hpp>
|
||||
#include <Metal/Metal.hpp>
|
||||
|
||||
@@ -40,10 +40,24 @@ using ComputeShader = ShaderBase<Gfx::ComputeShader, Gfx::SE_SHADER_STAGE_COMPUT
|
||||
using TaskShader = ShaderBase<Gfx::TaskShader, Gfx::SE_SHADER_STAGE_TASK_BIT_EXT>;
|
||||
using MeshShader = ShaderBase<Gfx::MeshShader, Gfx::SE_SHADER_STAGE_MESH_BIT_EXT>;
|
||||
|
||||
using RayGenShader = ShaderBase<Gfx::RayGenShader, Gfx::SE_SHADER_STAGE_RAYGEN_BIT_KHR>;
|
||||
using ClosestHitShader = ShaderBase<Gfx::ClosestHitShader, Gfx::SE_SHADER_STAGE_CLOSEST_HIT_BIT_KHR>;
|
||||
using IntersectionShader = ShaderBase<Gfx::IntersectionShader, Gfx::SE_SHADER_STAGE_INTERSECTION_BIT_KHR>;
|
||||
using AnyHitShader = ShaderBase<Gfx::AnyHitShader, Gfx::SE_SHADER_STAGE_ANY_HIT_BIT_KHR>;
|
||||
using MissShader = ShaderBase<Gfx::MissShader, Gfx::SE_SHADER_STAGE_MISS_BIT_KHR>;
|
||||
using CallableShader = ShaderBase<Gfx::CallableShader, Gfx::SE_SHADER_STAGE_CALLABLE_BIT_KHR>;
|
||||
|
||||
DEFINE_REF(VertexShader)
|
||||
DEFINE_REF(FragmentShader)
|
||||
DEFINE_REF(ComputeShader)
|
||||
DEFINE_REF(TaskShader)
|
||||
DEFINE_REF(MeshShader)
|
||||
|
||||
DEFINE_REF(RayGenShader)
|
||||
DEFINE_REF(ClosestHitShader)
|
||||
DEFINE_REF(IntersectionShader)
|
||||
DEFINE_REF(AnyHitShader)
|
||||
DEFINE_REF(MissShader)
|
||||
DEFINE_REF(CallableShader)
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
@@ -25,10 +25,9 @@ Shader::~Shader() {
|
||||
}
|
||||
|
||||
void Shader::create(const ShaderCreateInfo &createInfo) {
|
||||
std::cout << "Compiling " << createInfo.name << std::endl;
|
||||
Map<std::string, uint32> paramMapping;
|
||||
Slang::ComPtr<slang::IBlob> kernelBlob =
|
||||
generateShader(createInfo, SLANG_METAL, paramMapping);
|
||||
auto [kernelBlob, entryPoint] =
|
||||
generateShader(createInfo);
|
||||
std::cout << (char *)kernelBlob->getBufferPointer() << std::endl;
|
||||
hash = CRC::Calculate(kernelBlob->getBufferPointer(),
|
||||
kernelBlob->getBufferSize(), CRC::CRC_32());
|
||||
@@ -44,10 +43,11 @@ void Shader::create(const ShaderCreateInfo &createInfo) {
|
||||
<< std::endl;
|
||||
}
|
||||
function = library->newFunction(NS::String::string(
|
||||
createInfo.entryPoint.c_str(), NS::ASCIIStringEncoding));
|
||||
entryPoint.c_str(), NS::ASCIIStringEncoding));
|
||||
if (!function) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 Shader::getShaderHash() const { return hash; }
|
||||
|
||||
@@ -1,35 +1,25 @@
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Texture.h"
|
||||
|
||||
#include "Metal/MTLTexture.hpp"
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class TextureBase {
|
||||
class TextureHandle {
|
||||
public:
|
||||
TextureBase(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, Gfx::QueueType& owner,
|
||||
MTL::Texture* existingImage = nullptr);
|
||||
virtual ~TextureBase();
|
||||
uint32 getWidth() const { return width; }
|
||||
uint32 getHeight() const { return height; }
|
||||
uint32 getDepth() const { return depth; }
|
||||
constexpr MTL::Texture* getTexture() const { return texture; }
|
||||
constexpr Gfx::SeImageLayout getLayout() const { return layout; }
|
||||
void setLayout(Gfx::SeImageLayout val) { layout = val; }
|
||||
constexpr Gfx::SeFormat getFormat() const { return format; }
|
||||
constexpr Gfx::SeSampleCountFlags getNumSamples() const { return samples; }
|
||||
constexpr uint32 getMipLevels() const { return mipLevels; }
|
||||
void executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage);
|
||||
virtual ~TextureHandle();
|
||||
void pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void transferOwnership(Gfx::QueueType newOwner);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage);
|
||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||
|
||||
protected:
|
||||
// Updates via reference
|
||||
Gfx::QueueType& currentOwner;
|
||||
PGraphics graphics;
|
||||
void generateMipmaps();
|
||||
|
||||
MTL::Texture* texture;
|
||||
MTL::TextureType type;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 depth;
|
||||
@@ -39,26 +29,62 @@ class TextureBase {
|
||||
uint32 samples;
|
||||
Gfx::SeFormat format;
|
||||
Gfx::SeImageUsageFlags usage;
|
||||
MTL::Texture* texture;
|
||||
MTL::TextureType type;
|
||||
Gfx::SeImageLayout layout;
|
||||
Gfx::SeImageAspectFlags aspect;
|
||||
uint8 ownsImage;
|
||||
};
|
||||
DEFINE_REF(TextureHandle)
|
||||
|
||||
|
||||
class TextureBase {
|
||||
public:
|
||||
TextureBase(PGraphics graphics, MTL::TextureType textureType, const TextureCreateInfo& createInfo,
|
||||
MTL::Texture* existingImage = nullptr);
|
||||
virtual ~TextureBase();
|
||||
uint32 getWidth() const { return handle->width; }
|
||||
uint32 getHeight() const { return handle->height; }
|
||||
uint32 getDepth() const { return handle->depth; }
|
||||
PTextureHandle getHandle() const { return handle; }
|
||||
MTL::Texture* getImage() const { return handle->texture; };
|
||||
constexpr Gfx::SeImageLayout getLayout() const { return handle->layout; }
|
||||
void setLayout(Gfx::SeImageLayout val) { handle->layout = val; }
|
||||
constexpr Gfx::SeImageAspectFlags getAspect() const { return handle->aspect; }
|
||||
constexpr Gfx::SeImageUsageFlags getUsage() const { return handle->usage; }
|
||||
constexpr Gfx::SeFormat getFormat() const { return handle->format; }
|
||||
constexpr Gfx::SeSampleCountFlags getNumSamples() const { return handle->samples; }
|
||||
constexpr uint32 getMipLevels() const { return handle->mipLevels; }
|
||||
constexpr bool isDepthStencil() const { return handle->aspect & (Gfx::SE_IMAGE_ASPECT_DEPTH_BIT | Gfx::SE_IMAGE_ASPECT_STENCIL_BIT); }
|
||||
|
||||
void pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage);
|
||||
void transferOwnership(Gfx::QueueType newOwner);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage);
|
||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||
void generateMipmaps();
|
||||
protected:
|
||||
OTextureHandle handle;
|
||||
// Updates via reference
|
||||
PGraphics graphics;
|
||||
Gfx::QueueType initialOwner;
|
||||
friend class Graphics;
|
||||
};
|
||||
DEFINE_REF(TextureBase)
|
||||
|
||||
class Texture2D : public Gfx::Texture2D, public TextureBase {
|
||||
public:
|
||||
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* exisitingTexture = nullptr);
|
||||
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* existingImage = nullptr);
|
||||
virtual ~Texture2D();
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual uint32 getWidth() const override { return handle->width; }
|
||||
virtual uint32 getHeight() const override { return handle->height; }
|
||||
virtual uint32 getDepth() const override { return handle->depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
virtual void generateMipmaps() override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
@@ -67,19 +93,21 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(Texture2D)
|
||||
|
||||
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||
public:
|
||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo);
|
||||
virtual ~Texture3D();
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual uint32 getWidth() const override { return handle->width; }
|
||||
virtual uint32 getHeight() const override { return handle->height; }
|
||||
virtual uint32 getDepth() const override { return handle->depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
virtual void generateMipmaps() override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
@@ -88,19 +116,21 @@ class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(Texture3D)
|
||||
class TextureCube : public Gfx::TextureCube, TextureBase {
|
||||
|
||||
class TextureCube : public Gfx::TextureCube, public TextureBase {
|
||||
public:
|
||||
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo);
|
||||
virtual ~TextureCube();
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual uint32 getWidth() const override { return handle->width; }
|
||||
virtual uint32 getHeight() const override { return handle->height; }
|
||||
virtual uint32 getDepth() const override { return handle->depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
virtual void generateMipmaps() override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
|
||||
@@ -3,20 +3,21 @@
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Graphics.h"
|
||||
#include "Metal/MTLTexture.hpp"
|
||||
#include "Metal/MTLTypes.hpp"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type,
|
||||
TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type,
|
||||
const TextureCreateInfo &createInfo,
|
||||
Gfx::QueueType &owner, MTL::Texture *existingImage)
|
||||
: currentOwner(owner), graphics(graphics), width(createInfo.width),
|
||||
MTL::Texture *existingImage)
|
||||
: texture(existingImage),
|
||||
type(type), width(createInfo.width),
|
||||
height(createInfo.height), depth(createInfo.depth),
|
||||
arrayCount(createInfo.elements), layerCount(createInfo.layers),
|
||||
mipLevels(createInfo.mipLevels), samples(createInfo.samples),
|
||||
format(createInfo.format), usage(createInfo.usage),
|
||||
texture(existingImage), type(type),
|
||||
layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED),
|
||||
ownsImage(existingImage == nullptr) {
|
||||
if (existingImage == nullptr) {
|
||||
@@ -55,124 +56,118 @@ TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type,
|
||||
// }
|
||||
}
|
||||
|
||||
TextureBase::~TextureBase() {
|
||||
TextureHandle::~TextureHandle() {
|
||||
if (ownsImage) {
|
||||
texture->release();
|
||||
}
|
||||
}
|
||||
|
||||
void TextureBase::executePipelineBarrier(Gfx::SeAccessFlags,
|
||||
void TextureHandle::pipelineBarrier(Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags,
|
||||
Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags) {}
|
||||
|
||||
void TextureBase::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags,
|
||||
void TextureHandle::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags, Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags) {}
|
||||
|
||||
void TextureBase::download(uint32, uint32, uint32, Array<uint8> &) {}
|
||||
void TextureHandle::transferOwnership(Gfx::QueueType newOwner) {
|
||||
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo &createInfo,
|
||||
MTL::Texture *exisitingTexture)
|
||||
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.sourceData.owner),
|
||||
TextureBase(graphics,
|
||||
createInfo.elements > 1
|
||||
? (createInfo.samples > 1
|
||||
? MTL::TextureType2DMultisampleArray
|
||||
: MTL::TextureType2DArray)
|
||||
: (createInfo.samples > 1 ? MTL::TextureType2DMultisample
|
||||
: MTL::TextureType2D),
|
||||
createInfo, Gfx::Texture2D::currentOwner, exisitingTexture) {}
|
||||
void TextureHandle::download(uint32, uint32, uint32, Array<uint8> &) {}
|
||||
|
||||
void TextureHandle::generateMipmaps()
|
||||
{
|
||||
}
|
||||
|
||||
TextureBase::TextureBase(PGraphics graphics, MTL::TextureType viewType, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
||||
: handle(new TextureHandle(graphics, viewType, createInfo, existingImage)), graphics(graphics)
|
||||
{}
|
||||
|
||||
TextureBase::~TextureBase() { }
|
||||
|
||||
void TextureBase::pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
handle->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
void TextureBase::transferOwnership(Gfx::QueueType newOwner) { handle->transferOwnership(newOwner); }
|
||||
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||
handle->changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||
handle->download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void TextureBase::generateMipmaps() { handle->generateMipmaps(); }
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
||||
: Gfx::Texture2D(graphics->getFamilyMapping()),
|
||||
TextureBase(graphics, createInfo.elements > 1 ? MTL::TextureType2DArray : MTL::TextureType2D, createInfo, existingImage) {}
|
||||
|
||||
Texture2D::~Texture2D() {}
|
||||
|
||||
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
|
||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
void Texture2D::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||
|
||||
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||
|
||||
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo &createInfo)
|
||||
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner),
|
||||
TextureBase(graphics, MTL::TextureType3D, createInfo,
|
||||
Gfx::Texture3D::currentOwner) {}
|
||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo)
|
||||
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, MTL::TextureType3D, createInfo) {}
|
||||
|
||||
Texture3D::~Texture3D() {}
|
||||
|
||||
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
|
||||
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
void Texture3D::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||
|
||||
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||
|
||||
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
TextureCube::TextureCube(PGraphics graphics,
|
||||
const TextureCreateInfo &createInfo)
|
||||
: Gfx::TextureCube(graphics->getFamilyMapping(),
|
||||
createInfo.sourceData.owner),
|
||||
TextureBase(graphics,
|
||||
createInfo.elements > 1 ? MTL::TextureTypeCubeArray
|
||||
: MTL::TextureTypeCube,
|
||||
createInfo, Gfx::TextureCube::currentOwner) {}
|
||||
TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo)
|
||||
: Gfx::TextureCube(graphics->getFamilyMapping()),
|
||||
TextureBase(graphics, createInfo.elements > 1 ? MTL::TextureTypeCubeArray : MTL::TextureTypeCube, createInfo) {}
|
||||
|
||||
TextureCube::~TextureCube() {}
|
||||
|
||||
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
|
||||
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
void TextureCube::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||
|
||||
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||
|
||||
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
-59435
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user