1 #pragma once 2 3 #include <memory> 4 #include "GSH_VulkanContext.h" 5 #include "GSH_VulkanFrameCommandBuffer.h" 6 #include "GSH_VulkanPipelineCache.h" 7 #include "vulkan/ShaderModule.h" 8 #include "vulkan/Buffer.h" 9 #include "vulkan/Image.h" 10 #include "Convertible.h" 11 12 namespace GSH_Vulkan 13 { 14 class CDraw : public IFrameCommandBufferWriter 15 { 16 public: 17 enum 18 { 19 MAX_FRAMES = CFrameCommandBuffer::MAX_FRAMES, 20 }; 21 22 typedef uint64 PipelineCapsInt; 23 24 enum PIPELINE_PRIMITIVE_TYPE 25 { 26 PIPELINE_PRIMITIVE_TRIANGLE = 0, 27 PIPELINE_PRIMITIVE_LINE = 1, 28 }; 29 30 struct PIPELINE_CAPS : public convertible<PipelineCapsInt> 31 { 32 uint32 primitiveType : 2; 33 34 uint32 hasTexture : 1; 35 uint32 textureHasAlpha : 1; 36 uint32 textureBlackIsTransparent : 1; 37 uint32 textureFunction : 2; 38 uint32 textureUseLinearFiltering : 1; 39 uint32 texClampU : 2; 40 uint32 texClampV : 2; 41 42 uint32 hasFog : 1; 43 44 uint32 maskColor : 1; 45 uint32 writeDepth : 1; 46 47 uint32 hasAlphaBlending : 1; 48 uint32 alphaA : 2; 49 uint32 alphaB : 2; 50 uint32 alphaC : 2; 51 uint32 alphaD : 2; 52 53 uint32 depthTestFunction : 2; 54 uint32 alphaTestFunction : 3; 55 uint32 alphaTestFailAction : 2; 56 57 uint32 hasDstAlphaTest : 1; 58 uint32 dstAlphaTestRef : 1; 59 60 uint32 textureFormat : 6; 61 uint32 clutFormat : 6; 62 uint32 framebufferFormat : 6; 63 uint32 depthbufferFormat : 6; 64 }; 65 static_assert(sizeof(PIPELINE_CAPS) <= sizeof(PipelineCapsInt), "PIPELINE_CAPS too big for PipelineCapsInt"); 66 67 struct PRIM_VERTEX 68 { 69 float x, y; 70 uint32 z; 71 uint32 color; 72 float s, t, q; 73 float f; 74 }; 75 76 CDraw(const ContextPtr&, const FrameCommandBufferPtr&); 77 virtual ~CDraw(); 78 79 void SetPipelineCaps(const PIPELINE_CAPS&); 80 void SetFramebufferParams(uint32, uint32, uint32); 81 void SetDepthbufferParams(uint32, uint32); 82 void SetTextureParams(uint32, uint32, uint32, uint32, uint32); 83 void SetClutBufferOffset(uint32); 84 void SetTextureAlphaParams(uint32, uint32); 85 void SetTextureClampParams(uint32, uint32, uint32, uint32); 86 void SetFogParams(float, float, float); 87 void SetAlphaBlendingParams(uint32); 88 void SetAlphaTestParams(uint32); 89 void SetScissor(uint32, uint32, uint32, uint32); 90 91 void AddVertices(const PRIM_VERTEX*, const PRIM_VERTEX*); 92 void FlushVertices(); 93 void FlushRenderPass(); 94 95 void PreFlushFrameCommandBuffer() override; 96 void PostFlushFrameCommandBuffer() override; 97 98 private: 99 struct FRAMECONTEXT 100 { 101 Framework::Vulkan::CBuffer vertexBuffer; 102 PRIM_VERTEX* vertexBufferPtr = nullptr; 103 }; 104 105 typedef uint32 DescriptorSetCapsInt; 106 107 struct DESCRIPTORSET_CAPS : public convertible<DescriptorSetCapsInt> 108 { 109 uint32 hasTexture : 1; 110 uint32 textureFormat : 6; 111 uint32 framebufferFormat : 6; 112 uint32 depthbufferFormat : 6; 113 }; 114 static_assert(sizeof(DESCRIPTORSET_CAPS) == sizeof(DescriptorSetCapsInt)); 115 typedef std::unordered_map<DescriptorSetCapsInt, VkDescriptorSet> DescriptorSetCache; 116 117 typedef CPipelineCache<PipelineCapsInt> PipelineCache; 118 119 struct DRAW_PIPELINE_PUSHCONSTANTS 120 { 121 //fbDepthParams 122 uint32 fbBufAddr = 0; 123 uint32 fbBufWidth = 0; 124 uint32 depthBufAddr = 0; 125 uint32 depthBufWidth = 0; 126 127 //texParams0 128 uint32 texBufAddr = 0; 129 uint32 texBufWidth = 0; 130 uint32 texWidth = 0; 131 uint32 texHeight = 0; 132 133 //texParams1 134 uint32 texCsa = 0; 135 uint32 texA0 = 0; 136 uint32 texA1 = 0; 137 uint32 texParams1Reserved = 0; 138 139 //texParams2 140 uint32 clampMin[2]; 141 uint32 clampMax[2]; 142 143 //alphaFbParams 144 uint32 fbWriteMask = 0; 145 uint32 alphaFix = 0; 146 uint32 alphaRef = 0; 147 uint32 alphaFbParamsReserved = 0; 148 149 //fogColor 150 float fogColor[4]; 151 }; 152 static_assert(sizeof(DRAW_PIPELINE_PUSHCONSTANTS) <= 128, "Push constants size can't exceed 128 bytes."); 153 154 VkDescriptorSet PrepareDescriptorSet(VkDescriptorSetLayout, const DESCRIPTORSET_CAPS&); 155 156 void CreateFramebuffer(); 157 void CreateRenderPass(); 158 void CreateDrawImage(); 159 160 PIPELINE CreateDrawPipeline(const PIPELINE_CAPS&); 161 Framework::Vulkan::CShaderModule CreateVertexShader(); 162 Framework::Vulkan::CShaderModule CreateFragmentShader(const PIPELINE_CAPS&); 163 164 ContextPtr m_context; 165 FrameCommandBufferPtr m_frameCommandBuffer; 166 PipelineCache m_pipelineCache; 167 DescriptorSetCache m_descriptorSetCache; 168 169 VkRenderPass m_renderPass = VK_NULL_HANDLE; 170 VkFramebuffer m_framebuffer = VK_NULL_HANDLE; 171 172 FRAMECONTEXT m_frames[MAX_FRAMES]; 173 174 Framework::Vulkan::CImage m_drawImage; 175 VkImageView m_drawImageView = VK_NULL_HANDLE; 176 177 uint32 m_passVertexStart = 0; 178 uint32 m_passVertexEnd = 0; 179 bool m_renderPassBegun = false; 180 181 PIPELINE_CAPS m_pipelineCaps; 182 DRAW_PIPELINE_PUSHCONSTANTS m_pushConstants; 183 uint32 m_scissorX = 0; 184 uint32 m_scissorY = 0; 185 uint32 m_scissorWidth = 0; 186 uint32 m_scissorHeight = 0; 187 uint32 m_clutBufferOffset = 0; 188 }; 189 190 typedef std::shared_ptr<CDraw> DrawPtr; 191 } 192