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

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

Issue 1718693002: Add vulkan files into skia repo. (Closed) Base URL: https://skia.googlesource.com/skia.git@merge
Patch Set: fix path Created 4 years, 10 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
« no previous file with comments | « src/gpu/vk/GrVkProgram.h ('k') | src/gpu/vk/GrVkProgramBuilder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "GrVkProgram.h"
9
10 #include "GrPipeline.h"
11 #include "GrVkCommandBuffer.h"
12 #include "GrVkDescriptorPool.h"
13 #include "GrVkGpu.h"
14 #include "GrVkImageView.h"
15 #include "GrVkMemory.h"
16 #include "GrVkPipeline.h"
17 #include "GrVkSampler.h"
18 #include "GrVkTexture.h"
19 #include "GrVkUniformBuffer.h"
20 #include "glsl/GrGLSLFragmentProcessor.h"
21 #include "glsl/GrGLSLGeometryProcessor.h"
22 #include "glsl/GrGLSLXferProcessor.h"
23
24 GrVkProgram::GrVkProgram(GrVkGpu* gpu,
25 GrVkPipeline* pipeline,
26 VkPipelineLayout layout,
27 VkDescriptorSetLayout dsLayout[2],
28 GrVkDescriptorPool* descriptorPool,
29 VkDescriptorSet descriptorSets[2],
30 const BuiltinUniformHandles& builtinUniformHandles,
31 const UniformInfoArray& uniforms,
32 uint32_t vertexUniformSize,
33 uint32_t fragmentUniformSize,
34 uint32_t numSamplers,
35 GrGLSLPrimitiveProcessor* geometryProcessor,
36 GrGLSLXferProcessor* xferProcessor,
37 const GrGLSLFragProcs& fragmentProcessors)
38 : fDescriptorPool(descriptorPool)
39 , fPipeline(pipeline)
40 , fPipelineLayout(layout)
41 , fBuiltinUniformHandles(builtinUniformHandles)
42 , fGeometryProcessor(geometryProcessor)
43 , fXferProcessor(xferProcessor)
44 , fFragmentProcessors(fragmentProcessors)
45 , fProgramDataManager(uniforms, vertexUniformSize, fragmentUniformSize) {
46 fSamplers.setReserve(numSamplers);
47 fTextureViews.setReserve(numSamplers);
48 fTextures.setReserve(numSamplers);
49
50 memcpy(fDSLayout, dsLayout, 2 * sizeof(VkDescriptorSetLayout));
51 memcpy(fDescriptorSets, descriptorSets, 2 * sizeof(VkDescriptorSetLayout));
52
53 fVertexUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, vertexUniformSize, true));
54 fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformS ize, true));
55
56 #ifdef SK_DEBUG
57 fNumSamplers = numSamplers;
58 #endif
59 }
60
61 GrVkProgram::~GrVkProgram() {
62 // Must of freed all GPU resources before this is destroyed
63 SkASSERT(!fPipeline);
64 SkASSERT(!fDescriptorPool);
65 SkASSERT(!fPipelineLayout);
66 SkASSERT(!fDSLayout[0]);
67 SkASSERT(!fDSLayout[1]);
68 SkASSERT(!fSamplers.count());
69 SkASSERT(!fTextureViews.count());
70 SkASSERT(!fTextures.count());
71 }
72
73 void GrVkProgram::freeTempResources(const GrVkGpu* gpu) {
74 for (int i = 0; i < fSamplers.count(); ++i) {
75 fSamplers[i]->unref(gpu);
76 }
77 fSamplers.rewind();
78
79 for (int i = 0; i < fTextureViews.count(); ++i) {
80 fTextureViews[i]->unref(gpu);
81 }
82 fTextureViews.rewind();
83
84 for (int i = 0; i < fTextures.count(); ++i) {
85 fTextures[i]->unref(gpu);
86 }
87 fTextures.rewind();
88 }
89
90 void GrVkProgram::freeGPUResources(const GrVkGpu* gpu) {
91 if (fPipeline) {
92 fPipeline->unref(gpu);
93 fPipeline = nullptr;
94 }
95 if (fDescriptorPool) {
96 fDescriptorPool->unref(gpu);
97 fDescriptorPool = nullptr;
98 }
99 if (fPipelineLayout) {
100 GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(),
101 fPipelineLayout,
102 nullptr));
103 fPipelineLayout = nullptr;
104 }
105
106 if (fDSLayout[0]) {
107 GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDSLayout[0],
108 nullptr));
109 fDSLayout[0] = nullptr;
110 }
111 if (fDSLayout[1]) {
112 GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDSLayout[1],
113 nullptr));
114 fDSLayout[1] = nullptr;
115 }
116
117 if (fVertexUniformBuffer) {
118 fVertexUniformBuffer->release(gpu);
119 }
120
121 if (fFragmentUniformBuffer) {
122 fFragmentUniformBuffer->release(gpu);
123 }
124 this->freeTempResources(gpu);
125 }
126
127 void GrVkProgram::abandonGPUResources() {
128 fPipeline->unrefAndAbandon();
129 fPipeline = nullptr;
130 fDescriptorPool->unrefAndAbandon();
131 fDescriptorPool = nullptr;
132 fPipelineLayout = nullptr;
133 fDSLayout[0] = nullptr;
134 fDSLayout[1] = nullptr;
135
136 fVertexUniformBuffer->abandon();
137 fFragmentUniformBuffer->abandon();
138
139 for (int i = 0; i < fSamplers.count(); ++i) {
140 fSamplers[i]->unrefAndAbandon();
141 }
142 fSamplers.rewind();
143
144 for (int i = 0; i < fTextureViews.count(); ++i) {
145 fTextureViews[i]->unrefAndAbandon();
146 }
147 fTextureViews.rewind();
148
149 for (int i = 0; i < fTextures.count(); ++i) {
150 fTextures[i]->unrefAndAbandon();
151 }
152 fTextures.rewind();
153 }
154
155 static void append_texture_bindings(const GrProcessor& processor,
156 SkTArray<const GrTextureAccess*>* textureBin dings) {
157 if (int numTextures = processor.numTextures()) {
158 const GrTextureAccess** bindings = textureBindings->push_back_n(numTextu res);
159 int i = 0;
160 do {
161 bindings[i] = &processor.textureAccess(i);
162 } while (++i < numTextures);
163 }
164 }
165
166 void GrVkProgram::setData(const GrVkGpu* gpu,
167 const GrPrimitiveProcessor& primProc,
168 const GrPipeline& pipeline) {
169 // This is here to protect against someone calling setData multiple times in a row without
170 // freeing the tempData between calls.
171 this->freeTempResources(gpu);
172
173 this->setRenderTargetState(pipeline);
174
175 SkSTArray<8, const GrTextureAccess*> textureBindings;
176
177 fGeometryProcessor->setData(fProgramDataManager, primProc);
178 append_texture_bindings(primProc, &textureBindings);
179
180 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
181 const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i);
182 fFragmentProcessors[i]->setData(fProgramDataManager, processor);
183 fGeometryProcessor->setTransformData(primProc, fProgramDataManager, i,
184 processor.coordTransforms());
185 append_texture_bindings(processor, &textureBindings);
186 }
187
188 fXferProcessor->setData(fProgramDataManager, pipeline.getXferProcessor());
189 append_texture_bindings(pipeline.getXferProcessor(), &textureBindings);
190
191 this->writeUniformBuffers(gpu);
192
193 this->writeSamplers(gpu, textureBindings);
194 }
195
196 void GrVkProgram::writeUniformBuffers(const GrVkGpu* gpu) {
197 fProgramDataManager.uploadUniformBuffers(gpu, fVertexUniformBuffer, fFragmen tUniformBuffer);
198
199 VkWriteDescriptorSet descriptorWrites[2];
200 memset(descriptorWrites, 0, 2 * sizeof(VkWriteDescriptorSet));
201
202 uint32_t firstUniformWrite = 0;
203 uint32_t uniformBindingUpdateCount = 0;
204
205 // Vertex Uniform Buffer
206 if (fVertexUniformBuffer.get()) {
207 ++uniformBindingUpdateCount;
208 VkDescriptorBufferInfo vertBufferInfo;
209 memset(&vertBufferInfo, 0, sizeof(VkDescriptorBufferInfo));
210 vertBufferInfo.buffer = fVertexUniformBuffer->buffer();
211 vertBufferInfo.offset = 0;
212 vertBufferInfo.range = fVertexUniformBuffer->size();
213
214 descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
215 descriptorWrites[0].pNext = nullptr;
216 descriptorWrites[0].dstSet = fDescriptorSets[1];
217 descriptorWrites[0].dstBinding = GrVkUniformHandler::kVertexBinding;
218 descriptorWrites[0].dstArrayElement = 0;
219 descriptorWrites[0].descriptorCount = 1;
220 descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
221 descriptorWrites[0].pImageInfo = nullptr;
222 descriptorWrites[0].pBufferInfo = &vertBufferInfo;
223 descriptorWrites[0].pTexelBufferView = nullptr;
224 }
225
226 // Fragment Uniform Buffer
227 if (fFragmentUniformBuffer.get()) {
228 if (0 == uniformBindingUpdateCount) {
229 firstUniformWrite = 1;
230 }
231 ++uniformBindingUpdateCount;
232 VkDescriptorBufferInfo fragBufferInfo;
233 memset(&fragBufferInfo, 0, sizeof(VkDescriptorBufferInfo));
234 fragBufferInfo.buffer = fFragmentUniformBuffer->buffer();
235 fragBufferInfo.offset = 0;
236 fragBufferInfo.range = fFragmentUniformBuffer->size();
237
238 descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
239 descriptorWrites[1].pNext = nullptr;
240 descriptorWrites[1].dstSet = fDescriptorSets[1];
241 descriptorWrites[1].dstBinding = GrVkUniformHandler::kFragBinding;;
242 descriptorWrites[1].dstArrayElement = 0;
243 descriptorWrites[1].descriptorCount = 1;
244 descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
245 descriptorWrites[1].pImageInfo = nullptr;
246 descriptorWrites[1].pBufferInfo = &fragBufferInfo;
247 descriptorWrites[1].pTexelBufferView = nullptr;
248 }
249
250 if (uniformBindingUpdateCount) {
251 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
252 uniformBindingUpdate Count,
253 &descriptorWrites[fi rstUniformWrite],
254 0, nullptr));
255 }
256 }
257
258 void GrVkProgram::writeSamplers(const GrVkGpu* gpu,
259 const SkTArray<const GrTextureAccess*>& textureB indings) {
260 SkASSERT(fNumSamplers == textureBindings.count());
261
262 for (int i = 0; i < textureBindings.count(); ++i) {
263 fSamplers.push(GrVkSampler::Create(gpu, *textureBindings[i]));
264
265 GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->get Texture());
266
267 const GrVkImage::Resource* textureResource = texture->resource();
268 textureResource->ref();
269 fTextures.push(textureResource);
270
271 const GrVkImageView* textureView = texture->textureView();
272 textureView->ref();
273 fTextureViews.push(textureView);
274
275 // Change texture layout so it can be read in shader
276 VkImageLayout layout = texture->currentLayout();
277 VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFla gs(layout);
278 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
279 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout);
280 VkAccessFlags dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
281 texture->setImageLayout(gpu,
282 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
283 srcAccessMask,
284 dstAccessMask,
285 srcStageMask,
286 dstStageMask,
287 false);
288
289 VkDescriptorImageInfo imageInfo;
290 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
291 imageInfo.sampler = fSamplers[i]->sampler();
292 imageInfo.imageView = texture->textureView()->imageView();
293 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
294
295 VkWriteDescriptorSet writeInfo;
296 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
297 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
298 writeInfo.pNext = nullptr;
299 writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet];
300 writeInfo.dstBinding = i;
301 writeInfo.dstArrayElement = 0;
302 writeInfo.descriptorCount = 1;
303 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
304 writeInfo.pImageInfo = &imageInfo;
305 writeInfo.pBufferInfo = nullptr;
306 writeInfo.pTexelBufferView = nullptr;
307
308 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
309 1,
310 &writeInfo,
311 0,
312 nullptr));
313 }
314 }
315
316 void GrVkProgram::setRenderTargetState(const GrPipeline& pipeline) {
317 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
318 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
319 fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget ()->height()) {
320 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni,
321 SkIntToScalar(pipeline.getRenderTarget()->heig ht()));
322 }
323
324 // set RT adjustment
325 const GrRenderTarget* rt = pipeline.getRenderTarget();
326 SkISize size;
327 size.set(rt->width(), rt->height());
328 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
329 if (fRenderTargetState.fRenderTargetOrigin != rt->origin() ||
330 fRenderTargetState.fRenderTargetSize != size) {
331 fRenderTargetState.fRenderTargetSize = size;
332 fRenderTargetState.fRenderTargetOrigin = rt->origin();
333
334 float rtAdjustmentVec[4];
335 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
336 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, r tAdjustmentVec);
337 }
338 }
339
340 void GrVkProgram::bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) {
341 commandBuffer->bindPipeline(gpu, fPipeline);
342 commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, 0, 2, fDescrip torSets, 0,
343 nullptr);
344 }
345
346 void GrVkProgram::addUniformResources(GrVkCommandBuffer& commandBuffer) {
347 #if 1
348 commandBuffer.addResource(fDescriptorPool);
349 if (fVertexUniformBuffer.get()) {
350 commandBuffer.addResource(fVertexUniformBuffer->resource());
351 }
352 if (fFragmentUniformBuffer.get()) {
353 commandBuffer.addResource(fFragmentUniformBuffer->resource());
354 }
355 for (int i = 0; i < fSamplers.count(); ++i) {
356 commandBuffer.addResource(fSamplers[i]);
357 }
358
359 for (int i = 0; i < fTextureViews.count(); ++i) {
360 commandBuffer.addResource(fTextureViews[i]);
361 }
362
363 for (int i = 0; i < fTextures.count(); ++i) {
364 commandBuffer.addResource(fTextures[i]);
365 }
366 #endif
367 }
OLDNEW
« no previous file with comments | « src/gpu/vk/GrVkProgram.h ('k') | src/gpu/vk/GrVkProgramBuilder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698