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

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

Issue 2274663005: Add GrVkCopyPipeline to handle vulkan copies as draws (Closed) Base URL: https://skia.googlesource.com/skia.git@compatibleCopyDS
Patch Set: indent nits Created 4 years, 2 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/GrVkCopyManager.h ('k') | src/gpu/vk/GrVkGpu.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 "GrVkCopyManager.h"
9
10 #include "GrSurface.h"
11 #include "GrTextureParams.h"
12 #include "GrTexturePriv.h"
13 #include "GrVkCommandBuffer.h"
14 #include "GrVkCopyPipeline.h"
15 #include "GrVkDescriptorSet.h"
16 #include "GrVkGpu.h"
17 #include "GrVkImageView.h"
18 #include "GrVkRenderTarget.h"
19 #include "GrVkResourceProvider.h"
20 #include "GrVkSampler.h"
21 #include "GrVkTexture.h"
22 #include "GrVkUniformBuffer.h"
23 #include "GrVkVertexBuffer.h"
24 #include "SkPoint.h"
25 #include "SkRect.h"
26
27 bool GrVkCopyManager::createCopyProgram(GrVkGpu* gpu) {
28 const GrGLSLCaps* glslCaps = gpu->vkCaps().glslCaps();
29 const char* version = glslCaps->versionDeclString();
30 SkString vertShaderText(version);
31 vertShaderText.append(
32 "#extension GL_ARB_separate_shader_objects : enable\n"
33 "#extension GL_ARB_shading_language_420pack : enable\n"
34
35 "layout(set = 0, binding = 0) uniform vertexUniformBuffer {"
36 "mediump vec4 uPosXform;"
37 "mediump vec4 uTexCoordXform;"
38 "};"
39 "layout(location = 0) in highp vec2 inPosition;"
40 "layout(location = 1) out mediump vec2 vTexCoord;"
41
42 "// Copy Program VS\n"
43 "void main() {"
44 "vTexCoord = inPosition * uTexCoordXform.xy + uTexCoordXform.zw;"
45 "gl_Position.xy = inPosition * uPosXform.xy + uPosXform.zw;"
46 "gl_Position.zw = vec2(0, 1);"
47 "}"
48 );
49
50 SkString fragShaderText(version);
51 fragShaderText.append(
52 "#extension GL_ARB_separate_shader_objects : enable\n"
53 "#extension GL_ARB_shading_language_420pack : enable\n"
54
55 "precision mediump float;"
56
57 "layout(set = 1, binding = 0) uniform mediump sampler2D uTextureSampler; "
58 "layout(location = 1) in mediump vec2 vTexCoord;"
59 "layout(location = 0, index = 0) out mediump vec4 fsColorOut;"
60
61 "// Copy Program FS\n"
62 "void main() {"
63 "fsColorOut = texture(uTextureSampler, vTexCoord);"
64 "}"
65 );
66
67 if (!GrCompileVkShaderModule(gpu, vertShaderText.c_str(),
68 VK_SHADER_STAGE_VERTEX_BIT,
69 &fVertShaderModule, &fShaderStageInfo[0])) {
70 this->destroyResources(gpu);
71 return false;
72 }
73
74 if (!GrCompileVkShaderModule(gpu, fragShaderText.c_str(),
75 VK_SHADER_STAGE_FRAGMENT_BIT,
76 &fFragShaderModule, &fShaderStageInfo[1])) {
77 this->destroyResources(gpu);
78 return false;
79 }
80
81 VkDescriptorSetLayout dsLayout[2];
82
83 GrVkResourceProvider& resourceProvider = gpu->resourceProvider();
84
85 dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUn iformDSLayout();
86
87 uint32_t samplerVisibility = kFragment_GrShaderFlag;
88 SkTArray<uint32_t> visibilityArray(&samplerVisibility, 1);
89
90 resourceProvider.getSamplerDescriptorSetHandle(visibilityArray, &fSamplerDSH andle);
91 dsLayout[GrVkUniformHandler::kSamplerDescSet] =
92 resourceProvider.getSamplerDSLayout(fSamplerDSHandle);
93
94 // Create the VkPipelineLayout
95 VkPipelineLayoutCreateInfo layoutCreateInfo;
96 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
97 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
98 layoutCreateInfo.pNext = 0;
99 layoutCreateInfo.flags = 0;
100 layoutCreateInfo.setLayoutCount = 2;
101 layoutCreateInfo.pSetLayouts = dsLayout;
102 layoutCreateInfo.pushConstantRangeCount = 0;
103 layoutCreateInfo.pPushConstantRanges = nullptr;
104
105 VkResult err = GR_VK_CALL(gpu->vkInterface(), CreatePipelineLayout(gpu->devi ce(),
106 &layoutCr eateInfo,
107 nullptr,
108 &fPipelin eLayout));
109 if (err) {
110 this->destroyResources(gpu);
111 return false;
112 }
113
114 static const float vdata[] = {
115 0, 0,
116 0, 1,
117 1, 0,
118 1, 1
119 };
120 fVertexBuffer.reset(GrVkVertexBuffer::Create(gpu, sizeof(vdata), false));
121 SkASSERT(fVertexBuffer.get());
122 fVertexBuffer->updateData(vdata, sizeof(vdata));
123
124 // We use 2 vec4's for uniforms
125 fUniformBuffer = GrVkUniformBuffer::Create(gpu, 8 * sizeof(float));
126 SkASSERT(fUniformBuffer);
127
128 return true;
129 }
130
131 bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu,
132 GrSurface* dst,
133 GrSurface* src,
134 const SkIRect& srcRect,
135 const SkIPoint& dstPoint) {
136 if (!gpu->vkCaps().supportsCopiesAsDraws()) {
137 return false;
138 }
139
140 GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(dst->asRenderTarget()) ;
141 if (!rt) {
142 return false;
143 }
144
145 GrVkTexture* srcTex = static_cast<GrVkTexture*>(src->asTexture());
146 if (!srcTex) {
147 return false;
148 }
149
150 if (VK_NULL_HANDLE == fVertShaderModule) {
151 SkASSERT(VK_NULL_HANDLE == fFragShaderModule &&
152 VK_NULL_HANDLE == fPipelineLayout &&
153 nullptr == fVertexBuffer.get() &&
154 nullptr == fUniformBuffer);
155 if (!this->createCopyProgram(gpu)) {
156 SkDebugf("Failed to create copy program.\n");
157 return false;
158 }
159 }
160
161 GrVkResourceProvider& resourceProv = gpu->resourceProvider();
162
163 GrVkCopyPipeline* pipeline = resourceProv.findOrCreateCopyPipeline(rt,
164 fShaderSt ageInfo,
165 fPipeline Layout);
166 if (!pipeline) {
167 return false;
168 }
169
170 // UPDATE UNIFORM DESCRIPTOR SET
171 int w = srcRect.width();
172 int h = srcRect.height();
173
174 // dst rect edges in NDC (-1 to 1)
175 int dw = dst->width();
176 int dh = dst->height();
177 float dx0 = 2.f * dstPoint.fX / dw - 1.f;
178 float dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
179 float dy0 = 2.f * dstPoint.fY / dh - 1.f;
180 float dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
181 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
182 dy0 = -dy0;
183 dy1 = -dy1;
184 }
185
186
187 float sx0 = (float)srcRect.fLeft;
188 float sx1 = (float)(srcRect.fLeft + w);
189 float sy0 = (float)srcRect.fTop;
190 float sy1 = (float)(srcRect.fTop + h);
191 int sh = src->height();
192 if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
193 sy0 = sh - sy0;
194 sy1 = sh - sy1;
195 }
196 // src rect edges in normalized texture space (0 to 1).
197 int sw = src->width();
198 sx0 /= sw;
199 sx1 /= sw;
200 sy0 /= sh;
201 sy1 /= sh;
202
203 float uniData[] = { dx1 - dx0, dy1 - dy0, dx0, dy0, // posXform
204 sx1 - sx0, sy1 - sy0, sx0, sy0 }; // texCoordXform
205
206 fUniformBuffer->updateData(gpu, uniData, sizeof(uniData), nullptr);
207
208 const GrVkDescriptorSet* uniformDS = resourceProv.getUniformDescriptorSet();
209 SkASSERT(uniformDS);
210
211 VkDescriptorBufferInfo uniBufferInfo;
212 uniBufferInfo.buffer = fUniformBuffer->buffer();
213 uniBufferInfo.offset = fUniformBuffer->offset();
214 uniBufferInfo.range = fUniformBuffer->size();
215
216 VkWriteDescriptorSet descriptorWrites;
217 descriptorWrites.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
218 descriptorWrites.pNext = nullptr;
219 descriptorWrites.dstSet = uniformDS->descriptorSet();
220 descriptorWrites.dstBinding = GrVkUniformHandler::kVertexBinding;
221 descriptorWrites.dstArrayElement = 0;
222 descriptorWrites.descriptorCount = 1;
223 descriptorWrites.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
224 descriptorWrites.pImageInfo = nullptr;
225 descriptorWrites.pBufferInfo = &uniBufferInfo;
226 descriptorWrites.pTexelBufferView = nullptr;
227
228 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
229 1,
230 &descriptorWrites,
231 0, nullptr));
232
233 // UPDATE SAMPLER DESCRIPTOR SET
234 const GrVkDescriptorSet* samplerDS =
235 gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
236
237 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_Fil terMode);
238
239 GrVkSampler* sampler =
240 resourceProv.findOrCreateCompatibleSampler(params, srcTex->texturePriv() .maxMipMapLevel());
241
242 VkDescriptorImageInfo imageInfo;
243 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
244 imageInfo.sampler = sampler->sampler();
245 imageInfo.imageView = srcTex->textureView(true)->imageView();
246 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
247
248 VkWriteDescriptorSet writeInfo;
249 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
250 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
251 writeInfo.pNext = nullptr;
252 writeInfo.dstSet = samplerDS->descriptorSet();
253 writeInfo.dstBinding = 0;
254 writeInfo.dstArrayElement = 0;
255 writeInfo.descriptorCount = 1;
256 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
257 writeInfo.pImageInfo = &imageInfo;
258 writeInfo.pBufferInfo = nullptr;
259 writeInfo.pTexelBufferView = nullptr;
260
261 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
262 1,
263 &writeInfo,
264 0, nullptr));
265
266 VkDescriptorSet vkDescSets[] = { uniformDS->descriptorSet(), samplerDS->desc riptorSet() };
267
268 GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(srcTex->asRenderTar get());
269 if (texRT) {
270 gpu->onResolveRenderTarget(texRT);
271 }
272
273 GrVkPrimaryCommandBuffer* cmdBuffer = gpu->currentCommandBuffer();
274
275 // TODO: Make tighter bounds and then adjust bounds for origin and granulari ty if we see
276 // any perf issues with using the whole bounds
277 SkIRect bounds = SkIRect::MakeWH(rt->width(), rt->height());
278
279 // Change layouts of rt and texture
280 GrVkImage* targetImage = rt->msaaImage() ? rt->msaaImage() : rt;
281 targetImage->setImageLayout(gpu,
282 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
283 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
284 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
285 false);
286
287 srcTex->setImageLayout(gpu,
288 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
289 VK_ACCESS_SHADER_READ_BIT,
290 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
291 false);
292
293 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
294 VK_ATTACHMENT_STORE_OP_STORE);
295 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
296 VK_ATTACHMENT_STORE_OP_STORE);
297 GrVkRenderPass::LoadStoreOps vkResolveOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
298 VK_ATTACHMENT_STORE_OP_STORE);
299 const GrVkRenderPass* renderPass;
300 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
301 rt->compatibleRenderPassHandle();
302 if (rpHandle.isValid()) {
303 renderPass = gpu->resourceProvider().findRenderPass(rpHandle,
304 vkColorOps,
305 vkResolveOps,
306 vkStencilOps);
307 } else {
308 renderPass = gpu->resourceProvider().findRenderPass(*rt,
309 vkColorOps,
310 vkResolveOps,
311 vkStencilOps);
312 }
313
314 SkASSERT(renderPass->isCompatible(*rt->simpleRenderPass()));
315
316
317 cmdBuffer->beginRenderPass(gpu, renderPass, 0, nullptr, *rt, bounds, false);
318 cmdBuffer->bindPipeline(gpu, pipeline);
319
320 // Uniform DescriptorSet, Sampler DescriptorSet, and vertex shader uniformBu ffer
321 SkSTArray<3, const GrVkRecycledResource*> descriptorRecycledResources;
322 descriptorRecycledResources.push_back(uniformDS);
323 descriptorRecycledResources.push_back(samplerDS);
324 descriptorRecycledResources.push_back(fUniformBuffer->resource());
325
326 // One sampler, texture view, and texture
327 SkSTArray<3, const GrVkResource*> descriptorResources;
328 descriptorResources.push_back(sampler);
329 descriptorResources.push_back(srcTex->textureView(true));
330 descriptorResources.push_back(srcTex->resource());
331
332 cmdBuffer->bindDescriptorSets(gpu,
333 descriptorRecycledResources,
334 descriptorResources,
335 fPipelineLayout,
336 0,
337 2,
338 vkDescSets,
339 0,
340 nullptr);
341
342 // Set Dynamic viewport and stencil
343 // We always use one viewport the size of the RT
344 VkViewport viewport;
345 viewport.x = 0.0f;
346 viewport.y = 0.0f;
347 viewport.width = SkIntToScalar(rt->width());
348 viewport.height = SkIntToScalar(rt->height());
349 viewport.minDepth = 0.0f;
350 viewport.maxDepth = 1.0f;
351 cmdBuffer->setViewport(gpu, 0, 1, &viewport);
352
353 // We assume the scissor is not enabled so just set it to the whole RT
354 VkRect2D scissor;
355 scissor.extent.width = rt->width();
356 scissor.extent.height = rt->height();
357 scissor.offset.x = 0;
358 scissor.offset.y = 0;
359 cmdBuffer->setScissor(gpu, 0, 1, &scissor);
360
361 cmdBuffer->bindVertexBuffer(gpu, fVertexBuffer);
362 cmdBuffer->draw(gpu, 4, 1, 0, 0);
363 cmdBuffer->endRenderPass(gpu);
364
365 // Release all temp resources which should now be reffed by the cmd buffer
366 pipeline->unref(gpu);
367 uniformDS->unref(gpu);
368 samplerDS->unref(gpu);
369 sampler->unref(gpu);
370 renderPass->unref(gpu);
371
372 return true;
373 }
374
375 void GrVkCopyManager::destroyResources(GrVkGpu* gpu) {
376 if (VK_NULL_HANDLE != fVertShaderModule) {
377 GR_VK_CALL(gpu->vkInterface(), DestroyShaderModule(gpu->device(), fVertS haderModule,
378 nullptr));
379 fVertShaderModule = VK_NULL_HANDLE;
380 }
381
382 if (VK_NULL_HANDLE != fFragShaderModule) {
383 GR_VK_CALL(gpu->vkInterface(), DestroyShaderModule(gpu->device(), fFragS haderModule,
384 nullptr));
385 fFragShaderModule = VK_NULL_HANDLE;
386 }
387
388 if (VK_NULL_HANDLE != fPipelineLayout) {
389 GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), fPip elineLayout,
390 nullptr));
391 fPipelineLayout = VK_NULL_HANDLE;
392 }
393
394 if (fUniformBuffer) {
395 fUniformBuffer->release(gpu);
396 fUniformBuffer = nullptr;
397 }
398 }
399
400 void GrVkCopyManager::abandonResources() {
401 fVertShaderModule = VK_NULL_HANDLE;
402 fFragShaderModule = VK_NULL_HANDLE;
403 fPipelineLayout = VK_NULL_HANDLE;
404
405 if (fUniformBuffer) {
406 fUniformBuffer->abandon();
407 fUniformBuffer = nullptr;
408 }
409 }
OLDNEW
« no previous file with comments | « src/gpu/vk/GrVkCopyManager.h ('k') | src/gpu/vk/GrVkGpu.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698