Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(421)

Side by Side Diff: src/gpu/vk/GrVkProgramCache.cpp

Issue 1816153002: Set up cache in vulkan to reuse GrVkPrograms (aka VkPipelines) (Closed) Base URL: https://skia.googlesource.com/skia.git@progSamplers
Patch Set: cleanup Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2016 Google Inc.
bsalomon 2016/03/22 14:00:33 spaces?
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrGLGpu.h" 8 #include "GrVkResourceProvider.h"
9 9
10 #include "builders/GrGLProgramBuilder.h" 10 #include "GrVkGpu.h"
11 #include "GrProcessor.h" 11 #include "GrProcessor.h"
12 #include "GrGLPathRendering.h" 12 #include "GrVkProgram.h"
13 #include "GrVkProgramBuilder.h"
14 #include "SkRTConf.h"
15 #include "SkTSearch.h"
13 #include "glsl/GrGLSLFragmentProcessor.h" 16 #include "glsl/GrGLSLFragmentProcessor.h"
14 #include "glsl/GrGLSLProgramDataManager.h" 17 #include "glsl/GrGLSLProgramDataManager.h"
15 #include "SkRTConf.h"
16 #include "SkTSearch.h"
17 18
18 #ifdef PROGRAM_CACHE_STATS 19 #ifdef PROGRAM_CACHE_STATS
19 SK_CONF_DECLARE(bool, c_DisplayCache, "gpu.displayCache", false, 20 SK_CONF_DECLARE(bool, c_DisplayCache, "gpu.displayCache", false,
20 "Display program cache usage."); 21 "Display program cache usage.");
21 #endif 22 #endif
22 23
23 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; 24 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
24 25
25 struct GrGLGpu::ProgramCache::Entry { 26 struct GrVkResourceProvider::ProgramCache::Entry {
26 27
27 Entry() : fProgram(nullptr), fLRUStamp(0) {} 28 Entry() : fProgram(nullptr), fLRUStamp(0) {}
28 29
29 SkAutoTUnref<GrGLProgram> fProgram; 30 SkAutoTUnref<GrVkProgram> fProgram;
30 unsigned int fLRUStamp; 31 unsigned int fLRUStamp;
31 }; 32 };
32 33
33 struct GrGLGpu::ProgramCache::ProgDescLess { 34 struct GrVkResourceProvider::ProgramCache::PipelineDescLess {
34 bool operator() (const GrProgramDesc& desc, const Entry* entry) { 35 bool operator() (const GrVkProgram::PipelineDesc& desc, const Entry* entry) {
35 SkASSERT(entry->fProgram.get()); 36 SkASSERT(entry->fProgram.get());
36 return GrProgramDesc::Less(desc, entry->fProgram->getDesc()); 37 return GrVkProgram::PipelineDesc::Less(desc, entry->fProgram->getDesc()) ;
37 } 38 }
38 39
39 bool operator() (const Entry* entry, const GrProgramDesc& desc) { 40 bool operator() (const Entry* entry, const GrVkProgram::PipelineDesc& desc) {
40 SkASSERT(entry->fProgram.get()); 41 SkASSERT(entry->fProgram.get());
41 return GrProgramDesc::Less(entry->fProgram->getDesc(), desc); 42 return GrVkProgram::PipelineDesc::Less(entry->fProgram->getDesc(), desc) ;
42 } 43 }
43 }; 44 };
44 45
45 GrGLGpu::ProgramCache::ProgramCache(GrGLGpu* gpu) 46 GrVkResourceProvider::ProgramCache::ProgramCache(GrVkGpu* gpu)
46 : fCount(0) 47 : fCount(0)
47 , fCurrLRUStamp(0) 48 , fCurrLRUStamp(0)
48 , fGpu(gpu) 49 , fGpu(gpu)
49 #ifdef PROGRAM_CACHE_STATS 50 #ifdef PROGRAM_CACHE_STATS
50 , fTotalRequests(0) 51 , fTotalRequests(0)
51 , fCacheMisses(0) 52 , fCacheMisses(0)
52 , fHashMisses(0) 53 , fHashMisses(0)
53 #endif 54 #endif
54 { 55 {
55 for (int i = 0; i < 1 << kHashBits; ++i) { 56 for (int i = 0; i < 1 << kHashBits; ++i) {
56 fHashTable[i] = nullptr; 57 fHashTable[i] = nullptr;
57 } 58 }
58 } 59 }
59 60
60 GrGLGpu::ProgramCache::~ProgramCache() { 61 GrVkResourceProvider::ProgramCache::~ProgramCache() {
61 for (int i = 0; i < fCount; ++i){ 62 SkASSERT(0 == fCount);
62 delete fEntries[i];
63 }
64 // dump stats 63 // dump stats
65 #ifdef PROGRAM_CACHE_STATS 64 #ifdef PROGRAM_CACHE_STATS
66 if (c_DisplayCache) { 65 if (c_DisplayCache) {
67 SkDebugf("--- Program Cache ---\n"); 66 SkDebugf("--- Program Cache ---\n");
68 SkDebugf("Total requests: %d\n", fTotalRequests); 67 SkDebugf("Total requests: %d\n", fTotalRequests);
69 SkDebugf("Cache misses: %d\n", fCacheMisses); 68 SkDebugf("Cache misses: %d\n", fCacheMisses);
70 SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ? 69 SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ?
71 100.f * fCacheMisses / fTotalRequest s : 70 100.f * fCacheMisses / fTotalRequests :
72 0.f); 71 0.f);
73 int cacheHits = fTotalRequests - fCacheMisses; 72 int cacheHits = fTotalRequests - fCacheMisses;
74 SkDebugf("Hash miss %%: %f\n", (cacheHits > 0) ? 100.f * fHashMisses / c acheHits : 0.f); 73 SkDebugf("Hash miss %%: %f\n", (cacheHits > 0) ? 100.f * fHashMisses / c acheHits : 0.f);
75 SkDebugf("---------------------\n"); 74 SkDebugf("---------------------\n");
76 } 75 }
77 #endif 76 #endif
78 } 77 }
79 78
80 void GrGLGpu::ProgramCache::reset() { 79 void GrVkResourceProvider::ProgramCache::reset() {
81 for (int i = 0; i < fCount; ++i) { 80 for (int i = 0; i < fCount; ++i) {
82 SkASSERT(fEntries[i]->fProgram.get());
83 fEntries[i]->fProgram->abandon();
84 delete fEntries[i]; 81 delete fEntries[i];
85 fEntries[i] = nullptr; 82 fEntries[i] = nullptr;
86 } 83 }
87 fCount = 0; 84 fCount = 0;
88 85
89 // zero out hash table 86 // zero out hash table
90 for (int i = 0; i < 1 << kHashBits; i++) { 87 for (int i = 0; i < 1 << kHashBits; i++) {
91 fHashTable[i] = nullptr; 88 fHashTable[i] = nullptr;
92 } 89 }
93 90
94 fCurrLRUStamp = 0; 91 fCurrLRUStamp = 0;
95 #ifdef PROGRAM_CACHE_STATS
96 fTotalRequests = 0;
97 fCacheMisses = 0;
98 fHashMisses = 0;
99 #endif
100 } 92 }
101 93
102 void GrGLGpu::ProgramCache::abandon() { 94 void GrVkResourceProvider::ProgramCache::abandon() {
95 for (int i = 0; i < fCount; ++i) {
96 SkASSERT(fEntries[i]->fProgram.get());
97 fEntries[i]->fProgram->abandonGPUResources();
98 }
103 this->reset(); 99 this->reset();
104 } 100 }
105 101
106 int GrGLGpu::ProgramCache::search(const GrProgramDesc& desc) const { 102 void GrVkResourceProvider::ProgramCache::release() {
107 ProgDescLess less; 103 for (int i = 0; i < fCount; ++i) {
104 SkASSERT(fEntries[i]->fProgram.get());
105 fEntries[i]->fProgram->freeGPUResources(fGpu);
106 }
107 this->reset();
108 }
109
110 int GrVkResourceProvider::ProgramCache::search(const GrVkProgram::PipelineDesc& desc) const {
111 PipelineDescLess less;
108 return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less); 112 return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less);
109 } 113 }
110 114
111 GrGLProgram* GrGLGpu::ProgramCache::refProgram(const GrGLGpu* gpu, 115 GrVkProgram* GrVkResourceProvider::ProgramCache::refProgram(const GrPipeline& pi peline,
112 const GrPipeline& pipeline, 116 const GrPrimitivePro cessor& primProc,
113 const GrPrimitiveProcessor& primP roc) { 117 GrPrimitiveType prim iteType,
118 const GrVkRenderPass & renderPass) {
114 #ifdef PROGRAM_CACHE_STATS 119 #ifdef PROGRAM_CACHE_STATS
115 ++fTotalRequests; 120 ++fTotalRequests;
116 #endif 121 #endif
117 122
118 // Get GrGLProgramDesc 123 Entry* entry = nullptr;
119 GrGLProgramDesc desc; 124
120 if (!GrGLProgramDescBuilder::Build(&desc, primProc, pipeline, *gpu->glCaps() .glslCaps())) { 125 // Get GrVkProgramDesc
121 GrCapsDebugf(gpu->caps(), "Failed to gl program descriptor!\n"); 126 GrVkProgram::PipelineDesc desc;
122 return nullptr; 127 if (!GrVkProgramDescBuilder::Build(&desc.fProgramDesc,
128 primProc,
129 pipeline,
130 *fGpu->vkCaps().glslCaps())) {
131 GrCapsDebugf(fGpu->caps(), "Failed to vk program descriptor!\n");
jvanverth1 2016/03/21 21:16:16 Failed to build?
132 return false;
123 } 133 }
124 134
125 Entry* entry = nullptr; 135 // Get vulkan specific descriptor key
136 GrVkProgram::BuildVkKey(pipeline, primiteType, &desc.fVkKey);
137 // Get checksum of entire PipelineDesc
138 int keyLength = desc.fVkKey.count();
139 SkASSERT(0 == (keyLength % 4));
140 // Seed the checksum with the checksome of the programDesc then add the vulk an key to it.
jvanverth1 2016/03/21 21:16:16 Checksum (sp)
141 desc.fChecksum = SkChecksum::Murmur3(desc.fVkKey.begin(), keyLength,
142 desc.fProgramDesc.getChecksum());
126 143
127 uint32_t hashIdx = desc.getChecksum(); 144 uint32_t hashIdx = desc.fChecksum;
128 hashIdx ^= hashIdx >> 16; 145 hashIdx ^= hashIdx >> 16;
129 if (kHashBits <= 8) { 146 if (kHashBits <= 8) {
130 hashIdx ^= hashIdx >> 8; 147 hashIdx ^= hashIdx >> 8;
131 } 148 }
132 hashIdx &=((1 << kHashBits) - 1); 149 hashIdx &= ((1 << kHashBits) - 1);
133 Entry* hashedEntry = fHashTable[hashIdx]; 150 Entry* hashedEntry = fHashTable[hashIdx];
134 if (hashedEntry && hashedEntry->fProgram->getDesc() == desc) { 151 if (hashedEntry && hashedEntry->fProgram->getDesc() == desc) {
135 SkASSERT(hashedEntry->fProgram); 152 SkASSERT(hashedEntry->fProgram);
136 entry = hashedEntry; 153 entry = hashedEntry;
137 } 154 }
138 155
139 int entryIdx; 156 int entryIdx;
140 if (nullptr == entry) { 157 if (nullptr == entry) {
141 entryIdx = this->search(desc); 158 entryIdx = this->search(desc);
142 if (entryIdx >= 0) { 159 if (entryIdx >= 0) {
143 entry = fEntries[entryIdx]; 160 entry = fEntries[entryIdx];
144 #ifdef PROGRAM_CACHE_STATS 161 #ifdef PROGRAM_CACHE_STATS
145 ++fHashMisses; 162 ++fHashMisses;
146 #endif 163 #endif
147 } 164 }
148 } 165 }
149 166
150 if (nullptr == entry) { 167 if (nullptr == entry) {
151 // We have a cache miss 168 // We have a cache miss
152 #ifdef PROGRAM_CACHE_STATS 169 #ifdef PROGRAM_CACHE_STATS
153 ++fCacheMisses; 170 ++fCacheMisses;
154 #endif 171 #endif
155 GrGLProgram* program = GrGLProgramBuilder::CreateProgram(pipeline, primP roc, desc, fGpu); 172 GrVkProgram* program = GrVkProgramBuilder::CreateProgram(fGpu,
173 pipeline,
174 primProc,
175 primiteType,
176 desc,
177 renderPass);
156 if (nullptr == program) { 178 if (nullptr == program) {
157 return nullptr; 179 return nullptr;
158 } 180 }
159 int purgeIdx = 0; 181 int purgeIdx = 0;
160 if (fCount < kMaxEntries) { 182 if (fCount < kMaxEntries) {
161 entry = new Entry; 183 entry = new Entry;
162 purgeIdx = fCount++; 184 purgeIdx = fCount++;
163 fEntries[purgeIdx] = entry; 185 fEntries[purgeIdx] = entry;
164 } else { 186 } else {
165 SkASSERT(fCount == kMaxEntries); 187 SkASSERT(fCount == kMaxEntries);
166 purgeIdx = 0; 188 purgeIdx = 0;
167 for (int i = 1; i < kMaxEntries; ++i) { 189 for (int i = 1; i < kMaxEntries; ++i) {
168 if (fEntries[i]->fLRUStamp < fEntries[purgeIdx]->fLRUStamp) { 190 if (fEntries[i]->fLRUStamp < fEntries[purgeIdx]->fLRUStamp) {
169 purgeIdx = i; 191 purgeIdx = i;
170 } 192 }
171 } 193 }
172 entry = fEntries[purgeIdx]; 194 entry = fEntries[purgeIdx];
173 int purgedHashIdx = entry->fProgram->getDesc().getChecksum() & ((1 < < kHashBits) - 1); 195 int purgedHashIdx = entry->fProgram->getDesc().fChecksum & ((1 << kH ashBits) - 1);
174 if (fHashTable[purgedHashIdx] == entry) { 196 if (fHashTable[purgedHashIdx] == entry) {
175 fHashTable[purgedHashIdx] = nullptr; 197 fHashTable[purgedHashIdx] = nullptr;
176 } 198 }
199 entry->fProgram->freeGPUResources(fGpu);
177 } 200 }
178 SkASSERT(fEntries[purgeIdx] == entry); 201 SkASSERT(fEntries[purgeIdx] == entry);
179 entry->fProgram.reset(program); 202 entry->fProgram.reset(program);
180 // We need to shift fEntries around so that the entry currently at purge Idx is placed 203 // We need to shift fEntries around so that the entry currently at purge Idx is placed
181 // just before the entry at ~entryIdx (in order to keep fEntries sorted by descriptor). 204 // just before the entry at ~entryIdx (in order to keep fEntries sorted by descriptor).
182 entryIdx = ~entryIdx; 205 entryIdx = ~entryIdx;
183 if (entryIdx < purgeIdx) { 206 if (entryIdx < purgeIdx) {
184 // Let E and P be the entries at index entryIdx and purgeIdx, respe ctively. 207 // Let E and P be the entries at index entryIdx and purgeIdx, respe ctively.
185 // If the entries array looks like this: 208 // If the entries array looks like this:
186 // aaaaEbbbbbPccccc 209 // aaaaEbbbbbPccccc
187 // we rearrange it to look like this: 210 // we rearrange it to look like this:
188 // aaaaPEbbbbbccccc 211 // aaaaPEbbbbbccccc
189 size_t copySize = (purgeIdx - entryIdx) * sizeof(Entry*); 212 size_t copySize = (purgeIdx - entryIdx) * sizeof(Entry*);
190 memmove(fEntries + entryIdx + 1, fEntries + entryIdx, copySize); 213 memmove(fEntries + entryIdx + 1, fEntries + entryIdx, copySize);
191 fEntries[entryIdx] = entry; 214 fEntries[entryIdx] = entry;
192 } else if (purgeIdx < entryIdx) { 215 } else if (purgeIdx < entryIdx) {
193 // If the entries array looks like this: 216 // If the entries array looks like this:
194 // aaaaPbbbbbEccccc 217 // aaaaPbbbbbEccccc
195 // we rearrange it to look like this: 218 // we rearrange it to look like this:
196 // aaaabbbbbPEccccc 219 // aaaabbbbbPEccccc
197 size_t copySize = (entryIdx - purgeIdx - 1) * sizeof(Entry*); 220 size_t copySize = (entryIdx - purgeIdx - 1) * sizeof(Entry*);
198 memmove(fEntries + purgeIdx, fEntries + purgeIdx + 1, copySize); 221 memmove(fEntries + purgeIdx, fEntries + purgeIdx + 1, copySize);
199 fEntries[entryIdx - 1] = entry; 222 fEntries[entryIdx - 1] = entry;
200 } 223 }
201 #ifdef SK_DEBUG 224 #ifdef SK_DEBUG
202 SkASSERT(fEntries[0]->fProgram.get()); 225 SkASSERT(fEntries[0]->fProgram.get());
203 for (int i = 0; i < fCount - 1; ++i) { 226 for (int i = 0; i < fCount - 1; ++i) {
204 SkASSERT(fEntries[i + 1]->fProgram.get()); 227 SkASSERT(fEntries[i + 1]->fProgram.get());
205 const GrProgramDesc& a = fEntries[i]->fProgram->getDesc(); 228 const GrVkProgram::PipelineDesc& a = fEntries[i]->fProgram->getDesc( );
206 const GrProgramDesc& b = fEntries[i + 1]->fProgram->getDesc(); 229 const GrVkProgram::PipelineDesc& b = fEntries[i + 1]->fProgram->getD esc();
207 SkASSERT(GrProgramDesc::Less(a, b)); 230 SkASSERT(GrVkProgram::PipelineDesc::Less(a, b));
208 SkASSERT(!GrProgramDesc::Less(b, a)); 231 SkASSERT(!GrVkProgram::PipelineDesc::Less(b, a));
209 } 232 }
210 #endif 233 #endif
211 } 234 }
212 235
213 fHashTable[hashIdx] = entry; 236 fHashTable[hashIdx] = entry;
214 entry->fLRUStamp = fCurrLRUStamp; 237 entry->fLRUStamp = fCurrLRUStamp;
215 238
216 if (SK_MaxU32 == fCurrLRUStamp) { 239 if (SK_MaxU32 == fCurrLRUStamp) {
217 // wrap around! just trash our LRU, one time hit. 240 // wrap around! just trash our LRU, one time hit.
218 for (int i = 0; i < fCount; ++i) { 241 for (int i = 0; i < fCount; ++i) {
219 fEntries[i]->fLRUStamp = 0; 242 fEntries[i]->fLRUStamp = 0;
220 } 243 }
221 } 244 }
222 ++fCurrLRUStamp; 245 ++fCurrLRUStamp;
223 return SkRef(entry->fProgram.get()); 246 return SkRef(entry->fProgram.get());
224 } 247 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698