From 9f2e83b66c56e23bc14feabc6bc9070132ec50a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 26 Dec 2016 17:03:01 +0100 Subject: [PATCH] Bundle up more state in the pipeline object. Lets us get rid of Vulkan's pipeline cache. --- GPU/Software/SoftGpu.cpp | 36 ++---- UI/DevScreens.cpp | 5 +- UI/NativeApp.cpp | 32 ++++- ext/native/gfx_es2/draw_buffer.cpp | 29 ++--- ext/native/gfx_es2/draw_buffer.h | 8 +- ext/native/thin3d/thin3d.h | 49 ++++---- ext/native/thin3d/thin3d_d3d9.cpp | 80 ++++++------ ext/native/thin3d/thin3d_gl.cpp | 112 +++++++++-------- ext/native/thin3d/thin3d_vulkan.cpp | 181 +++++++--------------------- ext/native/ui/ui_context.cpp | 16 --- ext/native/ui/ui_context.h | 3 - 11 files changed, 230 insertions(+), 321 deletions(-) diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 48ae0540af..6de4355bab 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -42,10 +42,6 @@ FormatBuffer fb; FormatBuffer depthbuf; u32 clut[4096]; -static Draw::InputLayout *vformat = nullptr; -static Draw::DepthStencilState *depth = nullptr; -static Draw::RasterState *rasterNoCull = nullptr; -static Draw::BlendState *blendstateOff = nullptr; static Draw::SamplerState *samplerNearest = nullptr; static Draw::SamplerState *samplerLinear = nullptr; static Draw::Buffer *vdata = nullptr; @@ -69,25 +65,28 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *_thin3D) }; ShaderModule *vshader = thin3d->GetVshaderPreset(VS_TEXTURE_COLOR_2D); - vformat = thin3d->CreateInputLayout(desc); vdata = thin3d->CreateBuffer(24 * 4, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA); idata = thin3d->CreateBuffer(sizeof(int) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA); - depth = thin3d->CreateDepthStencilState({ false, false, Comparison::LESS }); - blendstateOff = thin3d->CreateBlendState({ false }); + + InputLayout *inputLayout = thin3d->CreateInputLayout(desc); + DepthStencilState *depth = thin3d->CreateDepthStencilState({ false, false, Comparison::LESS }); + BlendState *blendstateOff = thin3d->CreateBlendState({ false }); + RasterState *rasterNoCull = thin3d->CreateRasterState({}); + samplerNearest = thin3d->CreateSamplerState({ TextureFilter::NEAREST, TextureFilter::NEAREST, TextureFilter::NEAREST }); samplerLinear = thin3d->CreateSamplerState({ TextureFilter::LINEAR, TextureFilter::LINEAR, TextureFilter::LINEAR }); - PipelineDesc pipelineDesc; - pipelineDesc.shaders = { thin3d->GetVshaderPreset(VS_TEXTURE_COLOR_2D), thin3d->GetFshaderPreset(FS_TEXTURE_COLOR_2D) }; + PipelineDesc pipelineDesc{ + Primitive::TRIANGLE_LIST, + { thin3d->GetVshaderPreset(VS_TEXTURE_COLOR_2D), thin3d->GetFshaderPreset(FS_TEXTURE_COLOR_2D) }, + inputLayout, depth, blendstateOff, rasterNoCull + }; texColor = thin3d->CreateGraphicsPipeline(pipelineDesc); fb.data = Memory::GetPointer(0x44000000); // TODO: correct default address? depthbuf.data = Memory::GetPointer(0x44000000); // TODO: correct default address? - RasterStateDesc rasterDesc{}; - rasterNoCull = thin3d->CreateRasterState(rasterDesc); - framebufferDirty_ = true; // TODO: Is there a default? displayFramebuf_ = 0; @@ -107,8 +106,6 @@ SoftGPU::~SoftGPU() { texColor->Release(); texColor = nullptr; - vformat->Release(); - vformat = nullptr; fbTex->Release(); fbTex = nullptr; @@ -116,12 +113,6 @@ SoftGPU::~SoftGPU() { vdata = nullptr; idata->Release(); idata = nullptr; - depth->Release(); - depth = nullptr; - rasterNoCull->Release(); - rasterNoCull = nullptr; - blendstateOff->Release(); - blendstateOff = nullptr; samplerNearest->Release(); samplerNearest = nullptr; samplerLinear->Release(); @@ -147,7 +138,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { Viewport viewport = {0.0f, 0.0f, dstwidth, dstheight, 0.0f, 1.0f}; thin3d->SetViewports(1, &viewport); - thin3d->SetBlendState(blendstateOff); SamplerState *sampler; if (g_Config.iBufFilter == SCALE_NEAREST) { sampler = samplerNearest; @@ -155,8 +145,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { sampler = samplerLinear; } thin3d->BindSamplerStates(0, 1, &sampler); - thin3d->SetDepthStencilState(depth); - thin3d->SetRasterState(rasterNoCull); thin3d->SetScissorRect(0, 0, dstwidth, dstheight); float u0 = 0.0f; @@ -255,7 +243,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { texColor->SetMatrix4x4("WorldViewProj", identity4x4); thin3d->BindPipeline(texColor); - thin3d->DrawIndexed(Primitive::TRIANGLE_LIST, vformat, vdata, idata, 6, 0); + thin3d->DrawIndexed(vdata, idata, 6, 0); } void SoftGPU::CopyDisplayToOutput() diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 341676107f..af57cd4068 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -315,11 +315,10 @@ const char *GetCompilerABI() { void SystemInfoScreen::CreateViews() { using namespace Draw; - + using namespace UI; + // NOTE: Do not translate this section. It will change a lot and will be impossible to keep up. I18NCategory *di = GetI18NCategory("Dialog"); - - using namespace UI; root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); ViewGroup *leftColumn = new AnchorLayout(new LinearLayoutParams(1.0f)); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 7b0ef73202..00002c7239 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -578,9 +578,6 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) { ui_theme.popupTitle.fgColor = 0xFF59BEE3; #endif - ui_draw2d.Init(thin3d); - ui_draw2d_front.Init(thin3d); - uiTexture = thin3d->CreateTextureFromFile("ui_atlas.zim", ImageFileType::ZIM); if (!uiTexture) { PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory."); @@ -594,13 +591,38 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) { uiContext = new UIContext(); uiContext->theme = &ui_theme; - PipelineDesc colorDesc{ { thin3d->GetVshaderPreset(VS_COLOR_2D), thin3d->GetFshaderPreset(FS_COLOR_2D) } }; - PipelineDesc texColorDesc{ { thin3d->GetVshaderPreset(VS_TEXTURE_COLOR_2D), thin3d->GetFshaderPreset(FS_TEXTURE_COLOR_2D) } }; + Draw::InputLayout *inputLayout = ui_draw2d.CreateInputLayout(thin3d); + Draw::BlendState *blendNormal = thin3d->CreateBlendState({ true, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA }); + Draw::DepthStencilState *depth = thin3d->CreateDepthStencilState({ false, false, Comparison::LESS }); + Draw::RasterState *rasterNoCull = thin3d->CreateRasterState({}); + + PipelineDesc colorDesc{ + Primitive::TRIANGLE_LIST, + { thin3d->GetVshaderPreset(VS_COLOR_2D), thin3d->GetFshaderPreset(FS_COLOR_2D) }, + inputLayout, depth, blendNormal, rasterNoCull + }; + PipelineDesc texColorDesc{ + Primitive::TRIANGLE_LIST, + { thin3d->GetVshaderPreset(VS_TEXTURE_COLOR_2D), thin3d->GetFshaderPreset(FS_TEXTURE_COLOR_2D) }, + inputLayout, depth, blendNormal, rasterNoCull + }; colorPipeline = thin3d->CreateGraphicsPipeline(colorDesc); texColorPipeline = thin3d->CreateGraphicsPipeline(texColorDesc); + inputLayout->Release(); + rasterNoCull->Release(); + blendNormal->Release(); + depth->Release(); + + ui_draw2d.Init(thin3d, texColorPipeline); + ui_draw2d_front.Init(thin3d, texColorPipeline); + uiContext->Init(thin3d, texColorPipeline, colorPipeline, uiTexture, &ui_draw2d, &ui_draw2d_front); + RasterStateDesc desc; + desc.cull = CullMode::NONE; + desc.facing = Facing::CCW; + if (uiContext->Text()) uiContext->Text()->SetFont("Tahoma", 20, 0); diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index 0045f01fba..1aa70c88af 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -32,7 +32,7 @@ DrawBuffer::~DrawBuffer() { delete [] verts_; } -void DrawBuffer::Init(Draw::DrawContext *t3d) { +void DrawBuffer::Init(Draw::DrawContext *t3d, Draw::Pipeline *pipeline) { using namespace Draw; if (inited_) @@ -41,9 +41,18 @@ void DrawBuffer::Init(Draw::DrawContext *t3d) { t3d_ = t3d; inited_ = true; + if (pipeline->RequiresBuffer()) { + vbuf_ = t3d_->CreateBuffer(MAX_VERTS * sizeof(Vertex), BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA); + } else { + vbuf_ = nullptr; + } +} + +Draw::InputLayout *DrawBuffer::CreateInputLayout(Draw::DrawContext *t3d) { + using namespace Draw; InputLayoutDesc desc = { { - {sizeof(Vertex), false}, + { sizeof(Vertex), false }, }, { { 0, SEM_POSITION, DataFormat::R32G32B32_FLOAT, 0 }, @@ -52,27 +61,19 @@ void DrawBuffer::Init(Draw::DrawContext *t3d) { }, }; - vformat_ = t3d_->CreateInputLayout(desc); - if (vformat_->RequiresBuffer()) { - vbuf_ = t3d_->CreateBuffer(MAX_VERTS * sizeof(Vertex), BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA); - } else { - vbuf_ = nullptr; - } + return t3d->CreateInputLayout(desc); } void DrawBuffer::Shutdown() { if (vbuf_) { vbuf_->Release(); } - vformat_->Release(); - inited_ = false; } -void DrawBuffer::Begin(Draw::Pipeline *program, DrawBufferPrimitiveMode dbmode) { +void DrawBuffer::Begin(Draw::Pipeline *program) { pipeline_ = program; count_ = 0; - mode_ = dbmode; } void DrawBuffer::End() { @@ -94,9 +95,9 @@ void DrawBuffer::Flush(bool set_blend_state) { if (vbuf_) { vbuf_->SubData((const uint8_t *)verts_, 0, sizeof(Vertex) * count_); int offset = 0; - t3d_->Draw(mode_ == DBMODE_NORMAL ? Primitive::TRIANGLE_LIST : Primitive::LINE_LIST, vformat_, vbuf_, count_, offset); + t3d_->Draw(vbuf_, count_, offset); } else { - t3d_->DrawUP(mode_ == DBMODE_NORMAL ? Primitive::TRIANGLE_LIST : Primitive::LINE_LIST, vformat_, (const void *)verts_, count_); + t3d_->DrawUP((const void *)verts_, count_); } count_ = 0; } diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h index 9ceffc5e58..2627fa9708 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/ext/native/gfx_es2/draw_buffer.h @@ -63,13 +63,16 @@ public: DrawBuffer(); ~DrawBuffer(); - void Begin(Draw::Pipeline *shaders, DrawBufferPrimitiveMode mode = DBMODE_NORMAL); + void Begin(Draw::Pipeline *pipeline); void End(); // TODO: Enforce these. Now Init is autocalled and shutdown not called. - void Init(Draw::DrawContext *t3d); + void Init(Draw::DrawContext *t3d, Draw::Pipeline *pipeline); void Shutdown(); + // So that callers can create appropriate pipelines. + Draw::InputLayout *CreateInputLayout(Draw::DrawContext *t3d); + int Count() const { return count_; } void Flush(bool set_blend_state = true); @@ -159,7 +162,6 @@ private: Draw::DrawContext *t3d_; Draw::Buffer *vbuf_; - Draw::InputLayout *vformat_; Draw::Pipeline *pipeline_; Vertex *verts_; diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 14e0c92500..8f5109cdb6 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -309,10 +309,7 @@ struct InputLayoutDesc { std::vector attributes; }; -class InputLayout : public RefCountedObject { -public: - virtual bool RequiresBuffer() = 0; -}; +class InputLayout : public RefCountedObject { }; enum class ShaderStage { VERTEX, @@ -360,17 +357,16 @@ public: // TODO: Use a uniform-buffer based interface instead. virtual void SetVector(const char *name, float *value, int n) = 0; virtual void SetMatrix4x4(const char *name, const float value[16]) = 0; + virtual bool RequiresBuffer() = 0; }; -class RasterState : public RefCountedObject { -public: -}; +class RasterState : public RefCountedObject {}; struct DepthStencilStateDesc { bool depthTestEnabled; bool depthWriteEnabled; Comparison depthCompare; - // Ignore stencil + // Ignore stencil for now, will need soon. }; struct BlendStateDesc { @@ -432,7 +428,12 @@ struct RasterStateDesc { }; struct PipelineDesc { + Primitive prim; std::vector shaders; + InputLayout *inputLayout; + DepthStencilState *depthStencil; + BlendState *blend; + RasterState *raster; }; class DrawContext : public RefCountedObject { @@ -441,17 +442,15 @@ public: virtual std::vector GetFeatureList() { return std::vector(); } + // Partial pipeline state, used to create pipelines. (in practice, in d3d11 they'll use the native state objects directly). virtual DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) = 0; virtual BlendState *CreateBlendState(const BlendStateDesc &desc) = 0; virtual SamplerState *CreateSamplerState(const SamplerStateDesc &desc) = 0; virtual RasterState *CreateRasterState(const RasterStateDesc &desc) = 0; - virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0; virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0; + // virtual ComputePipeline CreateComputePipeline(const ComputePipelineDesc &desc) = 0 virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0; - virtual Texture *CreateTexture() = 0; // To be later filled in by ->LoadFromFile or similar. - virtual Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) = 0; - // Common Thin3D function, uses CreateTexture Texture *CreateTextureFromFile(const char *filename, ImageFileType fileType); Texture *CreateTextureFromFileData(const uint8_t *data, int size, ImageFileType fileType); @@ -460,30 +459,30 @@ public: ShaderModule *GetVshaderPreset(VertexShaderPreset preset) { return fsPresets_[preset]; } ShaderModule *GetFshaderPreset(FragmentShaderPreset preset) { return vsPresets_[preset]; } + // Resources + virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0; + virtual Texture *CreateTexture() = 0; // To be later filled in by ->LoadFromFile or similar. + virtual Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) = 0; + // The implementation makes the choice of which shader code to use. virtual ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) = 0; - // Bound state objects. Too cumbersome to add them all as parameters to Draw. - virtual void SetBlendState(BlendState *state) = 0; - virtual void BindSamplerStates(int start, int count, SamplerState **state) = 0; - virtual void SetDepthStencilState(DepthStencilState *state) = 0; - virtual void SetRasterState(RasterState *state) = 0; + // Dynamic state + virtual void SetScissorRect(int left, int top, int width, int height) = 0; + virtual void SetViewports(int count, Viewport *viewports) = 0; + virtual void BindSamplerStates(int start, int count, SamplerState **state) = 0; virtual void BindTextures(int start, int count, Texture **textures) = 0; void BindTexture(int stage, Texture *texture) { BindTextures(stage, 1, &texture); } // from sampler 0 and upwards - // Raster state - virtual void SetScissorRect(int left, int top, int width, int height) = 0; - virtual void SetViewports(int count, Viewport *viewports) = 0; - virtual void BindPipeline(Pipeline *pipeline) = 0; // TODO: Add more sophisticated draws with buffer offsets, and multidraws. - virtual void Draw(Primitive prim, InputLayout *format, Buffer *vdata, int vertexCount, int offset) = 0; - virtual void DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, Buffer *idata, int vertexCount, int offset) = 0; - virtual void DrawUP(Primitive prim, InputLayout *format, const void *vdata, int vertexCount) = 0; + virtual void Draw(Buffer *vdata, int vertexCount, int offset) = 0; + virtual void DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) = 0; + virtual void DrawUP(const void *vdata, int vertexCount) = 0; // Render pass management. Default implementations here. virtual void Begin(bool clear, uint32_t colorval, float depthVal, int stencilVal) { @@ -509,8 +508,6 @@ protected: int targetWidth_; int targetHeight_; - -private: }; DrawContext *T3DCreateGLContext(); diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 7eb51b6f88..d3842db8b2 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -242,9 +242,6 @@ public: void Apply(LPDIRECT3DDEVICE9 device) { device->SetVertexDeclaration(decl_); } - bool RequiresBuffer() override { - return false; - } private: LPDIRECT3DVERTEXDECLARATION9 decl_; @@ -284,8 +281,26 @@ private: class D3D9Pipeline : public Pipeline { public: D3D9Pipeline(LPDIRECT3DDEVICE9 device) : device_(device) {} + ~D3D9Pipeline() { + if (depthStencil) depthStencil->Release(); + if (blend) blend->Release(); + if (raster) raster->Release(); + if (inputLayout) inputLayout->Release(); + } + bool RequiresBuffer() override { + return false; + } + D3D9ShaderModule *vshader; D3D9ShaderModule *pshader; + + D3DPRIMITIVETYPE prim; + int primDivisor; + D3D9InputLayout *inputLayout = nullptr; + D3D9DepthStencilState *depthStencil = nullptr; + D3D9BlendState *blend = nullptr; + D3D9RasterState *raster = nullptr; + void Apply(LPDIRECT3DDEVICE9 device); void SetVector(const char *name, float *value, int n) { vshader->SetVector(device_, name, value, n); pshader->SetVector(device_, name, value, n); } void SetMatrix4x4(const char *name, const float value[16]) { vshader->SetMatrix4x4(device_, name, value); } // pshaders don't usually have matrices @@ -466,20 +481,6 @@ public: Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override; - // Bound state objects. Too cumbersome to add them all as parameters to Draw. - void SetBlendState(BlendState *state) override { - D3D9BlendState *bs = static_cast(state); - bs->Apply(device_); - } - void SetDepthStencilState(DepthStencilState *state) override { - D3D9DepthStencilState *bs = static_cast(state); - bs->Apply(device_); - } - void SetRasterState(RasterState *state) override { - D3D9RasterState *bs = static_cast(state); - bs->Apply(device_); - } - void BindTextures(int start, int count, Texture **textures) override; void BindSamplerStates(int start, int count, SamplerState **states) override { for (int i = 0; i < count; ++i) { @@ -495,9 +496,9 @@ public: void SetScissorRect(int left, int top, int width, int height) override; void SetViewports(int count, Viewport *viewports) override; - void Draw(Primitive prim, InputLayout *format, Buffer *vdata, int vertexCount, int offset) override; - void DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, Buffer *idata, int vertexCount, int offset) override; - void DrawUP(Primitive prim, InputLayout *format, const void *vdata, int vertexCount) override; + void Draw(Buffer *vdata, int vertexCount, int offset) override; + void DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) override; + void DrawUP(const void *vdata, int vertexCount) override; void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal); std::string GetInfoString(InfoField info) const override { @@ -562,6 +563,16 @@ Pipeline *D3D9Context::CreateGraphicsPipeline(const PipelineDesc &desc) { pipeline->vshader = static_cast(iter); } } + pipeline->prim = primToD3D9[(int)desc.prim]; + pipeline->primDivisor = primCountDivisor[(int)desc.prim]; + pipeline->depthStencil = (D3D9DepthStencilState *)desc.depthStencil; + pipeline->blend = (D3D9BlendState *)desc.blend; + pipeline->raster = (D3D9RasterState *)desc.raster; + pipeline->inputLayout = (D3D9InputLayout *)desc.inputLayout; + pipeline->depthStencil->AddRef(); + pipeline->blend->AddRef(); + pipeline->raster->AddRef(); + pipeline->inputLayout->AddRef(); return pipeline; } @@ -709,36 +720,35 @@ Buffer *D3D9Context::CreateBuffer(size_t size, uint32_t usageFlags) { void D3D9Pipeline::Apply(LPDIRECT3DDEVICE9 device) { vshader->Apply(device); pshader->Apply(device); + blend->Apply(device); + depthStencil->Apply(device); + raster->Apply(device); } -void D3D9Context::Draw(Primitive prim, InputLayout *format, Buffer *vdata, int vertexCount, int offset) { +void D3D9Context::Draw(Buffer *vdata, int vertexCount, int offset) { Thin3DDX9Buffer *vbuf = static_cast(vdata); - D3D9InputLayout *fmt = static_cast(format); - vbuf->BindAsVertexBuf(device_, fmt->GetStride(9), offset); + vbuf->BindAsVertexBuf(device_, curPipeline_->inputLayout->GetStride(9), offset); curPipeline_->Apply(device_); - fmt->Apply(device_); - device_->DrawPrimitive(primToD3D9[(int)prim], offset, vertexCount / 3); + curPipeline_->inputLayout->Apply(device_); + device_->DrawPrimitive(curPipeline_->prim, offset, vertexCount / 3); } -void D3D9Context::DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, Buffer *idata, int vertexCount, int offset) { +void D3D9Context::DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) { Thin3DDX9Buffer *vbuf = static_cast(vdata); Thin3DDX9Buffer *ibuf = static_cast(idata); - D3D9InputLayout *fmt = static_cast(format); curPipeline_->Apply(device_); - fmt->Apply(device_); - vbuf->BindAsVertexBuf(device_, fmt->GetStride(0), offset); + curPipeline_->inputLayout->Apply(device_); + vbuf->BindAsVertexBuf(device_, curPipeline_->inputLayout->GetStride(0), offset); ibuf->BindAsIndexBuf(device_); - device_->DrawIndexedPrimitive(primToD3D9[(int)prim], 0, 0, vertexCount, 0, vertexCount / primCountDivisor[(int)prim]); + device_->DrawIndexedPrimitive(curPipeline_->prim, 0, 0, vertexCount, 0, vertexCount / curPipeline_->primDivisor); } -void D3D9Context::DrawUP(Primitive prim, InputLayout *format, const void *vdata, int vertexCount) { - D3D9InputLayout *fmt = static_cast(format); - +void D3D9Context::DrawUP(const void *vdata, int vertexCount) { curPipeline_->Apply(device_); - fmt->Apply(device_); - device_->DrawPrimitiveUP(primToD3D9[(int)prim], vertexCount / 3, vdata, fmt->GetStride(0)); + curPipeline_->inputLayout->Apply(device_); + device_->DrawPrimitiveUP(curPipeline_->prim, vertexCount / 3, vdata, curPipeline_->inputLayout->GetStride(0)); } static uint32_t SwapRB(uint32_t c) { diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 5330ac9467..82781ff751 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -339,7 +339,7 @@ public: void Compile(); void GLRestore() override; void GLLost() override; - bool RequiresBuffer() override { + bool RequiresBuffer() { return id_ != 0; } @@ -369,8 +369,16 @@ public: iter->Release(); } glDeleteProgram(program_); + if (depthStencil) depthStencil->Release(); + if (blend) blend->Release(); + if (raster) raster->Release(); + if (inputLayout) inputLayout->Release(); } - bool Link(); + bool RequiresBuffer() override { + return inputLayout->RequiresBuffer(); + } + + bool LinkShaders(); void Apply(); void Unapply(); @@ -391,10 +399,15 @@ public: for (auto iter : shaders) { iter->Compile(iter->GetSource().c_str()); } - Link(); + LinkShaders(); } + GLuint prim; std::vector shaders; + OpenGLInputLayout *inputLayout = nullptr; + OpenGLDepthStencilState *depthStencil = nullptr; + OpenGLBlendState *blend = nullptr; + OpenGLRasterState *raster = nullptr; private: GLuint program_; @@ -416,12 +429,6 @@ public: Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; Texture *CreateTexture() override; - // Bound state objects - void SetBlendState(BlendState *state) override { - OpenGLBlendState *s = static_cast(state); - s->Apply(); - } - void BindSamplerStates(int start, int count, SamplerState **states) override { if (samplerStates_.size() < (size_t)(start + count)) { samplerStates_.resize(start + count); @@ -441,18 +448,6 @@ public: s->Apply(false, true); } } - - } - - // Bound state objects - void SetDepthStencilState(DepthStencilState *state) override { - OpenGLDepthStencilState *s = static_cast(state); - s->Apply(); - } - - void SetRasterState(RasterState *state) override { - OpenGLRasterState *rs = static_cast(state); - rs->Apply(); } ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override; @@ -472,14 +467,12 @@ public: } void BindTextures(int start, int count, Texture **textures) override; - void BindPipeline(Pipeline *pipeline) { - curPipeline_ = (OpenGLPipeline *)pipeline; - } + void BindPipeline(Pipeline *pipeline) override; // TODO: Add more sophisticated draws. - void Draw(Primitive prim, InputLayout *format, Buffer *vdata, int vertexCount, int offset) override; - void DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, Buffer *idata, int vertexCount, int offset) override; - void DrawUP(Primitive prim, InputLayout *format, const void *vdata, int vertexCount) override; + void Draw(Buffer *vdata, int vertexCount, int offset) override; + void DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) override; + void DrawUP(const void *vdata, int vertexCount) override; void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override; std::string GetInfoString(InfoField info) const override { @@ -812,7 +805,17 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { iter->AddRef(); pipeline->shaders.push_back(static_cast(iter)); } - if (pipeline->Link()) { + if (pipeline->LinkShaders()) { + // Build the rest of the virtual pipeline object. + pipeline->prim = primToGL[(int)desc.prim]; + pipeline->depthStencil = (OpenGLDepthStencilState *)desc.depthStencil; + pipeline->blend = (OpenGLBlendState *)desc.blend; + pipeline->raster = (OpenGLRasterState *)desc.raster; + pipeline->inputLayout = (OpenGLInputLayout *)desc.inputLayout; + pipeline->depthStencil->AddRef(); + pipeline->blend->AddRef(); + pipeline->raster->AddRef(); + pipeline->inputLayout->AddRef(); return pipeline; } else { delete pipeline; @@ -844,7 +847,7 @@ ShaderModule *OpenGLContext::CreateShaderModule(ShaderStage stage, const char *g } } -bool OpenGLPipeline::Link() { +bool OpenGLPipeline::LinkShaders() { program_ = glCreateProgram(); for (auto iter : shaders) { glAttachShader(program_, iter->GetShader()); @@ -936,49 +939,52 @@ void OpenGLPipeline::Unapply() { glUseProgram(0); } -void OpenGLContext::Draw(Primitive prim, InputLayout *format, Buffer *vdata, int vertexCount, int offset) { - OpenGLBuffer *vbuf = static_cast(vdata); - OpenGLInputLayout *fmt = static_cast(format); - - vbuf->Bind(); - fmt->Apply(); - curPipeline_->Apply(); - - glDrawArrays(primToGL[(int)prim], offset, vertexCount); - - curPipeline_->Unapply(); - fmt->Unapply(); +void OpenGLContext::BindPipeline(Pipeline *pipeline) { + curPipeline_ = (OpenGLPipeline *)pipeline; + curPipeline_->blend->Apply(); + curPipeline_->depthStencil->Apply(); + curPipeline_->raster->Apply(); } -void OpenGLContext::DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, Buffer *idata, int vertexCount, int offset) { +void OpenGLContext::Draw(Buffer *vdata, int vertexCount, int offset) { OpenGLBuffer *vbuf = static_cast(vdata); - OpenGLBuffer *ibuf = static_cast(idata); - OpenGLInputLayout *fmt = static_cast(format); vbuf->Bind(); - fmt->Apply(); + curPipeline_->inputLayout->Apply(); + curPipeline_->Apply(); + + glDrawArrays(curPipeline_->prim, offset, vertexCount); + + curPipeline_->Unapply(); + curPipeline_->inputLayout->Unapply(); +} + +void OpenGLContext::DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) { + OpenGLBuffer *vbuf = static_cast(vdata); + OpenGLBuffer *ibuf = static_cast(idata); + + vbuf->Bind(); + curPipeline_->inputLayout->Apply(); curPipeline_->Apply(); // Note: ibuf binding is stored in the VAO, so call this after binding the fmt. ibuf->Bind(); - glDrawElements(primToGL[(int)prim], vertexCount, GL_UNSIGNED_INT, (const void *)(size_t)offset); + glDrawElements(curPipeline_->prim, vertexCount, GL_UNSIGNED_INT, (const void *)(size_t)offset); curPipeline_->Unapply(); - fmt->Unapply(); + curPipeline_->inputLayout->Unapply(); } -void OpenGLContext::DrawUP(Primitive prim, InputLayout *format, const void *vdata, int vertexCount) { - OpenGLInputLayout *fmt = static_cast(format); - - fmt->Apply(vdata); +void OpenGLContext::DrawUP(const void *vdata, int vertexCount) { + curPipeline_->inputLayout->Apply(vdata); curPipeline_->Apply(); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDrawArrays(primToGL[(int)prim], 0, vertexCount); + glDrawArrays(curPipeline_->prim, 0, vertexCount); curPipeline_->Unapply(); - fmt->Unapply(); + curPipeline_->inputLayout->Unapply(); } void OpenGLContext::Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) { diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 0a60e80497..f2d6cbb6e5 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -119,7 +119,6 @@ static inline void Uint8x4ToFloat4(uint32_t u, float f[4]) { f[3] = ((u >> 24) & 0xFF) * (1.0f / 255.0f); } - class VKBlendState : public BlendState { public: bool blendEnabled; @@ -128,7 +127,7 @@ public: bool logicEnabled; VkLogicOp logicOp; - void ToVulkan(VkPipelineColorBlendStateCreateInfo *info, VkPipelineColorBlendAttachmentState *attachments) { + void ToVulkan(VkPipelineColorBlendStateCreateInfo *info, VkPipelineColorBlendAttachmentState *attachments) const { memset(info, 0, sizeof(*info)); info->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; info->attachmentCount = 1; @@ -152,7 +151,7 @@ public: bool depthWriteEnabled; VkCompareOp depthComp; - void ToVulkan(VkPipelineDepthStencilStateCreateInfo *info) { + void ToVulkan(VkPipelineDepthStencilStateCreateInfo *info) const { memset(info, 0, sizeof(*info)); info->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; info->depthCompareOp = depthComp; @@ -172,7 +171,7 @@ public: Facing frontFace; CullMode cullFace; - void ToVulkan(VkPipelineRasterizationStateCreateInfo *info) { + void ToVulkan(VkPipelineRasterizationStateCreateInfo *info) const { memset(info, 0, sizeof(*info)); info->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; info->frontFace = frontFace == Facing::CCW ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE; @@ -299,10 +298,6 @@ inline VkFormat ConvertVertexDataTypeToVk(DataFormat type) { class VKInputLayout : public InputLayout { public: - bool RequiresBuffer() { - return false; - } - std::vector bindings; std::vector attributes; VkPipelineVertexInputStateCreateInfo visc; @@ -316,12 +311,8 @@ public: ubo_ = new uint8_t[uboSize_]; } ~VKPipeline() { - for (auto iter : shaders) { - iter->Release(); - } delete[] ubo_; } - bool Link(); // Returns the binding offset, and the VkBuffer to bind. size_t PushUBO(VulkanPushBuffer *buf, VulkanContext *vulkan, VkBuffer *vkbuf) { @@ -336,36 +327,18 @@ public: int GetUBOSize() const { return uboSize_; } + bool RequiresBuffer() { + return false; + } - std::vector shaders; + VkPipeline vkpipeline; + int stride[4]; private: uint8_t *ubo_; int uboSize_; }; -struct PipelineKey { - VKDepthStencilState *depthStencil; - VKBlendState *blend; - VKPipeline *pipeline; - VkPrimitiveTopology topology; - VKRasterState *raster; - - // etc etc - - bool operator < (const PipelineKey &other) const { - if (depthStencil < other.depthStencil) return true; else if (depthStencil > other.depthStencil) return false; - if (blend < other.blend) return true; else if (blend > other.blend) return false; - if (pipeline < other.pipeline) return true; else if (pipeline > other.pipeline) return false; - if (topology < other.topology) return true; else if (topology > other.topology) return false; - if (raster < other.raster) return true; else if (raster > other.raster) return false; - // etc etc - return false; - } -}; - - - class VKTexture; class VKSamplerState; @@ -400,26 +373,7 @@ public: Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; Texture *CreateTexture() override; - // Bound state objects - void SetBlendState(BlendState *state) override { - VKBlendState *s = static_cast(state); - curBlendState_ = s; - } - - // Bound state objects - void SetDepthStencilState(DepthStencilState *state) override { - VKDepthStencilState *s = static_cast(state); - curDepthStencilState_ = s; - } - - // Bound state objects - void SetRasterState(RasterState *state) override { - VKRasterState *s = static_cast(state); - curRasterState_ = s; - } - void SetScissorRect(int left, int top, int width, int height) override; - void SetViewports(int count, Viewport *viewports) override; void BindSamplerStates(int start, int count, SamplerState **state) override; @@ -429,9 +383,9 @@ public: } // TODO: Add more sophisticated draws. - void Draw(Primitive prim, InputLayout *format, Buffer *vdata, int vertexCount, int offset) override; - void DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, Buffer *idata, int vertexCount, int offset) override; - void DrawUP(Primitive prim, InputLayout *format, const void *vdata, int vertexCount) override; + void Draw(Buffer *vdata, int vertexCount, int offset) override; + void DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) override; + void DrawUP(const void *vdata, int vertexCount) override; void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override; @@ -455,7 +409,6 @@ public: } } - VkPipeline GetOrCreatePipeline(); VkDescriptorSet GetOrCreateDescriptorSet(VkBuffer buffer); std::vector GetFeatureList() override; @@ -466,16 +419,7 @@ private: VulkanContext *vulkan_; - // These are used to compose the pipeline cache key. - VKBlendState *curBlendState_; - VKDepthStencilState *curDepthStencilState_; VKPipeline *curPipeline_; - VkPrimitiveTopology curPrim_; - VKInputLayout *curInputLayout_; - VKRasterState *curRasterState_; - - // We keep a pipeline state cache. - std::map pipelines_; VkDescriptorSetLayout descriptorSetLayout_; VkPipelineLayout pipelineLayout_; @@ -744,9 +688,6 @@ VKContext::VKContext(VulkanContext *vulkan) } VKContext::~VKContext() { - for (auto x : pipelines_) { - vkDestroyPipeline(device_, x.second, nullptr); - } vkDestroyCommandPool(device_, cmdPool_, nullptr); // This also destroys all descriptor sets. for (int i = 0; i < 2; i++) { @@ -861,42 +802,40 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) { return descSet; } -VkPipeline VKContext::GetOrCreatePipeline() { - PipelineKey key; - key.blend = curBlendState_; - key.depthStencil = curDepthStencilState_; - key.pipeline = curPipeline_; - key.topology = curPrim_; - key.raster = curRasterState_; - - auto iter = pipelines_.find(key); - if (iter != pipelines_.end()) { - return iter->second; +Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { + VKPipeline *pipeline = new VKPipeline(); + VKInputLayout *input = (VKInputLayout *)desc.inputLayout; + VKBlendState *blend = (VKBlendState *)desc.blend; + VKDepthStencilState *depth = (VKDepthStencilState *)desc.depthStencil; + VKRasterState *raster = (VKRasterState *)desc.raster; + for (int i = 0; i < input->bindings.size(); i++) { + pipeline->stride[i] = input->bindings[i].stride; } std::vector stages; - stages.resize(curPipeline_->shaders.size()); + stages.resize(desc.shaders.size()); int i = 0; - for (auto &iter : curPipeline_->shaders) { + for (auto &iter : desc.shaders) { + VKShaderModule *vkshader = (VKShaderModule *)iter; VkPipelineShaderStageCreateInfo &stage = stages[i++]; stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stage.pNext = nullptr; stage.pSpecializationInfo = nullptr; - stage.stage = StageToVulkan(iter->GetStage()); - stage.module = iter->Get(); + stage.stage = StageToVulkan(vkshader->GetStage()); + stage.module = vkshader->Get(); stage.pName = "main"; stage.flags = 0; } VkPipelineColorBlendStateCreateInfo colorBlend; VkPipelineColorBlendAttachmentState attachment0; - curBlendState_->ToVulkan(&colorBlend, &attachment0); + blend->ToVulkan(&colorBlend, &attachment0); VkPipelineDepthStencilStateCreateInfo depthStencil; - curDepthStencilState_->ToVulkan(&depthStencil); + depth->ToVulkan(&depthStencil); VkPipelineInputAssemblyStateCreateInfo inputAssembly = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; - inputAssembly.topology = curPrim_; + inputAssembly.topology = primToVK[(int)desc.prim]; inputAssembly.primitiveRestartEnable = false; VkDynamicState dynamics[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; @@ -904,9 +843,6 @@ VkPipeline VKContext::GetOrCreatePipeline() { dynamicInfo.dynamicStateCount = ARRAY_SIZE(dynamics); dynamicInfo.pDynamicStates = dynamics; - VkPipelineRasterizationStateCreateInfo raster; - curRasterState_->ToVulkan(&raster); - VkPipelineMultisampleStateCreateInfo ms = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; ms.pNext = nullptr; ms.pSampleMask = nullptr; @@ -919,6 +855,9 @@ VkPipeline VKContext::GetOrCreatePipeline() { vs.pViewports = nullptr; // dynamic vs.pScissors = nullptr; // dynamic + VkPipelineRasterizationStateCreateInfo rs{ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + raster->ToVulkan(&rs); + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; info.pNext = nullptr; info.flags = 0; @@ -930,22 +869,20 @@ VkPipeline VKContext::GetOrCreatePipeline() { info.pInputAssemblyState = &inputAssembly; info.pTessellationState = nullptr; info.pMultisampleState = &ms; - info.pVertexInputState = &curInputLayout_->visc; - info.pRasterizationState = &raster; + info.pVertexInputState = &input->visc; + info.pRasterizationState = &rs; info.pViewportState = &vs; // Must set viewport and scissor counts even if we set the actual state dynamically. info.layout = pipelineLayout_; info.subpass = 0; info.renderPass = vulkan_->GetSurfaceRenderPass(); // OK, need to create a new pipeline. - VkPipeline pipeline; - VkResult result = vkCreateGraphicsPipelines(device_, pipelineCache_, 1, &info, nullptr, &pipeline); + VkResult result = vkCreateGraphicsPipelines(device_, pipelineCache_, 1, &info, nullptr, &pipeline->vkpipeline); if (result != VK_SUCCESS) { ELOG("Failed to create graphics pipeline"); - return VK_NULL_HANDLE; + delete pipeline; + return nullptr; } - - pipelines_.insert(std::make_pair(key, pipeline)); return pipeline; } @@ -1058,24 +995,6 @@ Buffer *VKContext::CreateBuffer(size_t size, uint32_t usageFlags) { return new Thin3DVKBuffer(size, usageFlags); } -Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { - if (!desc.shaders.size()) { - ELOG("Pipeline requires at least one shader"); - return NULL; - } - VKPipeline *pipeline = new VKPipeline(); - for (auto iter : desc.shaders) { - iter->AddRef(); - pipeline->shaders.push_back(static_cast(iter)); - } - if (pipeline->Link()) { - return pipeline; - } else { - delete pipeline; - return NULL; - } -} - void VKContext::BindTextures(int start, int count, Texture **textures) { for (int i = start; i < start + count; i++) { boundTextures_[i] = static_cast(textures[i]); @@ -1093,11 +1012,6 @@ ShaderModule *VKContext::CreateShaderModule(ShaderStage stage, const char *glsl_ } } -bool VKPipeline::Link() { - // There is no link step. However, we will create and cache Pipeline objects in the device context. - return true; -} - int VKPipeline::GetUniformLoc(const char *name) { int loc = -1; @@ -1138,11 +1052,9 @@ inline VkPrimitiveTopology PrimToVK(Primitive prim) { } } -void VKContext::Draw(Primitive prim, InputLayout *format, Buffer *vdata, int vertexCount, int offset) { +void VKContext::Draw(Buffer *vdata, int vertexCount, int offset) { ApplyDynamicState(); - curPrim_ = PrimToVK(prim); - curInputLayout_ = (VKInputLayout *)format; Thin3DVKBuffer *vbuf = static_cast(vdata); VkBuffer vulkanVbuf; @@ -1150,8 +1062,7 @@ void VKContext::Draw(Primitive prim, InputLayout *format, Buffer *vdata, int ver uint32_t ubo_offset = (uint32_t)curPipeline_->PushUBO(push_, vulkan_, &vulkanUBObuf); size_t vbBindOffset = push_->Push(vbuf->GetData(), vbuf->GetSize(), &vulkanVbuf); - VkPipeline vkpipeline = GetOrCreatePipeline(); - vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, vkpipeline); + vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, curPipeline_->vkpipeline); VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf); vkCmdBindDescriptorSets(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &descSet, 1, &ubo_offset); VkBuffer buffers[1] = { vulkanVbuf }; @@ -1160,12 +1071,9 @@ void VKContext::Draw(Primitive prim, InputLayout *format, Buffer *vdata, int ver vkCmdDraw(cmd_, vertexCount, 1, offset, 0); } -void VKContext::DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, Buffer *idata, int vertexCount, int offset) { +void VKContext::DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) { ApplyDynamicState(); - curPrim_ = PrimToVK(prim); - curInputLayout_ = (VKInputLayout *)format; - Thin3DVKBuffer *ibuf = static_cast(idata); Thin3DVKBuffer *vbuf = static_cast(vdata); @@ -1174,8 +1082,7 @@ void VKContext::DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, size_t vbBindOffset = push_->Push(vbuf->GetData(), vbuf->GetSize(), &vulkanVbuf); size_t ibBindOffset = push_->Push(ibuf->GetData(), ibuf->GetSize(), &vulkanIbuf); - VkPipeline pipeline = GetOrCreatePipeline(); - vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, curPipeline_->vkpipeline); VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf); vkCmdBindDescriptorSets(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &descSet, 1, &ubo_offset); @@ -1188,18 +1095,14 @@ void VKContext::DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, vkCmdDrawIndexed(cmd_, vertexCount, 1, 0, offset, 0); } -void VKContext::DrawUP(Primitive prim, InputLayout *format, const void *vdata, int vertexCount) { +void VKContext::DrawUP(const void *vdata, int vertexCount) { ApplyDynamicState(); - curPrim_ = PrimToVK(prim); - curInputLayout_ = (VKInputLayout *)format; - VkBuffer vulkanVbuf, vulkanUBObuf; - size_t vbBindOffset = push_->Push(vdata, vertexCount * curInputLayout_->bindings[0].stride, &vulkanVbuf); + size_t vbBindOffset = push_->Push(vdata, vertexCount * curPipeline_->stride[0], &vulkanVbuf); uint32_t ubo_offset = (uint32_t)curPipeline_->PushUBO(push_, vulkan_, &vulkanUBObuf); - VkPipeline pipeline = GetOrCreatePipeline(); - vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, curPipeline_->vkpipeline); VkBuffer buffers[1] = { vulkanVbuf }; VkDeviceSize offsets[1] = { vbBindOffset }; diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index c7fc6e9400..44418b1f5b 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -16,23 +16,12 @@ UIContext::UIContext() UIContext::~UIContext() { delete fontStyle_; delete textDrawer_; - // Not releasing blend_, it's a preset. Should really make them AddRef, though.. - depth_->Release(); - sampler_->Release(); - rasterNoCull_->Release(); - blendNormal_->Release(); } void UIContext::Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pipeline *uipipenotex, Draw::Texture *uitexture, DrawBuffer *uidrawbuffer, DrawBuffer *uidrawbufferTop) { using namespace Draw; thin3d_ = thin3d; - blendNormal_ = thin3d_->CreateBlendState({ true, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA }); sampler_ = thin3d_->CreateSamplerState({ TextureFilter::LINEAR, TextureFilter::LINEAR, TextureFilter::LINEAR }); - depth_ = thin3d_->CreateDepthStencilState({ false, false, Comparison::LESS }); - RasterStateDesc desc; - desc.cull = CullMode::NONE; - desc.facing = Facing::CCW; - rasterNoCull_ = thin3d_->CreateRasterState(desc); ui_pipeline_ = uipipe; ui_pipeline_notex_ = uipipenotex; uitexture_ = uitexture; @@ -46,18 +35,13 @@ void UIContext::Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pi } void UIContext::Begin() { - thin3d_->SetBlendState(blendNormal_); thin3d_->BindSamplerStates(0, 1, &sampler_); - thin3d_->SetDepthStencilState(depth_); - thin3d_->SetRasterState(rasterNoCull_); thin3d_->BindTexture(0, uitexture_); UIBegin(ui_pipeline_); } void UIContext::BeginNoTex() { - thin3d_->SetBlendState(blendNormal_); thin3d_->BindSamplerStates(0, 1, &sampler_); - thin3d_->SetRasterState(rasterNoCull_); UIBegin(ui_pipeline_notex_); } diff --git a/ext/native/ui/ui_context.h b/ext/native/ui/ui_context.h index 7f81fe9ca4..7b34ba2626 100644 --- a/ext/native/ui/ui_context.h +++ b/ext/native/ui/ui_context.h @@ -86,10 +86,7 @@ private: TextDrawer *textDrawer_; Draw::DrawContext *thin3D_; - Draw::DepthStencilState *depth_; Draw::SamplerState *sampler_; - Draw::RasterState *rasterNoCull_; - Draw::BlendState *blendNormal_; Draw::Pipeline *ui_pipeline_; Draw::Pipeline *ui_pipeline_notex_; Draw::Texture *uitexture_;