1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef sw_VertexProcessor_hpp 16 #define sw_VertexProcessor_hpp 17 18 #include "Context.hpp" 19 #include "Memset.hpp" 20 #include "RoutineCache.hpp" 21 #include "Vertex.hpp" 22 #include "Pipeline/SpirvShader.hpp" 23 24 #include <memory> 25 26 namespace sw { 27 28 struct DrawData; 29 30 // Basic direct mapped vertex cache. 31 struct VertexCache 32 { 33 static constexpr uint32_t SIZE = 64; // TODO: Variable size? 34 static constexpr uint32_t TAG_MASK = SIZE - 1; // Size must be power of 2. 35 36 void clear(); 37 38 Vertex vertex[SIZE]; 39 uint32_t tag[SIZE]; 40 41 // Identifier of the draw call for the cache data. If this cache is 42 // used with a different draw call, then the cache should be invalidated 43 // before use. 44 int drawCall = -1; 45 }; 46 47 struct VertexTask 48 { 49 unsigned int vertexCount; 50 unsigned int primitiveStart; 51 VertexCache vertexCache; 52 }; 53 54 using VertexRoutineFunction = FunctionT<void(Vertex *output, unsigned int *batch, VertexTask *vertextask, DrawData *draw)>; 55 56 class VertexProcessor 57 { 58 public: 59 struct States : Memset<States> 60 { Statessw::VertexProcessor::States61 States() 62 : Memset(this, 0) 63 {} 64 65 uint32_t computeHash(); 66 67 uint64_t shaderID; 68 uint32_t pipelineLayoutIdentifier; 69 70 struct Input 71 { operator boolsw::VertexProcessor::States::Input72 operator bool() const // Returns true if stream contains data 73 { 74 return format != VK_FORMAT_UNDEFINED; 75 } 76 77 VkFormat format; // TODO(b/148016460): Could be restricted to VK_FORMAT_END_RANGE 78 unsigned int attribType : BITS(SpirvShader::ATTRIBTYPE_LAST); 79 }; 80 81 Input input[MAX_INTERFACE_COMPONENTS / 4]; 82 bool robustBufferAccess : 1; 83 bool isPoint : 1; 84 }; 85 86 struct State : States 87 { 88 bool operator==(const State &state) const; 89 90 uint32_t hash; 91 }; 92 93 using RoutineType = VertexRoutineFunction::RoutineType; 94 95 VertexProcessor(); 96 97 const State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *vertexShader, const vk::Inputs &inputs); 98 RoutineType routine(const State &state, vk::PipelineLayout const *pipelineLayout, 99 SpirvShader const *vertexShader, const vk::DescriptorSet::Bindings &descriptorSets); 100 101 void setRoutineCacheSize(int cacheSize); 102 103 private: 104 using RoutineCacheType = RoutineCache<State, VertexRoutineFunction::CFunctionType>; 105 std::unique_ptr<RoutineCacheType> routineCache; 106 }; 107 108 } // namespace sw 109 110 namespace std { 111 112 template<> 113 struct hash<sw::VertexProcessor::State> 114 { operator ()std::hash115 uint64_t operator()(const sw::VertexProcessor::State &state) const 116 { 117 return state.hash; 118 } 119 }; 120 121 } // namespace std 122 123 #endif // sw_VertexProcessor_hpp 124