diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 80236f84c11e..48ae0540aff4 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -78,6 +78,10 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *_thin3D) 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) }; + texColor = thin3d->CreateGraphicsPipeline(pipelineDesc); + fb.data = Memory::GetPointer(0x44000000); // TODO: correct default address? depthbuf.data = Memory::GetPointer(0x44000000); // TODO: correct default address? @@ -100,6 +104,9 @@ void SoftGPU::DeviceRestore() { } SoftGPU::~SoftGPU() { + texColor->Release(); + texColor = nullptr; + vformat->Release(); vformat = nullptr; fbTex->Release(); @@ -238,7 +245,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { idata->SetData((const uint8_t *)indexes, sizeof(indexes)); thin3d->BindTexture(0, fbTex); - Pipeline *texColor = thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D); static const float identity4x4[16] = { 1.0f, 0.0f, 0.0f, 0.0f, diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index 6afd3698c462..a8cb42c53a9d 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -19,6 +19,7 @@ #include "GPU/GPUCommon.h" #include "GPU/Common/GPUDebugInterface.h" +#include "thin3d/thin3d.h" typedef struct { union { @@ -45,10 +46,6 @@ typedef struct { } FormatBuffer; class ShaderManager; -namespace Draw { - class DrawContext; - class Texture; -} class SoftGPU : public GPUCommon { public: @@ -109,5 +106,6 @@ class SoftGPU : public GPUCommon { GraphicsContext *gfxCtx_; Draw::Texture *fbTex; Draw::DrawContext *thin3d; + Draw::Pipeline *texColor; std::vector fbTexBuffer; }; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 5d7c3d44cf72..7b0ef73202ab 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -140,6 +140,8 @@ struct PendingMessage { static recursive_mutex pendingMutex; static std::vector pendingMessages; static Draw::DrawContext *thin3d; +static Draw::Pipeline *colorPipeline; +static Draw::Pipeline *texColorPipeline; static UIContext *uiContext; static std::vector inputboxValue; @@ -592,7 +594,13 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) { uiContext = new UIContext(); uiContext->theme = &ui_theme; - uiContext->Init(thin3d, thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), thin3d->GetShaderSetPreset(SS_COLOR_2D), uiTexture, &ui_draw2d, &ui_draw2d_front); + 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) } }; + + colorPipeline = thin3d->CreateGraphicsPipeline(colorDesc); + texColorPipeline = thin3d->CreateGraphicsPipeline(texColorDesc); + + uiContext->Init(thin3d, texColorPipeline, colorPipeline, uiTexture, &ui_draw2d, &ui_draw2d_front); if (uiContext->Text()) uiContext->Text()->SetFont("Tahoma", 20, 0); @@ -628,6 +636,9 @@ void NativeShutdownGraphics() { ui_draw2d.Shutdown(); ui_draw2d_front.Shutdown(); + colorPipeline->Release(); + texColorPipeline->Release(); + // TODO: Reconsider this annoying ref counting stuff. if (thin3d->Release()) { thin3d = nullptr; diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index dec33f86d153..b4926117ff3b 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -161,26 +161,14 @@ void DrawContext::CreatePresets() { fsPresets_[FS_TEXTURE_COLOR_2D] = CreateShaderModule(ShaderStage::FRAGMENT, glsl_fsTexCol, hlslFsTexCol, vulkan_fsTexCol); fsPresets_[FS_COLOR_2D] = CreateShaderModule(ShaderStage::FRAGMENT, glsl_fsCol, hlslFsCol, vulkan_fsCol); - - ssPresets_[SS_TEXTURE_COLOR_2D] = CreatePipeline({ {vsPresets_[VS_TEXTURE_COLOR_2D], fsPresets_[FS_TEXTURE_COLOR_2D]} }); - ssPresets_[SS_COLOR_2D] = CreatePipeline({{vsPresets_[VS_COLOR_2D], fsPresets_[FS_COLOR_2D]}}); } DrawContext::~DrawContext() { for (int i = 0; i < VS_MAX_PRESET; i++) { - if (vsPresets_[i]) { - vsPresets_[i]->Release(); - } + vsPresets_[i]->Release(); } for (int i = 0; i < FS_MAX_PRESET; i++) { - if (fsPresets_[i]) { - fsPresets_[i]->Release(); - } - } - for (int i = 0; i < SS_MAX_PRESET; i++) { - if (ssPresets_[i]) { - ssPresets_[i]->Release(); - } + fsPresets_[i]->Release(); } } diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 676684633f42..14e0c9250032 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -136,13 +136,6 @@ enum FragmentShaderPreset : int { FS_MAX_PRESET, }; -// Predefined full shader setups. -enum ShaderSetPreset : int { - SS_COLOR_2D, - SS_TEXTURE_COLOR_2D, - SS_MAX_PRESET, -}; - enum ClearFlag : int { COLOR = 1, DEPTH = 2, @@ -453,7 +446,7 @@ class DrawContext : public RefCountedObject { 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 *CreatePipeline(const PipelineDesc &desc) = 0; + virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0; virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0; virtual Texture *CreateTexture() = 0; // To be later filled in by ->LoadFromFile or similar. @@ -466,7 +459,6 @@ class DrawContext : public RefCountedObject { // Note that these DO NOT AddRef so you must not ->Release presets unless you manually AddRef them. ShaderModule *GetVshaderPreset(VertexShaderPreset preset) { return fsPresets_[preset]; } ShaderModule *GetFshaderPreset(FragmentShaderPreset preset) { return vsPresets_[preset]; } - Pipeline *GetShaderSetPreset(ShaderSetPreset preset) { return ssPresets_[preset]; } // 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; @@ -514,7 +506,6 @@ class DrawContext : public RefCountedObject { ShaderModule *vsPresets_[VS_MAX_PRESET]; ShaderModule *fsPresets_[FS_MAX_PRESET]; - Pipeline *ssPresets_[SS_MAX_PRESET]; int targetWidth_; int targetHeight_; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index cfb84838551e..7eb51b6f887d 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -460,7 +460,7 @@ class D3D9Context : public DrawContext { SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; RasterState *CreateRasterState(const RasterStateDesc &desc) override; Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override; - Pipeline *CreatePipeline(const PipelineDesc &desc) override; + Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override; InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override; Texture *CreateTexture() override; Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; @@ -548,21 +548,21 @@ ShaderModule *D3D9Context::CreateShaderModule(ShaderStage stage, const char *gls } } -Pipeline *D3D9Context::CreatePipeline(const PipelineDesc &desc) { +Pipeline *D3D9Context::CreateGraphicsPipeline(const PipelineDesc &desc) { if (!desc.shaders.size()) { - ELOG("ShaderSet requires at least one shader"); + ELOG("Pipeline requires at least one shader"); return NULL; } - D3D9Pipeline *shaderSet = new D3D9Pipeline(device_); + D3D9Pipeline *pipeline = new D3D9Pipeline(device_); for (auto iter : desc.shaders) { if (iter->GetStage() == ShaderStage::FRAGMENT) { - shaderSet->pshader = static_cast(iter); + pipeline->pshader = static_cast(iter); } else if (iter->GetStage() == ShaderStage::VERTEX) { - shaderSet->vshader = static_cast(iter); + pipeline->vshader = static_cast(iter); } } - return shaderSet; + return pipeline; } DepthStencilState *D3D9Context::CreateDepthStencilState(const DepthStencilStateDesc &desc) { diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 91551d1a759b..5330ac94670c 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -268,7 +268,7 @@ GLuint ShaderStageToOpenGL(ShaderStage stage) { } } -// Not registering this as a resource holder, instead ShaderSet is registered. It will +// Not registering this as a resource holder, instead Pipeline is registered. It will // invoke Compile again to recreate the shader then link them together. class OpenGLShaderModule : public ShaderModule { public: @@ -411,7 +411,7 @@ class OpenGLContext : public DrawContext { SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; RasterState *CreateRasterState(const RasterStateDesc &desc) override; Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override; - Pipeline *CreatePipeline(const PipelineDesc &desc) override; + Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override; InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override; Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; Texture *CreateTexture() override; @@ -802,20 +802,20 @@ Buffer *OpenGLContext::CreateBuffer(size_t size, uint32_t usageFlags) { return new OpenGLBuffer(size, usageFlags); } -Pipeline *OpenGLContext::CreatePipeline(const PipelineDesc &desc) { +Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { if (!desc.shaders.size()) { - ELOG("ShaderSet requires at least one shader"); + ELOG("Pipeline requires at least one shader"); return NULL; } - OpenGLPipeline *shaderSet = new OpenGLPipeline(); + OpenGLPipeline *pipeline = new OpenGLPipeline(); for (auto iter : desc.shaders) { iter->AddRef(); - shaderSet->shaders.push_back(static_cast(iter)); + pipeline->shaders.push_back(static_cast(iter)); } - if (shaderSet->Link()) { - return shaderSet; + if (pipeline->Link()) { + return pipeline; } else { - delete shaderSet; + delete pipeline; return NULL; } } @@ -1027,7 +1027,7 @@ void OpenGLInputLayout::Apply(const void *base) { intptr_t b = (intptr_t)base; if (b != lastBase_) { for (size_t i = 0; i < desc.attributes.size(); i++) { - size_t stride = desc.bindings[desc.attributes[i].binding].stride; + GLsizei stride = (GLsizei)desc.bindings[desc.attributes[i].binding].stride; switch (desc.attributes[i].format) { case DataFormat::R32G32_FLOAT: glVertexAttribPointer(desc.attributes[i].location, 2, GL_FLOAT, GL_FALSE, stride, (void *)(b + (intptr_t)desc.attributes[i].offset)); diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 52886c0b62e8..0a60e8049759 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -231,7 +231,7 @@ VkShaderStageFlagBits StageToVulkan(ShaderStage stage) { } } -// Not registering this as a resource holder, instead ShaderSet is registered. It will +// Not registering this as a resource holder, instead the pipeline is registered. It will // invoke Compile again to recreate the shader then link them together. class VKShaderModule : public ShaderModule { public: @@ -347,7 +347,7 @@ class VKPipeline : public Pipeline { struct PipelineKey { VKDepthStencilState *depthStencil; VKBlendState *blend; - VKPipeline *shaderSet; + VKPipeline *pipeline; VkPrimitiveTopology topology; VKRasterState *raster; @@ -356,7 +356,7 @@ struct PipelineKey { 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 (shaderSet < other.shaderSet) return true; else if (shaderSet > other.shaderSet) 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 @@ -393,7 +393,7 @@ class VKContext : public DrawContext { InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override; SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; RasterState *CreateRasterState(const RasterStateDesc &desc) override; - Pipeline *CreatePipeline(const PipelineDesc &desc) override; + Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override; // The implementation makes the choice of which shader code to use. ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override; @@ -865,7 +865,7 @@ VkPipeline VKContext::GetOrCreatePipeline() { PipelineKey key; key.blend = curBlendState_; key.depthStencil = curDepthStencilState_; - key.shaderSet = curPipeline_; + key.pipeline = curPipeline_; key.topology = curPrim_; key.raster = curRasterState_; @@ -1058,20 +1058,20 @@ Buffer *VKContext::CreateBuffer(size_t size, uint32_t usageFlags) { return new Thin3DVKBuffer(size, usageFlags); } -Pipeline *VKContext::CreatePipeline(const PipelineDesc &desc) { +Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { if (!desc.shaders.size()) { - ELOG("ShaderSet requires at least one shader"); + ELOG("Pipeline requires at least one shader"); return NULL; } - VKPipeline *shaderSet = new VKPipeline(); + VKPipeline *pipeline = new VKPipeline(); for (auto iter : desc.shaders) { iter->AddRef(); - shaderSet->shaders.push_back(static_cast(iter)); + pipeline->shaders.push_back(static_cast(iter)); } - if (shaderSet->Link()) { - return shaderSet; + if (pipeline->Link()) { + return pipeline; } else { - delete shaderSet; + delete pipeline; return NULL; } }