1 // Copyright (c) 2013- 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 <vector> 21 22 #include "Common/CommonTypes.h" 23 #include "Common/Data/Collections/Hashmaps.h" 24 25 #include "GPU/GPUState.h" 26 #include "GPU/Common/GPUDebugInterface.h" 27 #include "GPU/Common/IndexGenerator.h" 28 #include "GPU/Common/VertexDecoderCommon.h" 29 30 class VertexDecoder; 31 32 enum { 33 VERTEX_BUFFER_MAX = 65536, 34 DECODED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 64, 35 DECODED_INDEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 16, 36 }; 37 38 inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) { 39 // As the decoder depends on the UVGenMode when we use UV prescale, we simply mash it 40 // into the top of the verttype where there are unused bits. 41 return (vertType & 0xFFFFFF) | (uvGenMode << 24); 42 } 43 44 struct SimpleVertex; 45 namespace Spline { struct Weight2D; } 46 47 class TessellationDataTransfer { 48 public: 49 virtual ~TessellationDataTransfer() {} 50 void CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType); 51 virtual void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) = 0; 52 }; 53 54 class DrawEngineCommon { 55 public: 56 DrawEngineCommon(); 57 virtual ~DrawEngineCommon(); 58 59 void Init(); 60 61 bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices); 62 63 static u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, VertexDecoder *dec, int lowerBound, int upperBound, u32 vertType); 64 65 // Flush is normally non-virtual but here's a virtual way to call it, used by the shared spline code, which is expensive anyway. 66 // Not really sure if these wrappers are worth it... 67 virtual void DispatchFlush() = 0; 68 69 // This would seem to be unnecessary now, but is still required for splines/beziers to work in the software backend since SubmitPrim 70 // is different. Should probably refactor that. 71 // Note that vertTypeID should be computed using GetVertTypeID(). 72 virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { 73 SubmitPrim(verts, inds, prim, vertexCount, vertTypeID, cullMode, bytesRead); 74 } 75 76 bool TestBoundingBox(void* control_points, int vertexCount, u32 vertType, int *bytesRead); 77 78 void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead); 79 template<class Surface> 80 void SubmitCurve(const void *control_points, const void *indices, Surface &surface, u32 vertType, int *bytesRead, const char *scope); 81 void ClearSplineBezierWeights(); 82 83 bool CanUseHardwareTransform(int prim); 84 bool CanUseHardwareTessellation(GEPatchPrimType prim); 85 86 std::vector<std::string> DebugGetVertexLoaderIDs(); 87 std::string DebugGetVertexLoaderString(std::string id, DebugShaderStringType stringType); 88 89 virtual void Resized(); 90 91 bool IsCodePtrVertexDecoder(const u8 *ptr) const { 92 return decJitCache_->IsInSpace(ptr); 93 } 94 int GetNumDrawCalls() const { 95 return numDrawCalls; 96 } 97 98 VertexDecoder *GetVertexDecoder(u32 vtype); 99 100 protected: 101 virtual bool UpdateUseHWTessellation(bool enabled) { return enabled; } 102 virtual void ClearTrackedVertexArrays() {} 103 104 int ComputeNumVertsToDecode() const; 105 void DecodeVerts(u8 *dest); 106 107 // Preprocessing for spline/bezier 108 u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType, int *vertexSize = nullptr); 109 110 // Utility for vertex caching 111 u32 ComputeMiniHash(); 112 uint64_t ComputeHash(); 113 114 // Vertex decoding 115 void DecodeVertsStep(u8 *dest, int &i, int &decodedVerts); 116 117 bool ApplyFramebufferRead(bool *fboTexNeedsBind); 118 119 inline int IndexSize(u32 vtype) const { 120 const u32 indexType = (vtype & GE_VTYPE_IDX_MASK); 121 if (indexType == GE_VTYPE_IDX_16BIT) { 122 return 2; 123 } else if (indexType == GE_VTYPE_IDX_32BIT) { 124 return 4; 125 } 126 return 1; 127 } 128 129 bool useHWTransform_ = false; 130 bool useHWTessellation_ = false; 131 132 // Vertex collector buffers 133 u8 *decoded = nullptr; 134 u16 *decIndex = nullptr; 135 136 // Cached vertex decoders 137 u32 lastVType_ = -1; 138 DenseHashMap<u32, VertexDecoder *, nullptr> decoderMap_; 139 VertexDecoder *dec_ = nullptr; 140 VertexDecoderJitCache *decJitCache_ = nullptr; 141 VertexDecoderOptions decOptions_{}; 142 143 TransformedVertex *transformed = nullptr; 144 TransformedVertex *transformedExpanded = nullptr; 145 146 // Defer all vertex decoding to a "Flush" (except when software skinning) 147 struct DeferredDrawCall { 148 void *verts; 149 void *inds; 150 u32 vertexCount; 151 u8 indexType; 152 s8 prim; 153 u16 indexLowerBound; 154 u16 indexUpperBound; 155 UVScale uvScale; 156 int cullMode; 157 }; 158 159 enum { MAX_DEFERRED_DRAW_CALLS = 128 }; 160 DeferredDrawCall drawCalls[MAX_DEFERRED_DRAW_CALLS]; 161 int numDrawCalls = 0; 162 int vertexCountInDrawCalls_ = 0; 163 164 int decimationCounter_ = 0; 165 int decodeCounter_ = 0; 166 u32 dcid_ = 0; 167 168 // Vertex collector state 169 IndexGenerator indexGen; 170 int decodedVerts_ = 0; 171 GEPrimitiveType prevPrim_ = GE_PRIM_INVALID; 172 173 // Shader blending state 174 bool fboTexNeedsBind_ = false; 175 bool fboTexBound_ = false; 176 177 // Hardware tessellation 178 TessellationDataTransfer *tessDataTransfer; 179 }; 180