1 // Copyright (c) 2017- PPSSPP Project. 2 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, version 2.0 or later versions. 6 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License 2.0 for more details. 11 12 // A copy of the GPL 2.0 should have been included with the program. 13 // If not, see http://www.gnu.org/licenses/ 14 15 // Official git repository and contact information can be found at 16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. 17 18 #pragma once 19 20 #include <map> 21 22 #include <d3d11.h> 23 24 #include "Common/Common.h" 25 #include "GPU/Common/ShaderCommon.h" 26 #include "GPU/Common/ShaderId.h" 27 #include "GPU/Common/ShaderUniforms.h" 28 #include "GPU/Common/FragmentShaderGenerator.h" 29 30 class D3D11Context; 31 class D3D11PushBuffer; 32 33 class D3D11FragmentShader { 34 public: 35 D3D11FragmentShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, FShaderID id, const char *code, bool useHWTransform); 36 ~D3D11FragmentShader(); 37 source()38 const std::string &source() const { return source_; } 39 Failed()40 bool Failed() const { return failed_; } UseHWTransform()41 bool UseHWTransform() const { return useHWTransform_; } 42 43 std::string GetShaderString(DebugShaderStringType type) const; GetShader()44 ID3D11PixelShader *GetShader() const { return module_; } 45 46 protected: 47 ID3D11PixelShader *module_ = nullptr; 48 49 ID3D11Device *device_; 50 std::string source_; 51 bool failed_ = false; 52 bool useHWTransform_; 53 FShaderID id_; 54 }; 55 56 class D3D11VertexShader { 57 public: 58 D3D11VertexShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, VShaderID id, const char *code, int vertType, bool useHWTransform); 59 ~D3D11VertexShader(); 60 source()61 const std::string &source() const { return source_; } bytecode()62 const std::vector<uint8_t> &bytecode() const { return bytecode_; } Failed()63 bool Failed() const { return failed_; } UseHWTransform()64 bool UseHWTransform() const { return useHWTransform_; } 65 66 std::string GetShaderString(DebugShaderStringType type) const; GetShader()67 ID3D11VertexShader *GetShader() const { return module_; } 68 69 protected: 70 ID3D11VertexShader *module_ = nullptr; 71 72 ID3D11Device *device_; 73 std::string source_; 74 std::vector<uint8_t> bytecode_; 75 76 bool failed_ = false; 77 bool useHWTransform_; 78 VShaderID id_; 79 }; 80 81 class D3D11PushBuffer; 82 83 class ShaderManagerD3D11 : public ShaderManagerCommon { 84 public: 85 ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel); 86 ~ShaderManagerD3D11(); 87 88 void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat); 89 void ClearShaders(); 90 void DirtyLastShader() override; 91 GetNumVertexShaders()92 int GetNumVertexShaders() const { return (int)vsCache_.size(); } GetNumFragmentShaders()93 int GetNumFragmentShaders() const { return (int)fsCache_.size(); } 94 95 std::vector<std::string> DebugGetShaderIDs(DebugShaderType type); 96 std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType); 97 98 uint64_t UpdateUniforms(bool useBufferedRendering); 99 void BindUniforms(); 100 101 // TODO: Avoid copying these buffers if same as last draw, can still point to it assuming we're still in the same pushbuffer. 102 // Applies dirty changes and copies the buffer. IsBaseDirty()103 bool IsBaseDirty() { return true; } IsLightDirty()104 bool IsLightDirty() { return true; } IsBoneDirty()105 bool IsBoneDirty() { return true; } 106 107 private: 108 void Clear(); 109 110 ID3D11Device *device_; 111 ID3D11DeviceContext *context_; 112 D3D_FEATURE_LEVEL featureLevel_; 113 114 typedef std::map<FShaderID, D3D11FragmentShader *> FSCache; 115 FSCache fsCache_; 116 117 typedef std::map<VShaderID, D3D11VertexShader *> VSCache; 118 VSCache vsCache_; 119 120 char *codeBuffer_; 121 122 // Uniform block scratchpad. These (the relevant ones) are copied to the current pushbuffer at draw time. 123 UB_VS_FS_Base ub_base; 124 UB_VS_Lights ub_lights; 125 UB_VS_Bones ub_bones; 126 127 // Not actual pushbuffers, requires D3D11.1, let's try to live without that first. 128 ID3D11Buffer *push_base; 129 ID3D11Buffer *push_lights; 130 ID3D11Buffer *push_bones; 131 132 D3D11FragmentShader *lastFShader_ = nullptr; 133 D3D11VertexShader *lastVShader_ = nullptr; 134 135 FShaderID lastFSID_; 136 VShaderID lastVSID_; 137 }; 138