Initial work on render queue manager

This commit is contained in:
Henrik Rydgård 2017-08-16 23:03:30 +02:00
parent a33daa4985
commit 84ed793adf
6 changed files with 210 additions and 1 deletions

View File

@ -249,6 +249,7 @@
<ClInclude Include="Vulkan\VulkanImage.h" />
<ClInclude Include="Vulkan\VulkanLoader.h" />
<ClInclude Include="Vulkan\VulkanMemory.h" />
<ClInclude Include="Vulkan\VulkanRenderManager.h" />
<ClInclude Include="x64Analyzer.h" />
<ClInclude Include="x64Emitter.h" />
</ItemGroup>
@ -320,6 +321,7 @@
<ClCompile Include="Vulkan\VulkanImage.cpp" />
<ClCompile Include="Vulkan\VulkanLoader.cpp" />
<ClCompile Include="Vulkan\VulkanMemory.cpp" />
<ClCompile Include="Vulkan\VulkanRenderManager.cpp" />
<ClCompile Include="x64Analyzer.cpp" />
<ClCompile Include="x64Emitter.cpp" />
</ItemGroup>

View File

@ -75,6 +75,7 @@
</ClInclude>
<ClInclude Include="OSVersion.h" />
<ClInclude Include="Hashmaps.h" />
<ClInclude Include="Vulkan\VulkanRenderManager.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />
@ -138,6 +139,7 @@
<ClCompile Include="MemArenaAndroid.cpp" />
<ClCompile Include="MemArenaDarwin.cpp" />
<ClCompile Include="OSVersion.cpp" />
<ClCompile Include="Vulkan\VulkanRenderManager.cpp" />
</ItemGroup>
<ItemGroup>
<Filter Include="Crypto">
@ -153,4 +155,4 @@
<UniqueIdentifier>{c14d66ef-5f7c-4565-975a-72774e7ccfb9}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
</Project>

View File

@ -0,0 +1,67 @@
#include "VulkanRenderManager.h"
void VulkanRenderManager::Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask) {
// If this is the first drawing command, merge it into the pass.
if (curRp_->numDraws == 0) {
curRp_->clearColor = clearColor;
curRp_->clearZ = clearZ;
curRp_->clearStencil = clearStencil;
curRp_->clearMask = clearMask;
} else {
VkRenderData data{ VKR_CLEAR };
data.clear.clearColor = clearColor;
data.clear.clearZ = clearZ;
data.clear.clearStencil = clearStencil;
data.clear.clearMask = clearMask;
curRp_->commands.push_back(data);
}
}
void VulkanRenderManager::Flush(VkCommandBuffer cmdbuf) {
// Optimizes renderpasses, then sequences them.
for (int i = 0; i < renderPasses_.size(); i++) {
auto &commands = renderPasses_[i]->commands;
for (const auto &c : commands) {
switch (c.cmd) {
case VKR_VIEWPORT:
vkCmdSetViewport(cmdbuf, 0, 1, &c.viewport.vp);
break;
case VKR_SCISSOR:
vkCmdSetScissor(cmdbuf, 0, 1, &c.scissor.scissor);
break;
case VKR_DRAW_INDEXED:
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, c.drawIndexed.pipelineLayout, 0, 1, &c.drawIndexed.ds, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
vkCmdBindIndexBuffer(cmdbuf, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, VK_INDEX_TYPE_UINT16);
vkCmdBindVertexBuffers(cmdbuf, 0, 1, &c.drawIndexed.vbuffer, &c.drawIndexed.voffset);
vkCmdDrawIndexed(cmdbuf, c.drawIndexed.count, c.drawIndexed.instances, 0, 0, 0);
break;
case VKR_DRAW:
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, c.drawIndexed.pipelineLayout, 0, 1, &c.draw.ds, c.draw.numUboOffsets, c.draw.uboOffsets);
vkCmdBindVertexBuffers(cmdbuf, 0, 1, &c.drawIndexed.vbuffer, &c.drawIndexed.voffset);
vkCmdDraw(cmdbuf, c.drawIndexed.count, c.drawIndexed.instances, 0, 0);
break;
case VKR_STENCIL:
vkCmdSetStencilWriteMask(cmdbuf, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilWriteMask);
vkCmdSetStencilCompareMask(cmdbuf, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilCompareMask);
vkCmdSetStencilReference(cmdbuf, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilRef);
break;
case VKR_BLEND:
vkCmdSetBlendConstants(cmdbuf, c.blendColor.color);
break;
case VKR_CLEAR:
// vkCmdClearAttachments
break;
}
}
}
}
void VulkanRenderManager::Sync(VkCommandBuffer cmd) {
}

View File

