| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #include <algorithm> | ||
| #include <cstring> | ||
|
|
||
| #include "Common/Assert.h" | ||
| #include "Common/Logging/Log.h" | ||
|
|
||
| #include "VideoBackends/D3D/D3DBase.h" | ||
| #include "VideoBackends/D3D/D3DState.h" | ||
| #include "VideoBackends/D3D/DXPipeline.h" | ||
| #include "VideoBackends/D3D/DXShader.h" | ||
| #include "VideoBackends/D3D/DXTexture.h" | ||
| #include "VideoBackends/D3D/Render.h" | ||
| #include "VideoBackends/D3D/VertexManager.h" | ||
|
|
||
| namespace DX11 | ||
| { | ||
| DXPipeline::DXPipeline(ID3D11InputLayout* input_layout, ID3D11VertexShader* vertex_shader, | ||
| ID3D11GeometryShader* geometry_shader, ID3D11PixelShader* pixel_shader, | ||
| ID3D11RasterizerState* rasterizer_state, | ||
| ID3D11DepthStencilState* depth_state, ID3D11BlendState* blend_state, | ||
| D3D11_PRIMITIVE_TOPOLOGY primitive_topology) | ||
| : m_input_layout(input_layout), m_vertex_shader(vertex_shader), | ||
| m_geometry_shader(geometry_shader), m_pixel_shader(pixel_shader), | ||
| m_rasterizer_state(rasterizer_state), m_depth_state(depth_state), m_blend_state(blend_state), | ||
| m_primitive_topology(primitive_topology) | ||
| { | ||
| if (m_input_layout) | ||
| m_input_layout->AddRef(); | ||
| if (m_vertex_shader) | ||
| m_vertex_shader->AddRef(); | ||
| if (m_geometry_shader) | ||
| m_geometry_shader->AddRef(); | ||
| if (m_pixel_shader) | ||
| m_pixel_shader->AddRef(); | ||
| if (m_rasterizer_state) | ||
| m_rasterizer_state->AddRef(); | ||
| if (m_depth_state) | ||
| m_depth_state->AddRef(); | ||
| if (m_blend_state) | ||
| m_blend_state->AddRef(); | ||
| } | ||
|
|
||
| DXPipeline::~DXPipeline() | ||
| { | ||
| if (m_input_layout) | ||
| m_input_layout->Release(); | ||
| if (m_vertex_shader) | ||
| m_vertex_shader->Release(); | ||
| if (m_geometry_shader) | ||
| m_geometry_shader->Release(); | ||
| if (m_pixel_shader) | ||
| m_pixel_shader->Release(); | ||
| if (m_rasterizer_state) | ||
| m_rasterizer_state->Release(); | ||
| if (m_depth_state) | ||
| m_depth_state->Release(); | ||
| if (m_blend_state) | ||
| m_blend_state->Release(); | ||
| } | ||
|
|
||
| std::unique_ptr<DXPipeline> DXPipeline::Create(const AbstractPipelineConfig& config) | ||
| { | ||
| StateCache& state_cache = static_cast<Renderer*>(g_renderer.get())->GetStateCache(); | ||
| ID3D11RasterizerState* rasterizer_state = state_cache.Get(config.rasterization_state); | ||
| ID3D11DepthStencilState* depth_state = state_cache.Get(config.depth_state); | ||
| ID3D11BlendState* blend_state = state_cache.Get(config.blending_state); | ||
| D3D11_PRIMITIVE_TOPOLOGY primitive_topology = | ||
| StateCache::GetPrimitiveTopology(config.rasterization_state.primitive); | ||
| if (!rasterizer_state || !depth_state || !blend_state) | ||
| { | ||
| SAFE_RELEASE(rasterizer_state); | ||
| SAFE_RELEASE(depth_state); | ||
| SAFE_RELEASE(blend_state); | ||
| return nullptr; | ||
| } | ||
|
|
||
| const DXShader* vertex_shader = static_cast<const DXShader*>(config.vertex_shader); | ||
| const DXShader* geometry_shader = static_cast<const DXShader*>(config.geometry_shader); | ||
| const DXShader* pixel_shader = static_cast<const DXShader*>(config.pixel_shader); | ||
| _assert_(vertex_shader != nullptr && pixel_shader != nullptr); | ||
|
|
||
| ID3D11InputLayout* input_layout = | ||
| const_cast<D3DVertexFormat*>(static_cast<const D3DVertexFormat*>(config.vertex_format)) | ||
| ->GetInputLayout(vertex_shader->GetByteCode()); | ||
|
|
||
| return std::make_unique<DXPipeline>(input_layout, vertex_shader->GetD3DVertexShader(), | ||
| geometry_shader ? geometry_shader->GetD3DGeometryShader() : | ||
| nullptr, | ||
| pixel_shader->GetD3DPixelShader(), rasterizer_state, | ||
| depth_state, blend_state, primitive_topology); | ||
| } | ||
| } // namespace DX11 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <d3d11.h> | ||
| #include <memory> | ||
| #include "VideoCommon/AbstractPipeline.h" | ||
|
|
||
| namespace DX11 | ||
| { | ||
| class DXPipeline final : public AbstractPipeline | ||
| { | ||
| public: | ||
| DXPipeline(ID3D11InputLayout* input_layout, ID3D11VertexShader* vertex_shader, | ||
| ID3D11GeometryShader* geometry_shader, ID3D11PixelShader* pixel_shader, | ||
| ID3D11RasterizerState* rasterizer_state, ID3D11DepthStencilState* depth_state, | ||
| ID3D11BlendState* blend_state, D3D11_PRIMITIVE_TOPOLOGY primitive_topology); | ||
| ~DXPipeline() override; | ||
|
|
||
| ID3D11InputLayout* GetInputLayout() const { return m_input_layout; } | ||
| ID3D11VertexShader* GetVertexShader() const { return m_vertex_shader; } | ||
| ID3D11GeometryShader* GetGeometryShader() const { return m_geometry_shader; } | ||
| ID3D11PixelShader* GetPixelShader() const { return m_pixel_shader; } | ||
| ID3D11RasterizerState* GetRasterizerState() const { return m_rasterizer_state; } | ||
| ID3D11DepthStencilState* GetDepthState() const { return m_depth_state; } | ||
| ID3D11BlendState* GetBlendState() const { return m_blend_state; } | ||
| D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveTopology() const { return m_primitive_topology; } | ||
| bool HasGeometryShader() const { return m_geometry_shader != nullptr; } | ||
| static std::unique_ptr<DXPipeline> Create(const AbstractPipelineConfig& config); | ||
|
|
||
| private: | ||
| ID3D11InputLayout* m_input_layout; | ||
| ID3D11VertexShader* m_vertex_shader; | ||
| ID3D11GeometryShader* m_geometry_shader; | ||
| ID3D11PixelShader* m_pixel_shader; | ||
| ID3D11RasterizerState* m_rasterizer_state; | ||
| ID3D11DepthStencilState* m_depth_state; | ||
| ID3D11BlendState* m_blend_state; | ||
| D3D11_PRIMITIVE_TOPOLOGY m_primitive_topology; | ||
| }; | ||
| } // namespace DX11 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #include "Common/Assert.h" | ||
|
|
||
| #include "VideoBackends/D3D/D3DBase.h" | ||
| #include "VideoBackends/D3D/D3DShader.h" | ||
| #include "VideoBackends/D3D/DXShader.h" | ||
|
|
||
| namespace DX11 | ||
| { | ||
| DXShader::DXShader(D3DBlob* bytecode, ID3D11VertexShader* vs) | ||
| : AbstractShader(ShaderStage::Vertex), m_bytecode(bytecode), m_shader(vs) | ||
| { | ||
| } | ||
|
|
||
| DXShader::DXShader(D3DBlob* bytecode, ID3D11GeometryShader* gs) | ||
| : AbstractShader(ShaderStage::Geometry), m_bytecode(bytecode), m_shader(gs) | ||
| { | ||
| } | ||
|
|
||
| DXShader::DXShader(D3DBlob* bytecode, ID3D11PixelShader* ps) | ||
| : AbstractShader(ShaderStage::Pixel), m_bytecode(bytecode), m_shader(ps) | ||
| { | ||
| } | ||
|
|
||
| DXShader::DXShader(D3DBlob* bytecode, ID3D11ComputeShader* cs) | ||
| : AbstractShader(ShaderStage::Compute), m_bytecode(bytecode), m_shader(cs) | ||
| { | ||
| } | ||
|
|
||
| DXShader::~DXShader() | ||
| { | ||
| m_shader->Release(); | ||
| m_bytecode->Release(); | ||
| } | ||
|
|
||
| D3DBlob* DXShader::GetByteCode() const | ||
| { | ||
| return m_bytecode; | ||
| } | ||
|
|
||
| ID3D11VertexShader* DXShader::GetD3DVertexShader() const | ||
| { | ||
| _dbg_assert_(VIDEO, m_stage == ShaderStage::Vertex); | ||
| return static_cast<ID3D11VertexShader*>(m_shader); | ||
| } | ||
|
|
||
| ID3D11GeometryShader* DXShader::GetD3DGeometryShader() const | ||
| { | ||
| _dbg_assert_(VIDEO, m_stage == ShaderStage::Geometry); | ||
| return static_cast<ID3D11GeometryShader*>(m_shader); | ||
| } | ||
|
|
||
| ID3D11PixelShader* DXShader::GetD3DPixelShader() const | ||
| { | ||
| _dbg_assert_(VIDEO, m_stage == ShaderStage::Pixel); | ||
| return static_cast<ID3D11PixelShader*>(m_shader); | ||
| } | ||
|
|
||
| ID3D11ComputeShader* DXShader::GetD3DComputeShader() const | ||
| { | ||
| _dbg_assert_(VIDEO, m_stage == ShaderStage::Compute); | ||
| return static_cast<ID3D11ComputeShader*>(m_shader); | ||
| } | ||
|
|
||
| bool DXShader::HasBinary() const | ||
| { | ||
| _assert_(m_bytecode); | ||
| return true; | ||
| } | ||
|
|
||
| AbstractShader::BinaryData DXShader::GetBinary() const | ||
| { | ||
| return BinaryData(m_bytecode->Data(), m_bytecode->Data() + m_bytecode->Size()); | ||
| } | ||
|
|
||
| std::unique_ptr<DXShader> DXShader::CreateFromBlob(ShaderStage stage, D3DBlob* bytecode) | ||
| { | ||
| switch (stage) | ||
| { | ||
| case ShaderStage::Vertex: | ||
| { | ||
| ID3D11VertexShader* vs = D3D::CreateVertexShaderFromByteCode(bytecode); | ||
| if (vs) | ||
| return std::make_unique<DXShader>(bytecode, vs); | ||
| } | ||
| break; | ||
|
|
||
| case ShaderStage::Geometry: | ||
| { | ||
| ID3D11GeometryShader* gs = D3D::CreateGeometryShaderFromByteCode(bytecode); | ||
| if (gs) | ||
| return std::make_unique<DXShader>(bytecode, gs); | ||
| } | ||
| break; | ||
|
|
||
| case ShaderStage::Pixel: | ||
| { | ||
| ID3D11PixelShader* ps = D3D::CreatePixelShaderFromByteCode(bytecode); | ||
| if (ps) | ||
| return std::make_unique<DXShader>(bytecode, ps); | ||
| } | ||
| break; | ||
|
|
||
| case ShaderStage::Compute: | ||
| { | ||
| ID3D11ComputeShader* cs = D3D::CreateComputeShaderFromByteCode(bytecode); | ||
| if (cs) | ||
| return std::make_unique<DXShader>(bytecode, cs); | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
| break; | ||
| } | ||
|
|
||
| return nullptr; | ||
| } | ||
|
|
||
| std::unique_ptr<DXShader> DXShader::CreateFromSource(ShaderStage stage, const char* source, | ||
| size_t length) | ||
| { | ||
| D3DBlob* bytecode; | ||
| switch (stage) | ||
| { | ||
| case ShaderStage::Vertex: | ||
| { | ||
| if (!D3D::CompileVertexShader(std::string(source, length), &bytecode)) | ||
| return nullptr; | ||
| } | ||
| break; | ||
|
|
||
| case ShaderStage::Geometry: | ||
| { | ||
| if (!D3D::CompileGeometryShader(std::string(source, length), &bytecode)) | ||
| return nullptr; | ||
| } | ||
| break; | ||
|
|
||
| case ShaderStage::Pixel: | ||
| { | ||
| if (!D3D::CompilePixelShader(std::string(source, length), &bytecode)) | ||
| return nullptr; | ||
| } | ||
| break; | ||
|
|
||
| case ShaderStage::Compute: | ||
| { | ||
| if (!D3D::CompileComputeShader(std::string(source, length), &bytecode)) | ||
| return nullptr; | ||
| } | ||
|
|
||
| default: | ||
| return nullptr; | ||
| } | ||
|
|
||
| std::unique_ptr<DXShader> shader = CreateFromBlob(stage, bytecode); | ||
| if (!shader) | ||
| { | ||
| bytecode->Release(); | ||
| return nullptr; | ||
| } | ||
|
|
||
| return shader; | ||
| } | ||
|
|
||
| std::unique_ptr<DXShader> DXShader::CreateFromBinary(ShaderStage stage, const void* data, | ||
| size_t length) | ||
| { | ||
| D3DBlob* bytecode = new D3DBlob(static_cast<unsigned int>(length), static_cast<const u8*>(data)); | ||
| std::unique_ptr<DXShader> shader = CreateFromBlob(stage, bytecode); | ||
| if (!shader) | ||
| { | ||
| bytecode->Release(); | ||
| return nullptr; | ||
| } | ||
|
|
||
| return shader; | ||
| } | ||
|
|
||
| } // namespace DX11 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cstddef> | ||
| #include <d3d11.h> | ||
| #include <memory> | ||
| #include "Common/CommonTypes.h" | ||
|
|
||
| #include "VideoBackends/D3D/D3DBlob.h" | ||
| #include "VideoCommon/AbstractShader.h" | ||
|
|
||
| namespace DX11 | ||
| { | ||
| class DXShader final : public AbstractShader | ||
| { | ||
| public: | ||
| // Note: vs/gs/ps/cs references are transferred. | ||
| DXShader(D3DBlob* bytecode, ID3D11VertexShader* vs); | ||
| DXShader(D3DBlob* bytecode, ID3D11GeometryShader* gs); | ||
| DXShader(D3DBlob* bytecode, ID3D11PixelShader* ps); | ||
| DXShader(D3DBlob* bytecode, ID3D11ComputeShader* cs); | ||
| ~DXShader() override; | ||
|
|
||
| D3DBlob* GetByteCode() const; | ||
| ID3D11VertexShader* GetD3DVertexShader() const; | ||
| ID3D11GeometryShader* GetD3DGeometryShader() const; | ||
| ID3D11PixelShader* GetD3DPixelShader() const; | ||
| ID3D11ComputeShader* GetD3DComputeShader() const; | ||
|
|
||
| bool HasBinary() const override; | ||
| BinaryData GetBinary() const override; | ||
|
|
||
| // Creates a new shader object. The reference to bytecode is not transfered upon failure. | ||
| static std::unique_ptr<DXShader> CreateFromBlob(ShaderStage stage, D3DBlob* bytecode); | ||
| static std::unique_ptr<DXShader> CreateFromBinary(ShaderStage stage, const void* data, | ||
| size_t length); | ||
| static std::unique_ptr<DXShader> CreateFromSource(ShaderStage stage, const char* source, | ||
| size_t length); | ||
|
|
||
| private: | ||
| ID3D11DeviceChild* m_shader; | ||
| D3DBlob* m_bytecode; | ||
| }; | ||
|
|
||
| } // namespace DX11 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #include "Common/Assert.h" | ||
|
|
||
| #include "VideoBackends/OGL/OGLPipeline.h" | ||
| #include "VideoBackends/OGL/OGLShader.h" | ||
| #include "VideoBackends/OGL/ProgramShaderCache.h" | ||
| #include "VideoBackends/OGL/Render.h" | ||
| #include "VideoBackends/OGL/VertexManager.h" | ||
|
|
||
| namespace OGL | ||
| { | ||
| static GLenum MapToGLPrimitive(PrimitiveType primitive_type) | ||
| { | ||
| switch (primitive_type) | ||
| { | ||
| case PrimitiveType::Points: | ||
| return GL_POINTS; | ||
| case PrimitiveType::Lines: | ||
| return GL_LINES; | ||
| case PrimitiveType::Triangles: | ||
| return GL_TRIANGLES; | ||
| case PrimitiveType::TriangleStrip: | ||
| return GL_TRIANGLE_STRIP; | ||
| default: | ||
| return 0; | ||
| } | ||
| } | ||
| OGLPipeline::OGLPipeline(const GLVertexFormat* vertex_format, | ||
| const RasterizationState& rasterization_state, | ||
| const DepthState& depth_state, const BlendingState& blending_state, | ||
| const PipelineProgram* program, GLuint gl_primitive) | ||
| : m_vertex_format(vertex_format), m_rasterization_state(rasterization_state), | ||
| m_depth_state(depth_state), m_blending_state(blending_state), m_program(program), | ||
| m_gl_primitive(gl_primitive) | ||
| { | ||
| } | ||
|
|
||
| OGLPipeline::~OGLPipeline() | ||
| { | ||
| // We don't want to destroy the shaders. | ||
| ProgramShaderCache::ReleasePipelineProgram(m_program); | ||
| } | ||
|
|
||
| std::unique_ptr<OGLPipeline> OGLPipeline::Create(const AbstractPipelineConfig& config) | ||
| { | ||
| const PipelineProgram* program = | ||
| ProgramShaderCache::GetPipelineProgram(static_cast<const OGLShader*>(config.vertex_shader), | ||
| static_cast<const OGLShader*>(config.geometry_shader), | ||
| static_cast<const OGLShader*>(config.pixel_shader)); | ||
| if (!program) | ||
| return nullptr; | ||
|
|
||
| const GLVertexFormat* vertex_format = static_cast<const GLVertexFormat*>(config.vertex_format); | ||
| GLenum gl_primitive = MapToGLPrimitive(config.rasterization_state.primitive); | ||
| return std::make_unique<OGLPipeline>(vertex_format, config.rasterization_state, | ||
| config.depth_state, config.blending_state, program, | ||
| gl_primitive); | ||
| } | ||
| } // namespace OGL |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <memory> | ||
|
|
||
| #include "Common/GL/GLUtil.h" | ||
| #include "VideoBackends/OGL/ProgramShaderCache.h" | ||
| #include "VideoCommon/AbstractPipeline.h" | ||
| #include "VideoCommon/RenderState.h" | ||
|
|
||
| namespace OGL | ||
| { | ||
| class OGLPipeline final : public AbstractPipeline | ||
| { | ||
| public: | ||
| explicit OGLPipeline(const GLVertexFormat* vertex_format, | ||
| const RasterizationState& rasterization_state, const DepthState& depth_state, | ||
| const BlendingState& blending_state, const PipelineProgram* program, | ||
| GLenum gl_primitive); | ||
| ~OGLPipeline() override; | ||
|
|
||
| const GLVertexFormat* GetVertexFormat() const { return m_vertex_format; } | ||
| const RasterizationState& GetRasterizationState() const { return m_rasterization_state; } | ||
| const DepthState& GetDepthState() const { return m_depth_state; } | ||
| const BlendingState& GetBlendingState() const { return m_blending_state; } | ||
| const PipelineProgram* GetProgram() const { return m_program; } | ||
| bool HasVertexInput() const { return m_vertex_format != nullptr; } | ||
| GLenum GetGLPrimitive() const { return m_gl_primitive; } | ||
| static std::unique_ptr<OGLPipeline> Create(const AbstractPipelineConfig& config); | ||
|
|
||
| private: | ||
| const GLVertexFormat* m_vertex_format; | ||
| RasterizationState m_rasterization_state; | ||
| DepthState m_depth_state; | ||
| BlendingState m_blending_state; | ||
| const PipelineProgram* m_program; | ||
| GLenum m_gl_primitive; | ||
| }; | ||
|
|
||
| } // namespace OGL |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #include "VideoBackends/OGL/OGLShader.h" | ||
| #include "VideoBackends/OGL/ProgramShaderCache.h" | ||
|
|
||
| namespace OGL | ||
| { | ||
| static GLenum GetGLShaderTypeForStage(ShaderStage stage) | ||
| { | ||
| switch (stage) | ||
| { | ||
| case ShaderStage::Vertex: | ||
| return GL_VERTEX_SHADER; | ||
| case ShaderStage::Geometry: | ||
| return GL_GEOMETRY_SHADER; | ||
| case ShaderStage::Pixel: | ||
| return GL_FRAGMENT_SHADER; | ||
| case ShaderStage::Compute: | ||
| return GL_COMPUTE_SHADER; | ||
| default: | ||
| return 0; | ||
| } | ||
| } | ||
|
|
||
| OGLShader::OGLShader(ShaderStage stage, GLenum gl_type, GLuint shader_id) | ||
| : AbstractShader(stage), m_type(gl_type), m_id(shader_id) | ||
| { | ||
| } | ||
|
|
||
| OGLShader::OGLShader(GLuint compute_program_id) | ||
| : AbstractShader(ShaderStage::Compute), m_type(GL_COMPUTE_SHADER), m_id(compute_program_id) | ||
| { | ||
| } | ||
|
|
||
| OGLShader::~OGLShader() | ||
| { | ||
| if (m_stage != ShaderStage::Compute) | ||
| glDeleteShader(m_id); | ||
| else | ||
| glDeleteProgram(m_compute_program_id); | ||
| } | ||
|
|
||
| bool OGLShader::HasBinary() const | ||
| { | ||
| // NOTE: GL shaders do not have binaries, programs do. | ||
| return false; | ||
| } | ||
|
|
||
| AbstractShader::BinaryData OGLShader::GetBinary() const | ||
| { | ||
| return {}; | ||
| } | ||
|
|
||
| std::unique_ptr<OGLShader> OGLShader::CreateFromSource(ShaderStage stage, const char* source, | ||
| size_t length) | ||
| { | ||
| if (stage != ShaderStage::Compute) | ||
| { | ||
| GLenum shader_type = GetGLShaderTypeForStage(stage); | ||
| GLuint shader_id = | ||
| ProgramShaderCache::CompileSingleShader(shader_type, std::string(source, length)); | ||
| if (!shader_id) | ||
| return nullptr; | ||
|
|
||
| return std::make_unique<OGLShader>(stage, shader_type, shader_id); | ||
| } | ||
|
|
||
| // Compute shaders. | ||
| SHADER prog; | ||
| if (!ProgramShaderCache::CompileComputeShader(prog, std::string(source, length))) | ||
| return nullptr; | ||
| return std::make_unique<OGLShader>(prog.glprogid); | ||
| } | ||
|
|
||
| } // namespace OGL |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cstddef> | ||
| #include <memory> | ||
|
|
||
| #include "Common/CommonTypes.h" | ||
| #include "Common/GL/GLUtil.h" | ||
| #include "VideoCommon/AbstractShader.h" | ||
|
|
||
| namespace OGL | ||
| { | ||
| class OGLShader final : public AbstractShader | ||
| { | ||
| public: | ||
| explicit OGLShader(ShaderStage stage, GLenum gl_type, GLuint shader_id); | ||
| explicit OGLShader(GLuint compute_program_id); | ||
| ~OGLShader() override; | ||
|
|
||
| GLenum GetGLShaderType() const { return m_type; } | ||
| GLuint GetGLShaderID() const { return m_id; } | ||
| GLuint GetGLComputeProgramID() const { return m_compute_program_id; } | ||
| bool HasBinary() const override; | ||
| BinaryData GetBinary() const override; | ||
|
|
||
| static std::unique_ptr<OGLShader> CreateFromSource(ShaderStage stage, const char* source, | ||
| size_t length); | ||
|
|
||
| private: | ||
| GLenum m_type; | ||
| GLuint m_id; | ||
| GLuint m_compute_program_id; | ||
| }; | ||
|
|
||
| } // namespace OGL |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #include "Common/Assert.h" | ||
| #include "Common/MsgHandler.h" | ||
|
|
||
| #include "VideoBackends/Vulkan/ObjectCache.h" | ||
| #include "VideoBackends/Vulkan/Util.h" | ||
| #include "VideoBackends/Vulkan/VKPipeline.h" | ||
| #include "VideoBackends/Vulkan/VKShader.h" | ||
| #include "VideoBackends/Vulkan/VertexFormat.h" | ||
| #include "VideoBackends/Vulkan/VulkanContext.h" | ||
|
|
||
| namespace Vulkan | ||
| { | ||
| VKPipeline::VKPipeline(VkPipeline pipeline) : m_pipeline(pipeline) | ||
| { | ||
| } | ||
|
|
||
| VKPipeline::~VKPipeline() | ||
| { | ||
| vkDestroyPipeline(g_vulkan_context->GetDevice(), m_pipeline, nullptr); | ||
| } | ||
|
|
||
| std::unique_ptr<VKPipeline> VKPipeline::Create(const AbstractPipelineConfig& config) | ||
| { | ||
| _dbg_assert_(VIDEO, config.vertex_shader && config.pixel_shader); | ||
|
|
||
| // Get render pass for config. | ||
| VkRenderPass render_pass = g_object_cache->GetRenderPass( | ||
| Util::GetVkFormatForHostTextureFormat(config.framebuffer_state.color_texture_format), | ||
| VK_FORMAT_UNDEFINED, config.framebuffer_state.samples, VK_ATTACHMENT_LOAD_OP_LOAD); | ||
|
|
||
| // Get pipeline layout. | ||
| VkPipelineLayout pipeline_layout; | ||
| switch (config.usage) | ||
| { | ||
| case AbstractPipelineUsage::GX: | ||
| pipeline_layout = g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD); | ||
| break; | ||
| case AbstractPipelineUsage::Utility: | ||
| pipeline_layout = g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_UTILITY); | ||
| break; | ||
| default: | ||
| PanicAlert("Unknown pipeline layout."); | ||
| return nullptr; | ||
| } | ||
|
|
||
| // TODO: Move ShaderCache stuff to here. | ||
| PipelineInfo pinfo; | ||
| pinfo.vertex_format = static_cast<const VertexFormat*>(config.vertex_format); | ||
| pinfo.pipeline_layout = pipeline_layout; | ||
| pinfo.vs = static_cast<const VKShader*>(config.vertex_shader)->GetShaderModule(); | ||
| pinfo.ps = static_cast<const VKShader*>(config.pixel_shader)->GetShaderModule(); | ||
| pinfo.gs = config.geometry_shader ? | ||
| static_cast<const VKShader*>(config.geometry_shader)->GetShaderModule() : | ||
| VK_NULL_HANDLE; | ||
| pinfo.render_pass = render_pass; | ||
| pinfo.rasterization_state.hex = config.rasterization_state.hex; | ||
| pinfo.depth_state.hex = config.depth_state.hex; | ||
| pinfo.blend_state.hex = config.blending_state.hex; | ||
| pinfo.multisampling_state.hex = 0; | ||
| pinfo.multisampling_state.samples = config.framebuffer_state.samples; | ||
| pinfo.multisampling_state.per_sample_shading = config.framebuffer_state.per_sample_shading; | ||
|
|
||
| VkPipeline pipeline = g_shader_cache->CreatePipeline(pinfo); | ||
| if (pipeline == VK_NULL_HANDLE) | ||
| return nullptr; | ||
|
|
||
| return std::make_unique<VKPipeline>(pipeline); | ||
| } | ||
| } // namespace Vulkan |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Copyright 2017 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <memory> | ||
|
|
||
| #include "VideoBackends/Vulkan/VulkanLoader.h" | ||
| #include "VideoCommon/AbstractPipeline.h" | ||
|
|
||
| namespace Vulkan | ||
| { | ||
| class VKPipeline final : public AbstractPipeline | ||
| { | ||
| public: | ||
| explicit VKPipeline(VkPipeline pipeline); | ||
| ~VKPipeline() override; | ||
|
|
||
| VkPipeline GetPipeline() const { return m_pipeline; } | ||
| static std::unique_ptr<VKPipeline> Create(const AbstractPipelineConfig& config); | ||
|
|
||
| private: | ||
| VkPipeline m_pipeline; | ||
| }; | ||
|
|
||
| } // namespace Vulkan |