| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | // Copyright 2016 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2+
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 23:07:50 -04:00
										 |  |  | #include <array>
 | 
					
						
							|  |  |  | #include <cstddef>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | #include "VideoBackends/Vulkan/Constants.h"
 | 
					
						
							|  |  |  | #include "VideoBackends/Vulkan/ObjectCache.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-20 15:25:33 +10:00
										 |  |  | #include "VideoBackends/Vulkan/ShaderCache.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-17 23:14:17 +10:00
										 |  |  | #include "VideoCommon/RenderState.h"
 | 
					
						
							| 
									
										
										
										
											2017-06-12 12:37:28 -05:00
										 |  |  | #include "VideoCommon/TextureConfig.h"
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Vulkan | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | class CommandBufferManager; | 
					
						
							|  |  |  | class StateTracker; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Util | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | size_t AlignBufferOffset(size_t offset, size_t alignment); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u32 MakeRGBA8Color(float r, float g, float b, float a); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool IsDepthFormat(VkFormat format); | 
					
						
							| 
									
										
										
										
											2017-04-16 22:23:33 +10:00
										 |  |  | bool IsCompressedFormat(VkFormat format); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | VkFormat GetLinearFormat(VkFormat format); | 
					
						
							| 
									
										
										
										
											2017-06-12 12:37:28 -05:00
										 |  |  | VkFormat GetVkFormatForHostTextureFormat(AbstractTextureFormat format); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | u32 GetTexelSize(VkFormat format); | 
					
						
							| 
									
										
										
										
											2017-04-16 22:23:33 +10:00
										 |  |  | u32 GetBlockSize(VkFormat format); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-15 19:55:32 +10:00
										 |  |  | // Clamps a VkRect2D to the specified dimensions.
 | 
					
						
							|  |  |  | VkRect2D ClampRect2D(const VkRect2D& rect, u32 width, u32 height); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | // Map {SRC,DST}_COLOR to {SRC,DST}_ALPHA
 | 
					
						
							|  |  |  | VkBlendFactor GetAlphaBlendFactor(VkBlendFactor factor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RasterizationState GetNoCullRasterizationState(); | 
					
						
							| 
									
										
										
										
											2017-04-30 15:54:45 +10:00
										 |  |  | DepthState GetNoDepthTestingDepthStencilState(); | 
					
						
							| 
									
										
										
										
											2017-04-17 23:14:17 +10:00
										 |  |  | BlendingState GetNoBlendingBlendState(); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Combines viewport and scissor updates
 | 
					
						
							|  |  |  | void SetViewportAndScissor(VkCommandBuffer command_buffer, int x, int y, int width, int height, | 
					
						
							|  |  |  |                            float min_depth = 0.0f, float max_depth = 1.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Wrapper for creating an barrier on a buffer
 | 
					
						
							|  |  |  | void BufferMemoryBarrier(VkCommandBuffer command_buffer, VkBuffer buffer, | 
					
						
							|  |  |  |                          VkAccessFlags src_access_mask, VkAccessFlags dst_access_mask, | 
					
						
							|  |  |  |                          VkDeviceSize offset, VkDeviceSize size, | 
					
						
							|  |  |  |                          VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Completes the current render pass, executes the command buffer, and restores state ready for next
 | 
					
						
							|  |  |  | // render. Use when you want to kick the current buffer to make room for new data.
 | 
					
						
							| 
									
										
										
										
											2016-10-22 20:50:36 +10:00
										 |  |  | void ExecuteCurrentCommandsAndRestoreState(bool execute_off_thread, | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |                                            bool wait_for_completion = false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Create a shader module from the specified SPIR-V.
 | 
					
						
							|  |  |  | VkShaderModule CreateShaderModule(const u32* spv, size_t spv_word_count); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Compile a vertex shader and create a shader module, discarding the intermediate SPIR-V.
 | 
					
						
							| 
									
										
										
										
											2017-09-03 15:30:52 +10:00
										 |  |  | VkShaderModule CompileAndCreateVertexShader(const std::string& source_code, | 
					
						
							|  |  |  |                                             bool prepend_header = true); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Compile a geometry shader and create a shader module, discarding the intermediate SPIR-V.
 | 
					
						
							| 
									
										
										
										
											2017-09-03 15:30:52 +10:00
										 |  |  | VkShaderModule CompileAndCreateGeometryShader(const std::string& source_code, | 
					
						
							|  |  |  |                                               bool prepend_header = true); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Compile a fragment shader and create a shader module, discarding the intermediate SPIR-V.
 | 
					
						
							| 
									
										
										
										
											2017-09-03 15:30:52 +10:00
										 |  |  | VkShaderModule CompileAndCreateFragmentShader(const std::string& source_code, | 
					
						
							|  |  |  |                                               bool prepend_header = true); | 
					
						
							| 
									
										
										
										
											2016-12-09 22:23:04 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Compile a compute shader and create a shader module, discarding the intermediate SPIR-V.
 | 
					
						
							| 
									
										
										
										
											2017-09-03 15:30:52 +10:00
										 |  |  | VkShaderModule CompileAndCreateComputeShader(const std::string& source_code, | 
					
						
							|  |  |  |                                              bool prepend_header = true); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Utility shader vertex format
 | 
					
						
							|  |  |  | #pragma pack(push, 1)
 | 
					
						
							|  |  |  | struct UtilityShaderVertex | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   float Position[4]; | 
					
						
							|  |  |  |   float TexCoord[4]; | 
					
						
							|  |  |  |   u32 Color; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void SetPosition(float x, float y) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     Position[0] = x; | 
					
						
							|  |  |  |     Position[1] = y; | 
					
						
							|  |  |  |     Position[2] = 0.0f; | 
					
						
							|  |  |  |     Position[3] = 1.0f; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   void SetPosition(float x, float y, float z) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     Position[0] = x; | 
					
						
							|  |  |  |     Position[1] = y; | 
					
						
							|  |  |  |     Position[2] = z; | 
					
						
							|  |  |  |     Position[3] = 1.0f; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   void SetTextureCoordinates(float u, float v) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     TexCoord[0] = u; | 
					
						
							|  |  |  |     TexCoord[1] = v; | 
					
						
							|  |  |  |     TexCoord[2] = 0.0f; | 
					
						
							|  |  |  |     TexCoord[3] = 0.0f; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   void SetTextureCoordinates(float u, float v, float w) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     TexCoord[0] = u; | 
					
						
							|  |  |  |     TexCoord[1] = v; | 
					
						
							|  |  |  |     TexCoord[2] = w; | 
					
						
							|  |  |  |     TexCoord[3] = 0.0f; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   void SetTextureCoordinates(float u, float v, float w, float x) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     TexCoord[0] = u; | 
					
						
							|  |  |  |     TexCoord[1] = v; | 
					
						
							|  |  |  |     TexCoord[2] = w; | 
					
						
							|  |  |  |     TexCoord[3] = x; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   void SetColor(u32 color) { Color = color; } | 
					
						
							|  |  |  |   void SetColor(float r, float g, float b) { Color = Util::MakeRGBA8Color(r, g, b, 1.0f); } | 
					
						
							|  |  |  |   void SetColor(float r, float g, float b, float a) { Color = Util::MakeRGBA8Color(r, g, b, a); } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | #pragma pack(pop)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class UtilityShaderDraw | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   UtilityShaderDraw(VkCommandBuffer command_buffer, VkPipelineLayout pipeline_layout, | 
					
						
							|  |  |  |                     VkRenderPass render_pass, VkShaderModule vertex_shader, | 
					
						
							| 
									
										
										
										
											2017-04-30 18:07:57 +10:00
										 |  |  |                     VkShaderModule geometry_shader, VkShaderModule pixel_shader, | 
					
						
							|  |  |  |                     PrimitiveType primitive = PrimitiveType::TriangleStrip); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 18:07:57 +10:00
										 |  |  |   UtilityShaderVertex* ReserveVertices(size_t count); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   void CommitVertices(size_t count); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 18:07:57 +10:00
										 |  |  |   void UploadVertices(UtilityShaderVertex* vertices, size_t count); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   u8* AllocateVSUniforms(size_t size); | 
					
						
							|  |  |  |   void CommitVSUniforms(size_t size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   u8* AllocatePSUniforms(size_t size); | 
					
						
							|  |  |  |   void CommitPSUniforms(size_t size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void SetPushConstants(const void* data, size_t data_size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void SetPSSampler(size_t index, VkImageView view, VkSampler sampler); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-20 00:02:06 +10:00
										 |  |  |   void SetPSTexelBuffer(VkBufferView view); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   void SetRasterizationState(const RasterizationState& state); | 
					
						
							| 
									
										
										
										
											2017-04-30 18:07:57 +10:00
										 |  |  |   void SetMultisamplingState(const MultisamplingState& state); | 
					
						
							| 
									
										
										
										
											2017-04-30 15:54:45 +10:00
										 |  |  |   void SetDepthState(const DepthState& state); | 
					
						
							| 
									
										
										
										
											2017-04-17 23:14:17 +10:00
										 |  |  |   void SetBlendState(const BlendingState& state); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void BeginRenderPass(VkFramebuffer framebuffer, const VkRect2D& region, | 
					
						
							|  |  |  |                        const VkClearValue* clear_value = nullptr); | 
					
						
							|  |  |  |   void EndRenderPass(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void Draw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // NOTE: These methods alter the viewport state of the command buffer.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Sets texture coordinates to 0..1
 | 
					
						
							|  |  |  |   void DrawQuad(int x, int y, int width, int height, float z = 0.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Sets texture coordinates to the specified range
 | 
					
						
							|  |  |  |   void DrawQuad(int dst_x, int dst_y, int dst_width, int dst_height, int src_x, int src_y, | 
					
						
							|  |  |  |                 int src_layer, int src_width, int src_height, int src_full_width, | 
					
						
							|  |  |  |                 int src_full_height, float z = 0.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void DrawColoredQuad(int x, int y, int width, int height, u32 color, float z = 0.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void DrawColoredQuad(int x, int y, int width, int height, float r, float g, float b, float a, | 
					
						
							|  |  |  |                        float z = 0.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw without a vertex buffer. Assumes viewport has been initialized separately.
 | 
					
						
							|  |  |  |   void SetViewportAndScissor(int x, int y, int width, int height); | 
					
						
							| 
									
										
										
										
											2017-04-30 18:07:57 +10:00
										 |  |  |   void DrawWithoutVertexBuffer(u32 vertex_count); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |   void BindVertexBuffer(); | 
					
						
							|  |  |  |   void BindDescriptors(); | 
					
						
							|  |  |  |   bool BindPipeline(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VkCommandBuffer m_command_buffer = VK_NULL_HANDLE; | 
					
						
							|  |  |  |   VkBuffer m_vertex_buffer = VK_NULL_HANDLE; | 
					
						
							|  |  |  |   VkDeviceSize m_vertex_buffer_offset = 0; | 
					
						
							|  |  |  |   uint32_t m_vertex_count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VkDescriptorBufferInfo m_vs_uniform_buffer = {}; | 
					
						
							|  |  |  |   VkDescriptorBufferInfo m_ps_uniform_buffer = {}; | 
					
						
							|  |  |  |   std::array<uint32_t, NUM_UBO_DESCRIPTOR_SET_BINDINGS> m_ubo_offsets = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::array<VkDescriptorImageInfo, NUM_PIXEL_SHADER_SAMPLERS> m_ps_samplers = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-20 00:02:06 +10:00
										 |  |  |   VkBufferView m_ps_texel_buffer = VK_NULL_HANDLE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   PipelineInfo m_pipeline_info = {}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-09 22:23:04 +10:00
										 |  |  | class ComputeShaderDispatcher | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   ComputeShaderDispatcher(VkCommandBuffer command_buffer, VkPipelineLayout pipeline_layout, | 
					
						
							|  |  |  |                           VkShaderModule compute_shader); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   u8* AllocateUniformBuffer(size_t size); | 
					
						
							|  |  |  |   void CommitUniformBuffer(size_t size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void SetPushConstants(const void* data, size_t data_size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void SetSampler(size_t index, VkImageView view, VkSampler sampler); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void SetTexelBuffer(size_t index, VkBufferView view); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void SetStorageImage(VkImageView view, VkImageLayout image_layout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void Dispatch(u32 groups_x, u32 groups_y, u32 groups_z); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |   void BindDescriptors(); | 
					
						
							|  |  |  |   bool BindPipeline(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VkCommandBuffer m_command_buffer = VK_NULL_HANDLE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VkDescriptorBufferInfo m_uniform_buffer = {}; | 
					
						
							|  |  |  |   u32 m_uniform_buffer_offset = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::array<VkDescriptorImageInfo, 4> m_samplers = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::array<VkBufferView, 2> m_texel_buffers = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VkDescriptorImageInfo m_storage_image = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ComputePipelineInfo m_pipeline_info = {}; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | }  // namespace Vulkan
 |