@ -0,0 +1,131 @@
#pragma once
#include <cstdint>
#include "Common/Vulkan/VulkanContext.h"
#include "thin3d/thin3d.h"
// Takes the role that a GL driver does of sequencing and optimizing render passes.
// Only draws and binds are handled here, resource creation and allocations are handled as normal.
enum VkRenderCmd : uint8_t {
VKR_STENCIL,
VKR_BLEND,
VKR_VIEWPORT,
VKR_SCISSOR,
VKR_CLEAR,
VKR_DRAW,
VKR_DRAW_INDEXED,
};
struct VkRenderData {
VkRenderCmd cmd;
union {
struct {
VkPipeline pipeline;
VkPipelineLayout pipelineLayout;
VkDescriptorSet ds;
int numUboOffsets;
uint32_t uboOffsets[3];
VkBuffer vbuffer;
int offset;
int count;
} draw;
struct {
VkPipeline pipeline;
VkPipelineLayout pipelineLayout;
VkDescriptorSet ds;
int numUboOffsets;
uint32_t uboOffsets[3];
VkBuffer vbuffer; // might need to increase at some point
VkDeviceSize voffset;
VkBuffer ibuffer;
VkDeviceSize ioffset;
int16_t count;
int16_t instances;
} drawIndexed;
struct {
uint32_t clearColor;
float clearZ;
int clearStencil;
int clearMask; // VK_IMAGE_ASPECT_COLOR_BIT etc
} clear;
struct {
VkViewport vp;
} viewport;
struct {
VkRect2D scissor;
} scissor;
struct {
uint8_t stencilWriteMask;
uint8_t stencilCompareMask;
uint8_t stencilRef;
} stencil;
struct {
float color[4];
} blendColor;
struct {
} beginRp;
struct {
} endRp;
};
};
struct VKRRenderPass {
VkFramebuffer framebuffer;
uint32_t clearColor;
float clearZ;
int clearStencil;
int clearMask = 0; // VK_IMAGE_ASPECT_COLOR_BIT etc
int dontCareMask = 0;
int numDraws;
std::vector<VkRenderData> commands;
};
class VulkanRenderManager {
public:
void SetViewport(VkViewport vp) {
VkRenderData data{ VKR_VIEWPORT };
data.viewport.vp = vp;
curRp_->commands.push_back(data);
}
void SetScissor(VkRect2D rc) {
VkRenderData data{ VKR_SCISSOR };
data.scissor.scissor = rc;
curRp_->commands.push_back(data);
}
void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask);
void Draw(VkPipeline pipeline, VkBuffer vbuffer, int offset, int count) {
VkRenderData data{ VKR_DRAW };
data.draw.vbuffer = vbuffer;
data.draw.offset = offset;
curRp_->commands.push_back(data);
curRp_->numDraws++;
}
void DrawIndexed(VkPipeline pipeline, VkPipelineLayout layout, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count) {
VkRenderData data{ VKR_DRAW };
data.drawIndexed.pipeline = pipeline;
data.drawIndexed.vbuffer = vbuffer;
data.drawIndexed.voffset = voffset;
data.drawIndexed.ibuffer = ibuffer;
data.drawIndexed.ioffset = ioffset;
curRp_->commands.push_back(data);
curRp_->numDraws++;
}
void Flush(VkCommandBuffer cmd);
// Bad for performance but sometimes necessary for synchonous CPU readbacks (screenshots and whatnot).
void Sync(VkCommandBuffer cmd);
std::vector<VKRRenderPass *> renderPasses_;
VKRRenderPass *curRp_;
};

View File

@ -325,6 +325,7 @@ enum class NativeObject {
CURRENT_RENDERPASS,
RENDERPASS_COMMANDBUFFER,
BOUND_TEXTURE_IMAGEVIEW,
RENDER_MANAGER,
};
enum FBColorDepth {

View File

@ -34,6 +34,7 @@
#include "Common/Vulkan/VulkanContext.h"
#include "Common/Vulkan/VulkanImage.h"
#include "Common/Vulkan/VulkanMemory.h"
#include "Common/Vulkan/VulkanRenderManager.h"
// We use a simple descriptor set for all rendering: 1 sampler, 1 texture, 1 UBO binding point.
// binding 0 - uniform data
@ -472,6 +473,9 @@ public:
return (uintptr_t)cmd_;
case NativeObject::BOUND_TEXTURE_IMAGEVIEW:
return (uintptr_t)boundImageView_[0];
case NativeObject::RENDER_MANAGER:
return renderManager_;
default:
return 0;
}
@ -491,6 +495,8 @@ private:
VulkanContext *vulkan_ = nullptr;
VulkanRenderManager renderManager_;
VKPipeline *curPipeline_ = nullptr;
VKBuffer *curVBuffers_[4]{};
int curVBufferOffsets_[4]{};