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(const vk::Device *device, 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 bool depthClipEnable : 1; 85 }; 86 87 struct State : States 88 { 89 bool operator==(const State &state) const; 90 91 uint32_t hash; 92 }; 93 94 using RoutineType = VertexRoutineFunction::RoutineType; 95 96 VertexProcessor(); 97 98 const State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *vertexShader, const vk::Inputs &inputs); 99 RoutineType routine(const State &state, vk::PipelineLayout const *pipelineLayout, 100 SpirvShader const *vertexShader, const vk::DescriptorSet::Bindings &descriptorSets); 101 102 void setRoutineCacheSize(int cacheSize); 103 104 private: 105 using RoutineCacheType = RoutineCache<State, VertexRoutineFunction::CFunctionType>; 106 std::unique_ptr<RoutineCacheType> routineCache; 107 }; 108 109 } // namespace sw 110 111 namespace std { 112 113 template<> 114 struct hash<sw::VertexProcessor::State> 115 { operator ()std::hash116 uint64_t operator()(const sw::VertexProcessor::State &state) const 117 { 118 return state.hash; 119 } 120 }; 121 122 } // namespace std 123 124 #endif // sw_VertexProcessor_hpp 125