Add Vulkan sphere integration support
This commit is contained in:
@@ -73,6 +73,18 @@ VkPipelineStageFlags ToVulkanStageMask(ResourceStates state) {
|
||||
}
|
||||
}
|
||||
|
||||
VkImageAspectFlags ResolveClearAspectMask(Format format, uint32_t buffers) {
|
||||
VkImageAspectFlags aspectMask = 0;
|
||||
const VkImageAspectFlags formatAspectMask = GetImageAspectMask(format);
|
||||
if ((buffers & 2) != 0) {
|
||||
aspectMask |= formatAspectMask & VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
if ((buffers & 4) != 0) {
|
||||
aspectMask |= formatAspectMask & VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
return aspectMask;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
VulkanCommandList::~VulkanCommandList() {
|
||||
@@ -398,40 +410,71 @@ void VulkanCommandList::DrawIndexed(uint32_t indexCount, uint32_t instanceCount,
|
||||
}
|
||||
|
||||
void VulkanCommandList::Clear(float r, float g, float b, float a, uint32_t buffers) {
|
||||
(void)buffers;
|
||||
if ((buffers & 1) != 0) {
|
||||
auto* colorView = static_cast<VulkanResourceView*>(m_currentColorTarget);
|
||||
if (colorView != nullptr && colorView->GetTexture() != nullptr) {
|
||||
EndActiveRenderPass();
|
||||
|
||||
auto* colorView = static_cast<VulkanResourceView*>(m_currentColorTarget);
|
||||
if (colorView == nullptr || colorView->GetTexture() == nullptr) {
|
||||
return;
|
||||
VulkanTexture* texture = colorView->GetTexture();
|
||||
TransitionTexture(texture, ResourceStates::CopyDst);
|
||||
|
||||
VkClearColorValue clearColor = {};
|
||||
clearColor.float32[0] = r;
|
||||
clearColor.float32[1] = g;
|
||||
clearColor.float32[2] = b;
|
||||
clearColor.float32[3] = a;
|
||||
|
||||
VkImageSubresourceRange range = {};
|
||||
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
range.baseMipLevel = 0;
|
||||
range.levelCount = 1;
|
||||
range.baseArrayLayer = 0;
|
||||
range.layerCount = 1;
|
||||
|
||||
vkCmdClearColorImage(
|
||||
m_commandBuffer,
|
||||
texture->GetImage(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&clearColor,
|
||||
1,
|
||||
&range);
|
||||
|
||||
TransitionTexture(texture, ResourceStates::RenderTarget);
|
||||
}
|
||||
}
|
||||
|
||||
EndActiveRenderPass();
|
||||
if ((buffers & (2 | 4)) != 0) {
|
||||
auto* depthView = static_cast<VulkanResourceView*>(m_currentDepthTarget);
|
||||
if (depthView != nullptr && depthView->GetTexture() != nullptr) {
|
||||
EndActiveRenderPass();
|
||||
|
||||
VulkanTexture* texture = colorView->GetTexture();
|
||||
TransitionTexture(texture, ResourceStates::CopyDst);
|
||||
VulkanTexture* texture = depthView->GetTexture();
|
||||
TransitionTexture(texture, ResourceStates::CopyDst);
|
||||
|
||||
VkClearColorValue clearColor = {};
|
||||
clearColor.float32[0] = r;
|
||||
clearColor.float32[1] = g;
|
||||
clearColor.float32[2] = b;
|
||||
clearColor.float32[3] = a;
|
||||
VkImageSubresourceRange range = {};
|
||||
range.aspectMask = ResolveClearAspectMask(texture->GetFormat(), buffers);
|
||||
range.baseMipLevel = 0;
|
||||
range.levelCount = 1;
|
||||
range.baseArrayLayer = 0;
|
||||
range.layerCount = 1;
|
||||
|
||||
VkImageSubresourceRange range = {};
|
||||
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
range.baseMipLevel = 0;
|
||||
range.levelCount = 1;
|
||||
range.baseArrayLayer = 0;
|
||||
range.layerCount = 1;
|
||||
if (range.aspectMask != 0) {
|
||||
VkClearDepthStencilValue clearValue = {};
|
||||
clearValue.depth = 1.0f;
|
||||
clearValue.stencil = 0;
|
||||
|
||||
vkCmdClearColorImage(
|
||||
m_commandBuffer,
|
||||
texture->GetImage(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&clearColor,
|
||||
1,
|
||||
&range);
|
||||
vkCmdClearDepthStencilImage(
|
||||
m_commandBuffer,
|
||||
texture->GetImage(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&clearValue,
|
||||
1,
|
||||
&range);
|
||||
}
|
||||
|
||||
TransitionTexture(texture, ResourceStates::RenderTarget);
|
||||
TransitionTexture(texture, ResourceStates::DepthWrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanCommandList::ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) {
|
||||
@@ -440,9 +483,36 @@ void VulkanCommandList::ClearRenderTarget(RHIResourceView* renderTarget, const f
|
||||
}
|
||||
|
||||
void VulkanCommandList::ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) {
|
||||
(void)depthStencil;
|
||||
(void)depth;
|
||||
(void)stencil;
|
||||
auto* depthView = static_cast<VulkanResourceView*>(depthStencil != nullptr ? depthStencil : m_currentDepthTarget);
|
||||
if (depthView == nullptr || depthView->GetTexture() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
EndActiveRenderPass();
|
||||
|
||||
VulkanTexture* texture = depthView->GetTexture();
|
||||
TransitionTexture(texture, ResourceStates::CopyDst);
|
||||
|
||||
VkClearDepthStencilValue clearValue = {};
|
||||
clearValue.depth = depth;
|
||||
clearValue.stencil = stencil;
|
||||
|
||||
VkImageSubresourceRange range = {};
|
||||
range.aspectMask = GetImageAspectMask(texture->GetFormat());
|
||||
range.baseMipLevel = 0;
|
||||
range.levelCount = 1;
|
||||
range.baseArrayLayer = 0;
|
||||
range.layerCount = 1;
|
||||
|
||||
vkCmdClearDepthStencilImage(
|
||||
m_commandBuffer,
|
||||
texture->GetImage(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&clearValue,
|
||||
1,
|
||||
&range);
|
||||
|
||||
TransitionTexture(texture, ResourceStates::DepthWrite);
|
||||
}
|
||||
|
||||
void VulkanCommandList::CopyResource(RHIResourceView* dst, RHIResourceView* src) {
|
||||
@@ -470,15 +540,28 @@ bool VulkanCommandList::EnsureGraphicsRenderPass() {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* depthView = static_cast<VulkanResourceView*>(m_currentDepthTarget);
|
||||
const bool expectsDepthAttachment = m_currentPipelineState->HasDepthStencilAttachment();
|
||||
if (expectsDepthAttachment &&
|
||||
(depthView == nullptr || depthView->GetTexture() == nullptr || depthView->GetImageView() == VK_NULL_HANDLE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VulkanTexture* texture = colorView->GetTexture();
|
||||
TransitionTexture(texture, ResourceStates::RenderTarget);
|
||||
if (expectsDepthAttachment) {
|
||||
TransitionTexture(depthView->GetTexture(), ResourceStates::DepthWrite);
|
||||
}
|
||||
|
||||
VkFramebufferCreateInfo framebufferInfo = {};
|
||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
framebufferInfo.renderPass = m_currentPipelineState->GetRenderPass();
|
||||
framebufferInfo.attachmentCount = 1;
|
||||
const VkImageView attachment = colorView->GetImageView();
|
||||
framebufferInfo.pAttachments = &attachment;
|
||||
VkImageView attachments[2] = { colorView->GetImageView(), VK_NULL_HANDLE };
|
||||
framebufferInfo.attachmentCount = expectsDepthAttachment ? 2 : 1;
|
||||
if (expectsDepthAttachment) {
|
||||
attachments[1] = depthView->GetImageView();
|
||||
}
|
||||
framebufferInfo.pAttachments = attachments;
|
||||
framebufferInfo.width = texture->GetWidth();
|
||||
framebufferInfo.height = texture->GetHeight();
|
||||
framebufferInfo.layers = 1;
|
||||
|
||||
Reference in New Issue
Block a user