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