Add Vulkan sphere integration support

This commit is contained in:
2026-03-27 15:07:21 +08:00
parent 18fd09b36f
commit 22ccdfb371
16 changed files with 429 additions and 63 deletions

View File

@@ -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;