diff options
| author | Pierre Bourdon <delroth@gmail.com> | 2018-12-04 08:47:46 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-04 08:47:46 +0100 |
| commit | 59de8ea50338b39f604fde738229aaeb791cc459 (patch) | |
| tree | 17f445fc7a686cd28859e6c46fb1a32d64a56123 /Source/Core/VideoCommon | |
| parent | c675ef148e6872115bd46cca5b5c51826c75b373 (diff) | |
| parent | 7afd5cc2fb7e45f2c497e5aed007a017b8461335 (diff) | |
Merge pull request #7592 from stenzek/imgui-prereq
VideoBackends: Share GX vertex/index/uniform buffers with utility draws
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/IndexGenerator.cpp | 8 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/IndexGenerator.h | 2 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/RenderBase.cpp | 16 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/RenderBase.h | 23 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexManagerBase.cpp | 58 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexManagerBase.h | 28 |
6 files changed, 104 insertions, 31 deletions
diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp index 6cb49aceba..5e45cc6a5f 100644 --- a/Source/Core/VideoCommon/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/IndexGenerator.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include <cstddef> +#include <cstring> #include "Common/CommonTypes.h" #include "Common/Compiler.h" @@ -56,6 +57,13 @@ void IndexGenerator::AddIndices(int primitive, u32 numVerts) base_index += numVerts; } +void IndexGenerator::AddExternalIndices(const u16* indices, u32 num_indices, u32 num_vertices) +{ + std::memcpy(index_buffer_current, indices, sizeof(u16) * num_indices); + index_buffer_current += num_indices; + base_index += num_vertices; +} + // Triangles template <bool pr> DOLPHIN_FORCE_INLINE u16* IndexGenerator::WriteTriangle(u16* Iptr, u32 index1, u32 index2, diff --git a/Source/Core/VideoCommon/IndexGenerator.h b/Source/Core/VideoCommon/IndexGenerator.h index 8d2a5e8700..67f16b66c1 100644 --- a/Source/Core/VideoCommon/IndexGenerator.h +++ b/Source/Core/VideoCommon/IndexGenerator.h @@ -18,6 +18,8 @@ public: static void AddIndices(int primitive, u32 numVertices); + static void AddExternalIndices(const u16* indices, u32 num_indices, u32 num_vertices); + // returns numprimitives static u32 GetNumVerts() { return base_index; } static u32 GetIndexLen() { return (u32)(index_buffer_current - BASEIptr); } diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 2e42ed984a..ba60e1636c 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -78,8 +78,10 @@ static float AspectToWidescreen(float aspect) return aspect * ((16.0f / 9.0f) / (4.0f / 3.0f)); } -Renderer::Renderer(int backbuffer_width, int backbuffer_height) - : m_backbuffer_width(backbuffer_width), m_backbuffer_height(backbuffer_height) +Renderer::Renderer(int backbuffer_width, int backbuffer_height, + AbstractTextureFormat backbuffer_format) + : m_backbuffer_width(backbuffer_width), m_backbuffer_height(backbuffer_height), + m_backbuffer_format(backbuffer_format) { UpdateActiveConfig(); UpdateDrawRectangle(); @@ -93,6 +95,11 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height) Renderer::~Renderer() = default; +bool Renderer::Initialize() +{ + return true; +} + void Renderer::Shutdown() { // First stop any framedumping, which might need to dump the last xfb frame. This process @@ -697,6 +704,11 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const m_last_xfb_region = xfb_rect; + // Since we use the common pipelines here and draw vertices if a batch is currently being + // built by the vertex loader, we end up trampling over its pointer, as we share the buffer + // with the loader, and it has not been unmapped yet. Force a pipeline flush to avoid this. + g_vertex_manager->Flush(); + // TODO: merge more generic parts into VideoCommon { std::lock_guard<std::mutex> guard(m_swap_mutex); diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index d5dd761c40..bea1f5ba0a 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -32,6 +32,7 @@ #include "VideoCommon/BPMemory.h" #include "VideoCommon/FPSCounter.h" #include "VideoCommon/RenderState.h" +#include "VideoCommon/TextureConfig.h" #include "VideoCommon/VideoCommon.h" class AbstractFramebuffer; @@ -72,13 +73,16 @@ enum class OSDMessage : s32 class Renderer { public: - Renderer(int backbuffer_width, int backbuffer_height); + Renderer(int backbuffer_width, int backbuffer_height, AbstractTextureFormat backbuffer_format); virtual ~Renderer(); using ClearColor = std::array<float, 4>; virtual bool IsHeadless() const = 0; + virtual bool Initialize(); + virtual void Shutdown(); + virtual void SetPipeline(const AbstractPipeline* pipeline) {} virtual void SetScissorRect(const MathUtil::Rectangle<int>& rc) {} virtual void SetTexture(u32 index, const AbstractTexture* texture) {} @@ -110,6 +114,10 @@ public: { } + // Drawing with currently-bound pipeline state. + virtual void Draw(u32 base_vertex, u32 num_vertices) {} + virtual void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) {} + // Shader modules/objects. virtual std::unique_ptr<AbstractShader> CreateShaderFromSource(ShaderStage stage, const char* source, size_t length) = 0; @@ -188,18 +196,6 @@ public: virtual std::unique_ptr<VideoCommon::AsyncShaderCompiler> CreateAsyncShaderCompiler(); - virtual void Shutdown(); - - // Drawing utility shaders. - virtual void DrawUtilityPipeline(const void* uniforms, u32 uniforms_size, const void* vertices, - u32 vertex_stride, u32 num_vertices) - { - } - virtual void DispatchComputeShader(const AbstractShader* shader, const void* uniforms, - u32 uniforms_size, u32 groups_x, u32 groups_y, u32 groups_z) - { - } - void ShowOSDMessage(OSDMessage message); protected: @@ -229,6 +225,7 @@ protected: // Backbuffer (window) size and render area int m_backbuffer_width = 0; int m_backbuffer_height = 0; + AbstractTextureFormat m_backbuffer_format = AbstractTextureFormat::Undefined; TargetRectangle m_target_rectangle = {}; FPSCounter m_fps_counter; diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 8364b039c5..0e178e4d9b 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -27,6 +27,7 @@ #include "VideoCommon/PixelShaderManager.h" #include "VideoCommon/RenderBase.h" #include "VideoCommon/SamplerCommon.h" +#include "VideoCommon/Statistics.h" #include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexShaderManager.h" @@ -131,7 +132,7 @@ DataReader VertexManagerBase::PrepareForAdditionalData(int primitive, u32 count, // need to alloc new buffer if (m_is_flushed) { - g_vertex_manager->ResetBuffer(stride); + g_vertex_manager->ResetBuffer(stride, cullall); m_is_flushed = false; } @@ -209,6 +210,28 @@ std::pair<size_t, size_t> VertexManagerBase::ResetFlushAspectRatioCount() return val; } +void VertexManagerBase::UploadUtilityVertices(const void* vertices, u32 vertex_stride, + u32 num_vertices, const u16* indices, u32 num_indices, + u32* out_base_vertex, u32* out_base_index) +{ + // The GX vertex list should be flushed before any utility draws occur. + ASSERT(m_is_flushed); + + // Copy into the buffers usually used for GX drawing. + ResetBuffer(std::max(vertex_stride, 1u), false); + if (vertices) + { + const u32 copy_size = vertex_stride * num_vertices; + ASSERT((m_cur_buffer_pointer + copy_size) <= m_end_buffer_pointer); + std::memcpy(m_cur_buffer_pointer, vertices, copy_size); + m_cur_buffer_pointer += copy_size; + } + if (indices) + IndexGenerator::AddExternalIndices(indices, num_indices, num_vertices); + + CommitBuffer(num_vertices, vertex_stride, num_indices, out_base_vertex, out_base_index); +} + static void SetSamplerState(u32 index, float custom_tex_scale, bool custom_tex, bool has_arbitrary_mips) { @@ -384,19 +407,35 @@ void VertexManagerBase::Flush() if (!m_cull_all) { + // Update and upload constants. Note for the Vulkan backend, this must occur before the + // vertex/index buffer is committed, otherwise the data will be associated with the + // previous command buffer, instead of the one with the draw if there is an overflow. + GeometryShaderManager::SetConstants(); + PixelShaderManager::SetConstants(); + UploadConstants(); + + // Now the vertices can be flushed to the GPU. + const u32 num_indices = IndexGenerator::GetIndexLen(); + u32 base_vertex, base_index; + CommitBuffer(IndexGenerator::GetNumVerts(), + VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(), num_indices, + &base_vertex, &base_index); + // Update the pipeline, or compile one if needed. UpdatePipelineConfig(); UpdatePipelineObject(); + if (m_current_pipeline_object) + { + g_renderer->SetPipeline(m_current_pipeline_object); + if (PerfQueryBase::ShouldEmulate()) + g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - // set the rest of the global constants - GeometryShaderManager::SetConstants(); - PixelShaderManager::SetConstants(); + DrawCurrentBatch(base_index, num_indices, base_vertex); + INCSTAT(stats.thisFrame.numDrawCalls); - if (PerfQueryBase::ShouldEmulate()) - g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - g_vertex_manager->vFlush(); - if (PerfQueryBase::ShouldEmulate()) - g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + if (PerfQueryBase::ShouldEmulate()) + g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + } } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); @@ -413,7 +452,6 @@ void VertexManagerBase::Flush() void VertexManagerBase::DoState(PointerWrap& p) { p.Do(m_zslope); - g_vertex_manager->vDoState(p); } void VertexManagerBase::CalculateZSlope(NativeVertexFormat* format) diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h index 88d9d9fbe0..cd3e4ed552 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.h +++ b/Source/Core/VideoCommon/VertexManagerBase.h @@ -69,9 +69,29 @@ public: m_pipeline_config_changed = true; } + // Utility pipeline drawing (e.g. EFB copies, post-processing, UI). + virtual void UploadUtilityUniforms(const void* uniforms, u32 uniforms_size) = 0; + void UploadUtilityVertices(const void* vertices, u32 vertex_stride, u32 num_vertices, + const u16* indices, u32 num_indices, u32* out_base_vertex, + u32* out_base_index); + protected: - virtual void vDoState(PointerWrap& p) {} - virtual void ResetBuffer(u32 stride) = 0; + // Vertex buffers/index buffer creation. + virtual void CreateDeviceObjects() {} + virtual void DestroyDeviceObjects() {} + + // Prepares the buffer for the next batch of vertices. + virtual void ResetBuffer(u32 vertex_stride, bool cull_all) = 0; + + // Commits/uploads the current batch of vertices. + virtual void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, + u32* out_base_vertex, u32* out_base_index) = 0; + + // Uploads uniform buffers for GX draws. + virtual void UploadConstants() = 0; + + // Issues the draw call for the current batch in the backend. + virtual void DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex) = 0; u8* m_cur_buffer_pointer = nullptr; u8* m_base_buffer_pointer = nullptr; @@ -98,10 +118,6 @@ private: size_t m_flush_count_4_3 = 0; size_t m_flush_count_anamorphic = 0; - virtual void vFlush() = 0; - - virtual void CreateDeviceObjects() {} - virtual void DestroyDeviceObjects() {} void UpdatePipelineConfig(); void UpdatePipelineObject(); }; |
