Provisional light culling
This commit is contained in:
@@ -8,7 +8,7 @@ struct ComputeShaderInput
|
|||||||
uint groupIndex : SV_GroupIndex;
|
uint groupIndex : SV_GroupIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 0, binding = 0, std430)
|
layout(set = 0, binding = 1, std430)
|
||||||
cbuffer DispatchParams
|
cbuffer DispatchParams
|
||||||
{
|
{
|
||||||
uint3 numThreadGroups;
|
uint3 numThreadGroups;
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import MATERIAL_IMPORT;
|
|||||||
import PrimitiveSceneData;
|
import PrimitiveSceneData;
|
||||||
import MaterialParameter;
|
import MaterialParameter;
|
||||||
|
|
||||||
//layout(set = 0, binding = 2)
|
layout(set = INDEX_LIGHT_ENV, binding = 1)
|
||||||
//StructuredBuffer<uint> lightIndexList;
|
StructuredBuffer<uint> lightIndexList;
|
||||||
//layout(set = 0, binding = 3)
|
layout(set = INDEX_LIGHT_ENV, binding = 2)
|
||||||
//RWTexture2D<uint2> lightGrid;
|
RWTexture2D<uint2> lightGrid;
|
||||||
|
|
||||||
|
|
||||||
struct VertexStageOutput
|
struct VertexStageOutput
|
||||||
@@ -56,20 +56,20 @@ float4 fragmentMain(
|
|||||||
|
|
||||||
float3 result = float3(0, 0, 0);
|
float3 result = float3(0, 0, 0);
|
||||||
|
|
||||||
for (int i = 0; i < gLightEnv.numDirectionalLights; i++)
|
for (int i = 0; i < gLightEnv[0].numDirectionalLights; i++)
|
||||||
{
|
{
|
||||||
result += gLightEnv.directionalLights[i].illuminate(materialParams, brdf, viewDir);
|
result += gLightEnv[0].directionalLights[i].illuminate(materialParams, brdf, viewDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint2 tileIndex = uint2(floor(materialParams.clipPosition.xy) / BLOCK_SIZE);
|
uint2 tileIndex = uint2(floor(materialParams.clipPosition.xy) / BLOCK_SIZE);
|
||||||
|
|
||||||
//uint startOffset = lightGrid[tileIndex].x;
|
uint startOffset = lightGrid[tileIndex].x;
|
||||||
//uint lightCount = lightGrid[tileIndex].y;
|
uint lightCount = lightGrid[tileIndex].y;
|
||||||
|
|
||||||
for (int j = 0; j < gLightEnv.numPointLights; ++j)
|
for (int j = 0; j < gLightEnv[0].numPointLights; ++j)
|
||||||
{
|
{
|
||||||
//uint lightIndex = lightIndexList[startOffset + j];
|
uint lightIndex = lightIndexList[startOffset + j];
|
||||||
PointLight pointLight = gLightEnv.pointLights[j];
|
PointLight pointLight = gLightEnv[0].pointLights[lightIndex];
|
||||||
result += pointLight.illuminate(materialParams, brdf, viewDir);
|
result += pointLight.illuminate(materialParams, brdf, viewDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ struct ComputeShaderInput
|
|||||||
uint3 dispatchThreadID : SV_DispatchThreadID;
|
uint3 dispatchThreadID : SV_DispatchThreadID;
|
||||||
uint groupIndex : SV_GroupIndex;
|
uint groupIndex : SV_GroupIndex;
|
||||||
};
|
};
|
||||||
layout(binding = 0)
|
layout(set = INDEX_VIEW_PARAMS, binding = 1)
|
||||||
cbuffer DispatchParams
|
cbuffer DispatchParams
|
||||||
{
|
{
|
||||||
uint3 numThreadGroups;
|
uint3 numThreadGroups;
|
||||||
@@ -17,23 +17,23 @@ cbuffer DispatchParams
|
|||||||
uint pad1;
|
uint pad1;
|
||||||
}
|
}
|
||||||
|
|
||||||
layout(binding = 2)
|
layout(set = INDEX_VIEW_PARAMS, binding = 2)
|
||||||
RWTexture2D depthTextureVS;
|
Texture2D depthTextureVS;
|
||||||
layout(binding = 4)
|
layout(set = INDEX_VIEW_PARAMS, binding = 3)
|
||||||
StructuredBuffer<Frustum> frustums;
|
StructuredBuffer<Frustum> frustums;
|
||||||
|
|
||||||
layout(binding = 5)
|
layout(set = INDEX_VIEW_PARAMS, binding = 4)
|
||||||
RWStructuredBuffer<uint> oLightIndexCounter;
|
RWStructuredBuffer<uint> oLightIndexCounter;
|
||||||
layout(binding = 6)
|
layout(set = INDEX_VIEW_PARAMS, binding = 5)
|
||||||
RWStructuredBuffer<uint> tLightIndexCounter;
|
RWStructuredBuffer<uint> tLightIndexCounter;
|
||||||
|
|
||||||
layout(binding = 7)
|
layout(set = INDEX_VIEW_PARAMS, binding = 6)
|
||||||
RWStructuredBuffer<uint> oLightIndexList;
|
RWStructuredBuffer<uint> oLightIndexList;
|
||||||
layout(binding = 8)
|
layout(set = INDEX_VIEW_PARAMS, binding = 7)
|
||||||
RWStructuredBuffer<uint> tLightIndexList;
|
RWStructuredBuffer<uint> tLightIndexList;
|
||||||
layout(binding = 9)
|
layout(set = INDEX_VIEW_PARAMS, binding = 8)
|
||||||
RWTexture2D<uint2> oLightGrid;
|
RWTexture2D<uint2> oLightGrid;
|
||||||
layout(binding = 10)
|
layout(set = INDEX_VIEW_PARAMS, binding = 9)
|
||||||
RWTexture2D<uint2> tLightGrid;
|
RWTexture2D<uint2> tLightGrid;
|
||||||
|
|
||||||
groupshared uint uMinDepth;
|
groupshared uint uMinDepth;
|
||||||
@@ -71,9 +71,10 @@ void tAppendLight(uint lightIndex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)]
|
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)]
|
||||||
|
[shader("compute")]
|
||||||
void cullLights(ComputeShaderInput in)
|
void cullLights(ComputeShaderInput in)
|
||||||
{
|
{
|
||||||
int2 texCoord = in.dispatchThreadID.xy;
|
int3 texCoord = int3(in.dispatchThreadID.xy, 0);
|
||||||
float fDepth = depthTextureVS.Load(texCoord).r;
|
float fDepth = depthTextureVS.Load(texCoord).r;
|
||||||
|
|
||||||
uint uDepth = asuint(fDepth);
|
uint uDepth = asuint(fDepth);
|
||||||
@@ -101,10 +102,10 @@ void cullLights(ComputeShaderInput in)
|
|||||||
|
|
||||||
Plane minPlane = {float3(0, 0, -1), -minDepthVS};
|
Plane minPlane = {float3(0, 0, -1), -minDepthVS};
|
||||||
|
|
||||||
for ( uint i = in.groupIndex; i < lights.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
|
for ( uint i = in.groupIndex; i < gLightEnv[0].numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
|
||||||
{
|
{
|
||||||
PointLight light = lights.pointLights[i];
|
PointLight light = gLightEnv[0].pointLights[i];
|
||||||
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
|
//if(gLightEnv.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
|
||||||
{
|
{
|
||||||
//InterlockedAdd(tLightCount, 1, index);
|
//InterlockedAdd(tLightCount, 1, index);
|
||||||
//if(index < 1024)
|
//if(index < 1024)
|
||||||
|
|||||||
@@ -6,24 +6,18 @@ struct ViewParameter
|
|||||||
{
|
{
|
||||||
float4x4 viewMatrix;
|
float4x4 viewMatrix;
|
||||||
float4x4 projectionMatrix;
|
float4x4 projectionMatrix;
|
||||||
|
float4x4 inverseProjection;
|
||||||
|
float2 screenDimensions;
|
||||||
float4 cameraPos_WS;
|
float4 cameraPos_WS;
|
||||||
}
|
}
|
||||||
layout(set = INDEX_VIEW_PARAMS, binding = 0, std430)
|
layout(set = INDEX_VIEW_PARAMS, binding = 0, std430)
|
||||||
ConstantBuffer<ViewParameter> gViewParams;
|
ConstantBuffer<ViewParameter> gViewParams;
|
||||||
|
|
||||||
struct ScreenToViewParams
|
|
||||||
{
|
|
||||||
float4x4 inverseProjection;
|
|
||||||
float2 screenDimensions;
|
|
||||||
}
|
|
||||||
layout(set = INDEX_VIEW_PARAMS, binding = 1, std430)
|
|
||||||
ConstantBuffer<ScreenToViewParams> gScreenToViewParams;
|
|
||||||
|
|
||||||
// Convert clip space coordinates to view space
|
// Convert clip space coordinates to view space
|
||||||
float4 clipToView( float4 clip )
|
float4 clipToView( float4 clip )
|
||||||
{
|
{
|
||||||
// View space position.
|
// View space position.
|
||||||
float4 view = mul( gScreenToViewParams.inverseProjection, clip );
|
float4 view = mul( gViewParams.inverseProjection, clip );
|
||||||
// Perspective projection.
|
// Perspective projection.
|
||||||
view = view / view.w;
|
view = view / view.w;
|
||||||
|
|
||||||
@@ -34,7 +28,7 @@ float4 clipToView( float4 clip )
|
|||||||
float4 screenToView( float4 screen )
|
float4 screenToView( float4 screen )
|
||||||
{
|
{
|
||||||
// Convert to normalized texture coordinates
|
// Convert to normalized texture coordinates
|
||||||
float2 texCoord = screen.xy / gScreenToViewParams.screenDimensions;
|
float2 texCoord = screen.xy / gViewParams.screenDimensions;
|
||||||
|
|
||||||
// Convert to clip space
|
// Convert to clip space
|
||||||
float4 clip = float4( float2( texCoord.x, -texCoord.y ) * 2.0f - 1.0f, screen.z, screen.w );
|
float4 clip = float4( float2( texCoord.x, -texCoord.y ) * 2.0f - 1.0f, screen.z, screen.w );
|
||||||
|
|||||||
@@ -69,4 +69,4 @@ struct Lights
|
|||||||
};
|
};
|
||||||
|
|
||||||
layout(set = INDEX_LIGHT_ENV, binding = 0, std430)
|
layout(set = INDEX_LIGHT_ENV, binding = 0, std430)
|
||||||
ConstantBuffer<Lights> gLightEnv;
|
StructuredBuffer<Lights> gLightEnv;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ void TextureLoader::importAsset(const std::filesystem::path& filePath)
|
|||||||
AssetRegistry::get().textures[asset->getFileName()] = asset;
|
AssetRegistry::get().textures[asset->getFileName()] = asset;
|
||||||
futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
|
futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
std::this_thread::sleep_for(5s);
|
//std::this_thread::sleep_for(5s);
|
||||||
Gfx::PTexture2D texture = import(filePath);
|
Gfx::PTexture2D texture = import(filePath);
|
||||||
asset->setTexture(texture);
|
asset->setTexture(texture);
|
||||||
asset->setStatus(Asset::Status::Ready);
|
asset->setStatus(Asset::Status::Ready);
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace Seele
|
|||||||
_data = new T[other.allocated];
|
_data = new T[other.allocated];
|
||||||
assert(_data != nullptr);
|
assert(_data != nullptr);
|
||||||
markIteratorDirty();
|
markIteratorDirty();
|
||||||
std::copy(other.begin(), other.end(), beginIt);
|
std::copy(other.begin(), other.end(), begin());
|
||||||
}
|
}
|
||||||
Array(Array &&other) noexcept
|
Array(Array &&other) noexcept
|
||||||
: arraySize(std::move(other.arraySize))
|
: arraySize(std::move(other.arraySize))
|
||||||
@@ -97,7 +97,7 @@ namespace Seele
|
|||||||
}
|
}
|
||||||
arraySize = other.arraySize;
|
arraySize = other.arraySize;
|
||||||
markIteratorDirty();
|
markIteratorDirty();
|
||||||
std::copy(other.begin(), other.end(), beginIt);
|
std::copy(other.begin(), other.end(), begin());
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,20 +33,23 @@ public:
|
|||||||
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
||||||
virtual void endRenderPass() = 0;
|
virtual void endRenderPass() = 0;
|
||||||
|
|
||||||
virtual void executeCommands(Array<PRenderCommand> commands) = 0;
|
virtual void executeCommands(const Array<PRenderCommand>& commands) = 0;
|
||||||
|
virtual void executeCommands(const Array<PComputeCommand>& commands) = 0;
|
||||||
|
|
||||||
virtual PTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0;
|
virtual PTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0;
|
||||||
virtual PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) = 0;
|
virtual PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) = 0;
|
||||||
virtual PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) = 0;
|
virtual PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) = 0;
|
||||||
virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0;
|
virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0;
|
||||||
virtual PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0;
|
virtual PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0;
|
||||||
virtual PRenderCommand createRenderCommand() = 0;
|
virtual PRenderCommand createRenderCommand(const std::string& name = "") = 0;
|
||||||
|
virtual PComputeCommand createComputeCommand(const std::string& name = "") = 0;
|
||||||
virtual PVertexDeclaration createVertexDeclaration(const Array<VertexElement>& element) = 0;
|
virtual PVertexDeclaration createVertexDeclaration(const Array<VertexElement>& element) = 0;
|
||||||
virtual PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0;
|
virtual PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0;
|
||||||
virtual PControlShader createControlShader(const ShaderCreateInfo& createInfo) = 0;
|
virtual PControlShader createControlShader(const ShaderCreateInfo& createInfo) = 0;
|
||||||
virtual PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) = 0;
|
virtual PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) = 0;
|
||||||
virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0;
|
virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0;
|
||||||
virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0;
|
virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0;
|
||||||
|
virtual PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0;
|
||||||
virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0;
|
virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0;
|
||||||
virtual PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0;
|
virtual PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0;
|
||||||
virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
|
virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
|
||||||
@@ -54,6 +57,8 @@ public:
|
|||||||
virtual PDescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
|
virtual PDescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
|
||||||
virtual PPipelineLayout createPipelineLayout() = 0;
|
virtual PPipelineLayout createPipelineLayout() = 0;
|
||||||
|
|
||||||
|
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) = 0;
|
||||||
|
|
||||||
PVertexBuffer getNullVertexBuffer();
|
PVertexBuffer getNullVertexBuffer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ struct BulkResourceData
|
|||||||
{
|
{
|
||||||
uint32 size;
|
uint32 size;
|
||||||
uint8 *data;
|
uint8 *data;
|
||||||
Gfx::QueueType owner;
|
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
||||||
BulkResourceData()
|
BulkResourceData()
|
||||||
: size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS)
|
: size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS)
|
||||||
{
|
{
|
||||||
@@ -116,6 +116,15 @@ struct UniformBufferCreateInfo
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
struct StructuredBufferCreateInfo
|
||||||
|
{
|
||||||
|
BulkResourceData resourceData;
|
||||||
|
uint8 bDynamic: 1;
|
||||||
|
StructuredBufferCreateInfo()
|
||||||
|
: resourceData(), bDynamic(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
struct ShaderCreateInfo
|
struct ShaderCreateInfo
|
||||||
{
|
{
|
||||||
//It's possible to input multiple source files for materials or vertexFactories
|
//It's possible to input multiple source files for materials or vertexFactories
|
||||||
@@ -208,6 +217,7 @@ DECLARE_NAME_REF(Gfx, ControlShader)
|
|||||||
DECLARE_NAME_REF(Gfx, EvaluationShader)
|
DECLARE_NAME_REF(Gfx, EvaluationShader)
|
||||||
DECLARE_NAME_REF(Gfx, GeometryShader)
|
DECLARE_NAME_REF(Gfx, GeometryShader)
|
||||||
DECLARE_NAME_REF(Gfx, FragmentShader)
|
DECLARE_NAME_REF(Gfx, FragmentShader)
|
||||||
|
DECLARE_NAME_REF(Gfx, ComputeShader)
|
||||||
DECLARE_NAME_REF(Gfx, PipelineLayout)
|
DECLARE_NAME_REF(Gfx, PipelineLayout)
|
||||||
DECLARE_NAME_REF(Gfx, RenderPass)
|
DECLARE_NAME_REF(Gfx, RenderPass)
|
||||||
struct GraphicsPipelineCreateInfo
|
struct GraphicsPipelineCreateInfo
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorTyp
|
|||||||
descriptorBindings[bindingIndex] = binding;
|
descriptorBindings[bindingIndex] = binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
PDescriptorSet DescriptorLayout::allocatedDescriptorSet()
|
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
|
||||||
{
|
{
|
||||||
PDescriptorSet result;
|
PDescriptorSet result;
|
||||||
allocator->allocateDescriptorSet(result);
|
allocator->allocateDescriptorSet(result);
|
||||||
@@ -168,8 +168,14 @@ void QueueOwnedResource::transferOwnership(QueueType newOwner)
|
|||||||
if(mapping.needsTransfer(currentOwner, newOwner))
|
if(mapping.needsTransfer(currentOwner, newOwner))
|
||||||
{
|
{
|
||||||
executeOwnershipBarrier(newOwner);
|
executeOwnershipBarrier(newOwner);
|
||||||
|
}
|
||||||
currentOwner = newOwner;
|
currentOwner = newOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage)
|
||||||
|
{
|
||||||
|
// maybe add some checks
|
||||||
|
executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
|
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
|
||||||
@@ -314,6 +320,16 @@ RenderCommand::~RenderCommand()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComputeCommand::ComputeCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ComputeCommand::~ComputeCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
RenderTargetLayout::RenderTargetLayout()
|
RenderTargetLayout::RenderTargetLayout()
|
||||||
: inputAttachments()
|
: inputAttachments()
|
||||||
, colorAttachments()
|
, colorAttachments()
|
||||||
|
|||||||
@@ -148,14 +148,6 @@ private:
|
|||||||
};
|
};
|
||||||
DEFINE_REF(ShaderMap)
|
DEFINE_REF(ShaderMap)
|
||||||
|
|
||||||
class ComputeShader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ComputeShader() {}
|
|
||||||
virtual ~ComputeShader() {}
|
|
||||||
};
|
|
||||||
DEFINE_REF(ComputeShader)
|
|
||||||
|
|
||||||
class DescriptorBinding
|
class DescriptorBinding
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -233,7 +225,7 @@ public:
|
|||||||
virtual void create() = 0;
|
virtual void create() = 0;
|
||||||
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
|
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual PDescriptorSet allocatedDescriptorSet();
|
virtual PDescriptorSet allocateDescriptorSet();
|
||||||
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
|
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
|
||||||
inline uint32 getSetIndex() const { return setIndex; }
|
inline uint32 getSetIndex() const { return setIndex; }
|
||||||
|
|
||||||
@@ -301,9 +293,12 @@ public:
|
|||||||
|
|
||||||
//Preliminary checks to see if the barrier should be executed at all
|
//Preliminary checks to see if the barrier should be executed at all
|
||||||
void transferOwnership(QueueType newOwner);
|
void transferOwnership(QueueType newOwner);
|
||||||
|
void pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||||
|
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||||
Gfx::QueueType currentOwner;
|
Gfx::QueueType currentOwner;
|
||||||
QueueFamilyMapping mapping;
|
QueueFamilyMapping mapping;
|
||||||
};
|
};
|
||||||
@@ -353,6 +348,8 @@ protected:
|
|||||||
Array<uint8> contents;
|
Array<uint8> contents;
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||||
|
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||||
};
|
};
|
||||||
DEFINE_REF(UniformBuffer)
|
DEFINE_REF(UniformBuffer)
|
||||||
|
|
||||||
@@ -374,6 +371,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||||
|
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||||
uint32 numVertices;
|
uint32 numVertices;
|
||||||
uint32 vertexSize;
|
uint32 vertexSize;
|
||||||
};
|
};
|
||||||
@@ -396,6 +395,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||||
|
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||||
Gfx::SeIndexType indexType;
|
Gfx::SeIndexType indexType;
|
||||||
uint32 numIndices;
|
uint32 numIndices;
|
||||||
};
|
};
|
||||||
@@ -409,6 +410,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||||
|
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||||
};
|
};
|
||||||
DEFINE_REF(StructuredBuffer)
|
DEFINE_REF(StructuredBuffer)
|
||||||
|
|
||||||
@@ -480,10 +483,14 @@ public:
|
|||||||
virtual uint32 getSizeX() const = 0;
|
virtual uint32 getSizeX() const = 0;
|
||||||
virtual uint32 getSizeY() const = 0;
|
virtual uint32 getSizeY() const = 0;
|
||||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||||
|
virtual void changeLayout(SeImageLayout newLayout) = 0;
|
||||||
virtual class Texture2D* getTexture2D() { return nullptr; }
|
virtual class Texture2D* getTexture2D() { return nullptr; }
|
||||||
|
virtual void* getNativeHandle() { return nullptr; }
|
||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||||
|
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Texture)
|
DEFINE_REF(Texture)
|
||||||
class Texture2D : public Texture
|
class Texture2D : public Texture
|
||||||
@@ -496,10 +503,13 @@ public:
|
|||||||
virtual uint32 getSizeX() const = 0;
|
virtual uint32 getSizeX() const = 0;
|
||||||
virtual uint32 getSizeY() const = 0;
|
virtual uint32 getSizeY() const = 0;
|
||||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||||
|
virtual void changeLayout(SeImageLayout newLayout) = 0;
|
||||||
virtual class Texture2D* getTexture2D() { return this; }
|
virtual class Texture2D* getTexture2D() { return this; }
|
||||||
protected:
|
protected:
|
||||||
//Inherited via QueueOwnedResource
|
//Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||||
|
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Texture2D)
|
DEFINE_REF(Texture2D)
|
||||||
|
|
||||||
@@ -517,8 +527,22 @@ public:
|
|||||||
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0;
|
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0;
|
||||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
|
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
|
||||||
virtual void draw(const MeshBatchElement& data) = 0;
|
virtual void draw(const MeshBatchElement& data) = 0;
|
||||||
|
std::string name;
|
||||||
};
|
};
|
||||||
DEFINE_REF(RenderCommand)
|
DEFINE_REF(RenderCommand)
|
||||||
|
class ComputeCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ComputeCommand();
|
||||||
|
virtual ~ComputeCommand();
|
||||||
|
virtual bool isReady() = 0;
|
||||||
|
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
|
||||||
|
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
|
||||||
|
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
|
||||||
|
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
DEFINE_REF(ComputeCommand)
|
||||||
|
|
||||||
class Window
|
class Window
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void BasePassMeshProcessor::addMeshBatch(
|
|||||||
assert(collection != nullptr);
|
assert(collection != nullptr);
|
||||||
for(uint32 i = 0; i < batch.elements.size(); ++i)
|
for(uint32 i = 0; i < batch.elements.size(); ++i)
|
||||||
{
|
{
|
||||||
Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocatedDescriptorSet();
|
Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocateDescriptorSet();
|
||||||
descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer);
|
descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer);
|
||||||
descriptorSet->writeChanges();
|
descriptorSet->writeChanges();
|
||||||
cachedPrimitiveSets.add(descriptorSet);
|
cachedPrimitiveSets.add(descriptorSet);
|
||||||
@@ -92,14 +92,12 @@ BasePass::BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics
|
|||||||
basePassLayout = graphics->createPipelineLayout();
|
basePassLayout = graphics->createPipelineLayout();
|
||||||
|
|
||||||
lightLayout = graphics->createDescriptorLayout("LightLayout");
|
lightLayout = graphics->createDescriptorLayout("LightLayout");
|
||||||
lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
uniformInitializer.resourceData.size = sizeof(LightEnv);
|
lightLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
uniformInitializer.resourceData.data = nullptr;
|
lightLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||||
uniformInitializer.bDynamic = true;
|
|
||||||
lightUniform = graphics->createUniformBuffer(uniformInitializer);
|
|
||||||
lightLayout->create();
|
lightLayout->create();
|
||||||
basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, lightLayout);
|
basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, lightLayout);
|
||||||
descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocatedDescriptorSet();
|
descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocateDescriptorSet();
|
||||||
|
|
||||||
viewLayout = graphics->createDescriptorLayout("ViewLayout");
|
viewLayout = graphics->createDescriptorLayout("ViewLayout");
|
||||||
viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
@@ -107,14 +105,9 @@ BasePass::BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics
|
|||||||
uniformInitializer.resourceData.data = (uint8*)&viewParams;
|
uniformInitializer.resourceData.data = (uint8*)&viewParams;
|
||||||
uniformInitializer.bDynamic = true;
|
uniformInitializer.bDynamic = true;
|
||||||
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
|
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
|
||||||
viewLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
|
||||||
uniformInitializer.resourceData.size = sizeof(ScreenToViewParameter);
|
|
||||||
uniformInitializer.resourceData.data = (uint8*)&screenToViewParams;
|
|
||||||
uniformInitializer.bDynamic = true;
|
|
||||||
screenToViewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
|
|
||||||
viewLayout->create();
|
viewLayout->create();
|
||||||
basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout);
|
basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout);
|
||||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocatedDescriptorSet();
|
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||||
|
|
||||||
primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout");
|
primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout");
|
||||||
primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
@@ -131,25 +124,16 @@ void BasePass::beginFrame()
|
|||||||
processor->clearCommands();
|
processor->clearCommands();
|
||||||
primitiveLayout->reset();
|
primitiveLayout->reset();
|
||||||
BulkResourceData uniformUpdate;
|
BulkResourceData uniformUpdate;
|
||||||
uniformUpdate.size = sizeof(LightEnv);
|
|
||||||
uniformUpdate.data = (uint8*)&scene->getLightEnvironment();
|
|
||||||
lightUniform->updateContents(uniformUpdate);
|
|
||||||
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, lightUniform);
|
|
||||||
descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
|
|
||||||
|
|
||||||
viewParams.viewMatrix = source->getViewMatrix();
|
viewParams.viewMatrix = source->getViewMatrix();
|
||||||
viewParams.projectionMatrix = source->getProjectionMatrix();
|
viewParams.projectionMatrix = source->getProjectionMatrix();
|
||||||
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
||||||
screenToViewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
||||||
screenToViewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||||
uniformUpdate.size = sizeof(ViewParameter);
|
uniformUpdate.size = sizeof(ViewParameter);
|
||||||
uniformUpdate.data = (uint8*)&viewParams;
|
uniformUpdate.data = (uint8*)&viewParams;
|
||||||
viewParamBuffer->updateContents(uniformUpdate);
|
viewParamBuffer->updateContents(uniformUpdate);
|
||||||
uniformUpdate.size = sizeof(ScreenToViewParameter);
|
|
||||||
uniformUpdate.data = (uint8*)&screenToViewParams;
|
|
||||||
screenToViewParamBuffer->updateContents(uniformUpdate);
|
|
||||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
||||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(1, screenToViewParamBuffer);
|
|
||||||
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
||||||
for(auto &&meshBatch : scene->getStaticMeshes())
|
for(auto &&meshBatch : scene->getStaticMeshes())
|
||||||
{
|
{
|
||||||
@@ -159,6 +143,17 @@ void BasePass::beginFrame()
|
|||||||
|
|
||||||
void BasePass::render()
|
void BasePass::render()
|
||||||
{
|
{
|
||||||
|
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, scene->getLightBuffer());
|
||||||
|
|
||||||
|
oLightIndexList->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);
|
||||||
|
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);
|
||||||
|
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(1, oLightIndexList);
|
||||||
|
descriptorSets[INDEX_LIGHT_ENV]->updateTexture(2, oLightGrid);
|
||||||
|
descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
for (auto &&meshBatch : scene->getStaticMeshes())
|
for (auto &&meshBatch : scene->getStaticMeshes())
|
||||||
{
|
{
|
||||||
@@ -184,6 +179,8 @@ void BasePass::createRenderPass()
|
|||||||
depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment);
|
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment);
|
||||||
renderPass = graphics->createRenderPass(layout);
|
renderPass = graphics->createRenderPass(layout);
|
||||||
|
oLightIndexList = renderGraph->requestBuffer("LIGHTCULLING_OLIGHTLIST");
|
||||||
|
oLightGrid = renderGraph->requestTexture("LIGHTCULLING_OLIGHTGRID");
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePass::modifyRenderPassMacros(Map<const char*, const char*>& defines)
|
void BasePass::modifyRenderPassMacros(Map<const char*, const char*>& defines)
|
||||||
|
|||||||
@@ -54,13 +54,13 @@ private:
|
|||||||
Gfx::PPipelineLayout basePassLayout;
|
Gfx::PPipelineLayout basePassLayout;
|
||||||
// Set 0: Light environment
|
// Set 0: Light environment
|
||||||
static constexpr uint32 INDEX_LIGHT_ENV = 0;
|
static constexpr uint32 INDEX_LIGHT_ENV = 0;
|
||||||
|
Gfx::PStructuredBuffer oLightIndexList;
|
||||||
|
Gfx::PTexture oLightGrid;
|
||||||
Gfx::PDescriptorLayout lightLayout;
|
Gfx::PDescriptorLayout lightLayout;
|
||||||
Gfx::PUniformBuffer lightUniform;
|
|
||||||
// Set 1: viewParameter
|
// Set 1: viewParameter
|
||||||
static constexpr uint32 INDEX_VIEW_PARAMS = 1;
|
static constexpr uint32 INDEX_VIEW_PARAMS = 1;
|
||||||
Gfx::PDescriptorLayout viewLayout;
|
Gfx::PDescriptorLayout viewLayout;
|
||||||
Gfx::PUniformBuffer viewParamBuffer;
|
Gfx::PUniformBuffer viewParamBuffer;
|
||||||
Gfx::PUniformBuffer screenToViewParamBuffer;
|
|
||||||
// Set 2: materials, generated
|
// Set 2: materials, generated
|
||||||
static constexpr uint32 INDEX_MATERIAL = 2;
|
static constexpr uint32 INDEX_MATERIAL = 2;
|
||||||
// Set 3: primitive scene data
|
// Set 3: primitive scene data
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void DepthPrepassMeshProcessor::addMeshBatch(
|
|||||||
assert(collection != nullptr);
|
assert(collection != nullptr);
|
||||||
for(uint32 i = 0; i < batch.elements.size(); ++i)
|
for(uint32 i = 0; i < batch.elements.size(); ++i)
|
||||||
{
|
{
|
||||||
Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocatedDescriptorSet();
|
Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocateDescriptorSet();
|
||||||
descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer);
|
descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer);
|
||||||
descriptorSet->writeChanges();
|
descriptorSet->writeChanges();
|
||||||
cachedPrimitiveSets.add(descriptorSet);
|
cachedPrimitiveSets.add(descriptorSet);
|
||||||
@@ -97,14 +97,9 @@ DepthPrepass::DepthPrepass(PRenderGraph renderGraph, const PScene scene, Gfx::PG
|
|||||||
uniformInitializer.resourceData.data = (uint8*)&viewParams;
|
uniformInitializer.resourceData.data = (uint8*)&viewParams;
|
||||||
uniformInitializer.bDynamic = true;
|
uniformInitializer.bDynamic = true;
|
||||||
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
|
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
|
||||||
viewLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
|
||||||
uniformInitializer.resourceData.size = sizeof(ScreenToViewParameter);
|
|
||||||
uniformInitializer.resourceData.data = (uint8*)&screenToViewParams;
|
|
||||||
uniformInitializer.bDynamic = true;
|
|
||||||
screenToViewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
|
|
||||||
viewLayout->create();
|
viewLayout->create();
|
||||||
depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout);
|
depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout);
|
||||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocatedDescriptorSet();
|
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||||
|
|
||||||
primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout");
|
primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout");
|
||||||
primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
@@ -125,16 +120,12 @@ void DepthPrepass::beginFrame()
|
|||||||
viewParams.viewMatrix = source->getViewMatrix();
|
viewParams.viewMatrix = source->getViewMatrix();
|
||||||
viewParams.projectionMatrix = source->getProjectionMatrix();
|
viewParams.projectionMatrix = source->getProjectionMatrix();
|
||||||
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
||||||
screenToViewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
||||||
screenToViewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||||
uniformUpdate.size = sizeof(ViewParameter);
|
uniformUpdate.size = sizeof(ViewParameter);
|
||||||
uniformUpdate.data = (uint8*)&viewParams;
|
uniformUpdate.data = (uint8*)&viewParams;
|
||||||
viewParamBuffer->updateContents(uniformUpdate);
|
viewParamBuffer->updateContents(uniformUpdate);
|
||||||
uniformUpdate.size = sizeof(ScreenToViewParameter);
|
|
||||||
uniformUpdate.data = (uint8*)&screenToViewParams;
|
|
||||||
screenToViewParamBuffer->updateContents(uniformUpdate);
|
|
||||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
||||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(1, screenToViewParamBuffer);
|
|
||||||
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
||||||
for(auto &&meshBatch : scene->getStaticMeshes())
|
for(auto &&meshBatch : scene->getStaticMeshes())
|
||||||
{
|
{
|
||||||
@@ -144,6 +135,10 @@ void DepthPrepass::beginFrame()
|
|||||||
|
|
||||||
void DepthPrepass::render()
|
void DepthPrepass::render()
|
||||||
{
|
{
|
||||||
|
depthAttachment->getTexture()->pipelineBarrier(
|
||||||
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
|
||||||
|
depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
for (auto &&meshBatch : scene->getStaticMeshes())
|
for (auto &&meshBatch : scene->getStaticMeshes())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ private:
|
|||||||
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
|
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
|
||||||
Gfx::PDescriptorLayout viewLayout;
|
Gfx::PDescriptorLayout viewLayout;
|
||||||
Gfx::PUniformBuffer viewParamBuffer;
|
Gfx::PUniformBuffer viewParamBuffer;
|
||||||
Gfx::PUniformBuffer screenToViewParamBuffer;
|
|
||||||
// Set 1: materials, generated
|
// Set 1: materials, generated
|
||||||
static constexpr uint32 INDEX_MATERIAL = 1;
|
static constexpr uint32 INDEX_MATERIAL = 1;
|
||||||
// Set 2: primitive scene data
|
// Set 2: primitive scene data
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
#include "LightCullingPass.h"
|
#include "LightCullingPass.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
|
#include "Scene/Scene.h"
|
||||||
#include "Scene/Actor/CameraActor.h"
|
#include "Scene/Actor/CameraActor.h"
|
||||||
#include "Scene/Components/CameraComponent.h"
|
#include "Scene/Components/CameraComponent.h"
|
||||||
|
#include "RenderGraph.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
LightCullingPass::LightCullingPass(PRenderGraph renderGraph, Gfx::PViewport viewport, Gfx::PGraphics graphics, PCameraActor camera)
|
LightCullingPass::LightCullingPass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera)
|
||||||
: RenderPass(renderGraph)
|
: RenderPass(renderGraph)
|
||||||
|
, scene(scene)
|
||||||
, viewport(viewport)
|
, viewport(viewport)
|
||||||
, graphics(graphics)
|
, graphics(graphics)
|
||||||
, source(camera->getCameraComponent())
|
, source(camera->getCameraComponent())
|
||||||
@@ -20,46 +23,58 @@ LightCullingPass::~LightCullingPass()
|
|||||||
|
|
||||||
void LightCullingPass::beginFrame()
|
void LightCullingPass::beginFrame()
|
||||||
{
|
{
|
||||||
uint32_t viewportWidth = viewport->getSizeX();
|
BulkResourceData uniformUpdate;
|
||||||
uint32_t viewportHeight = viewport->getSizeY();
|
viewParams.viewMatrix = source->getViewMatrix();
|
||||||
|
viewParams.projectionMatrix = source->getProjectionMatrix();
|
||||||
|
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
||||||
|
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
||||||
|
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||||
|
uniformUpdate.size = sizeof(ViewParameter);
|
||||||
|
uniformUpdate.data = (uint8*)&viewParams;
|
||||||
|
viewParamsBuffer->updateContents(uniformUpdate);
|
||||||
|
|
||||||
glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
cullingDescriptorLayout->reset();
|
||||||
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1));
|
lightEnvDescriptorLayout->reset();
|
||||||
|
cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet();
|
||||||
dispatchParams.numThreads = numThreads;
|
lightEnvDescriptorSet = lightEnvDescriptorLayout->allocateDescriptorSet();
|
||||||
dispatchParams.numThreadGroups = numThreadGroups;
|
cullingDescriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||||
ScreenToView screenToView;
|
cullingDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
|
||||||
screenToView.inverseProjection = glm::inverse(source->getProjectionMatrix());
|
cullingDescriptorSet->updateBuffer(3, frustumBuffer);
|
||||||
screenToView.screenDimensions = glm::vec2(viewportWidth, viewportHeight);
|
cullingDescriptorSet->updateBuffer(4, oLightIndexCounter);
|
||||||
|
cullingDescriptorSet->updateBuffer(5, tLightIndexCounter);
|
||||||
frustumShader = renderDevice->createComputeShader(loadPlaintext("./_Game/shaders/ComputeFrustums.slang"), "computeFrustums");
|
cullingDescriptorSet->updateBuffer(6, oLightIndexList);
|
||||||
frustumDescriptorLayout = renderDevice->createDescriptorLayout();
|
cullingDescriptorSet->updateBuffer(7, tLightIndexList);
|
||||||
frustumDescriptorLayout->addDescriptorBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
cullingDescriptorSet->updateTexture(8, oLightGrid);
|
||||||
frustumDescriptorLayout->addDescriptorBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
cullingDescriptorSet->updateTexture(9, tLightGrid);
|
||||||
frustumDescriptorLayout->addDescriptorBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
|
||||||
frustumLayout = renderDevice->createPipelineLayout();
|
|
||||||
frustumLayout->addPushConstants(init::PushConstantRange(VK_SHADER_STAGE_COMPUTE_BIT, sizeof(DispatchParams), 0));
|
|
||||||
frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout);
|
|
||||||
frustumLayout->create();
|
|
||||||
frustumShader->setPipelineLayout(frustumLayout);
|
|
||||||
RHIResourceCreateInfo frustumInfo;
|
|
||||||
frustumBuffer = renderDevice->createStructuredBuffer(sizeof(Frustum), sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z, BufferUsageFlags::BUF_UnorderedAccess, frustumInfo);
|
|
||||||
dispatchParamsBuffer = renderDevice->createUniformBuffer(&dispatchParams, sizeof(DispatchParams), UniformBuffer_MultiFrame);
|
|
||||||
screenToViewParams = renderDevice->createUniformBuffer(&screenToView, sizeof(ScreenToView), UniformBuffer_MultiFrame);
|
|
||||||
frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet();
|
|
||||||
frustumDescriptorSet->updateBuffer(0, dispatchParamsBuffer);
|
|
||||||
frustumDescriptorSet->updateBuffer(1, screenToViewParams);
|
|
||||||
frustumDescriptorSet->updateBuffer(2, frustumBuffer);
|
|
||||||
frustumDescriptorSet->writeChanges();
|
|
||||||
renderDevice->setComputeShader(frustumShader);
|
|
||||||
renderDevice->bindComputeDescriptors(frustumLayout, frustumDescriptorSet);
|
|
||||||
renderDevice->dispatchComputeShader(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
|
||||||
renderDevice->pipelineBarrier(frustumBuffer, VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::render()
|
void LightCullingPass::render()
|
||||||
{
|
{
|
||||||
|
oLightIndexList->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);
|
||||||
|
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);
|
||||||
|
depthAttachment->pipelineBarrier(
|
||||||
|
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_COMPUTE_SHADER_BIT);
|
||||||
|
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||||
|
depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE);
|
||||||
|
|
||||||
|
cullingDescriptorSet->updateTexture(2, depthAttachment);
|
||||||
|
cullingDescriptorSet->writeChanges();
|
||||||
|
lightEnvDescriptorSet->updateBuffer(0, scene->getLightBuffer());
|
||||||
|
lightEnvDescriptorSet->writeChanges();
|
||||||
|
Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||||
|
computeCommand->bindPipeline(cullingPipeline);
|
||||||
|
Array<Gfx::PDescriptorSet> descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet};
|
||||||
|
computeCommand->bindDescriptor(descriptorSets);
|
||||||
|
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||||
|
Array<Gfx::PComputeCommand> commands = {computeCommand};
|
||||||
|
graphics->executeCommands(commands);
|
||||||
|
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
|
depthAttachment->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::endFrame()
|
void LightCullingPass::endFrame()
|
||||||
@@ -69,15 +84,172 @@ void LightCullingPass::endFrame()
|
|||||||
|
|
||||||
void LightCullingPass::publishOutputs()
|
void LightCullingPass::publishOutputs()
|
||||||
{
|
{
|
||||||
|
setupFrustums();
|
||||||
|
BulkResourceData resourceData;
|
||||||
|
StructuredBufferCreateInfo createInfo;
|
||||||
|
resourceData.size = sizeof(uint32);
|
||||||
|
resourceData.data = nullptr;
|
||||||
|
resourceData.owner = Gfx::QueueType::COMPUTE;
|
||||||
|
createInfo.bDynamic = false;
|
||||||
|
createInfo.resourceData = resourceData;
|
||||||
|
oLightIndexCounter = graphics->createStructuredBuffer(createInfo);
|
||||||
|
tLightIndexCounter = graphics->createStructuredBuffer(createInfo);
|
||||||
|
resourceData.size = sizeof(uint32_t) * dispatchParams.numThreadGroups.x * dispatchParams.numThreadGroups.y * dispatchParams.numThreadGroups.z * 1024;
|
||||||
|
oLightIndexList = graphics->createStructuredBuffer(createInfo);
|
||||||
|
tLightIndexList = graphics->createStructuredBuffer(createInfo);
|
||||||
|
renderGraph->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
|
||||||
|
renderGraph->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
|
||||||
|
TextureCreateInfo textureInfo;
|
||||||
|
textureInfo.width = dispatchParams.numThreadGroups.x;
|
||||||
|
textureInfo.height = dispatchParams.numThreadGroups.y;
|
||||||
|
textureInfo.format = Gfx::SE_FORMAT_R16G16_UINT;
|
||||||
|
textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT;
|
||||||
|
oLightGrid = graphics->createTexture2D(textureInfo);
|
||||||
|
tLightGrid = graphics->createTexture2D(textureInfo);
|
||||||
|
renderGraph->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
|
||||||
|
renderGraph->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LightCullingPass::createRenderPass()
|
void LightCullingPass::createRenderPass()
|
||||||
{
|
{
|
||||||
|
cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout");
|
||||||
|
|
||||||
|
//ViewParams
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
|
//Dispatchparams
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
|
//DepthTexture
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||||
|
//Frustums
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
//o_lightIndexCounter
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
//t_lightIndexCounter
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
//o_lightIndexList
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
//t_lightIndexList
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
//o_lightGrid
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||||
|
//t_lightGrid
|
||||||
|
cullingDescriptorLayout->addDescriptorBinding(9, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||||
|
|
||||||
|
|
||||||
|
lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv");
|
||||||
|
//LightEnv
|
||||||
|
lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
|
||||||
|
cullingLayout = graphics->createPipelineLayout();
|
||||||
|
cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout);
|
||||||
|
cullingLayout->addDescriptorLayout(1, lightEnvDescriptorLayout);
|
||||||
|
cullingLayout->create();
|
||||||
|
|
||||||
|
ShaderCreateInfo createInfo;
|
||||||
|
createInfo.name = "Culling";
|
||||||
|
|
||||||
|
std::ifstream codeStream("./shaders/LightCulling.slang", std::ios::ate);
|
||||||
|
auto fileSize = codeStream.tellg();
|
||||||
|
codeStream.seekg(0);
|
||||||
|
Array<char> buffer(static_cast<uint32>(fileSize));
|
||||||
|
codeStream.read(buffer.data(), fileSize);
|
||||||
|
|
||||||
|
createInfo.shaderCode.add(std::string(buffer.data()));
|
||||||
|
createInfo.entryPoint = "cullLights";
|
||||||
|
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||||
|
createInfo.defines["INDEX_LIGHT_ENV"] = "1";
|
||||||
|
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0";
|
||||||
|
cullingShader = graphics->createComputeShader(createInfo);
|
||||||
|
|
||||||
|
ComputePipelineCreateInfo pipelineInfo;
|
||||||
|
pipelineInfo.computeShader = cullingShader;
|
||||||
|
pipelineInfo.pipelineLayout = cullingLayout;
|
||||||
|
cullingPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||||
|
|
||||||
|
depthAttachment = renderGraph->requestRenderTarget("DEPTHPREPASS_DEPTH")->getTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>& defines)
|
void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>& defines)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightCullingPass::setupFrustums()
|
||||||
|
{
|
||||||
|
uint32_t viewportWidth = viewport->getSizeX();
|
||||||
|
uint32_t viewportHeight = viewport->getSizeY();
|
||||||
|
|
||||||
|
glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
||||||
|
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1));
|
||||||
|
|
||||||
|
viewParams.viewMatrix = source->getViewMatrix();
|
||||||
|
viewParams.projectionMatrix = source->getProjectionMatrix();
|
||||||
|
viewParams.inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix());
|
||||||
|
viewParams.screenDimensions = glm::vec2(viewportWidth, viewportHeight);
|
||||||
|
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
||||||
|
dispatchParams.numThreads = numThreads;
|
||||||
|
dispatchParams.numThreadGroups = numThreadGroups;
|
||||||
|
|
||||||
|
Gfx::PDescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout");
|
||||||
|
frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
|
frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
|
frustumDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
frustumLayout = graphics->createPipelineLayout();
|
||||||
|
frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout);
|
||||||
|
frustumLayout->create();
|
||||||
|
ShaderCreateInfo createInfo;
|
||||||
|
createInfo.name = "Frustum";
|
||||||
|
|
||||||
|
std::ifstream codeStream("./shaders/ComputeFrustums.slang", std::ios::ate);
|
||||||
|
auto fileSize = codeStream.tellg();
|
||||||
|
codeStream.seekg(0);
|
||||||
|
Array<char> buffer(static_cast<uint32>(fileSize));
|
||||||
|
codeStream.read(buffer.data(), fileSize);
|
||||||
|
|
||||||
|
createInfo.shaderCode.add(std::string(buffer.data()));
|
||||||
|
createInfo.entryPoint = "computeFrustums";
|
||||||
|
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||||
|
frustumShader = graphics->createComputeShader(createInfo);
|
||||||
|
|
||||||
|
|
||||||
|
ComputePipelineCreateInfo pipelineInfo;
|
||||||
|
pipelineInfo.computeShader = frustumShader;
|
||||||
|
pipelineInfo.pipelineLayout = frustumLayout;
|
||||||
|
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||||
|
|
||||||
|
BulkResourceData resourceInfo;
|
||||||
|
UniformBufferCreateInfo uniformInfo;
|
||||||
|
resourceInfo.size = sizeof(ViewParameter);
|
||||||
|
resourceInfo.data = (uint8*)&viewParams;
|
||||||
|
resourceInfo.owner = Gfx::QueueType::COMPUTE;
|
||||||
|
uniformInfo.resourceData = resourceInfo;
|
||||||
|
uniformInfo.bDynamic = false;
|
||||||
|
viewParamsBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||||
|
|
||||||
|
resourceInfo.size = sizeof(DispatchParams);
|
||||||
|
resourceInfo.data = (uint8*)&dispatchParams;
|
||||||
|
uniformInfo.resourceData = resourceInfo;
|
||||||
|
uniformInfo.bDynamic = false;
|
||||||
|
dispatchParamsBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||||
|
|
||||||
|
StructuredBufferCreateInfo structuredInfo;
|
||||||
|
resourceInfo.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z;
|
||||||
|
resourceInfo.data = nullptr;
|
||||||
|
structuredInfo.resourceData = resourceInfo;
|
||||||
|
structuredInfo.bDynamic = false;
|
||||||
|
frustumBuffer = graphics->createStructuredBuffer(structuredInfo);
|
||||||
|
|
||||||
|
frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet();
|
||||||
|
frustumDescriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||||
|
frustumDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
|
||||||
|
frustumDescriptorSet->updateBuffer(2, frustumBuffer);
|
||||||
|
frustumDescriptorSet->writeChanges();
|
||||||
|
|
||||||
|
Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand");
|
||||||
|
command->bindPipeline(frustumPipeline);
|
||||||
|
command->bindDescriptor(frustumDescriptorSet);
|
||||||
|
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
||||||
|
Array<Gfx::PComputeCommand> commands = {command};
|
||||||
|
graphics->executeCommands(commands);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
|
#include "Graphics/GraphicsResources.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
DECLARE_REF(CameraActor)
|
DECLARE_REF(CameraActor)
|
||||||
DECLARE_REF(CameraComponent)
|
DECLARE_REF(CameraComponent)
|
||||||
DECLARE_NAME_REF(Gfx, Viewport)
|
DECLARE_REF(Scene)
|
||||||
DECLARE_NAME_REF(Gfx, Graphics)
|
DECLARE_REF(Viewport)
|
||||||
class LightCullingPass : public RenderPass
|
class LightCullingPass : public RenderPass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LightCullingPass(PRenderGraph renderGraph, Gfx::PViewport viewport, Gfx::PGraphics graphics, PCameraActor camera);
|
LightCullingPass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera);
|
||||||
virtual ~LightCullingPass();
|
virtual ~LightCullingPass();
|
||||||
virtual void beginFrame() override;
|
virtual void beginFrame() override;
|
||||||
virtual void render() override;
|
virtual void render() override;
|
||||||
@@ -19,7 +20,9 @@ public:
|
|||||||
virtual void createRenderPass() override;
|
virtual void createRenderPass() override;
|
||||||
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
|
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
|
||||||
private:
|
private:
|
||||||
|
void setupFrustums();
|
||||||
static constexpr uint32 BLOCK_SIZE = 8;
|
static constexpr uint32 BLOCK_SIZE = 8;
|
||||||
|
static constexpr uint32 INDEX_LIGHT_ENV = 1;
|
||||||
_declspec(align(16)) struct DispatchParams
|
_declspec(align(16)) struct DispatchParams
|
||||||
{
|
{
|
||||||
glm::uvec3 numThreadGroups;
|
glm::uvec3 numThreadGroups;
|
||||||
@@ -39,13 +42,36 @@ private:
|
|||||||
{
|
{
|
||||||
Plane planes[4];
|
Plane planes[4];
|
||||||
};
|
};
|
||||||
struct ScreenToView
|
|
||||||
{
|
PScene scene;
|
||||||
Matrix4 inverseProjection;
|
|
||||||
Vector2 screenDimensions;
|
|
||||||
};
|
|
||||||
Gfx::PViewport viewport;
|
Gfx::PViewport viewport;
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
|
|
||||||
|
Gfx::PStructuredBuffer frustumBuffer;
|
||||||
|
Gfx::PUniformBuffer dispatchParamsBuffer;
|
||||||
|
Gfx::PUniformBuffer viewParamsBuffer;
|
||||||
|
Gfx::PDescriptorSet frustumDescriptorSet;
|
||||||
|
Gfx::PComputeShader frustumShader;
|
||||||
|
Gfx::PPipelineLayout frustumLayout;
|
||||||
|
Gfx::PComputePipeline frustumPipeline;
|
||||||
|
|
||||||
|
Gfx::PTexture2D depthAttachment;
|
||||||
|
//Gfx::PTexture2D depthComputeTexture;
|
||||||
|
Gfx::PStructuredBuffer frustums;
|
||||||
|
Gfx::PStructuredBuffer oLightIndexCounter;
|
||||||
|
Gfx::PStructuredBuffer tLightIndexCounter;
|
||||||
|
Gfx::PStructuredBuffer oLightIndexList;
|
||||||
|
Gfx::PStructuredBuffer tLightIndexList;
|
||||||
|
Gfx::PTexture2D oLightGrid;
|
||||||
|
Gfx::PTexture2D tLightGrid;
|
||||||
|
Gfx::PDescriptorSet lightEnvDescriptorSet;
|
||||||
|
Gfx::PDescriptorSet cullingDescriptorSet;
|
||||||
|
Gfx::PDescriptorLayout lightEnvDescriptorLayout;
|
||||||
|
Gfx::PDescriptorLayout cullingDescriptorLayout;
|
||||||
|
Gfx::PComputeShader cullingShader;
|
||||||
|
Gfx::PPipelineLayout cullingLayout;
|
||||||
|
Gfx::PComputePipeline cullingPipeline;
|
||||||
PCameraComponent source;
|
PCameraComponent source;
|
||||||
};
|
};
|
||||||
|
DEFINE_REF(LightCullingPass)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ void RenderGraph::setup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderGraph::addRenderPass(PRenderPass renderPass)
|
||||||
|
{
|
||||||
|
renderPasses.add(renderPass);
|
||||||
|
}
|
||||||
|
|
||||||
Gfx::PRenderTargetAttachment RenderGraph::requestRenderTarget(const std::string& outputName)
|
Gfx::PRenderTargetAttachment RenderGraph::requestRenderTarget(const std::string& outputName)
|
||||||
{
|
{
|
||||||
if(registeredAttachments.find(outputName) == registeredAttachments.end())
|
if(registeredAttachments.find(outputName) == registeredAttachments.end())
|
||||||
@@ -33,7 +38,38 @@ Gfx::PRenderTargetAttachment RenderGraph::requestRenderTarget(const std::string&
|
|||||||
return registeredAttachments[outputName];
|
return registeredAttachments[outputName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gfx::PTexture RenderGraph::requestTexture(const std::string& outputName)
|
||||||
|
{
|
||||||
|
if(registeredTextures.find(outputName) == registeredTextures.end())
|
||||||
|
{
|
||||||
|
std::cout << "Attachment " << outputName << " not found" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return registeredTextures[outputName];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Gfx::PStructuredBuffer RenderGraph::requestBuffer(const std::string& outputName)
|
||||||
|
{
|
||||||
|
if(registeredBuffers.find(outputName) == registeredBuffers.end())
|
||||||
|
{
|
||||||
|
std::cout << "Attachment " << outputName << " not found" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return registeredBuffers[outputName];
|
||||||
|
}
|
||||||
|
|
||||||
void RenderGraph::registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment)
|
void RenderGraph::registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment)
|
||||||
{
|
{
|
||||||
registeredAttachments[outputName] = attachment;
|
registeredAttachments[outputName] = attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderGraph::registerTextureOutput(const std::string& outputName, Gfx::PTexture texture)
|
||||||
|
{
|
||||||
|
registeredTextures[outputName] = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGraph::registerBufferOutput(const std::string& outputName, Gfx::PStructuredBuffer buffer)
|
||||||
|
{
|
||||||
|
registeredBuffers[outputName] = buffer;
|
||||||
|
}
|
||||||
@@ -11,10 +11,17 @@ public:
|
|||||||
RenderGraph();
|
RenderGraph();
|
||||||
~RenderGraph();
|
~RenderGraph();
|
||||||
void setup();
|
void setup();
|
||||||
|
void addRenderPass(PRenderPass renderPass);
|
||||||
Gfx::PRenderTargetAttachment requestRenderTarget(const std::string& outputName);
|
Gfx::PRenderTargetAttachment requestRenderTarget(const std::string& outputName);
|
||||||
void registerRenderPassOutput(const std::string& ouputName, Gfx::PRenderTargetAttachment attachment);
|
Gfx::PTexture requestTexture(const std::string& outputName);
|
||||||
|
Gfx::PStructuredBuffer requestBuffer(const std::string& outputName);
|
||||||
|
void registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment);
|
||||||
|
void registerTextureOutput(const std::string& outputName, Gfx::PTexture buffer);
|
||||||
|
void registerBufferOutput(const std::string& outputName, Gfx::PStructuredBuffer buffer);
|
||||||
private:
|
private:
|
||||||
Map<std::string, Gfx::PRenderTargetAttachment> registeredAttachments;
|
Map<std::string, Gfx::PRenderTargetAttachment> registeredAttachments;
|
||||||
|
Map<std::string, Gfx::PTexture> registeredTextures;
|
||||||
|
Map<std::string, Gfx::PStructuredBuffer> registeredBuffers;
|
||||||
List<PRenderPass> renderPasses;
|
List<PRenderPass> renderPasses;
|
||||||
};
|
};
|
||||||
DEFINE_REF(RenderGraph)
|
DEFINE_REF(RenderGraph)
|
||||||
|
|||||||
@@ -21,13 +21,10 @@ protected:
|
|||||||
{
|
{
|
||||||
Matrix4 viewMatrix;
|
Matrix4 viewMatrix;
|
||||||
Matrix4 projectionMatrix;
|
Matrix4 projectionMatrix;
|
||||||
Vector4 cameraPosition;
|
|
||||||
} viewParams;
|
|
||||||
struct ScreenToViewParameter
|
|
||||||
{
|
|
||||||
Matrix4 inverseProjectionMatrix;
|
Matrix4 inverseProjectionMatrix;
|
||||||
Vector2 screenDimensions;
|
Vector2 screenDimensions;
|
||||||
} screenToViewParams;
|
Vector4 cameraPosition;
|
||||||
|
} viewParams;
|
||||||
Gfx::PRenderPass renderPass;
|
Gfx::PRenderPass renderPass;
|
||||||
PRenderGraph renderGraph;
|
PRenderGraph renderGraph;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,21 +16,19 @@ struct PendingBuffer
|
|||||||
|
|
||||||
static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
|
static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
|
||||||
|
|
||||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType)
|
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
|
||||||
: graphics(graphics)
|
: graphics(graphics)
|
||||||
, currentBuffer(0)
|
, currentBuffer(0)
|
||||||
, size(size)
|
, size(size)
|
||||||
, currentOwner(queueType)
|
, owner(queueType)
|
||||||
{
|
{
|
||||||
if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT ||
|
if(bDynamic)
|
||||||
usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ||
|
|
||||||
usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)
|
|
||||||
{
|
{
|
||||||
numBuffers = 1;
|
numBuffers = Gfx::numFramesBuffered;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
numBuffers = Gfx::numFramesBuffered;
|
numBuffers = 1;
|
||||||
}
|
}
|
||||||
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||||
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
@@ -63,7 +61,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u
|
|||||||
|
|
||||||
ShaderBuffer::~ShaderBuffer()
|
ShaderBuffer::~ShaderBuffer()
|
||||||
{
|
{
|
||||||
auto cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
auto cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||||
auto &deletionQueue = graphics->getDeletionQueue();
|
auto &deletionQueue = graphics->getDeletionQueue();
|
||||||
VkDevice device = graphics->getDevice();
|
VkDevice device = graphics->getDevice();
|
||||||
VkBuffer buf[Gfx::numFramesBuffered];
|
VkBuffer buf[Gfx::numFramesBuffered];
|
||||||
@@ -85,25 +83,25 @@ void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
|||||||
{
|
{
|
||||||
VkBufferMemoryBarrier barrier =
|
VkBufferMemoryBarrier barrier =
|
||||||
init::BufferMemoryBarrier();
|
init::BufferMemoryBarrier();
|
||||||
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
|
PCommandBufferManager sourceManager = graphics->getQueueCommands(owner);
|
||||||
PCommandBufferManager dstManager = nullptr;
|
PCommandBufferManager dstManager = nullptr;
|
||||||
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||||
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||||
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
||||||
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
|
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner);
|
||||||
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
|
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
|
||||||
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
|
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
|
||||||
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
if (owner == Gfx::QueueType::TRANSFER || owner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||||
{
|
{
|
||||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
}
|
}
|
||||||
else if (currentOwner == Gfx::QueueType::COMPUTE)
|
else if (owner == Gfx::QueueType::COMPUTE)
|
||||||
{
|
{
|
||||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
}
|
}
|
||||||
else if (currentOwner == Gfx::QueueType::GRAPHICS)
|
else if (owner == Gfx::QueueType::GRAPHICS)
|
||||||
{
|
{
|
||||||
barrier.srcAccessMask = getSourceAccessMask();
|
barrier.srcAccessMask = getSourceAccessMask();
|
||||||
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||||
@@ -135,17 +133,36 @@ void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
|||||||
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
|
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
|
||||||
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
|
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
|
||||||
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
||||||
for (uint32_t i = 0; i < numBuffers; ++i)
|
barrier.offset = 0;
|
||||||
|
barrier.size = size;
|
||||||
|
for (uint32 i = 0; i < numBuffers; ++i)
|
||||||
{
|
{
|
||||||
dynamicBarriers[i] = barrier;
|
dynamicBarriers[i] = barrier;
|
||||||
dynamicBarriers[i].buffer = buffers[i].buffer;
|
dynamicBarriers[i].buffer = buffers[i].buffer;
|
||||||
dynamicBarriers[i].offset = 0;
|
|
||||||
dynamicBarriers[i].size = size;
|
|
||||||
}
|
}
|
||||||
vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||||
vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||||
sourceManager->submitCommands();
|
sourceManager->submitCommands();
|
||||||
currentOwner = newOwner;
|
}
|
||||||
|
|
||||||
|
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||||
|
{
|
||||||
|
PCmdBuffer commandBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||||
|
VkBufferMemoryBarrier barrier = init::BufferMemoryBarrier();
|
||||||
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
barrier.dstAccessMask = dstAccess;
|
||||||
|
barrier.srcAccessMask = srcAccess;
|
||||||
|
barrier.offset = 0;
|
||||||
|
barrier.size = size;
|
||||||
|
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
||||||
|
for(uint32 i = 0; i < numBuffers; ++i)
|
||||||
|
{
|
||||||
|
dynamicBarriers[i] = barrier;
|
||||||
|
dynamicBarriers[i].buffer = buffers[i].buffer;
|
||||||
|
}
|
||||||
|
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ShaderBuffer::lock(bool bWriteOnly)
|
void *ShaderBuffer::lock(bool bWriteOnly)
|
||||||
@@ -168,7 +185,7 @@ void *ShaderBuffer::lock(bool bWriteOnly)
|
|||||||
|
|
||||||
PendingBuffer pending;
|
PendingBuffer pending;
|
||||||
pending.bWriteOnly = bWriteOnly;
|
pending.bWriteOnly = bWriteOnly;
|
||||||
pending.prevQueue = currentOwner;
|
pending.prevQueue = owner;
|
||||||
if (bWriteOnly)
|
if (bWriteOnly)
|
||||||
{
|
{
|
||||||
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||||
@@ -178,12 +195,12 @@ void *ShaderBuffer::lock(bool bWriteOnly)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PCmdBuffer current = graphics->getQueueCommands(currentOwner)->getCommands();
|
PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
|
||||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
graphics->getQueueCommands(owner)->submitCommands();
|
||||||
graphics->getQueueCommands(currentOwner)->waitForCommands(current);
|
current->waitForCommand();
|
||||||
|
|
||||||
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||||
VkCommandBuffer handle = graphics->getQueueCommands(currentOwner)->getCommands()->getHandle();
|
VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
|
||||||
|
|
||||||
VkBufferMemoryBarrier barrier =
|
VkBufferMemoryBarrier barrier =
|
||||||
init::BufferMemoryBarrier();
|
init::BufferMemoryBarrier();
|
||||||
@@ -205,8 +222,8 @@ void *ShaderBuffer::lock(bool bWriteOnly)
|
|||||||
|
|
||||||
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, ®ions);
|
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, ®ions);
|
||||||
|
|
||||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
graphics->getQueueCommands(owner)->submitCommands();
|
||||||
vkQueueWaitIdle(graphics->getQueueCommands(currentOwner)->getQueue()->getHandle());
|
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
|
||||||
|
|
||||||
stagingBuffer->flushMappedMemory();
|
stagingBuffer->flushMappedMemory();
|
||||||
pending.stagingBuffer = stagingBuffer;
|
pending.stagingBuffer = stagingBuffer;
|
||||||
@@ -230,14 +247,14 @@ void ShaderBuffer::unlock()
|
|||||||
if (pending.bWriteOnly)
|
if (pending.bWriteOnly)
|
||||||
{
|
{
|
||||||
PStagingBuffer stagingBuffer = pending.stagingBuffer;
|
PStagingBuffer stagingBuffer = pending.stagingBuffer;
|
||||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||||
|
|
||||||
VkBufferCopy region;
|
VkBufferCopy region;
|
||||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||||
region.size = size;
|
region.size = size;
|
||||||
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
graphics->getQueueCommands(owner)->submitCommands();
|
||||||
}
|
}
|
||||||
//requestOwnershipTransfer(pending.prevQueue);
|
//requestOwnershipTransfer(pending.prevQueue);
|
||||||
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
|
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
|
||||||
@@ -246,7 +263,7 @@ void ShaderBuffer::unlock()
|
|||||||
|
|
||||||
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
|
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
|
||||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData)
|
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData)
|
||||||
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, createInfo.resourceData.owner)
|
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic)
|
||||||
, dedicatedStagingBuffer(nullptr)
|
, dedicatedStagingBuffer(nullptr)
|
||||||
{
|
{
|
||||||
if(createInfo.bDynamic)
|
if(createInfo.bDynamic)
|
||||||
@@ -291,14 +308,14 @@ void UniformBuffer::unlock()
|
|||||||
if(dedicatedStagingBuffer != nullptr)
|
if(dedicatedStagingBuffer != nullptr)
|
||||||
{
|
{
|
||||||
dedicatedStagingBuffer->flushMappedMemory();
|
dedicatedStagingBuffer->flushMappedMemory();
|
||||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(ShaderBuffer::currentOwner)->getCommands();
|
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||||
|
|
||||||
VkBufferCopy region;
|
VkBufferCopy region;
|
||||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||||
region.size = ShaderBuffer::size;
|
region.size = ShaderBuffer::size;
|
||||||
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||||
graphics->getQueueCommands(ShaderBuffer::currentOwner)->submitCommands();
|
graphics->getQueueCommands(currentOwner)->submitCommands();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -309,7 +326,6 @@ void UniformBuffer::unlock()
|
|||||||
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||||
Vulkan::ShaderBuffer::currentOwner = newOwner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||||
@@ -317,6 +333,12 @@ void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
|||||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||||
|
{
|
||||||
|
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
VkAccessFlags UniformBuffer::getSourceAccessMask()
|
VkAccessFlags UniformBuffer::getSourceAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
@@ -327,14 +349,14 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
|
|||||||
return VK_ACCESS_UNIFORM_READ_BIT;
|
return VK_ACCESS_UNIFORM_READ_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructuredBuffer::StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
StructuredBuffer::StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData)
|
||||||
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.owner)
|
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.resourceData.owner)
|
||||||
, Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner)
|
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, resourceData.bDynamic)
|
||||||
{
|
{
|
||||||
if (resourceData.data != nullptr)
|
if (resourceData.resourceData.data != nullptr)
|
||||||
{
|
{
|
||||||
void *data = lock();
|
void *data = lock();
|
||||||
std::memcpy(data, resourceData.data, resourceData.size);
|
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,6 +375,12 @@ void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
|||||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StructuredBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||||
|
{
|
||||||
|
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
VkAccessFlags StructuredBuffer::getSourceAccessMask()
|
VkAccessFlags StructuredBuffer::getSourceAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
@@ -365,7 +393,7 @@ VkAccessFlags StructuredBuffer::getDestAccessMask()
|
|||||||
|
|
||||||
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
|
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
|
||||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
|
: Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
|
||||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.resourceData.owner)
|
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
|
||||||
{
|
{
|
||||||
if (resourceData.resourceData.data != nullptr)
|
if (resourceData.resourceData.data != nullptr)
|
||||||
{
|
{
|
||||||
@@ -389,6 +417,12 @@ void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
|||||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||||
|
{
|
||||||
|
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
VkAccessFlags VertexBuffer::getSourceAccessMask()
|
VkAccessFlags VertexBuffer::getSourceAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
@@ -401,7 +435,7 @@ VkAccessFlags VertexBuffer::getDestAccessMask()
|
|||||||
|
|
||||||
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
|
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
|
||||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
|
: Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
|
||||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.resourceData.owner)
|
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
|
||||||
{
|
{
|
||||||
if (resourceData.resourceData.data != nullptr)
|
if (resourceData.resourceData.data != nullptr)
|
||||||
{
|
{
|
||||||
@@ -425,6 +459,12 @@ void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
|||||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||||
|
{
|
||||||
|
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
VkAccessFlags IndexBuffer::getSourceAccessMask()
|
VkAccessFlags IndexBuffer::getSourceAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
|
|||||||
@@ -84,20 +84,38 @@ void CmdBuffer::endRenderPass()
|
|||||||
state = State::InsideBegin;
|
state = State::InsideBegin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdBuffer::executeCommands(Array<Gfx::PRenderCommand> commands)
|
void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||||
{
|
{
|
||||||
assert(state == State::RenderPassActive);
|
assert(state == State::RenderPassActive);
|
||||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||||
for (uint32 i = 0; i < commands.size(); ++i)
|
for (uint32 i = 0; i < commands.size(); ++i)
|
||||||
{
|
{
|
||||||
auto command = commands[i].cast<SecondaryCmdBuffer>();
|
auto command = commands[i].cast<RenderCommand>();
|
||||||
// Cache array and size to save on pointer access
|
// Cache array and size to save on pointer access
|
||||||
for(auto boundDescriptor : command->boundDescriptors)
|
for(auto boundDescriptor : command->boundDescriptors)
|
||||||
{
|
{
|
||||||
boundDescriptor->currentlyBound = this;
|
boundDescriptor->currentlyBound = this;
|
||||||
}
|
}
|
||||||
command->end();
|
command->end();
|
||||||
executingCommands.add(command);
|
executingRenders.add(command);
|
||||||
|
cmdBuffers[i] = command->getHandle();
|
||||||
|
}
|
||||||
|
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||||
|
{
|
||||||
|
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||||
|
for (uint32 i = 0; i < commands.size(); ++i)
|
||||||
|
{
|
||||||
|
auto command = commands[i].cast<ComputeCommand>();
|
||||||
|
// Cache array and size to save on pointer access
|
||||||
|
for(auto boundDescriptor : command->boundDescriptors)
|
||||||
|
{
|
||||||
|
boundDescriptor->currentlyBound = this;
|
||||||
|
}
|
||||||
|
command->end();
|
||||||
|
executingComputes.add(command);
|
||||||
cmdBuffers[i] = command->getHandle();
|
cmdBuffers[i] = command->getHandle();
|
||||||
}
|
}
|
||||||
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||||
@@ -117,11 +135,16 @@ void CmdBuffer::refreshFence()
|
|||||||
{
|
{
|
||||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||||
fence->reset();
|
fence->reset();
|
||||||
for(auto command : executingCommands)
|
for(auto command : executingComputes)
|
||||||
{
|
{
|
||||||
command->reset();
|
command->reset();
|
||||||
}
|
}
|
||||||
executingCommands.clear();
|
executingComputes.clear();
|
||||||
|
for(auto command : executingRenders)
|
||||||
|
{
|
||||||
|
command->reset();
|
||||||
|
}
|
||||||
|
executingRenders.clear();
|
||||||
state = State::ReadyBegin;
|
state = State::ReadyBegin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,6 +154,13 @@ void CmdBuffer::refreshFence()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CmdBuffer::waitForCommand(uint32 timeout)
|
||||||
|
{
|
||||||
|
fence->wait(timeout);
|
||||||
|
refreshFence();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PFence CmdBuffer::getFence()
|
PFence CmdBuffer::getFence()
|
||||||
{
|
{
|
||||||
return fence;
|
return fence;
|
||||||
@@ -157,20 +187,6 @@ SecondaryCmdBuffer::~SecondaryCmdBuffer()
|
|||||||
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecondaryCmdBuffer::begin(PCmdBuffer parent)
|
|
||||||
{
|
|
||||||
ready = false;
|
|
||||||
VkCommandBufferBeginInfo beginInfo =
|
|
||||||
init::CommandBufferBeginInfo();
|
|
||||||
VkCommandBufferInheritanceInfo inheritanceInfo =
|
|
||||||
init::CommandBufferInheritanceInfo();
|
|
||||||
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
|
|
||||||
inheritanceInfo.renderPass = parent->renderPass->getHandle();
|
|
||||||
inheritanceInfo.subpass = parent->subpassIndex;
|
|
||||||
beginInfo.pInheritanceInfo = &inheritanceInfo;
|
|
||||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
|
|
||||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SecondaryCmdBuffer::end()
|
void SecondaryCmdBuffer::end()
|
||||||
{
|
{
|
||||||
@@ -188,12 +204,37 @@ void SecondaryCmdBuffer::reset()
|
|||||||
ready = true;
|
ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SecondaryCmdBuffer::isReady()
|
RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||||
|
: SecondaryCmdBuffer(graphics, cmdPool)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
RenderCommand::~RenderCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderCommand::begin(PCmdBuffer parent)
|
||||||
|
{
|
||||||
|
ready = false;
|
||||||
|
VkCommandBufferBeginInfo beginInfo =
|
||||||
|
init::CommandBufferBeginInfo();
|
||||||
|
VkCommandBufferInheritanceInfo inheritanceInfo =
|
||||||
|
init::CommandBufferInheritanceInfo();
|
||||||
|
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
|
||||||
|
inheritanceInfo.renderPass = parent->renderPass->getHandle();
|
||||||
|
inheritanceInfo.subpass = parent->subpassIndex;
|
||||||
|
beginInfo.pInheritanceInfo = &inheritanceInfo;
|
||||||
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
|
||||||
|
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool RenderCommand::isReady()
|
||||||
{
|
{
|
||||||
return ready;
|
return ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport)
|
void RenderCommand::setViewport(Gfx::PViewport viewport)
|
||||||
{
|
{
|
||||||
VkViewport vp = viewport.cast<Viewport>()->getHandle();
|
VkViewport vp = viewport.cast<Viewport>()->getHandle();
|
||||||
VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY());
|
VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY());
|
||||||
@@ -201,19 +242,19 @@ void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport)
|
|||||||
vkCmdSetScissor(handle, 0, 1, &scissors);
|
vkCmdSetScissor(handle, 0, 1, &scissors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecondaryCmdBuffer::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
|
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
|
||||||
{
|
{
|
||||||
pipeline = gfxPipeline.cast<GraphicsPipeline>();
|
pipeline = gfxPipeline.cast<GraphicsPipeline>();
|
||||||
pipeline->bind(handle);
|
pipeline->bind(handle);
|
||||||
}
|
}
|
||||||
void SecondaryCmdBuffer::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
|
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
|
||||||
{
|
{
|
||||||
auto descriptor = descriptorSet.cast<DescriptorSet>();
|
auto descriptor = descriptorSet.cast<DescriptorSet>();
|
||||||
boundDescriptors.add(descriptor.getHandle());
|
boundDescriptors.add(descriptor.getHandle());
|
||||||
VkDescriptorSet setHandle = descriptor->getHandle();
|
VkDescriptorSet setHandle = descriptor->getHandle();
|
||||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
|
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
|
||||||
}
|
}
|
||||||
void SecondaryCmdBuffer::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets)
|
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets)
|
||||||
{
|
{
|
||||||
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
|
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
|
||||||
for(uint32 i = 0; i < descriptorSets.size(); ++i)
|
for(uint32 i = 0; i < descriptorSets.size(); ++i)
|
||||||
@@ -225,7 +266,7 @@ void SecondaryCmdBuffer::bindDescriptor(const Array<Gfx::PDescriptorSet>& descri
|
|||||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
|
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
|
||||||
delete[] sets;
|
delete[] sets;
|
||||||
}
|
}
|
||||||
void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& streams)
|
void RenderCommand::bindVertexBuffer(const Array<VertexInputStream>& streams)
|
||||||
{
|
{
|
||||||
Array<VkBuffer> buffers(streams.size());
|
Array<VkBuffer> buffers(streams.size());
|
||||||
Array<VkDeviceSize> offsets(streams.size());
|
Array<VkDeviceSize> offsets(streams.size());
|
||||||
@@ -237,16 +278,76 @@ void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& stream
|
|||||||
};
|
};
|
||||||
vkCmdBindVertexBuffers(handle, 0, (uint32)streams.size(), buffers.data(), offsets.data());
|
vkCmdBindVertexBuffers(handle, 0, (uint32)streams.size(), buffers.data(), offsets.data());
|
||||||
}
|
}
|
||||||
void SecondaryCmdBuffer::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
||||||
{
|
{
|
||||||
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
|
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
|
||||||
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
|
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
|
||||||
}
|
}
|
||||||
void SecondaryCmdBuffer::draw(const MeshBatchElement& data)
|
void RenderCommand::draw(const MeshBatchElement& data)
|
||||||
{
|
{
|
||||||
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
|
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||||
|
: SecondaryCmdBuffer(graphics, cmdPool)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ComputeCommand::~ComputeCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeCommand::begin(PCmdBuffer parent)
|
||||||
|
{
|
||||||
|
ready = false;
|
||||||
|
VkCommandBufferBeginInfo beginInfo =
|
||||||
|
init::CommandBufferBeginInfo();
|
||||||
|
VkCommandBufferInheritanceInfo inheritanceInfo =
|
||||||
|
init::CommandBufferInheritanceInfo();
|
||||||
|
inheritanceInfo.framebuffer = VK_NULL_HANDLE;
|
||||||
|
inheritanceInfo.renderPass = VK_NULL_HANDLE;
|
||||||
|
inheritanceInfo.subpass = 0;
|
||||||
|
beginInfo.pInheritanceInfo = &inheritanceInfo;
|
||||||
|
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ComputeCommand::isReady()
|
||||||
|
{
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline)
|
||||||
|
{
|
||||||
|
pipeline = computePipeline.cast<ComputePipeline>();
|
||||||
|
pipeline->bind(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
|
||||||
|
{
|
||||||
|
auto descriptor = descriptorSet.cast<DescriptorSet>();
|
||||||
|
boundDescriptors.add(descriptor.getHandle());
|
||||||
|
VkDescriptorSet setHandle = descriptor->getHandle();
|
||||||
|
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets)
|
||||||
|
{
|
||||||
|
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
|
||||||
|
for(uint32 i = 0; i < descriptorSets.size(); ++i)
|
||||||
|
{
|
||||||
|
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
|
||||||
|
boundDescriptors.add(descriptorSet.getHandle());
|
||||||
|
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
|
||||||
|
}
|
||||||
|
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
|
||||||
|
delete[] sets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
|
||||||
|
{
|
||||||
|
vkCmdDispatch(handle, threadX, threadY, threadZ);
|
||||||
|
}
|
||||||
|
|
||||||
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||||
: graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex())
|
: graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex())
|
||||||
{
|
{
|
||||||
@@ -275,20 +376,40 @@ PCmdBuffer CommandBufferManager::getCommands()
|
|||||||
return activeCmdBuffer;
|
return activeCmdBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer()
|
PRenderCommand CommandBufferManager::createRenderCommand(const std::string& name)
|
||||||
{
|
{
|
||||||
std::scoped_lock lck(allocatedSecondBufferLock);
|
std::scoped_lock lck(allocatedRenderLock);
|
||||||
for (uint32 i = 0; i < allocatedSecondBuffers.size(); ++i)
|
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
|
||||||
{
|
{
|
||||||
PSecondaryCmdBuffer cmdBuffer = allocatedSecondBuffers[i];
|
PRenderCommand cmdBuffer = allocatedRenderCommands[i];
|
||||||
if (cmdBuffer->isReady())
|
if (cmdBuffer->ready)
|
||||||
{
|
{
|
||||||
cmdBuffer->begin(activeCmdBuffer);
|
cmdBuffer->begin(activeCmdBuffer);
|
||||||
return cmdBuffer;
|
return cmdBuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PSecondaryCmdBuffer result = new SecondaryCmdBuffer(graphics, commandPool);
|
PRenderCommand result = new RenderCommand(graphics, commandPool);
|
||||||
allocatedSecondBuffers.add(result);
|
result->name = name;
|
||||||
|
allocatedRenderCommands.add(result);
|
||||||
|
result->begin(activeCmdBuffer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PComputeCommand CommandBufferManager::createComputeCommand(const std::string& name)
|
||||||
|
{
|
||||||
|
std::scoped_lock lck(allocatedComputeLock);
|
||||||
|
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
|
||||||
|
{
|
||||||
|
PComputeCommand cmdBuffer = allocatedComputeCommands[i];
|
||||||
|
if (cmdBuffer->ready)
|
||||||
|
{
|
||||||
|
cmdBuffer->begin(activeCmdBuffer);
|
||||||
|
return cmdBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PComputeCommand result = new ComputeCommand(graphics, commandPool);
|
||||||
|
result->name = name;
|
||||||
|
allocatedComputeCommands.add(result);
|
||||||
result->begin(activeCmdBuffer);
|
result->begin(activeCmdBuffer);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -332,9 +453,3 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
|||||||
allocatedBuffers.add(activeCmdBuffer);
|
allocatedBuffers.add(activeCmdBuffer);
|
||||||
activeCmdBuffer->begin();
|
activeCmdBuffer->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferManager::waitForCommands(PCmdBuffer cmdBuffer, uint32 timeout)
|
|
||||||
{
|
|
||||||
cmdBuffer->fence->wait(timeout);
|
|
||||||
cmdBuffer->refreshFence();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ protected:
|
|||||||
};
|
};
|
||||||
DEFINE_REF(CmdBufferBase)
|
DEFINE_REF(CmdBufferBase)
|
||||||
|
|
||||||
DECLARE_REF(SecondaryCmdBuffer)
|
DECLARE_REF(RenderCommand)
|
||||||
|
DECLARE_REF(ComputeCommand)
|
||||||
DECLARE_REF(CommandBufferManager)
|
DECLARE_REF(CommandBufferManager)
|
||||||
class CmdBuffer : public CmdBufferBase
|
class CmdBuffer : public CmdBufferBase
|
||||||
{
|
{
|
||||||
@@ -40,9 +41,11 @@ public:
|
|||||||
void end();
|
void end();
|
||||||
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
|
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||||
void endRenderPass();
|
void endRenderPass();
|
||||||
void executeCommands(Array<Gfx::PRenderCommand> secondaryCommands);
|
void executeCommands(const Array<Gfx::PRenderCommand>& secondaryCommands);
|
||||||
|
void executeCommands(const Array<Gfx::PComputeCommand>& secondaryCommands);
|
||||||
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||||
void refreshFence();
|
void refreshFence();
|
||||||
|
void waitForCommand(uint32 timeToWait = 1000000u);
|
||||||
PFence getFence();
|
PFence getFence();
|
||||||
PCommandBufferManager getManager();
|
PCommandBufferManager getManager();
|
||||||
enum State
|
enum State
|
||||||
@@ -63,23 +66,40 @@ private:
|
|||||||
State state;
|
State state;
|
||||||
Array<PSemaphore> waitSemaphores;
|
Array<PSemaphore> waitSemaphores;
|
||||||
Array<VkPipelineStageFlags> waitFlags;
|
Array<VkPipelineStageFlags> waitFlags;
|
||||||
Array<PSecondaryCmdBuffer> executingCommands;
|
Array<PRenderCommand> executingRenders;
|
||||||
friend class SecondaryCmdBuffer;
|
Array<PComputeCommand> executingComputes;
|
||||||
|
friend class RenderCommand;
|
||||||
friend class CommandBufferManager;
|
friend class CommandBufferManager;
|
||||||
friend class Queue;
|
friend class Queue;
|
||||||
};
|
};
|
||||||
DEFINE_REF(CmdBuffer)
|
DEFINE_REF(CmdBuffer)
|
||||||
|
|
||||||
DECLARE_REF(GraphicsPipeline)
|
DECLARE_REF(GraphicsPipeline)
|
||||||
|
DECLARE_REF(ComputePipeline)
|
||||||
DECLARE_REF(DescriptorSet)
|
DECLARE_REF(DescriptorSet)
|
||||||
class SecondaryCmdBuffer : public Gfx::RenderCommand, public CmdBufferBase
|
|
||||||
|
class SecondaryCmdBuffer: public CmdBufferBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
||||||
virtual ~SecondaryCmdBuffer();
|
virtual ~SecondaryCmdBuffer();
|
||||||
void begin(PCmdBuffer parent);
|
virtual void begin(PCmdBuffer parent) = 0;
|
||||||
void end();
|
void end();
|
||||||
void reset();
|
void reset();
|
||||||
|
bool ready;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Array<DescriptorSet*> boundDescriptors;
|
||||||
|
friend class CmdBuffer;
|
||||||
|
};
|
||||||
|
DEFINE_REF(SecondaryCmdBuffer);
|
||||||
|
|
||||||
|
class RenderCommand : public Gfx::RenderCommand, public SecondaryCmdBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||||
|
virtual ~RenderCommand();
|
||||||
|
virtual void begin(PCmdBuffer parent) override;
|
||||||
virtual bool isReady() override;
|
virtual bool isReady() override;
|
||||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||||
@@ -91,12 +111,26 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
PGraphicsPipeline pipeline;
|
PGraphicsPipeline pipeline;
|
||||||
Array<DescriptorSet*> boundDescriptors;
|
|
||||||
bool ready;
|
|
||||||
friend class CmdBuffer;
|
friend class CmdBuffer;
|
||||||
};
|
};
|
||||||
DEFINE_REF(SecondaryCmdBuffer)
|
DEFINE_REF(RenderCommand)
|
||||||
|
|
||||||
|
class ComputeCommand : public Gfx::ComputeCommand, public SecondaryCmdBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ComputeCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||||
|
virtual ~ComputeCommand();
|
||||||
|
virtual void begin(PCmdBuffer parent) override;
|
||||||
|
virtual bool isReady() override;
|
||||||
|
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||||
|
virtual void bindDescriptor(Gfx::PDescriptorSet set) override;
|
||||||
|
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override;
|
||||||
|
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||||
|
private:
|
||||||
|
PComputePipeline pipeline;
|
||||||
|
friend class CmdBuffer;
|
||||||
|
};
|
||||||
|
DEFINE_REF(ComputeCommand)
|
||||||
class CommandBufferManager
|
class CommandBufferManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -107,9 +141,9 @@ public:
|
|||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
PCmdBuffer getCommands();
|
PCmdBuffer getCommands();
|
||||||
PSecondaryCmdBuffer createSecondaryCmdBuffer();
|
PRenderCommand createRenderCommand(const std::string& name);
|
||||||
|
PComputeCommand createComputeCommand(const std::string& name);
|
||||||
void submitCommands(PSemaphore signalSemaphore = nullptr);
|
void submitCommands(PSemaphore signalSemaphore = nullptr);
|
||||||
void waitForCommands(PCmdBuffer cmdBuffer, uint32 timeToWait = 1000000u);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
@@ -119,8 +153,10 @@ private:
|
|||||||
PCmdBuffer activeCmdBuffer;
|
PCmdBuffer activeCmdBuffer;
|
||||||
std::mutex allocatedBufferLock;
|
std::mutex allocatedBufferLock;
|
||||||
Array<PCmdBuffer> allocatedBuffers;
|
Array<PCmdBuffer> allocatedBuffers;
|
||||||
std::mutex allocatedSecondBufferLock;
|
std::mutex allocatedRenderLock;
|
||||||
Array<PSecondaryCmdBuffer> allocatedSecondBuffers;
|
std::mutex allocatedComputeLock;
|
||||||
|
Array<PRenderCommand> allocatedRenderCommands;
|
||||||
|
Array<PComputeCommand> allocatedComputeCommands;
|
||||||
};
|
};
|
||||||
DEFINE_REF(CommandBufferManager)
|
DEFINE_REF(CommandBufferManager)
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ DescriptorSet::~DescriptorSet()
|
|||||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
|
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
|
||||||
{
|
{
|
||||||
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||||
UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[Gfx::currentFrameIndex][binding]);
|
UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[binding]);
|
||||||
/*if(vulkanBuffer->isDataEquals(cachedBuffer))
|
/*if(vulkanBuffer->isDataEquals(cachedBuffer))
|
||||||
{
|
{
|
||||||
std::cout << "uniform data equal, skip" << std::endl;
|
std::cout << "uniform data equal, skip" << std::endl;
|
||||||
@@ -125,32 +125,32 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
|
|||||||
}*/
|
}*/
|
||||||
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
|
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
|
||||||
|
|
||||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
|
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
|
||||||
writeDescriptors.add(writeDescriptor);
|
writeDescriptors.add(writeDescriptor);
|
||||||
|
|
||||||
cachedData[Gfx::currentFrameIndex][binding] = new UniformBuffer(*vulkanBuffer.getHandle());
|
cachedData[binding] = new UniformBuffer(*vulkanBuffer.getHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer)
|
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer)
|
||||||
{
|
{
|
||||||
PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>();
|
PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>();
|
||||||
StructuredBuffer* cachedBuffer = reinterpret_cast<StructuredBuffer*>(cachedData[Gfx::currentFrameIndex][binding]);
|
StructuredBuffer* cachedBuffer = reinterpret_cast<StructuredBuffer*>(cachedData[binding]);
|
||||||
if(vulkanBuffer.getHandle() == cachedBuffer)
|
if(vulkanBuffer.getHandle() == cachedBuffer)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
|
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
|
||||||
|
|
||||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
|
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
|
||||||
writeDescriptors.add(writeDescriptor);
|
writeDescriptors.add(writeDescriptor);
|
||||||
|
|
||||||
cachedData[Gfx::currentFrameIndex][binding] = vulkanBuffer.getHandle();
|
cachedData[binding] = vulkanBuffer.getHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState)
|
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState)
|
||||||
{
|
{
|
||||||
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
||||||
SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[Gfx::currentFrameIndex][binding]);
|
SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[binding]);
|
||||||
if(vulkanSampler.getHandle() == cachedSampler)
|
if(vulkanSampler.getHandle() == cachedSampler)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -162,16 +162,16 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerSt
|
|||||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||||
imageInfos.add(imageInfo);
|
imageInfos.add(imageInfo);
|
||||||
|
|
||||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back());
|
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back());
|
||||||
writeDescriptors.add(writeDescriptor);
|
writeDescriptors.add(writeDescriptor);
|
||||||
|
|
||||||
cachedData[Gfx::currentFrameIndex][binding] = vulkanSampler.getHandle();
|
cachedData[binding] = vulkanSampler.getHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
|
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
|
||||||
{
|
{
|
||||||
TextureHandle* vulkanTexture = TextureBase::cast(texture);
|
TextureHandle* vulkanTexture = TextureBase::cast(texture);
|
||||||
TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[Gfx::currentFrameIndex][binding]);
|
TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[binding]);
|
||||||
if(vulkanTexture == cachedTexture)
|
if(vulkanTexture == cachedTexture)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -181,7 +181,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
|||||||
init::DescriptorImageInfo(
|
init::DescriptorImageInfo(
|
||||||
VK_NULL_HANDLE,
|
VK_NULL_HANDLE,
|
||||||
vulkanTexture->getView(),
|
vulkanTexture->getView(),
|
||||||
vulkanTexture->getLayout());
|
cast(vulkanTexture->getLayout()));
|
||||||
if (samplerState != nullptr)
|
if (samplerState != nullptr)
|
||||||
{
|
{
|
||||||
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
||||||
@@ -190,7 +190,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
|||||||
imageInfos.add(imageInfo);
|
imageInfos.add(imageInfo);
|
||||||
VkWriteDescriptorSet writeDescriptor =
|
VkWriteDescriptorSet writeDescriptor =
|
||||||
init::WriteDescriptorSet(
|
init::WriteDescriptorSet(
|
||||||
setHandle[Gfx::currentFrameIndex],
|
setHandle,
|
||||||
samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
binding,
|
binding,
|
||||||
&imageInfos.back());
|
&imageInfos.back());
|
||||||
@@ -200,7 +200,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
|||||||
}
|
}
|
||||||
writeDescriptors.add(writeDescriptor);
|
writeDescriptors.add(writeDescriptor);
|
||||||
|
|
||||||
cachedData[Gfx::currentFrameIndex][binding] = vulkanTexture;
|
cachedData[binding] = vulkanTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
|
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
|
||||||
@@ -220,8 +220,8 @@ void DescriptorSet::writeChanges()
|
|||||||
{
|
{
|
||||||
if(isCurrentlyBound())
|
if(isCurrentlyBound())
|
||||||
{
|
{
|
||||||
graphics->getGraphicsCommands()->waitForCommands(currentlyBound);
|
currentlyBound->waitForCommand(1000000000u);
|
||||||
currentlyBound = nullptr;
|
assert(!isCurrentlyBound());
|
||||||
}
|
}
|
||||||
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
||||||
writeDescriptors.clear();
|
writeDescriptors.clear();
|
||||||
@@ -258,7 +258,11 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &l
|
|||||||
poolSizes.add(size);
|
poolSizes.add(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VkDescriptorPoolCreateInfo createInfo = init::DescriptorPoolCreateInfo((uint32)poolSizes.size(), poolSizes.data(), maxSets * Gfx::numFramesBuffered);
|
VkDescriptorPoolCreateInfo createInfo
|
||||||
|
= init::DescriptorPoolCreateInfo(
|
||||||
|
(uint32)poolSizes.size(),
|
||||||
|
poolSizes.data(),
|
||||||
|
maxSets * Gfx::numFramesBuffered);
|
||||||
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
|
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,14 +275,8 @@ DescriptorAllocator::~DescriptorAllocator()
|
|||||||
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet)
|
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet)
|
||||||
{
|
{
|
||||||
VkDescriptorSetLayout layoutHandle = layout.getHandle();
|
VkDescriptorSetLayout layoutHandle = layout.getHandle();
|
||||||
VkDescriptorSetLayout layoutArray[Gfx::numFramesBuffered];
|
|
||||||
for (uint32 i = 0; i < Gfx::numFramesBuffered; i++)
|
|
||||||
{
|
|
||||||
layoutArray[i] = layoutHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDescriptorSetAllocateInfo allocInfo =
|
VkDescriptorSetAllocateInfo allocInfo =
|
||||||
init::DescriptorSetAllocateInfo(poolHandle, layoutArray, Gfx::numFramesBuffered);
|
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
|
||||||
|
|
||||||
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
|
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
|
||||||
{
|
{
|
||||||
@@ -290,18 +288,17 @@ void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorS
|
|||||||
if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE)
|
if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
//If it hasnt been initialized, allocate it
|
//If it hasnt been initialized, allocate it
|
||||||
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, cachedHandles[setIndex]->setHandle));
|
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
|
||||||
|
|
||||||
}
|
}
|
||||||
cachedHandles[setIndex]->currentlyInUse = true;
|
cachedHandles[setIndex]->currentlyInUse = true;
|
||||||
descriptorSet = cachedHandles[setIndex];
|
descriptorSet = cachedHandles[setIndex];
|
||||||
|
|
||||||
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
|
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
|
||||||
for(uint32 frameIndex = 0; frameIndex < Gfx::numFramesBuffered; ++frameIndex)
|
vulkanSet->cachedData.resize(layout.bindings.size());
|
||||||
{
|
|
||||||
vulkanSet->cachedData[frameIndex].resize(layout.bindings.size());
|
|
||||||
// Not really pretty, but this way the set knows which ones are valid
|
// Not really pretty, but this way the set knows which ones are valid
|
||||||
std::memset(vulkanSet->cachedData[frameIndex].data(), 0, sizeof(void*) * vulkanSet->cachedData[frameIndex].size());
|
std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size());
|
||||||
}
|
|
||||||
//Found set, stop searching
|
//Found set, stop searching
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,9 +60,12 @@ class DescriptorSet : public Gfx::DescriptorSet
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
|
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
|
||||||
: graphics(graphics), owner(owner), currentlyInUse(false), currentlyBound(nullptr)
|
: setHandle(VK_NULL_HANDLE)
|
||||||
|
, graphics(graphics)
|
||||||
|
, owner(owner)
|
||||||
|
, currentlyInUse(false)
|
||||||
|
, currentlyBound(nullptr)
|
||||||
{
|
{
|
||||||
std::memset(setHandle, 0, sizeof(setHandle));
|
|
||||||
}
|
}
|
||||||
virtual ~DescriptorSet();
|
virtual ~DescriptorSet();
|
||||||
virtual void writeChanges();
|
virtual void writeChanges();
|
||||||
@@ -86,7 +89,7 @@ public:
|
|||||||
}
|
}
|
||||||
inline VkDescriptorSet getHandle() const
|
inline VkDescriptorSet getHandle() const
|
||||||
{
|
{
|
||||||
return setHandle[Gfx::currentFrameIndex];
|
return setHandle;
|
||||||
}
|
}
|
||||||
virtual uint32 getSetIndex() const;
|
virtual uint32 getSetIndex() const;
|
||||||
|
|
||||||
@@ -97,8 +100,8 @@ private:
|
|||||||
// contains the previously bound resources at every binding
|
// contains the previously bound resources at every binding
|
||||||
// since the layout is fixed, trying to bind a texture to a buffer
|
// since the layout is fixed, trying to bind a texture to a buffer
|
||||||
// would not work anyways, so casts should be safe
|
// would not work anyways, so casts should be safe
|
||||||
Array<void*> cachedData[Gfx::numFramesBuffered];
|
Array<void*> cachedData;
|
||||||
VkDescriptorSet setHandle[Gfx::numFramesBuffered];
|
VkDescriptorSet setHandle;
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
PDescriptorAllocator owner;
|
PDescriptorAllocator owner;
|
||||||
PCmdBuffer currentlyBound;
|
PCmdBuffer currentlyBound;
|
||||||
|
|||||||
@@ -81,13 +81,19 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
|||||||
void Graphics::endRenderPass()
|
void Graphics::endRenderPass()
|
||||||
{
|
{
|
||||||
getGraphicsCommands()->getCommands()->endRenderPass();
|
getGraphicsCommands()->getCommands()->endRenderPass();
|
||||||
|
getGraphicsCommands()->submitCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::executeCommands(Array<Gfx::PRenderCommand> commands)
|
void Graphics::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||||
{
|
{
|
||||||
getGraphicsCommands()->getCommands()->executeCommands(commands);
|
getGraphicsCommands()->getCommands()->executeCommands(commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||||
|
{
|
||||||
|
getComputeCommands()->getCommands()->executeCommands(commands);
|
||||||
|
}
|
||||||
|
|
||||||
Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
||||||
{
|
{
|
||||||
PTexture2D result = new Texture2D(this, createInfo);
|
PTexture2D result = new Texture2D(this, createInfo);
|
||||||
@@ -100,7 +106,7 @@ Gfx::PUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo
|
|||||||
return uniformBuffer;
|
return uniformBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const BulkResourceData &bulkData)
|
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const StructuredBufferCreateInfo &bulkData)
|
||||||
{
|
{
|
||||||
PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData);
|
PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData);
|
||||||
return structuredBuffer;
|
return structuredBuffer;
|
||||||
@@ -116,9 +122,15 @@ Gfx::PIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD
|
|||||||
PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData);
|
PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData);
|
||||||
return indexBuffer;
|
return indexBuffer;
|
||||||
}
|
}
|
||||||
Gfx::PRenderCommand Graphics::createRenderCommand()
|
Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
|
||||||
{
|
{
|
||||||
PSecondaryCmdBuffer cmdBuffer = getGraphicsCommands()->createSecondaryCmdBuffer();
|
PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(name);
|
||||||
|
return cmdBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
|
||||||
|
{
|
||||||
|
PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name);
|
||||||
return cmdBuffer;
|
return cmdBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +170,13 @@ Gfx::PFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& crea
|
|||||||
shader->create(createInfo);
|
shader->create(createInfo);
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
Gfx::PComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
||||||
|
{
|
||||||
|
PComputeShader shader = new ComputeShader(this);
|
||||||
|
shader->create(createInfo);
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo)
|
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
|
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
|
||||||
@@ -189,6 +208,73 @@ Gfx::PPipelineLayout Graphics::createPipelineLayout()
|
|||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture)
|
||||||
|
{
|
||||||
|
Texture2D* src = (Texture2D*)srcTexture->getTexture2D();
|
||||||
|
Texture2D* dst = (Texture2D*)dstTexture->getTexture2D();
|
||||||
|
TextureHandle* srcHandle = (TextureHandle*)src->getNativeHandle();
|
||||||
|
TextureHandle* dstHandle = (TextureHandle*)dst->getNativeHandle();
|
||||||
|
Gfx::SeImageLayout srcLayout = srcHandle->getLayout();
|
||||||
|
Gfx::SeImageLayout dstLayout = dstHandle->getLayout();
|
||||||
|
Gfx::QueueType dstOwner = dstHandle->currentOwner;
|
||||||
|
src->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
dst->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
dstTexture->transferOwnership(srcHandle->currentOwner);
|
||||||
|
PCmdBuffer cmdBuffer = getQueueCommands(srcHandle->currentOwner)->getCommands();
|
||||||
|
if(srcHandle->getAspect() != dstHandle->getAspect())
|
||||||
|
{
|
||||||
|
/*VkMemoryRequirements imageRequirements;
|
||||||
|
vkGetImageMemoryRequirements(handle, srcHandle->getImage(), &imageRequirements);
|
||||||
|
PStructuredBuffer tempBuffer = createStructuredBuffer();
|
||||||
|
VkBufferImageCopy bufferImageCopy;
|
||||||
|
bufferImageCopy.bufferOffset = 0;
|
||||||
|
bufferImageCopy.bufferRowLength = srcTexture->getSizeX();
|
||||||
|
bufferImageCopy.bufferImageHeight = srcTexture->getSizeY();
|
||||||
|
bufferImageCopy.imageExtent.width = srcTexture->getSizeX();
|
||||||
|
bufferImageCopy.imageExtent.height = srcTexture->getSizeY();
|
||||||
|
bufferImageCopy.imageExtent.depth = 1;
|
||||||
|
bufferImageCopy.imageOffset.x = 0;
|
||||||
|
bufferImageCopy.imageOffset.y = 0;
|
||||||
|
bufferImageCopy.imageOffset.z = 0;
|
||||||
|
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
bufferImageCopy.imageSubresource.baseArrayLayer = 0;
|
||||||
|
bufferImageCopy.imageSubresource.layerCount = 1;
|
||||||
|
bufferImageCopy.imageSubresource.mipLevel = 0;
|
||||||
|
|
||||||
|
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tempBufferAllocation->getHandle(), 1, &bufferImageCopy);
|
||||||
|
|
||||||
|
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
|
||||||
|
vkCmdCopyBufferToImage(cmdBuffer->getHandle(), tempBufferAllocation->getHandle(), dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopy);
|
||||||
|
delete tempBufferAllocation;*/
|
||||||
|
throw new std::logic_error("Not yet implemented!");
|
||||||
|
}
|
||||||
|
else if (src->getSizeX() != dst->getSizeX()
|
||||||
|
|| src->getSizeY() != dst->getSizeY())
|
||||||
|
{
|
||||||
|
throw new std::logic_error("Not yet implemented!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VkImageCopy copy;
|
||||||
|
std::memset(©, 0, sizeof(VkImageCopy));
|
||||||
|
copy.extent.width = srcTexture->getSizeX();
|
||||||
|
copy.extent.height = srcTexture->getSizeY();
|
||||||
|
copy.extent.depth = 1;
|
||||||
|
copy.srcSubresource.aspectMask = srcHandle->getAspect();
|
||||||
|
copy.srcSubresource.layerCount = 1;
|
||||||
|
copy.dstSubresource.aspectMask = dstHandle->getAspect();
|
||||||
|
copy.dstSubresource.layerCount = 1;
|
||||||
|
vkCmdCopyImage(cmdBuffer->getHandle(),
|
||||||
|
srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
1, ©);
|
||||||
|
src->changeLayout(srcLayout);
|
||||||
|
dst->changeLayout(dstLayout);
|
||||||
|
dstTexture->transferOwnership(dstOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VkInstance Graphics::getInstance() const
|
VkInstance Graphics::getInstance() const
|
||||||
{
|
{
|
||||||
return instance;
|
return instance;
|
||||||
|
|||||||
@@ -45,20 +45,23 @@ public:
|
|||||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||||
virtual void endRenderPass() override;
|
virtual void endRenderPass() override;
|
||||||
|
|
||||||
virtual void executeCommands(Array<Gfx::PRenderCommand> commands) override;
|
virtual void executeCommands(const Array<Gfx::PRenderCommand>& commands) override;
|
||||||
|
virtual void executeCommands(const Array<Gfx::PComputeCommand>& commands) override;
|
||||||
|
|
||||||
virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
|
virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
|
||||||
virtual Gfx::PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override;
|
virtual Gfx::PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override;
|
||||||
virtual Gfx::PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) override;
|
virtual Gfx::PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) override;
|
||||||
virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
|
virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
|
||||||
virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
|
virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
|
||||||
virtual Gfx::PRenderCommand createRenderCommand() override;
|
virtual Gfx::PRenderCommand createRenderCommand(const std::string& name) override;
|
||||||
|
virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override;
|
||||||
virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) override;
|
virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) override;
|
||||||
virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
|
virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
|
||||||
virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override;
|
virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override;
|
||||||
virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override;
|
virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override;
|
||||||
virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override;
|
virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override;
|
||||||
virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
|
virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
|
||||||
|
virtual Gfx::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
|
||||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
|
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
|
||||||
virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override;
|
virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override;
|
||||||
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
|
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
|
||||||
@@ -66,6 +69,7 @@ public:
|
|||||||
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||||
virtual Gfx::PPipelineLayout createPipelineLayout() override;
|
virtual Gfx::PPipelineLayout createPipelineLayout() override;
|
||||||
|
|
||||||
|
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
|
||||||
protected:
|
protected:
|
||||||
Array<const char *> getRequiredExtensions();
|
Array<const char *> getRequiredExtensions();
|
||||||
void initInstance(GraphicsInitializer initInfo);
|
void initInstance(GraphicsInitializer initInfo);
|
||||||
|
|||||||
@@ -1093,6 +1093,83 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
|
|||||||
return SE_FORMAT_MAX_ENUM;
|
return SE_FORMAT_MAX_ENUM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout)
|
||||||
|
{
|
||||||
|
switch (imageLayout)
|
||||||
|
{
|
||||||
|
case SE_IMAGE_LAYOUT_UNDEFINED:
|
||||||
|
return VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
case SE_IMAGE_LAYOUT_GENERAL:
|
||||||
|
return VK_IMAGE_LAYOUT_GENERAL;
|
||||||
|
case SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||||
|
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
case SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||||
|
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
case SE_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
|
||||||
|
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||||
|
case SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||||
|
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
case SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||||
|
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||||
|
case SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||||
|
return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||||
|
case SE_IMAGE_LAYOUT_PREINITIALIZED:
|
||||||
|
return VK_IMAGE_LAYOUT_PREINITIALIZED;
|
||||||
|
case SE_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
|
||||||
|
return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
case SE_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
|
||||||
|
return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
|
||||||
|
case SE_IMAGE_LAYOUT_PRESENT_SRC_KHR:
|
||||||
|
return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
case SE_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
|
||||||
|
return VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR;
|
||||||
|
case SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
|
||||||
|
return VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
|
||||||
|
case SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
|
||||||
|
return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
|
||||||
|
default:
|
||||||
|
return VK_IMAGE_LAYOUT_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
|
||||||
|
{
|
||||||
|
switch (imageLayout)
|
||||||
|
{
|
||||||
|
case VK_IMAGE_LAYOUT_UNDEFINED:
|
||||||
|
return SE_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
case VK_IMAGE_LAYOUT_GENERAL:
|
||||||
|
return SE_IMAGE_LAYOUT_GENERAL;
|
||||||
|
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||||
|
return SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||||
|
return SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
|
||||||
|
return SE_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||||
|
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||||
|
return SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||||
|
return SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||||
|
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||||
|
return SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||||
|
case VK_IMAGE_LAYOUT_PREINITIALIZED:
|
||||||
|
return SE_IMAGE_LAYOUT_PREINITIALIZED;
|
||||||
|
case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
|
||||||
|
return SE_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
|
||||||
|
return SE_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
|
||||||
|
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
|
||||||
|
return SE_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
|
||||||
|
return SE_IMAGE_LAYOUT_SHARED_PRESENT_KHR;
|
||||||
|
case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
|
||||||
|
return SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
|
||||||
|
case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
|
||||||
|
return SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
|
||||||
|
default:
|
||||||
|
return SE_IMAGE_LAYOUT_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
|
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
|
||||||
{
|
{
|
||||||
switch (storeOp)
|
switch (storeOp)
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
|
|||||||
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage);
|
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage);
|
||||||
VkFormat cast(const Gfx::SeFormat &format);
|
VkFormat cast(const Gfx::SeFormat &format);
|
||||||
Gfx::SeFormat cast(const VkFormat &format);
|
Gfx::SeFormat cast(const VkFormat &format);
|
||||||
|
VkImageLayout cast(const Gfx::SeImageLayout &imageLayout);
|
||||||
|
Gfx::SeImageLayout cast(const VkImageLayout &imageLayout);
|
||||||
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
|
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
|
||||||
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
|
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
|
||||||
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
|
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ void QueueOwnedResourceDeletion::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Semaphore::Semaphore(PGraphics graphics)
|
Semaphore::Semaphore(PGraphics graphics)
|
||||||
: graphics(graphics)
|
: graphics(graphics)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include "Graphics/GraphicsResources.h"
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include "Graphics/GraphicsResources.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ private:
|
|||||||
class ShaderBuffer
|
class ShaderBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType);
|
ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
|
||||||
virtual ~ShaderBuffer();
|
virtual ~ShaderBuffer();
|
||||||
VkBuffer getHandle() const
|
VkBuffer getHandle() const
|
||||||
{
|
{
|
||||||
@@ -115,11 +115,14 @@ protected:
|
|||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
uint32 currentBuffer;
|
uint32 currentBuffer;
|
||||||
uint32 size;
|
uint32 size;
|
||||||
Gfx::QueueType currentOwner;
|
Gfx::QueueType& owner;
|
||||||
BufferAllocation buffers[Gfx::numFramesBuffered];
|
BufferAllocation buffers[Gfx::numFramesBuffered];
|
||||||
uint32 numBuffers;
|
uint32 numBuffers;
|
||||||
|
|
||||||
void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||||
|
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||||
|
|
||||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
|
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
|
||||||
|
|
||||||
virtual VkAccessFlags getSourceAccessMask() = 0;
|
virtual VkAccessFlags getSourceAccessMask() = 0;
|
||||||
@@ -139,11 +142,14 @@ public:
|
|||||||
virtual void unlock() override;
|
virtual void unlock() override;
|
||||||
protected:
|
protected:
|
||||||
// Inherited via Vulkan::Buffer
|
// Inherited via Vulkan::Buffer
|
||||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
|
||||||
virtual VkAccessFlags getSourceAccessMask();
|
virtual VkAccessFlags getSourceAccessMask();
|
||||||
virtual VkAccessFlags getDestAccessMask();
|
virtual VkAccessFlags getDestAccessMask();
|
||||||
|
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||||
|
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PStagingBuffer dedicatedStagingBuffer;
|
PStagingBuffer dedicatedStagingBuffer;
|
||||||
};
|
};
|
||||||
@@ -152,7 +158,7 @@ DEFINE_REF(UniformBuffer)
|
|||||||
class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer
|
class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData);
|
||||||
virtual ~StructuredBuffer();
|
virtual ~StructuredBuffer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -162,6 +168,10 @@ protected:
|
|||||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||||
|
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||||
|
private:
|
||||||
|
PStagingBuffer dedicatedStagingBuffer;
|
||||||
};
|
};
|
||||||
DEFINE_REF(StructuredBuffer)
|
DEFINE_REF(StructuredBuffer)
|
||||||
|
|
||||||
@@ -178,6 +188,8 @@ protected:
|
|||||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||||
|
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||||
};
|
};
|
||||||
DEFINE_REF(VertexBuffer)
|
DEFINE_REF(VertexBuffer)
|
||||||
|
|
||||||
@@ -189,11 +201,13 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via Vulkan::Buffer
|
// Inherited via Vulkan::Buffer
|
||||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
|
||||||
virtual VkAccessFlags getSourceAccessMask();
|
virtual VkAccessFlags getSourceAccessMask();
|
||||||
virtual VkAccessFlags getDestAccessMask();
|
virtual VkAccessFlags getDestAccessMask();
|
||||||
|
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||||
|
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||||
};
|
};
|
||||||
DEFINE_REF(IndexBuffer)
|
DEFINE_REF(IndexBuffer)
|
||||||
|
|
||||||
@@ -201,14 +215,18 @@ class TextureHandle
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||||
const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE);
|
||||||
virtual ~TextureHandle();
|
virtual ~TextureHandle();
|
||||||
|
|
||||||
|
inline VkImage getImage() const
|
||||||
|
{
|
||||||
|
return image;
|
||||||
|
}
|
||||||
inline VkImageView getView() const
|
inline VkImageView getView() const
|
||||||
{
|
{
|
||||||
return defaultView;
|
return defaultView;
|
||||||
}
|
}
|
||||||
inline VkImageLayout getLayout() const
|
inline Gfx::SeImageLayout getLayout() const
|
||||||
{
|
{
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
@@ -233,10 +251,13 @@ public:
|
|||||||
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
}
|
}
|
||||||
void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||||
void changeLayout(VkImageLayout newLayout);
|
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||||
|
void changeLayout(Gfx::SeImageLayout newLayout);
|
||||||
|
|
||||||
Gfx::QueueType currentOwner;
|
|
||||||
private:
|
private:
|
||||||
|
//Updates via reference
|
||||||
|
Gfx::QueueType& currentOwner;
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
PSubAllocation allocation;
|
PSubAllocation allocation;
|
||||||
uint32 sizeX;
|
uint32 sizeX;
|
||||||
@@ -250,21 +271,22 @@ private:
|
|||||||
VkImage image;
|
VkImage image;
|
||||||
VkImageView defaultView;
|
VkImageView defaultView;
|
||||||
VkImageAspectFlags aspect;
|
VkImageAspectFlags aspect;
|
||||||
VkImageLayout layout;
|
Gfx::SeImageLayout layout;
|
||||||
friend class TextureBase;
|
friend class TextureBase;
|
||||||
friend class Texture2D;
|
friend class Texture2D;
|
||||||
|
friend class Graphics;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextureBase
|
class TextureBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static TextureHandle* cast(Gfx::PTexture texture);
|
static TextureHandle* cast(Gfx::PTexture texture);
|
||||||
void changeLayout(VkImageLayout newLayout);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TextureHandle* textureHandle;
|
TextureHandle* textureHandle;
|
||||||
|
friend class Graphics;
|
||||||
};
|
};
|
||||||
|
DECLARE_REF(TextureBase)
|
||||||
class Texture2D : public Gfx::Texture2D, public TextureBase
|
class Texture2D : public Gfx::Texture2D, public TextureBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -286,6 +308,11 @@ public:
|
|||||||
{
|
{
|
||||||
return textureHandle->getNumSamples();
|
return textureHandle->getNumSamples();
|
||||||
}
|
}
|
||||||
|
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
|
||||||
|
virtual void* getNativeHandle() override
|
||||||
|
{
|
||||||
|
return textureHandle;
|
||||||
|
}
|
||||||
inline VkImage getHandle() const
|
inline VkImage getHandle() const
|
||||||
{
|
{
|
||||||
return textureHandle->image;
|
return textureHandle->image;
|
||||||
@@ -301,6 +328,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||||
|
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||||
|
|
||||||
};
|
};
|
||||||
DEFINE_REF(Texture2D)
|
DEFINE_REF(Texture2D)
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ void Shader::create(const ShaderCreateInfo& createInfo)
|
|||||||
char const* diagnostics = spGetDiagnosticOutput(request);
|
char const* diagnostics = spGetDiagnosticOutput(request);
|
||||||
std::cout << "Compile error for shader " << createInfo.name << std::endl;
|
std::cout << "Compile error for shader " << createInfo.name << std::endl;
|
||||||
std::cout << diagnostics << std::endl;
|
std::cout << diagnostics << std::endl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
size_t dataSize = 0;
|
size_t dataSize = 0;
|
||||||
const uint32* data = reinterpret_cast<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize));
|
const uint32* data = reinterpret_cast<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize));
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||||
const TextureCreateInfo& createInfo, VkImage existingImage)
|
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage)
|
||||||
: currentOwner(createInfo.resourceData.owner)
|
: currentOwner(owner)
|
||||||
, graphics(graphics)
|
, graphics(graphics)
|
||||||
, sizeX(createInfo.width)
|
, sizeX(createInfo.width)
|
||||||
, sizeY(createInfo.height)
|
, sizeY(createInfo.height)
|
||||||
@@ -43,7 +43,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
|||||||
, usage(createInfo.usage)
|
, usage(createInfo.usage)
|
||||||
, image(existingImage)
|
, image(existingImage)
|
||||||
, aspect(getAspectFromFormat(createInfo.format))
|
, aspect(getAspectFromFormat(createInfo.format))
|
||||||
, layout(VK_IMAGE_LAYOUT_UNDEFINED)
|
, layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED)
|
||||||
{
|
{
|
||||||
if (existingImage == VK_NULL_HANDLE)
|
if (existingImage == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
@@ -79,18 +79,18 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.initialLayout = layout;
|
info.initialLayout = cast(layout);
|
||||||
info.mipLevels = mipLevels;
|
info.mipLevels = mipLevels;
|
||||||
info.arrayLayers = arrayCount * layerCount;
|
info.arrayLayers = arrayCount * layerCount;
|
||||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
info.samples = (VkSampleCountFlagBits)samples;
|
info.samples = (VkSampleCountFlagBits)samples;
|
||||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
info.usage = usage;
|
info.usage = usage;
|
||||||
//To upload to the image we need to specify transfer dst
|
// Most of these flags will almost always be used
|
||||||
if(createInfo.resourceData.size > 0)
|
|
||||||
{
|
|
||||||
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||||
}
|
info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
|
||||||
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
|
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
|
||||||
|
|
||||||
VkMemoryDedicatedRequirements memDedicatedRequirements;
|
VkMemoryDedicatedRequirements memDedicatedRequirements;
|
||||||
@@ -112,7 +112,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
|||||||
const BulkResourceData& resourceData = createInfo.resourceData;
|
const BulkResourceData& resourceData = createInfo.resourceData;
|
||||||
if(resourceData.size > 0)
|
if(resourceData.size > 0)
|
||||||
{
|
{
|
||||||
changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
PStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
PStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||||
void* data = staging->getMappedPointer();
|
void* data = staging->getMappedPointer();
|
||||||
std::memcpy(data, resourceData.data, resourceData.size);
|
std::memcpy(data, resourceData.data, resourceData.size);
|
||||||
@@ -136,11 +136,15 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
|||||||
staging->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
staging->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
|
|
||||||
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
|
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
|
||||||
changeLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
}
|
}
|
||||||
if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||||
{
|
{
|
||||||
changeLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageViewCreateInfo viewInfo =
|
VkImageViewCreateInfo viewInfo =
|
||||||
@@ -176,17 +180,20 @@ TextureHandle* TextureBase::cast(Gfx::PTexture texture)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureHandle::changeLayout(VkImageLayout newLayout)
|
void TextureHandle::changeLayout(Gfx::SeImageLayout newLayout)
|
||||||
{
|
{
|
||||||
VkImageMemoryBarrier barrier =
|
VkImageMemoryBarrier barrier =
|
||||||
init::ImageMemoryBarrier(
|
init::ImageMemoryBarrier(
|
||||||
image,
|
image,
|
||||||
layout,
|
cast(layout),
|
||||||
newLayout);
|
cast(newLayout));
|
||||||
|
barrier.subresourceRange =
|
||||||
|
init::ImageSubresourceRange(aspect);
|
||||||
PCommandBufferManager cmdManager = graphics->getQueueCommands(currentOwner);
|
PCommandBufferManager cmdManager = graphics->getQueueCommands(currentOwner);
|
||||||
vkCmdPipelineBarrier(cmdManager->getCommands()->getHandle(),
|
vkCmdPipelineBarrier(cmdManager->getCommands()->getHandle(),
|
||||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||||
|
cmdManager->submitCommands();
|
||||||
layout = newLayout;
|
layout = newLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,8 +202,8 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
|||||||
VkImageMemoryBarrier imageBarrier =
|
VkImageMemoryBarrier imageBarrier =
|
||||||
init::ImageMemoryBarrier();
|
init::ImageMemoryBarrier();
|
||||||
imageBarrier.image = image;
|
imageBarrier.image = image;
|
||||||
imageBarrier.oldLayout = layout;
|
imageBarrier.oldLayout = cast(layout);
|
||||||
imageBarrier.newLayout = layout;
|
imageBarrier.newLayout = cast(layout);
|
||||||
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
|
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
|
||||||
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
|
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
|
||||||
PCommandBufferManager dstManager = nullptr;
|
PCommandBufferManager dstManager = nullptr;
|
||||||
@@ -248,26 +255,49 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
|||||||
VkCommandBuffer destCmd = dstManager->getCommands()->getHandle();
|
VkCommandBuffer destCmd = dstManager->getCommands()->getHandle();
|
||||||
vkCmdPipelineBarrier(sourceCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
vkCmdPipelineBarrier(sourceCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
||||||
vkCmdPipelineBarrier(destCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
vkCmdPipelineBarrier(destCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
||||||
|
currentOwner = newOwner;
|
||||||
sourceManager->submitCommands();
|
sourceManager->submitCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBase::changeLayout(VkImageLayout newLayout)
|
void TextureHandle::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||||
{
|
{
|
||||||
textureHandle->changeLayout(newLayout);
|
VkImageMemoryBarrier imageBarrier =
|
||||||
|
init::ImageMemoryBarrier(
|
||||||
|
image,
|
||||||
|
cast(layout),
|
||||||
|
cast(layout)
|
||||||
|
);
|
||||||
|
imageBarrier.srcAccessMask = srcAccess;
|
||||||
|
imageBarrier.dstAccessMask = dstAccess;
|
||||||
|
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
|
||||||
|
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||||
|
vkCmdPipelineBarrier(cmdBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||||
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.resourceData.owner)
|
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.resourceData.owner)
|
||||||
{
|
{
|
||||||
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
|
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
|
||||||
createInfo, existingImage);
|
createInfo, currentOwner, existingImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D::~Texture2D()
|
Texture2D::~Texture2D()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout)
|
||||||
|
{
|
||||||
|
textureHandle->changeLayout(newLayout);
|
||||||
|
}
|
||||||
|
|
||||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
textureHandle->executeOwnershipBarrier(newOwner);
|
textureHandle->executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||||
|
{
|
||||||
|
textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
@@ -162,7 +162,7 @@ void Window::advanceBackBuffer()
|
|||||||
imageAcquiredSemaphore = imageAcquired[semaphoreIndex];
|
imageAcquiredSemaphore = imageAcquired[semaphoreIndex];
|
||||||
currentImageIndex = imageIndex;
|
currentImageIndex = imageIndex;
|
||||||
|
|
||||||
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||||
graphics->getGraphicsCommands()->getCommands()->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
graphics->getGraphicsCommands()->getCommands()->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
||||||
graphics->getGraphicsCommands()->submitCommands();
|
graphics->getGraphicsCommands()->submitCommands();
|
||||||
@@ -193,7 +193,7 @@ void Window::recreateSwapchain(const WindowCreateInfo &windowInfo)
|
|||||||
|
|
||||||
void Window::present()
|
void Window::present()
|
||||||
{
|
{
|
||||||
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]);
|
graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]);
|
||||||
VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle();
|
VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle();
|
||||||
VkPresentInfoKHR info;
|
VkPresentInfoKHR info;
|
||||||
@@ -258,7 +258,6 @@ void Window::createSwapchain()
|
|||||||
Array<VkImage> swapchainImages(numSwapchainImages);
|
Array<VkImage> swapchainImages(numSwapchainImages);
|
||||||
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data()));
|
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data()));
|
||||||
|
|
||||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
|
||||||
|
|
||||||
TextureCreateInfo backBufferCreateInfo;
|
TextureCreateInfo backBufferCreateInfo;
|
||||||
backBufferCreateInfo.width = sizeX;
|
backBufferCreateInfo.width = sizeX;
|
||||||
@@ -274,10 +273,11 @@ void Window::createSwapchain()
|
|||||||
|
|
||||||
VkClearColorValue clearColor;
|
VkClearColorValue clearColor;
|
||||||
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
|
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
|
||||||
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
|
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||||
vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
|
vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
|
||||||
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
}
|
}
|
||||||
graphics->getGraphicsCommands()->submitCommands();
|
graphics->getGraphicsCommands()->submitCommands();
|
||||||
currentImageIndex = -1;
|
currentImageIndex = -1;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ void MaterialAsset::endFrame()
|
|||||||
void MaterialAsset::updateDescriptorData()
|
void MaterialAsset::updateDescriptorData()
|
||||||
{
|
{
|
||||||
layout->reset();
|
layout->reset();
|
||||||
descriptorSet = layout->allocatedDescriptorSet();
|
descriptorSet = layout->allocateDescriptorSet();
|
||||||
BulkResourceData uniformUpdate;
|
BulkResourceData uniformUpdate;
|
||||||
uniformUpdate.size = uniformDataSize;
|
uniformUpdate.size = uniformDataSize;
|
||||||
uniformUpdate.data = uniformData;
|
uniformUpdate.data = uniformData;
|
||||||
|
|||||||
@@ -71,3 +71,18 @@ void SamplerParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui
|
|||||||
{
|
{
|
||||||
descriptorSet->updateSampler(binding, data);
|
descriptorSet->updateSampler(binding, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CombinedTextureParameter::CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding)
|
||||||
|
: ShaderParameter(name, byteOffset, binding)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CombinedTextureParameter::~CombinedTextureParameter()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst)
|
||||||
|
{
|
||||||
|
descriptorSet->updateTexture(binding, data->getTexture(), sampler);
|
||||||
|
}
|
||||||
@@ -60,5 +60,13 @@ struct SamplerParameter : public ShaderParameter
|
|||||||
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
|
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
|
||||||
};
|
};
|
||||||
DEFINE_REF(SamplerParameter)
|
DEFINE_REF(SamplerParameter)
|
||||||
|
struct CombinedTextureParameter : public ShaderParameter
|
||||||
|
{
|
||||||
|
PTextureAsset data;
|
||||||
|
Gfx::PSamplerState sampler;
|
||||||
|
CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding);
|
||||||
|
virtual ~CombinedTextureParameter();
|
||||||
|
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
|
||||||
|
};
|
||||||
|
DEFINE_REF(CombinedTextureParameter)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ Scene::Scene(Gfx::PGraphics graphics)
|
|||||||
lightEnv.pointLights[i].positionWS = Vector4(frand() * 200-100, frand(), frand() * 200-100, 1);
|
lightEnv.pointLights[i].positionWS = Vector4(frand() * 200-100, frand(), frand() * 200-100, 1);
|
||||||
}
|
}
|
||||||
lightEnv.numPointLights = MAX_POINT_LIGHTS;
|
lightEnv.numPointLights = MAX_POINT_LIGHTS;
|
||||||
|
|
||||||
|
BulkResourceData lightInit;
|
||||||
|
StructuredBufferCreateInfo structuredInfo;
|
||||||
|
lightInit.size = sizeof(LightEnv);
|
||||||
|
lightInit.data = (uint8*)&lightEnv;
|
||||||
|
structuredInfo.resourceData = lightInit;
|
||||||
|
structuredInfo.bDynamic = false;
|
||||||
|
lightBuffer = graphics->createStructuredBuffer(structuredInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene()
|
Scene::~Scene()
|
||||||
|
|||||||
@@ -46,13 +46,14 @@ public:
|
|||||||
|
|
||||||
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
|
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
|
||||||
const Array<MeshBatch>& getStaticMeshes() const { return staticMeshes; }
|
const Array<MeshBatch>& getStaticMeshes() const { return staticMeshes; }
|
||||||
const LightEnv& getLightEnvironment() const { return lightEnv; }
|
const Gfx::PStructuredBuffer& getLightBuffer() const { return lightBuffer; }
|
||||||
UPSceneUpdater& getSceneUpdater() { return updater; }
|
UPSceneUpdater& getSceneUpdater() { return updater; }
|
||||||
private:
|
private:
|
||||||
Array<MeshBatch> staticMeshes;
|
Array<MeshBatch> staticMeshes;
|
||||||
Array<PActor> rootActors;
|
Array<PActor> rootActors;
|
||||||
Array<PPrimitiveComponent> primitives;
|
Array<PPrimitiveComponent> primitives;
|
||||||
LightEnv lightEnv;
|
LightEnv lightEnv;
|
||||||
|
Gfx::PStructuredBuffer lightBuffer;
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
UPSceneUpdater updater;
|
UPSceneUpdater updater;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ SceneRenderPath::SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PVi
|
|||||||
{
|
{
|
||||||
renderGraph = new RenderGraph();
|
renderGraph = new RenderGraph();
|
||||||
depthPrepass = new DepthPrepass(renderGraph, scene, graphics, target, source);
|
depthPrepass = new DepthPrepass(renderGraph, scene, graphics, target, source);
|
||||||
|
lightCullingPass = new LightCullingPass(renderGraph, scene, graphics, target, source);
|
||||||
basePass = new BasePass(renderGraph, scene, graphics, target, source);
|
basePass = new BasePass(renderGraph, scene, graphics, target, source);
|
||||||
|
renderGraph->addRenderPass(depthPrepass);
|
||||||
|
renderGraph->addRenderPass(lightCullingPass);
|
||||||
|
renderGraph->addRenderPass(basePass);
|
||||||
renderGraph->setup();
|
renderGraph->setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,14 +37,20 @@ void SceneRenderPath::init()
|
|||||||
void SceneRenderPath::beginFrame()
|
void SceneRenderPath::beginFrame()
|
||||||
{
|
{
|
||||||
depthPrepass->beginFrame();
|
depthPrepass->beginFrame();
|
||||||
|
lightCullingPass->beginFrame();
|
||||||
|
basePass->beginFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderPath::render()
|
void SceneRenderPath::render()
|
||||||
{
|
{
|
||||||
depthPrepass->render();
|
depthPrepass->render();
|
||||||
|
lightCullingPass->render();
|
||||||
|
basePass->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderPath::endFrame()
|
void SceneRenderPath::endFrame()
|
||||||
{
|
{
|
||||||
depthPrepass->endFrame();
|
depthPrepass->endFrame();
|
||||||
|
lightCullingPass->endFrame();
|
||||||
|
basePass->endFrame();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "RenderPath.h"
|
#include "RenderPath.h"
|
||||||
#include "Graphics/RenderPass/BasePass.h"
|
|
||||||
#include "Graphics/RenderPass/DepthPrepass.h"
|
#include "Graphics/RenderPass/DepthPrepass.h"
|
||||||
|
#include "Graphics/RenderPass/LightCullingPass.h"
|
||||||
|
#include "Graphics/RenderPass/BasePass.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
@@ -22,6 +23,7 @@ protected:
|
|||||||
PScene scene;
|
PScene scene;
|
||||||
PRenderGraph renderGraph;
|
PRenderGraph renderGraph;
|
||||||
PDepthPrepass depthPrepass;
|
PDepthPrepass depthPrepass;
|
||||||
|
PLightCullingPass lightCullingPass;
|
||||||
PBasePass basePass;
|
PBasePass basePass;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user