Improve stability of Vulkan and D3D12 backends on large worlds
This commit is contained in:
@@ -153,7 +153,7 @@ void GPUContextDX12::SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURC
|
|||||||
if (state.AreAllSubresourcesSame())
|
if (state.AreAllSubresourcesSame())
|
||||||
{
|
{
|
||||||
// Transition entire resource at once
|
// Transition entire resource at once
|
||||||
const D3D12_RESOURCE_STATES before = state.GetSubresourceState(subresourceIndex);
|
const D3D12_RESOURCE_STATES before = state.GetSubresourceState(-1);
|
||||||
if (ResourceStateDX12::IsTransitionNeeded(before, after))
|
if (ResourceStateDX12::IsTransitionNeeded(before, after))
|
||||||
{
|
{
|
||||||
AddTransitionBarrier(resource, before, after, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
|
AddTransitionBarrier(resource, before, after, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
|
||||||
@@ -163,6 +163,7 @@ void GPUContextDX12::SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURC
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Slow path to transition each subresource
|
// Slow path to transition each subresource
|
||||||
|
bool hadAnyTransition = false;
|
||||||
for (int32 i = 0; i < state.GetSubresourcesCount(); i++)
|
for (int32 i = 0; i < state.GetSubresourcesCount(); i++)
|
||||||
{
|
{
|
||||||
const D3D12_RESOURCE_STATES before = state.GetSubresourceState(i);
|
const D3D12_RESOURCE_STATES before = state.GetSubresourceState(i);
|
||||||
@@ -170,10 +171,20 @@ void GPUContextDX12::SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURC
|
|||||||
{
|
{
|
||||||
AddTransitionBarrier(resource, before, after, i);
|
AddTransitionBarrier(resource, before, after, i);
|
||||||
state.SetSubresourceState(i, after);
|
state.SetSubresourceState(i, after);
|
||||||
|
hadAnyTransition = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT(state.CheckResourceState(after));
|
if (hadAnyTransition)
|
||||||
state.SetResourceState(after);
|
{
|
||||||
|
// Try merge all subresources states into a single state
|
||||||
|
after = state.GetSubresourceState(0);
|
||||||
|
for (int32 i = 1; i < state.GetSubresourcesCount(); i++)
|
||||||
|
{
|
||||||
|
if (state.GetSubresourceState(i) != after)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.SetResourceState(after);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -357,6 +368,21 @@ void GPUContextDX12::flushRTVs()
|
|||||||
{
|
{
|
||||||
depthBuffer = _rtDepth->DSV();
|
depthBuffer = _rtDepth->DSV();
|
||||||
auto states = _rtDepth->ReadOnlyDepthView ? D3D12_RESOURCE_STATE_DEPTH_READ : D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
auto states = _rtDepth->ReadOnlyDepthView ? D3D12_RESOURCE_STATE_DEPTH_READ : D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||||
|
if (_currentState && _rtDepth->ReadOnlyDepthView)
|
||||||
|
{
|
||||||
|
// If read-only depth buffer is also binded as shader input then ensure it has proper state bit
|
||||||
|
const uint32 srMask = _currentState->GetUsedSRsMask();
|
||||||
|
const uint32 srCount = Math::FloorLog2(srMask) + 1;
|
||||||
|
for (uint32 i = 0; i < srCount; i++)
|
||||||
|
{
|
||||||
|
const auto handle = _srHandles[i];
|
||||||
|
if (srMask & (1 << i) && handle == _rtDepth)
|
||||||
|
{
|
||||||
|
states |= D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
SetResourceState(_rtDepth->GetResourceOwner(), states, _rtDepth->SubresourceIndex);
|
SetResourceState(_rtDepth->GetResourceOwner(), states, _rtDepth->SubresourceIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -483,7 +509,7 @@ void GPUContextDX12::flushPS()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUContextDX12::onDrawCall()
|
void GPUContextDX12::OnDrawCall()
|
||||||
{
|
{
|
||||||
// Ensure state of the vertex and index buffers
|
// Ensure state of the vertex and index buffers
|
||||||
for (int32 i = 0; i < _vbCount; i++)
|
for (int32 i = 0; i < _vbCount; i++)
|
||||||
@@ -510,7 +536,7 @@ void GPUContextDX12::onDrawCall()
|
|||||||
if (srMask & (1 << i) && handle != nullptr && handle->GetResourceOwner())
|
if (srMask & (1 << i) && handle != nullptr && handle->GetResourceOwner())
|
||||||
{
|
{
|
||||||
const auto resourceOwner = handle->GetResourceOwner();
|
const auto resourceOwner = handle->GetResourceOwner();
|
||||||
bool isRtv = false;
|
bool isRtv = _rtDepth == handle;
|
||||||
for (int32 j = 0; j < _rtCount; j++)
|
for (int32 j = 0; j < _rtCount; j++)
|
||||||
{
|
{
|
||||||
if (_rtHandles[j] && _rtHandles[j]->GetResourceOwner() == resourceOwner)
|
if (_rtHandles[j] && _rtHandles[j]->GetResourceOwner() == resourceOwner)
|
||||||
@@ -970,14 +996,14 @@ void GPUContextDX12::ResolveMultisample(GPUTexture* sourceMultisampleTexture, GP
|
|||||||
|
|
||||||
void GPUContextDX12::DrawInstanced(uint32 verticesCount, uint32 instanceCount, int32 startInstance, int32 startVertex)
|
void GPUContextDX12::DrawInstanced(uint32 verticesCount, uint32 instanceCount, int32 startInstance, int32 startVertex)
|
||||||
{
|
{
|
||||||
onDrawCall();
|
OnDrawCall();
|
||||||
_commandList->DrawInstanced(verticesCount, instanceCount, startVertex, startInstance);
|
_commandList->DrawInstanced(verticesCount, instanceCount, startVertex, startInstance);
|
||||||
RENDER_STAT_DRAW_CALL(verticesCount * instanceCount, verticesCount * instanceCount / 3);
|
RENDER_STAT_DRAW_CALL(verticesCount * instanceCount, verticesCount * instanceCount / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUContextDX12::DrawIndexedInstanced(uint32 indicesCount, uint32 instanceCount, int32 startInstance, int32 startVertex, int32 startIndex)
|
void GPUContextDX12::DrawIndexedInstanced(uint32 indicesCount, uint32 instanceCount, int32 startInstance, int32 startVertex, int32 startIndex)
|
||||||
{
|
{
|
||||||
onDrawCall();
|
OnDrawCall();
|
||||||
_commandList->DrawIndexedInstanced(indicesCount, instanceCount, startIndex, startVertex, startInstance);
|
_commandList->DrawIndexedInstanced(indicesCount, instanceCount, startIndex, startVertex, startInstance);
|
||||||
RENDER_STAT_DRAW_CALL(0, indicesCount / 3 * instanceCount);
|
RENDER_STAT_DRAW_CALL(0, indicesCount / 3 * instanceCount);
|
||||||
}
|
}
|
||||||
@@ -990,7 +1016,7 @@ void GPUContextDX12::DrawInstancedIndirect(GPUBuffer* bufferForArgs, uint32 offs
|
|||||||
auto signature = _device->DrawIndirectCommandSignature->GetSignature();
|
auto signature = _device->DrawIndirectCommandSignature->GetSignature();
|
||||||
SetResourceState(bufferForArgsDX12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT);
|
SetResourceState(bufferForArgsDX12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT);
|
||||||
|
|
||||||
onDrawCall();
|
OnDrawCall();
|
||||||
_commandList->ExecuteIndirect(signature, 1, bufferForArgsDX12->GetResource(), (UINT64)offsetForArgs, nullptr, 0);
|
_commandList->ExecuteIndirect(signature, 1, bufferForArgsDX12->GetResource(), (UINT64)offsetForArgs, nullptr, 0);
|
||||||
RENDER_STAT_DRAW_CALL(0, 0);
|
RENDER_STAT_DRAW_CALL(0, 0);
|
||||||
}
|
}
|
||||||
@@ -1003,7 +1029,7 @@ void GPUContextDX12::DrawIndexedInstancedIndirect(GPUBuffer* bufferForArgs, uint
|
|||||||
auto signature = _device->DrawIndexedIndirectCommandSignature->GetSignature();
|
auto signature = _device->DrawIndexedIndirectCommandSignature->GetSignature();
|
||||||
SetResourceState(bufferForArgsDX12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT);
|
SetResourceState(bufferForArgsDX12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT);
|
||||||
|
|
||||||
onDrawCall();
|
OnDrawCall();
|
||||||
_commandList->ExecuteIndirect(signature, 1, bufferForArgsDX12->GetResource(), (UINT64)offsetForArgs, nullptr, 0);
|
_commandList->ExecuteIndirect(signature, 1, bufferForArgsDX12->GetResource(), (UINT64)offsetForArgs, nullptr, 0);
|
||||||
RENDER_STAT_DRAW_CALL(0, 0);
|
RENDER_STAT_DRAW_CALL(0, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ private:
|
|||||||
void flushCBs();
|
void flushCBs();
|
||||||
void flushRBs();
|
void flushRBs();
|
||||||
void flushPS();
|
void flushPS();
|
||||||
void onDrawCall();
|
void OnDrawCall();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,46 @@ static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartIndex) == OFFSET_OF(VkD
|
|||||||
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartVertex) == OFFSET_OF(VkDrawIndexedIndirectCommand, vertexOffset), "Wrong offset for GPUDrawIndexedIndirectArgs::StartVertex");
|
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartVertex) == OFFSET_OF(VkDrawIndexedIndirectCommand, vertexOffset), "Wrong offset for GPUDrawIndexedIndirectArgs::StartVertex");
|
||||||
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartInstance) == OFFSET_OF(VkDrawIndexedIndirectCommand, firstInstance), "Wrong offset for GPUDrawIndexedIndirectArgs::StartInstance");
|
static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartInstance) == OFFSET_OF(VkDrawIndexedIndirectCommand, firstInstance), "Wrong offset for GPUDrawIndexedIndirectArgs::StartInstance");
|
||||||
|
|
||||||
|
#if VK_ENABLE_BARRIERS_DEBUG
|
||||||
|
|
||||||
|
const Char* ToString(VkImageLayout layout)
|
||||||
|
{
|
||||||
|
switch (layout)
|
||||||
|
{
|
||||||
|
#define TO_STR(type) case type: return TEXT(#type)
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_UNDEFINED);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_GENERAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_PREINITIALIZED);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR);
|
||||||
|
TO_STR(VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR);
|
||||||
|
#undef TO_STR
|
||||||
|
default:
|
||||||
|
return TEXT("?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void PipelineBarrierVulkan::AddImageBarrier(VkImage image, const VkImageSubresourceRange& range, VkImageLayout srcLayout, VkImageLayout dstLayout, GPUTextureViewVulkan* handle)
|
void PipelineBarrierVulkan::AddImageBarrier(VkImage image, const VkImageSubresourceRange& range, VkImageLayout srcLayout, VkImageLayout dstLayout, GPUTextureViewVulkan* handle)
|
||||||
{
|
{
|
||||||
#if VK_ENABLE_BARRIERS_DEBUG
|
#if VK_ENABLE_BARRIERS_DEBUG
|
||||||
ImageBarriersDebug.Add(handle);
|
ImageBarriersDebug.Add(handle);
|
||||||
#endif
|
#endif
|
||||||
VkImageMemoryBarrier& imageBarrier = ImageBarriers.AddOne();
|
VkImageMemoryBarrier& imageBarrier = ImageBarriers.AddOne();
|
||||||
RenderToolsVulkan::ZeroStruct(imageBarrier, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER);
|
RenderToolsVulkan::ZeroStruct(imageBarrier, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER);
|
||||||
@@ -44,21 +80,21 @@ void PipelineBarrierVulkan::AddImageBarrier(VkImage image, const VkImageSubresou
|
|||||||
imageBarrier.subresourceRange = range;
|
imageBarrier.subresourceRange = range;
|
||||||
imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
imageBarrier.oldLayout = srcLayout;
|
||||||
RenderToolsVulkan::SetImageBarrierInfo(srcLayout, dstLayout, imageBarrier, SourceStage, DestStage);
|
imageBarrier.newLayout = dstLayout;
|
||||||
|
SourceStage |= RenderToolsVulkan::GetImageBarrierFlags(srcLayout, imageBarrier.srcAccessMask);
|
||||||
|
DestStage |= RenderToolsVulkan::GetImageBarrierFlags(dstLayout, imageBarrier.dstAccessMask);
|
||||||
#if VK_ENABLE_BARRIERS_DEBUG
|
#if VK_ENABLE_BARRIERS_DEBUG
|
||||||
LOG(Warning, "Image Barrier: 0x{0:x}, {1} -> {2} for baseMipLevel: {3}, baseArrayLayer: {4}, levelCount: {5}, layerCount: {6} ({7})",
|
LOG(Warning, "Image Barrier: 0x{0:x}, {1} -> {2} for baseMipLevel: {3}, baseArrayLayer: {4}, levelCount: {5}, layerCount: {6} ({7})",
|
||||||
(int)image,
|
(uintptr)image,
|
||||||
srcLayout,
|
ToString(srcLayout),
|
||||||
dstLayout,
|
ToString(dstLayout),
|
||||||
range.baseMipLevel,
|
range.baseMipLevel,
|
||||||
range.baseArrayLayer,
|
range.baseArrayLayer,
|
||||||
range.levelCount,
|
range.levelCount,
|
||||||
range.layerCount,
|
range.layerCount,
|
||||||
|
handle && handle->Owner->AsGPUResource() ? handle->Owner->AsGPUResource()->ToString() : String::Empty
|
||||||
handle && handle->Owner->AsGPUResource() ? handle->Owner->AsGPUResource()->ToString() : String::Empty
|
);
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,16 +109,14 @@ void PipelineBarrierVulkan::AddBufferBarrier(VkBuffer buffer, VkDeviceSize offse
|
|||||||
bufferBarrier.dstAccessMask = dstAccess;
|
bufferBarrier.dstAccessMask = dstAccess;
|
||||||
bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
SourceStage |= RenderToolsVulkan::GetBufferBarrierFlags(srcAccess);
|
||||||
RenderToolsVulkan::SetBufferBarrierInfo(srcAccess, dstAccess, SourceStage, DestStage);
|
DestStage |= RenderToolsVulkan::GetBufferBarrierFlags(dstAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineBarrierVulkan::Execute(CmdBufferVulkan* cmdBuffer)
|
void PipelineBarrierVulkan::Execute(CmdBufferVulkan* cmdBuffer)
|
||||||
{
|
{
|
||||||
ASSERT(cmdBuffer->IsOutsideRenderPass());
|
ASSERT(cmdBuffer->IsOutsideRenderPass());
|
||||||
|
|
||||||
vkCmdPipelineBarrier(cmdBuffer->GetHandle(), SourceStage, DestStage, 0, 0, nullptr, BufferBarriers.Count(), BufferBarriers.Get(), ImageBarriers.Count(), ImageBarriers.Get());
|
vkCmdPipelineBarrier(cmdBuffer->GetHandle(), SourceStage, DestStage, 0, 0, nullptr, BufferBarriers.Count(), BufferBarriers.Get(), ImageBarriers.Count(), ImageBarriers.Get());
|
||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,11 +161,11 @@ void GPUContextVulkan::AddImageBarrier(VkImage image, VkImageLayout srcLayout, V
|
|||||||
_barriers.AddImageBarrier(image, subresourceRange, srcLayout, dstLayout, handle);
|
_barriers.AddImageBarrier(image, subresourceRange, srcLayout, dstLayout, handle);
|
||||||
|
|
||||||
#if !VK_ENABLE_BARRIERS_BATCHING
|
#if !VK_ENABLE_BARRIERS_BATCHING
|
||||||
// Auto-flush without batching
|
// Auto-flush without batching
|
||||||
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
||||||
if (cmdBuffer->IsInsideRenderPass())
|
if (cmdBuffer->IsInsideRenderPass())
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
_barriers.Execute(cmdBuffer);
|
_barriers.Execute(cmdBuffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,15 +178,19 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
|||||||
const int32 mipLevels = state.GetSubresourcesCount() / handle->Owner->ArraySlices;
|
const int32 mipLevels = state.GetSubresourcesCount() / handle->Owner->ArraySlices;
|
||||||
if (state.AreAllSubresourcesSame())
|
if (state.AreAllSubresourcesSame())
|
||||||
{
|
{
|
||||||
// Transition entire resource at once
|
const VkImageLayout srcLayout = state.GetSubresourceState(-1);
|
||||||
const VkImageLayout srcLayout = state.GetSubresourceState(0);
|
if (srcLayout != dstLayout)
|
||||||
VkImageSubresourceRange range;
|
{
|
||||||
range.aspectMask = handle->Info.subresourceRange.aspectMask;
|
// Transition entire resource at once
|
||||||
range.baseMipLevel = 0;
|
VkImageSubresourceRange range;
|
||||||
range.levelCount = mipLevels;
|
range.aspectMask = handle->Info.subresourceRange.aspectMask;
|
||||||
range.baseArrayLayer = 0;
|
range.baseMipLevel = 0;
|
||||||
range.layerCount = handle->Owner->ArraySlices;
|
range.levelCount = mipLevels;
|
||||||
AddImageBarrier(handle->Image, srcLayout, dstLayout, range, handle);
|
range.baseArrayLayer = 0;
|
||||||
|
range.layerCount = handle->Owner->ArraySlices;
|
||||||
|
AddImageBarrier(handle->Image, srcLayout, dstLayout, range, handle);
|
||||||
|
state.SetResourceState(dstLayout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -172,8 +210,8 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
|||||||
state.SetSubresourceState(i, dstLayout);
|
state.SetSubresourceState(i, dstLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT(state.CheckResourceState(dstLayout));
|
|
||||||
}
|
}
|
||||||
|
ASSERT(state.CheckResourceState(dstLayout));
|
||||||
state.SetResourceState(dstLayout);
|
state.SetResourceState(dstLayout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -262,11 +300,11 @@ void GPUContextVulkan::AddBufferBarrier(GPUBufferVulkan* buffer, VkAccessFlags d
|
|||||||
buffer->Access = dstAccess;
|
buffer->Access = dstAccess;
|
||||||
|
|
||||||
#if !VK_ENABLE_BARRIERS_BATCHING
|
#if !VK_ENABLE_BARRIERS_BATCHING
|
||||||
// Auto-flush without batching
|
// Auto-flush without batching
|
||||||
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
||||||
if (cmdBuffer->IsInsideRenderPass())
|
if (cmdBuffer->IsInsideRenderPass())
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
_barriers.Execute(cmdBuffer);
|
_barriers.Execute(cmdBuffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,6 +666,18 @@ void GPUContextVulkan::OnDrawCall()
|
|||||||
UpdateDescriptorSets(pipelineState);
|
UpdateDescriptorSets(pipelineState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind any missing vertex buffers to null if required by the current state
|
||||||
|
const auto vertexInputState = pipelineState->GetVertexInputState();
|
||||||
|
const int32 missingVBs = vertexInputState->vertexBindingDescriptionCount - _vbCount;
|
||||||
|
if (missingVBs > 0)
|
||||||
|
{
|
||||||
|
VkBuffer buffers[GPU_MAX_VB_BINDED];
|
||||||
|
VkDeviceSize offsets[GPU_MAX_VB_BINDED] = {};
|
||||||
|
for (int32 i = 0; i < missingVBs; i++)
|
||||||
|
buffers[i] = _device->HelperResources.GetDummyVertexBuffer()->GetHandle();
|
||||||
|
vkCmdBindVertexBuffers(cmdBuffer->GetHandle(), _vbCount, missingVBs, buffers, offsets);
|
||||||
|
}
|
||||||
|
|
||||||
// Start render pass if not during one
|
// Start render pass if not during one
|
||||||
if (cmdBuffer->IsOutsideRenderPass())
|
if (cmdBuffer->IsOutsideRenderPass())
|
||||||
BeginRenderPass();
|
BeginRenderPass();
|
||||||
@@ -652,7 +702,7 @@ void GPUContextVulkan::OnDrawCall()
|
|||||||
_rtDirtyFlag = false;
|
_rtDirtyFlag = false;
|
||||||
|
|
||||||
#if VK_ENABLE_BARRIERS_DEBUG
|
#if VK_ENABLE_BARRIERS_DEBUG
|
||||||
LOG(Warning, "Draw");
|
LOG(Warning, "Draw");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,6 +718,7 @@ void GPUContextVulkan::FrameBegin()
|
|||||||
_srDirtyFlag = 0;
|
_srDirtyFlag = 0;
|
||||||
_uaDirtyFlag = 0;
|
_uaDirtyFlag = 0;
|
||||||
_rtCount = 0;
|
_rtCount = 0;
|
||||||
|
_vbCount = 0;
|
||||||
_renderPass = nullptr;
|
_renderPass = nullptr;
|
||||||
_currentState = nullptr;
|
_currentState = nullptr;
|
||||||
_rtDepth = nullptr;
|
_rtDepth = nullptr;
|
||||||
@@ -922,6 +973,7 @@ void GPUContextVulkan::BindUA(int32 slot, GPUResourceView* view)
|
|||||||
|
|
||||||
void GPUContextVulkan::BindVB(const Span<GPUBuffer*>& vertexBuffers, const uint32* vertexBuffersOffsets)
|
void GPUContextVulkan::BindVB(const Span<GPUBuffer*>& vertexBuffers, const uint32* vertexBuffersOffsets)
|
||||||
{
|
{
|
||||||
|
_vbCount = vertexBuffers.Length();
|
||||||
if (vertexBuffers.Length() == 0)
|
if (vertexBuffers.Length() == 0)
|
||||||
return;
|
return;
|
||||||
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
||||||
@@ -955,7 +1007,7 @@ void GPUContextVulkan::UpdateCB(GPUConstantBuffer* cb, const void* data)
|
|||||||
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
||||||
|
|
||||||
// Allocate bytes for the buffer
|
// Allocate bytes for the buffer
|
||||||
const auto allocation = _device->UniformBufferUploader->Allocate(size, 0, cmdBuffer);
|
const auto allocation = _device->UniformBufferUploader->Allocate(size, 0, this);
|
||||||
|
|
||||||
// Copy data
|
// Copy data
|
||||||
Platform::MemoryCopy(allocation.CPUAddress, data, allocation.Size);
|
Platform::MemoryCopy(allocation.CPUAddress, data, allocation.Size);
|
||||||
@@ -1002,7 +1054,7 @@ void GPUContextVulkan::Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCo
|
|||||||
RENDER_STAT_DISPATCH_CALL();
|
RENDER_STAT_DISPATCH_CALL();
|
||||||
|
|
||||||
#if VK_ENABLE_BARRIERS_DEBUG
|
#if VK_ENABLE_BARRIERS_DEBUG
|
||||||
LOG(Warning, "Dispatch");
|
LOG(Warning, "Dispatch");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1036,7 +1088,7 @@ void GPUContextVulkan::DispatchIndirect(GPUShaderProgramCS* shader, GPUBuffer* b
|
|||||||
RENDER_STAT_DISPATCH_CALL();
|
RENDER_STAT_DISPATCH_CALL();
|
||||||
|
|
||||||
#if VK_ENABLE_BARRIERS_DEBUG
|
#if VK_ENABLE_BARRIERS_DEBUG
|
||||||
LOG(Warning, "DispatchIndirect");
|
LOG(Warning, "DispatchIndirect");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ class DescriptorSetLayoutVulkan;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
#define VK_BARRIER_BUFFER_SIZE 16
|
#define VK_BARRIER_BUFFER_SIZE 16
|
||||||
|
|
||||||
#if VK_ENABLE_BARRIERS_BATCHING
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Vulkan pipeline resources layout barrier batching structure.
|
/// The Vulkan pipeline resources layout barrier batching structure.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -81,8 +79,6 @@ public:
|
|||||||
void Execute(CmdBufferVulkan* cmdBuffer);
|
void Execute(CmdBufferVulkan* cmdBuffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GPU Context for Vulkan backend.
|
/// GPU Context for Vulkan backend.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -93,9 +89,7 @@ private:
|
|||||||
GPUDeviceVulkan* _device;
|
GPUDeviceVulkan* _device;
|
||||||
QueueVulkan* _queue;
|
QueueVulkan* _queue;
|
||||||
CmdBufferManagerVulkan* _cmdBufferManager;
|
CmdBufferManagerVulkan* _cmdBufferManager;
|
||||||
#if VK_ENABLE_BARRIERS_BATCHING
|
|
||||||
PipelineBarrierVulkan _barriers;
|
PipelineBarrierVulkan _barriers;
|
||||||
#endif
|
|
||||||
|
|
||||||
int32 _psDirtyFlag : 1;
|
int32 _psDirtyFlag : 1;
|
||||||
int32 _rtDirtyFlag : 1;
|
int32 _rtDirtyFlag : 1;
|
||||||
@@ -104,6 +98,7 @@ private:
|
|||||||
int32 _uaDirtyFlag : 1;
|
int32 _uaDirtyFlag : 1;
|
||||||
|
|
||||||
int32 _rtCount;
|
int32 _rtCount;
|
||||||
|
int32 _vbCount;
|
||||||
|
|
||||||
RenderPassVulkan* _renderPass;
|
RenderPassVulkan* _renderPass;
|
||||||
GPUPipelineStateVulkan* _currentState;
|
GPUPipelineStateVulkan* _currentState;
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
|||||||
_descDynamic.pDynamicStates = _dynamicStates;
|
_descDynamic.pDynamicStates = _dynamicStates;
|
||||||
_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
|
_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
|
||||||
_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
|
_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
|
||||||
_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE;
|
//_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE;
|
||||||
static_assert(ARRAY_COUNT(_dynamicStates) <= 3, "Invalid dynamic states array.");
|
static_assert(ARRAY_COUNT(_dynamicStates) <= 3, "Invalid dynamic states array.");
|
||||||
_desc.pDynamicState = &_descDynamic;
|
_desc.pDynamicState = &_descDynamic;
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
const SpirvShaderDescriptorInfo* DescriptorInfoPerStage[DescriptorSet::GraphicsStagesCount];
|
const SpirvShaderDescriptorInfo* DescriptorInfoPerStage[DescriptorSet::GraphicsStagesCount];
|
||||||
|
|
||||||
|
const VkPipelineVertexInputStateCreateInfo* GetVertexInputState() const
|
||||||
|
{
|
||||||
|
return _desc.pVertexInputState;
|
||||||
|
}
|
||||||
|
|
||||||
DescriptorSetWriteContainerVulkan DSWriteContainer;
|
DescriptorSetWriteContainerVulkan DSWriteContainer;
|
||||||
DescriptorSetWriterVulkan DSWriter[DescriptorSet::GraphicsStagesCount];
|
DescriptorSetWriterVulkan DSWriter[DescriptorSet::GraphicsStagesCount];
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#if GRAPHICS_API_VULKAN
|
#if GRAPHICS_API_VULKAN
|
||||||
|
|
||||||
#include "GPUShaderVulkan.h"
|
#include "GPUShaderVulkan.h"
|
||||||
|
#include "GPUContextVulkan.h"
|
||||||
#include "GPUShaderProgramVulkan.h"
|
#include "GPUShaderProgramVulkan.h"
|
||||||
#include "RenderToolsVulkan.h"
|
#include "RenderToolsVulkan.h"
|
||||||
#include "CmdBufferVulkan.h"
|
#include "CmdBufferVulkan.h"
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||||
|
|
||||||
#if PLATFORM_DESKTOP
|
#if PLATFORM_DESKTOP
|
||||||
#define VULKAN_UNIFORM_RING_BUFFER_SIZE 16 * 1024 * 1024
|
#define VULKAN_UNIFORM_RING_BUFFER_SIZE 24 * 1024 * 1024
|
||||||
#else
|
#else
|
||||||
#define VULKAN_UNIFORM_RING_BUFFER_SIZE 8 * 1024 * 1024
|
#define VULKAN_UNIFORM_RING_BUFFER_SIZE 8 * 1024 * 1024
|
||||||
#endif
|
#endif
|
||||||
@@ -45,7 +46,7 @@ UniformBufferUploaderVulkan::UniformBufferUploaderVulkan(GPUDeviceVulkan* device
|
|||||||
LOG_VULKAN_RESULT(result);
|
LOG_VULKAN_RESULT(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformBufferUploaderVulkan::Allocation UniformBufferUploaderVulkan::Allocate(uint64 size, uint32 alignment, CmdBufferVulkan* cmdBuffer)
|
UniformBufferUploaderVulkan::Allocation UniformBufferUploaderVulkan::Allocate(uint64 size, uint32 alignment, GPUContextVulkan* context)
|
||||||
{
|
{
|
||||||
alignment = Math::Max(_minAlignment, alignment);
|
alignment = Math::Max(_minAlignment, alignment);
|
||||||
uint64 offset = Math::AlignUp<uint64>(_offset, alignment);
|
uint64 offset = Math::AlignUp<uint64>(_offset, alignment);
|
||||||
@@ -53,16 +54,12 @@ UniformBufferUploaderVulkan::Allocation UniformBufferUploaderVulkan::Allocate(ui
|
|||||||
// Check if wrap around ring buffer
|
// Check if wrap around ring buffer
|
||||||
if (offset + size >= _size)
|
if (offset + size >= _size)
|
||||||
{
|
{
|
||||||
if (_fenceCmdBuffer)
|
auto cmdBuffer = context->GetCmdBufferManager()->GetActiveCmdBuffer();
|
||||||
|
if (_fenceCmdBuffer && _fenceCounter == cmdBuffer->GetFenceSignaledCounter())
|
||||||
{
|
{
|
||||||
if (_fenceCmdBuffer == cmdBuffer && _fenceCounter == cmdBuffer->GetFenceSignaledCounter())
|
LOG(Error, "Wrapped around the ring buffer! Need to wait on the GPU!");
|
||||||
{
|
context->Flush();
|
||||||
LOG(Error, "Wrapped around the ring buffer. Requested more bytes than possible in the same cmd buffer!");
|
cmdBuffer = context->GetCmdBufferManager()->GetActiveCmdBuffer();
|
||||||
}
|
|
||||||
else if (_fenceCounter == _fenceCmdBuffer->GetFenceSignaledCounter())
|
|
||||||
{
|
|
||||||
LOG(Error, "Wrapped around the ring buffer! Need to wait on the GPU!!!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Allocation Allocate(uint64 size, uint32 alignment, CmdBufferVulkan* cmdBuffer);
|
Allocation Allocate(uint64 size, uint32 alignment, GPUContextVulkan* context);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -164,37 +164,6 @@ public:
|
|||||||
return stageFlags;
|
return stageFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void SetBufferBarrierInfo(VkAccessFlags source, VkAccessFlags dest, VkPipelineStageFlags& sourceStage, VkPipelineStageFlags& destStage)
|
|
||||||
{
|
|
||||||
sourceStage |= GetBufferBarrierFlags(source);
|
|
||||||
destStage |= GetBufferBarrierFlags(dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void SetImageBarrierInfo(VkImageLayout source, VkImageLayout dest, VkImageMemoryBarrier& barrier, VkPipelineStageFlags& sourceStage, VkPipelineStageFlags& destStage)
|
|
||||||
{
|
|
||||||
barrier.oldLayout = source;
|
|
||||||
barrier.newLayout = dest;
|
|
||||||
|
|
||||||
sourceStage |= GetImageBarrierFlags(source, barrier.srcAccessMask);
|
|
||||||
destStage |= GetImageBarrierFlags(dest, barrier.dstAccessMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImagePipelineBarrier(VkCommandBuffer cmdBuffer, VkImage img, VkImageLayout src, VkImageLayout dest, const VkImageSubresourceRange& subresourceRange)
|
|
||||||
{
|
|
||||||
VkImageMemoryBarrier imageBarrier;
|
|
||||||
ZeroStruct(imageBarrier, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER);
|
|
||||||
imageBarrier.image = img;
|
|
||||||
imageBarrier.subresourceRange = subresourceRange;
|
|
||||||
imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
|
|
||||||
VkPipelineStageFlags srcStages = (VkPipelineStageFlags)0;
|
|
||||||
VkPipelineStageFlags destStages = (VkPipelineStageFlags)0;
|
|
||||||
SetImageBarrierInfo(src, dest, imageBarrier, srcStages, destStages);
|
|
||||||
|
|
||||||
vkCmdPipelineBarrier(cmdBuffer, srcStages, destStages, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static FORCE_INLINE void ZeroStruct(T& data, VkStructureType type)
|
static FORCE_INLINE void ZeroStruct(T& data, VkStructureType type)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -206,8 +206,10 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB
|
|||||||
|
|
||||||
// Bind output
|
// Bind output
|
||||||
GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
|
GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
|
||||||
GPUTextureView* depthBufferHandle = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : nullptr;
|
const bool depthBufferReadOnly = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView;
|
||||||
context->SetRenderTarget(depthBufferHandle, lightBuffer);
|
GPUTextureView* depthBufferRTV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : nullptr;
|
||||||
|
GPUTextureView* depthBufferSRV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
|
||||||
|
context->SetRenderTarget(depthBufferRTV, lightBuffer);
|
||||||
|
|
||||||
// Set per frame data
|
// Set per frame data
|
||||||
GBufferPass::SetInputs(renderContext.View, perFrame.GBuffer);
|
GBufferPass::SetInputs(renderContext.View, perFrame.GBuffer);
|
||||||
@@ -225,7 +227,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB
|
|||||||
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
||||||
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
||||||
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
||||||
context->BindSR(3, depthBuffer);
|
context->BindSR(3, depthBufferSRV);
|
||||||
context->BindSR(4, renderContext.Buffers->GBuffer3);
|
context->BindSR(4, renderContext.Buffers->GBuffer3);
|
||||||
|
|
||||||
// Check if debug lights
|
// Check if debug lights
|
||||||
@@ -274,7 +276,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB
|
|||||||
ShadowsPass::Instance()->RenderShadow(renderContext, light, shadowMaskView);
|
ShadowsPass::Instance()->RenderShadow(renderContext, light, shadowMaskView);
|
||||||
|
|
||||||
// Bind output
|
// Bind output
|
||||||
context->SetRenderTarget(depthBufferHandle, lightBuffer);
|
context->SetRenderTarget(depthBufferRTV, lightBuffer);
|
||||||
|
|
||||||
// Set shadow mask
|
// Set shadow mask
|
||||||
context->BindSR(5, shadowMaskView);
|
context->BindSR(5, shadowMaskView);
|
||||||
@@ -329,7 +331,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB
|
|||||||
ShadowsPass::Instance()->RenderShadow(renderContext, light, shadowMaskView);
|
ShadowsPass::Instance()->RenderShadow(renderContext, light, shadowMaskView);
|
||||||
|
|
||||||
// Bind output
|
// Bind output
|
||||||
context->SetRenderTarget(depthBufferHandle, lightBuffer);
|
context->SetRenderTarget(depthBufferRTV, lightBuffer);
|
||||||
|
|
||||||
// Set shadow mask
|
// Set shadow mask
|
||||||
context->BindSR(5, shadowMaskView);
|
context->BindSR(5, shadowMaskView);
|
||||||
@@ -370,7 +372,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB
|
|||||||
ShadowsPass::Instance()->RenderShadow(renderContext, light, lightIndex, shadowMaskView);
|
ShadowsPass::Instance()->RenderShadow(renderContext, light, lightIndex, shadowMaskView);
|
||||||
|
|
||||||
// Bind output
|
// Bind output
|
||||||
context->SetRenderTarget(depthBufferHandle, lightBuffer);
|
context->SetRenderTarget(depthBufferRTV, lightBuffer);
|
||||||
|
|
||||||
// Set shadow mask
|
// Set shadow mask
|
||||||
context->BindSR(5, shadowMaskView);
|
context->BindSR(5, shadowMaskView);
|
||||||
|
|||||||
@@ -315,12 +315,12 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererPointLightD
|
|||||||
context->ResetRenderTarget();
|
context->ResetRenderTarget();
|
||||||
const Viewport viewport = renderContext.Task->GetViewport();
|
const Viewport viewport = renderContext.Task->GetViewport();
|
||||||
GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
|
GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
|
||||||
GPUTextureView* depthBufferHandle = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
|
GPUTextureView* depthBufferSRV = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
|
||||||
context->SetViewportAndScissors(viewport);
|
context->SetViewportAndScissors(viewport);
|
||||||
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
||||||
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
||||||
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
||||||
context->BindSR(3, depthBufferHandle);
|
context->BindSR(3, depthBufferSRV);
|
||||||
context->BindSR(4, renderContext.Buffers->GBuffer3);
|
context->BindSR(4, renderContext.Buffers->GBuffer3);
|
||||||
|
|
||||||
// Setup shader data
|
// Setup shader data
|
||||||
@@ -417,12 +417,12 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererSpotLightDa
|
|||||||
context->ResetRenderTarget();
|
context->ResetRenderTarget();
|
||||||
const Viewport viewport = renderContext.Task->GetViewport();
|
const Viewport viewport = renderContext.Task->GetViewport();
|
||||||
GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
|
GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
|
||||||
GPUTextureView* depthBufferHandle = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
|
GPUTextureView* depthBufferSRV = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
|
||||||
context->SetViewportAndScissors(viewport);
|
context->SetViewportAndScissors(viewport);
|
||||||
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
||||||
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
||||||
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
||||||
context->BindSR(3, depthBufferHandle);
|
context->BindSR(3, depthBufferSRV);
|
||||||
context->BindSR(4, renderContext.Buffers->GBuffer3);
|
context->BindSR(4, renderContext.Buffers->GBuffer3);
|
||||||
|
|
||||||
// Setup shader data
|
// Setup shader data
|
||||||
@@ -693,12 +693,12 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererDirectional
|
|||||||
context->ResetRenderTarget();
|
context->ResetRenderTarget();
|
||||||
const Viewport viewport = renderContext.Task->GetViewport();
|
const Viewport viewport = renderContext.Task->GetViewport();
|
||||||
GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
|
GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer;
|
||||||
GPUTextureView* depthBufferHandle = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
|
GPUTextureView* depthBufferSRV = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View();
|
||||||
context->SetViewportAndScissors(viewport);
|
context->SetViewportAndScissors(viewport);
|
||||||
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
||||||
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
||||||
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
||||||
context->BindSR(3, depthBufferHandle);
|
context->BindSR(3, depthBufferSRV);
|
||||||
context->BindSR(4, renderContext.Buffers->GBuffer3);
|
context->BindSR(4, renderContext.Buffers->GBuffer3);
|
||||||
|
|
||||||
// Setup shader data
|
// Setup shader data
|
||||||
|
|||||||
Reference in New Issue
Block a user