Vulkan: Implement render pass commands

This commit is contained in:
Corentin Wallez 2018-01-09 09:09:09 -08:00 committed by Corentin Wallez
parent 35fcfc737b
commit eb135f6fc0
3 changed files with 65 additions and 0 deletions

View File

@ -16,6 +16,8 @@
#include "backend/Commands.h"
#include "backend/vulkan/BufferVk.h"
#include "backend/vulkan/FramebufferVk.h"
#include "backend/vulkan/RenderPassVk.h"
#include "backend/vulkan/TextureVk.h"
#include "backend/vulkan/VulkanBackend.h"
@ -67,6 +69,7 @@ namespace backend { namespace vulkan {
Command type;
while (mCommands.NextCommandId(&type)) {
switch (type) {
case Command::CopyBufferToBuffer: {
CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
auto& src = copy->source;
@ -114,6 +117,38 @@ namespace backend { namespace vulkan {
dstBuffer, 1, &region);
} break;
case Command::BeginRenderPass: {
BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
Framebuffer* framebuffer = ToBackend(cmd->framebuffer.Get());
RenderPass* renderPass = ToBackend(cmd->renderPass.Get());
ASSERT(renderPass->GetSubpassCount() == 1);
ASSERT(renderPass->GetAttachmentCount() <= kMaxColorAttachments + 1);
std::array<VkClearValue, kMaxColorAttachments + 1> clearValues;
framebuffer->FillClearValues(clearValues.data());
VkRenderPassBeginInfo beginInfo;
beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
beginInfo.pNext = nullptr;
beginInfo.renderPass = renderPass->GetHandle();
beginInfo.framebuffer = framebuffer->GetHandle();
beginInfo.renderArea.offset.x = 0;
beginInfo.renderArea.offset.y = 0;
beginInfo.renderArea.extent.width = framebuffer->GetWidth();
beginInfo.renderArea.extent.height = framebuffer->GetHeight();
beginInfo.clearValueCount = renderPass->GetAttachmentCount();
beginInfo.pClearValues = clearValues.data();
device->fn.CmdBeginRenderPass(commands, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
} break;
case Command::BeginRenderSubpass: {
mCommands.NextCommand<BeginRenderSubpassCmd>();
// Do nothing because the single subpass is started in vkBeginRenderPass
} break;
case Command::DrawArrays: {
DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>();
@ -129,6 +164,16 @@ namespace backend { namespace vulkan {
draw->firstIndex, vertexOffset, draw->firstInstance);
} break;
case Command::EndRenderPass: {
mCommands.NextCommand<EndRenderPassCmd>();
device->fn.CmdEndRenderPass(commands);
} break;
case Command::EndRenderSubpass: {
mCommands.NextCommand<EndRenderSubpassCmd>();
// Do nothing because the single subpass is ended in vkEndRenderPass
} break;
case Command::SetIndexBuffer: {
SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>();
VkBuffer indexBuffer = ToBackend(cmd->buffer)->GetHandle();

View File

@ -63,4 +63,23 @@ namespace backend { namespace vulkan {
return mHandle;
}
void Framebuffer::FillClearValues(VkClearValue* values) {
const RenderPassBase* renderPass = GetRenderPass();
for (uint32_t i = 0; i < renderPass->GetAttachmentCount(); ++i) {
if (TextureFormatHasDepthOrStencil(renderPass->GetAttachmentInfo(i).format)) {
const auto& clearValues = GetClearDepthStencil(i);
values[i].depthStencil.depth = clearValues.depth;
values[i].depthStencil.stencil = clearValues.stencil;
} else {
const auto& clearValues = GetClearColor(i);
values[i].color.float32[0] = clearValues.color[0];
values[i].color.float32[1] = clearValues.color[1];
values[i].color.float32[2] = clearValues.color[2];
values[i].color.float32[3] = clearValues.color[3];
}
}
}
}} // namespace backend::vulkan

View File

@ -27,6 +27,7 @@ namespace backend { namespace vulkan {
~Framebuffer();
VkFramebuffer GetHandle() const;
void FillClearValues(VkClearValue* values);
private:
VkFramebuffer mHandle = VK_NULL_HANDLE;