mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Feat] (GL_State/RenderState): implement ClearStencil
This commit is contained in:
@@ -18,7 +18,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
|
||||
const auto& clearColor = MG_State::pGLContext->GetClearColor();
|
||||
pVulkanRenderer->RequestClear(mask, clearColor);
|
||||
const auto clearDepth = MG_State::pGLContext->GetClearDepth();
|
||||
const auto clearStencil = static_cast<Uint32>(MG_State::pGLContext->GetClearStencil());
|
||||
pVulkanRenderer->RequestClear(mask, clearColor, clearDepth, clearStencil);
|
||||
}
|
||||
|
||||
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) {
|
||||
|
||||
@@ -247,25 +247,35 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MGLOG_I("VulkanRenderer shut down completed");
|
||||
}
|
||||
|
||||
void VulkanRenderer::RequestClear(GLbitfield mask, const FloatVec4& color) {
|
||||
if ((mask & GL_COLOR_BUFFER_BIT) == 0) {
|
||||
void VulkanRenderer::RequestClear(GLbitfield mask, const FloatVec4& color, Float depth, Uint32 stencil) {
|
||||
const GLbitfield supportedMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||
const GLbitfield requestMask = (mask & supportedMask);
|
||||
if (requestMask == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_pendingClearColor.float32[0] = color.x();
|
||||
m_pendingClearColor.float32[1] = color.y();
|
||||
m_pendingClearColor.float32[2] = color.z();
|
||||
m_pendingClearColor.float32[3] = color.w();
|
||||
m_pendingColorClear = true;
|
||||
if ((requestMask & GL_COLOR_BUFFER_BIT) != 0) {
|
||||
m_pendingClearColor.float32[0] = color.x();
|
||||
m_pendingClearColor.float32[1] = color.y();
|
||||
m_pendingClearColor.float32[2] = color.z();
|
||||
m_pendingClearColor.float32[3] = color.w();
|
||||
}
|
||||
if ((requestMask & GL_DEPTH_BUFFER_BIT) != 0) {
|
||||
m_pendingClearDepth = depth;
|
||||
}
|
||||
if ((requestMask & GL_STENCIL_BUFFER_BIT) != 0) {
|
||||
m_pendingClearStencil = stencil;
|
||||
}
|
||||
m_pendingClearMask |= requestMask;
|
||||
}
|
||||
|
||||
Bool VulkanRenderer::ConsumePendingColorClear(VkClearColorValue& outClearColor) {
|
||||
if (!m_pendingColorClear) {
|
||||
if ((m_pendingClearMask & GL_COLOR_BUFFER_BIT) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outClearColor = m_pendingClearColor;
|
||||
m_pendingColorClear = false;
|
||||
m_pendingClearMask &= ~GL_COLOR_BUFFER_BIT;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -310,6 +320,66 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
vkCmdClearAttachments(commandBuffer, 1, &clearAttachment, 1, &clearRect);
|
||||
}
|
||||
|
||||
void VulkanRenderer::RecordDepthStencilClear(VkCommandBuffer commandBuffer, GLbitfield mask, Float depth, Uint32 stencil) {
|
||||
VkImageAspectFlags aspectMask = 0;
|
||||
if ((mask & GL_DEPTH_BUFFER_BIT) != 0) {
|
||||
aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
if ((mask & GL_STENCIL_BUFFER_BIT) != 0 && HasStencilComponent(m_depthStencilFormat)) {
|
||||
aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
if (aspectMask == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
VkClearAttachment clearAttachment{};
|
||||
clearAttachment.aspectMask = aspectMask;
|
||||
clearAttachment.clearValue.depthStencil.depth = depth;
|
||||
clearAttachment.clearValue.depthStencil.stencil = stencil;
|
||||
|
||||
VkClearRect clearRect{};
|
||||
clearRect.rect.offset = {0, 0};
|
||||
clearRect.rect.extent = m_swapchainObject.GetExtent();
|
||||
clearRect.baseArrayLayer = 0;
|
||||
clearRect.layerCount = 1;
|
||||
|
||||
vkCmdClearAttachments(commandBuffer, 1, &clearAttachment, 1, &clearRect);
|
||||
}
|
||||
|
||||
void VulkanRenderer::TransitionDepthStencilImageToAttachment(VkCommandBuffer commandBuffer, Uint32 imageIndex) {
|
||||
if (m_depthStencilImageLayouts.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto oldLayout = m_depthStencilImageLayouts[imageIndex];
|
||||
if (oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
VkImageMemoryBarrier barrier{};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
barrier.oldLayout = oldLayout;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = m_depthStencilImages[imageIndex];
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (HasStencilComponent(m_depthStencilFormat)) {
|
||||
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
|
||||
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
m_depthStencilImageLayouts[imageIndex] = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
}
|
||||
|
||||
void VulkanRenderer::EnsureFrameRecordingStarted() {
|
||||
auto& frame = m_frameContext.GetCurrent();
|
||||
if (frame.isCommandRecording) {
|
||||
@@ -323,12 +393,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
VkCommandBuffer& commandBuffer = m_frameContext.BeginCommandRecording();
|
||||
TransitionSwapchainImageToColorAttachment(commandBuffer, m_imageIndexAcquired);
|
||||
TransitionDepthStencilImageToAttachment(commandBuffer, m_imageIndexAcquired);
|
||||
|
||||
const Bool useRenderPassClearValue = m_pendingColorClear;
|
||||
VkClearValue clearValue{};
|
||||
const Bool useRenderPassClearValue = (m_pendingClearMask & GL_COLOR_BUFFER_BIT) != 0;
|
||||
VkClearValue clearValues[1]{};
|
||||
if (useRenderPassClearValue) {
|
||||
clearValue.color = m_pendingClearColor;
|
||||
m_pendingColorClear = false;
|
||||
clearValues[0].color = m_pendingClearColor;
|
||||
m_pendingClearMask &= ~GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
VkRenderPassBeginInfo renderPassInfo{};
|
||||
@@ -338,9 +409,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
renderPassInfo.renderArea.offset = {0, 0};
|
||||
renderPassInfo.renderArea.extent = m_swapchainObject.GetExtent();
|
||||
renderPassInfo.clearValueCount = useRenderPassClearValue ? 1 : 0;
|
||||
renderPassInfo.pClearValues = useRenderPassClearValue ? &clearValue : nullptr;
|
||||
renderPassInfo.pClearValues = useRenderPassClearValue ? clearValues : nullptr;
|
||||
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
m_isMainRenderPassActive = true;
|
||||
|
||||
if ((m_pendingClearMask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) {
|
||||
RecordDepthStencilClear(commandBuffer, m_pendingClearMask, m_pendingClearDepth, m_pendingClearStencil);
|
||||
m_pendingClearMask &= ~(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanRenderer::EndFrameRecordingIfNeeded() {
|
||||
@@ -393,14 +469,18 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MOBILEGL_ASSERT(m_imageIndexAcquired < m_swapchainObject.GetImageCount(),
|
||||
"Present, acquired image index out of range");
|
||||
auto& frame = m_frameContext.GetCurrent();
|
||||
if (m_pendingColorClear && frame.isCommandRecording && m_isMainRenderPassActive) {
|
||||
RecordColorClear(frame.commandBuffer, m_pendingClearColor);
|
||||
m_pendingColorClear = false;
|
||||
} else if (m_pendingColorClear && frame.hasCommandBufferRecorded) {
|
||||
if (m_pendingClearMask != 0 && frame.isCommandRecording && m_isMainRenderPassActive) {
|
||||
if ((m_pendingClearMask & GL_COLOR_BUFFER_BIT) != 0) {
|
||||
RecordColorClear(frame.commandBuffer, m_pendingClearColor);
|
||||
}
|
||||
if ((m_pendingClearMask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) {
|
||||
RecordDepthStencilClear(frame.commandBuffer, m_pendingClearMask, m_pendingClearDepth, m_pendingClearStencil);
|
||||
}
|
||||
m_pendingClearMask = 0;
|
||||
} else if (m_pendingClearMask != 0 && frame.hasCommandBufferRecorded) {
|
||||
MGLOG_W("Dropping pending clear for current frame because command buffer is already finalized");
|
||||
VkClearColorValue droppedClearColor{};
|
||||
ConsumePendingColorClear(droppedClearColor);
|
||||
} else if (m_pendingColorClear) {
|
||||
m_pendingClearMask = 0;
|
||||
} else if (m_pendingClearMask != 0) {
|
||||
EnsureFrameRecordingStarted();
|
||||
}
|
||||
EndFrameRecordingIfNeeded();
|
||||
@@ -775,6 +855,124 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
m_config.MaxFramesInFlight);
|
||||
}
|
||||
|
||||
Uint32 VulkanRenderer::FindMemoryType(Uint32 typeFilter, VkMemoryPropertyFlags properties) const {
|
||||
VkPhysicalDeviceMemoryProperties memProperties{};
|
||||
vkGetPhysicalDeviceMemoryProperties(m_physicalDevice.handle, &memProperties);
|
||||
|
||||
for (Uint32 i = 0; i < memProperties.memoryTypeCount; i++) {
|
||||
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
MOBILEGL_ASSERT(false, "Failed to find suitable memory type.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bool VulkanRenderer::HasStencilComponent(VkFormat format) {
|
||||
return format == VK_FORMAT_D24_UNORM_S8_UINT || format == VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
}
|
||||
|
||||
VkFormat VulkanRenderer::FindSupportedDepthStencilFormat(VkPhysicalDevice physicalDevice) {
|
||||
const VkFormat candidates[] = {
|
||||
VK_FORMAT_D24_UNORM_S8_UINT,
|
||||
VK_FORMAT_D32_SFLOAT_S8_UINT,
|
||||
VK_FORMAT_D32_SFLOAT
|
||||
};
|
||||
for (VkFormat format : candidates) {
|
||||
VkFormatProperties props{};
|
||||
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props);
|
||||
if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
void VulkanRenderer::CreateDepthStencilResources() {
|
||||
const auto imageCount = static_cast<Uint32>(m_swapchainObject.GetImageCount());
|
||||
if (imageCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_depthStencilFormat = FindSupportedDepthStencilFormat(m_physicalDevice.handle);
|
||||
MOBILEGL_ASSERT(m_depthStencilFormat != VK_FORMAT_UNDEFINED, "No supported depth/stencil format found.");
|
||||
|
||||
const auto extent = m_swapchainObject.GetExtent();
|
||||
m_depthStencilImages.assign(imageCount, VK_NULL_HANDLE);
|
||||
m_depthStencilImageMemories.assign(imageCount, VK_NULL_HANDLE);
|
||||
m_depthStencilImageViews.assign(imageCount, VK_NULL_HANDLE);
|
||||
m_depthStencilImageLayouts.assign(imageCount, VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
|
||||
for (Uint32 i = 0; i < imageCount; ++i) {
|
||||
VkImageCreateInfo imageInfo{};
|
||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageInfo.extent.width = extent.width;
|
||||
imageInfo.extent.height = extent.height;
|
||||
imageInfo.extent.depth = 1;
|
||||
imageInfo.mipLevels = 1;
|
||||
imageInfo.arrayLayers = 1;
|
||||
imageInfo.format = m_depthStencilFormat;
|
||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
VK_VERIFY(vkCreateImage(m_device, &imageInfo, nullptr, &m_depthStencilImages[i]), "vkCreateImage(depth)");
|
||||
|
||||
VkMemoryRequirements memRequirements{};
|
||||
vkGetImageMemoryRequirements(m_device, m_depthStencilImages[i], &memRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocInfo.allocationSize = memRequirements.size;
|
||||
allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
VK_VERIFY(vkAllocateMemory(m_device, &allocInfo, nullptr, &m_depthStencilImageMemories[i]), "vkAllocateMemory(depth)");
|
||||
VK_VERIFY(vkBindImageMemory(m_device, m_depthStencilImages[i], m_depthStencilImageMemories[i], 0), "vkBindImageMemory(depth)");
|
||||
|
||||
VkImageViewCreateInfo viewInfo{};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.image = m_depthStencilImages[i];
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.format = m_depthStencilFormat;
|
||||
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (HasStencilComponent(m_depthStencilFormat)) {
|
||||
viewInfo.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
VK_VERIFY(vkCreateImageView(m_device, &viewInfo, nullptr, &m_depthStencilImageViews[i]), "vkCreateImageView(depth)");
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanRenderer::DestroyDepthStencilResources() {
|
||||
for (auto view : m_depthStencilImageViews) {
|
||||
if (view != VK_NULL_HANDLE) {
|
||||
vkDestroyImageView(m_device, view, nullptr);
|
||||
}
|
||||
}
|
||||
m_depthStencilImageViews.clear();
|
||||
|
||||
for (auto image : m_depthStencilImages) {
|
||||
if (image != VK_NULL_HANDLE) {
|
||||
vkDestroyImage(m_device, image, nullptr);
|
||||
}
|
||||
}
|
||||
m_depthStencilImages.clear();
|
||||
|
||||
for (auto memory : m_depthStencilImageMemories) {
|
||||
if (memory != VK_NULL_HANDLE) {
|
||||
vkFreeMemory(m_device, memory, nullptr);
|
||||
}
|
||||
}
|
||||
m_depthStencilImageMemories.clear();
|
||||
m_depthStencilImageLayouts.clear();
|
||||
m_depthStencilFormat = VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
void VulkanRenderer::CreateCommandPool() {
|
||||
VkCommandPoolCreateInfo createInfo{VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO};
|
||||
createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
@@ -792,15 +990,29 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
color.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
color.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
VkAttachmentDescription depthStencil{};
|
||||
depthStencil.format = m_depthStencilFormat;
|
||||
depthStencil.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
depthStencil.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depthStencil.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
depthStencil.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depthStencil.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
depthStencil.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
depthStencil.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkAttachmentReference colorRef{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
||||
VkAttachmentReference depthStencilRef{1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
|
||||
VkSubpassDescription sub{};
|
||||
sub.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
sub.colorAttachmentCount = 1;
|
||||
sub.pColorAttachments = &colorRef;
|
||||
sub.pDepthStencilAttachment = &depthStencilRef;
|
||||
|
||||
VkAttachmentDescription attachments[] = {color, depthStencil};
|
||||
|
||||
VkRenderPassCreateInfo rpci{VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
|
||||
rpci.attachmentCount = 1;
|
||||
rpci.pAttachments = &color;
|
||||
rpci.attachmentCount = static_cast<Uint32>(std::size(attachments));
|
||||
rpci.pAttachments = attachments;
|
||||
rpci.subpassCount = 1;
|
||||
rpci.pSubpasses = ⊂
|
||||
|
||||
@@ -821,11 +1033,11 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
const auto swapchainExtent = m_swapchainObject.GetExtent();
|
||||
Vector<VkFramebuffer>& fbs = m_framebuffers;
|
||||
fbs.reserve(imageViews.size());
|
||||
for (auto iv : imageViews) {
|
||||
VkImageView attachments[] = {iv};
|
||||
for (SizeT i = 0; i < imageViews.size(); ++i) {
|
||||
VkImageView attachments[] = {imageViews[i], m_depthStencilImageViews[i]};
|
||||
VkFramebufferCreateInfo fbci{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO};
|
||||
fbci.renderPass = m_renderPassLoad;
|
||||
fbci.attachmentCount = 1;
|
||||
fbci.attachmentCount = static_cast<Uint32>(std::size(attachments));
|
||||
fbci.pAttachments = attachments;
|
||||
fbci.width = swapchainExtent.width;
|
||||
fbci.height = swapchainExtent.height;
|
||||
@@ -933,6 +1145,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
m_framebuffers.clear();
|
||||
|
||||
DestroyDepthStencilResources();
|
||||
|
||||
if (m_renderPassClear != VK_NULL_HANDLE) {
|
||||
vkDestroyRenderPass(m_device, m_renderPassClear, nullptr);
|
||||
m_renderPassClear = VK_NULL_HANDLE;
|
||||
@@ -959,6 +1173,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
ShutdownSwapchain();
|
||||
|
||||
CreateSwapchain();
|
||||
CreateDepthStencilResources();
|
||||
CreateDefaultRenderPass();
|
||||
CreateDefaultFramebuffers();
|
||||
if (m_frameContext.GetFrameCount() > 0) {
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
|
||||
void RequestClear(GLbitfield mask, const FloatVec4& color);
|
||||
void RequestClear(GLbitfield mask, const FloatVec4& color, Float depth, Uint32 stencil);
|
||||
Bool ConsumePendingColorClear(VkClearColorValue& outClearColor);
|
||||
void EnsureFrameRecordingStarted();
|
||||
void Render();
|
||||
@@ -76,14 +76,21 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
VkRenderPass m_renderPassLoad = VK_NULL_HANDLE;
|
||||
VkRenderPass m_renderPassClear = VK_NULL_HANDLE;
|
||||
Vector<VkFramebuffer> m_framebuffers;
|
||||
VkFormat m_depthStencilFormat = VK_FORMAT_UNDEFINED;
|
||||
Vector<VkImage> m_depthStencilImages;
|
||||
Vector<VkDeviceMemory> m_depthStencilImageMemories;
|
||||
Vector<VkImageView> m_depthStencilImageViews;
|
||||
Vector<VkImageLayout> m_depthStencilImageLayouts;
|
||||
|
||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||
|
||||
Uint m_imageIndexAcquired = 0;
|
||||
FrameContext m_frameContext;
|
||||
Bool m_pendingColorClear = false;
|
||||
GLbitfield m_pendingClearMask = 0;
|
||||
VkClearColorValue m_pendingClearColor = {{0.0f, 0.0f, 0.0f, 1.0f}};
|
||||
Float m_pendingClearDepth = 1.0f;
|
||||
Uint32 m_pendingClearStencil = 0;
|
||||
Bool m_isMainRenderPassActive = false;
|
||||
|
||||
UniquePtr<ProgramFactory> m_programFactory;
|
||||
@@ -98,12 +105,16 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void CreateSwapchain();
|
||||
void CreateCommandPool();
|
||||
void CreateFrameContexts();
|
||||
void CreateDepthStencilResources();
|
||||
void DestroyDepthStencilResources();
|
||||
void CreateDefaultRenderPass();
|
||||
VkRenderPass CreateDefaultRenderPass(VkAttachmentLoadOp loadOp);
|
||||
void CreateDefaultFramebuffers();
|
||||
void PrepareDemoPipeline();
|
||||
void TransitionSwapchainImageToColorAttachment(VkCommandBuffer commandBuffer, Uint32 imageIndex);
|
||||
void TransitionDepthStencilImageToAttachment(VkCommandBuffer commandBuffer, Uint32 imageIndex);
|
||||
void RecordColorClear(VkCommandBuffer commandBuffer, const VkClearColorValue& clearColor);
|
||||
void RecordDepthStencilClear(VkCommandBuffer commandBuffer, GLbitfield mask, Float depth, Uint32 stencil);
|
||||
void EndFrameRecordingIfNeeded();
|
||||
|
||||
void ShutdownSwapchain();
|
||||
@@ -116,6 +127,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
static Vector<VkExtensionProperties> EnumerateInstanceExtensions();
|
||||
static Bool IsNecessaryDeviceExtensionSupported(VkPhysicalDevice device);
|
||||
static Bool GetMoreCapablePhysicalDevice(VkPhysicalDevice newVkDevice, VkSurfaceKHR surface, const PhysicalDevice& compareWithDevice, PhysicalDevice& outBetterDevice);
|
||||
Uint32 FindMemoryType(Uint32 typeFilter, VkMemoryPropertyFlags properties) const;
|
||||
static Bool HasStencilComponent(VkFormat format);
|
||||
static VkFormat FindSupportedDepthStencilFormat(VkPhysicalDevice physicalDevice);
|
||||
static constexpr VkDynamicState s_dynamicStates[] = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR
|
||||
|
||||
@@ -86,6 +86,7 @@ int main() {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
MobileGL::MG_Backend::DirectVulkan::pVulkanRenderer->Render();
|
||||
eglSwapBuffers(display, surface);
|
||||
++i;
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
|
||||
Reference in New Issue
Block a user