mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-21 06:33:22 +00:00
Initial work on render queue manager
This commit is contained in:
parent
a33daa4985
commit
84ed793adf
@ -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>
|
||||
|
@ -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>
|
||||
|
67
Common/Vulkan/VulkanRenderManager.cpp
Normal file
67
Common/Vulkan/VulkanRenderManager.cpp
Normal 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) {
|
||||
|
||||
}
|
131
Common/Vulkan/VulkanRenderManager.h
Normal file
131
Common/Vulkan/VulkanRenderManager.h
Normal 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_;
|
||||
};
|
@ -325,6 +325,7 @@ enum class NativeObject {
|
||||
CURRENT_RENDERPASS,
|
||||
RENDERPASS_COMMANDBUFFER,
|
||||
BOUND_TEXTURE_IMAGEVIEW,
|
||||
RENDER_MANAGER,
|
||||
};
|
||||
|
||||
enum FBColorDepth {
|
||||
|
@ -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]{};
|
||||
|
Loading…
x
Reference in New Issue
Block a user