blob: 1fba26f8924097dfeb5bc5dbb2b72820476ffe44 [file] [log] [blame]
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -05001//
2// Copyright 2018 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
Shahbaz Youssefie3219402018-12-08 16:54:14 +01006// UtilsVk.cpp:
7// Implements the UtilsVk class.
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -05008//
9
Shahbaz Youssefie3219402018-12-08 16:54:14 +010010#include "libANGLE/renderer/vulkan/UtilsVk.h"
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050011
Shahbaz Youssefie3219402018-12-08 16:54:14 +010012#include "libANGLE/renderer/vulkan/ContextVk.h"
13#include "libANGLE/renderer/vulkan/FramebufferVk.h"
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050014#include "libANGLE/renderer/vulkan/RendererVk.h"
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050015
16namespace rx
17{
18
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010019namespace BufferUtils_comp = vk::InternalShader::BufferUtils_comp;
20namespace ConvertVertex_comp = vk::InternalShader::ConvertVertex_comp;
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010021namespace ImageCopy_frag = vk::InternalShader::ImageCopy_frag;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050022
23namespace
24{
25// All internal shaders assume there is only one descriptor set, indexed at 0
26constexpr uint32_t kSetIndex = 0;
27
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010028constexpr uint32_t kBufferClearOutputBinding = 0;
29constexpr uint32_t kBufferCopyDestinationBinding = 0;
30constexpr uint32_t kBufferCopySourceBinding = 1;
31constexpr uint32_t kConvertVertexDestinationBinding = 0;
32constexpr uint32_t kConvertVertexSourceBinding = 1;
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010033constexpr uint32_t kImageCopySourceBinding = 0;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050034
35uint32_t GetBufferUtilsFlags(size_t dispatchSize, const vk::Format &format)
36{
37 uint32_t flags = dispatchSize % 64 == 0 ? BufferUtils_comp::kIsAligned : 0;
38 const angle::Format &bufferFormat = format.bufferFormat();
39
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010040 flags |= bufferFormat.isInt()
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050041 ? BufferUtils_comp::kIsInt
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010042 : bufferFormat.isUint() ? BufferUtils_comp::kIsUint : BufferUtils_comp::kIsFloat;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050043
44 return flags;
45}
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010046
Shahbaz Youssefie3219402018-12-08 16:54:14 +010047uint32_t GetConvertVertexFlags(const UtilsVk::ConvertVertexParameters &params)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010048{
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010049 bool srcIsInt = params.srcFormat->isInt();
50 bool srcIsUint = params.srcFormat->isUint();
51 bool srcIsSnorm = params.srcFormat->isSnorm();
52 bool srcIsUnorm = params.srcFormat->isUnorm();
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010053 bool srcIsFixed = params.srcFormat->isFixed;
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010054 bool srcIsFloat = params.srcFormat->isFloat();
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010055
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010056 bool destIsInt = params.destFormat->isInt();
57 bool destIsUint = params.destFormat->isUint();
58 bool destIsFloat = params.destFormat->isFloat();
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010059
60 // Assert on the types to make sure the shader supports its. These are based on
61 // ConvertVertex_comp::Conversion values.
62 ASSERT(!destIsInt || srcIsInt); // If destination is int, src must be int too
63 ASSERT(!destIsUint || srcIsUint); // If destination is uint, src must be uint too
64 ASSERT(!srcIsFixed || destIsFloat); // If source is fixed, dest must be float
65 // One of each bool set must be true
66 ASSERT(srcIsInt || srcIsUint || srcIsSnorm || srcIsUnorm || srcIsFixed || srcIsFloat);
67 ASSERT(destIsInt || destIsUint || destIsFloat);
68
69 // We currently don't have any big-endian devices in the list of supported platforms. The
70 // shader is capable of supporting big-endian architectures, but the relevant flag (IsBigEndian)
71 // is not added to the build configuration file (to reduce binary size). If necessary, add
72 // IsBigEndian to ConvertVertex.comp.json and select the appropriate flag based on the
73 // endian-ness test here.
74 uint32_t endiannessTest = 0;
75 *reinterpret_cast<uint8_t *>(&endiannessTest) = 1;
76 ASSERT(endiannessTest == 1);
77
78 uint32_t flags = 0;
79
80 if (srcIsInt && destIsInt)
81 {
82 flags |= ConvertVertex_comp::kIntToInt;
83 }
84 else if (srcIsUint && destIsUint)
85 {
86 flags |= ConvertVertex_comp::kUintToUint;
87 }
88 else if (srcIsInt)
89 {
90 flags |= ConvertVertex_comp::kIntToFloat;
91 }
92 else if (srcIsUint)
93 {
94 flags |= ConvertVertex_comp::kUintToFloat;
95 }
96 else if (srcIsSnorm)
97 {
98 flags |= ConvertVertex_comp::kSnormToFloat;
99 }
100 else if (srcIsUnorm)
101 {
102 flags |= ConvertVertex_comp::kUnormToFloat;
103 }
104 else if (srcIsFixed)
105 {
106 flags |= ConvertVertex_comp::kFixedToFloat;
107 }
108 else if (srcIsFloat)
109 {
110 flags |= ConvertVertex_comp::kFloatToFloat;
111 }
112 else
113 {
114 UNREACHABLE();
115 }
116
117 return flags;
118}
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100119
120uint32_t GetImageCopyFlags(const vk::Format &srcFormat, const vk::Format &destFormat)
121{
122 const angle::Format &srcAngleFormat = srcFormat.angleFormat();
123 const angle::Format &destAngleFormat = destFormat.angleFormat();
124
125 uint32_t flags = 0;
126
127 flags |= srcAngleFormat.isInt() ? ImageCopy_frag::kSrcIsInt
128 : srcAngleFormat.isUint() ? ImageCopy_frag::kSrcIsUint
129 : ImageCopy_frag::kSrcIsFloat;
130 flags |= destAngleFormat.isInt() ? ImageCopy_frag::kDestIsInt
131 : destAngleFormat.isUint() ? ImageCopy_frag::kDestIsUint
132 : ImageCopy_frag::kDestIsFloat;
133
134 return flags;
135}
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500136
137uint32_t GetFormatDefaultChannelMask(const vk::Format &format)
138{
139 uint32_t mask = 0;
140
141 const angle::Format &angleFormat = format.angleFormat();
142 const angle::Format &textureFormat = format.textureFormat();
143
144 // Red can never be introduced due to format emulation (except for luma which is handled
145 // especially)
146 ASSERT(((angleFormat.redBits > 0) == (textureFormat.redBits > 0)) || angleFormat.isLUMA());
147 mask |= angleFormat.greenBits == 0 && textureFormat.greenBits > 0 ? 2 : 0;
148 mask |= angleFormat.blueBits == 0 && textureFormat.blueBits > 0 ? 4 : 0;
149 mask |= angleFormat.alphaBits == 0 && textureFormat.alphaBits > 0 ? 8 : 0;
150
151 return mask;
152}
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500153} // namespace
154
Jamie Madillab2bfa82019-01-15 19:06:47 -0500155UtilsVk::ConvertVertexShaderParams::ConvertVertexShaderParams() = default;
156
157UtilsVk::ImageCopyShaderParams::ImageCopyShaderParams() = default;
158
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100159UtilsVk::UtilsVk() = default;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500160
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100161UtilsVk::~UtilsVk() = default;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500162
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100163void UtilsVk::destroy(VkDevice device)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500164{
165 for (Function f : angle::AllEnums<Function>())
166 {
167 for (auto &descriptorSetLayout : mDescriptorSetLayouts[f])
168 {
169 descriptorSetLayout.reset();
170 }
171 mPipelineLayouts[f].reset();
172 mDescriptorPools[f].destroy(device);
173 }
174
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100175 for (vk::ShaderProgramHelper &program : mBufferUtilsPrograms)
176 {
177 program.destroy(device);
178 }
179 for (vk::ShaderProgramHelper &program : mConvertVertexPrograms)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500180 {
181 program.destroy(device);
182 }
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100183 mImageClearProgram.destroy(device);
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100184 for (vk::ShaderProgramHelper &program : mImageCopyPrograms)
185 {
186 program.destroy(device);
187 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500188}
189
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100190angle::Result UtilsVk::ensureResourcesInitialized(vk::Context *context,
191 Function function,
192 VkDescriptorPoolSize *setSizes,
193 size_t setSizesCount,
194 size_t pushConstantsSize)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500195{
196 RendererVk *renderer = context->getRenderer();
197
198 vk::DescriptorSetLayoutDesc descriptorSetDesc;
199
200 uint32_t currentBinding = 0;
201 for (size_t i = 0; i < setSizesCount; ++i)
202 {
203 descriptorSetDesc.update(currentBinding, setSizes[i].type, setSizes[i].descriptorCount);
204 currentBinding += setSizes[i].descriptorCount;
205 }
206
207 ANGLE_TRY(renderer->getDescriptorSetLayout(context, descriptorSetDesc,
208 &mDescriptorSetLayouts[function][kSetIndex]));
209
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100210 gl::ShaderType pushConstantsShaderStage = function >= Function::ComputeStartIndex
211 ? gl::ShaderType::Compute
212 : gl::ShaderType::Fragment;
213
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500214 // Corresponding pipeline layouts:
215 vk::PipelineLayoutDesc pipelineLayoutDesc;
216
217 pipelineLayoutDesc.updateDescriptorSetLayout(kSetIndex, descriptorSetDesc);
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100218 pipelineLayoutDesc.updatePushConstantRange(pushConstantsShaderStage, 0, pushConstantsSize);
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500219
220 ANGLE_TRY(renderer->getPipelineLayout(
221 context, pipelineLayoutDesc, mDescriptorSetLayouts[function], &mPipelineLayouts[function]));
222
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100223 if (setSizesCount > 0)
224 {
225 ANGLE_TRY(mDescriptorPools[function].init(context, setSizes, setSizesCount));
226 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500227
Jamie Madill7c985f52018-11-29 18:16:17 -0500228 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500229}
230
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100231angle::Result UtilsVk::ensureBufferClearResourcesInitialized(vk::Context *context)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500232{
233 if (mPipelineLayouts[Function::BufferClear].valid())
234 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500235 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500236 }
237
238 VkDescriptorPoolSize setSizes[1] = {
239 {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1},
240 };
241
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100242 return ensureResourcesInitialized(context, Function::BufferClear, setSizes, ArraySize(setSizes),
243 sizeof(BufferUtilsShaderParams));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500244}
245
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100246angle::Result UtilsVk::ensureBufferCopyResourcesInitialized(vk::Context *context)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500247{
248 if (mPipelineLayouts[Function::BufferCopy].valid())
249 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500250 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500251 }
252
253 VkDescriptorPoolSize setSizes[2] = {
254 {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1},
255 {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1},
256 };
257
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100258 return ensureResourcesInitialized(context, Function::BufferCopy, setSizes, ArraySize(setSizes),
259 sizeof(BufferUtilsShaderParams));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500260}
261
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100262angle::Result UtilsVk::ensureConvertVertexResourcesInitialized(vk::Context *context)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100263{
264 if (mPipelineLayouts[Function::ConvertVertexBuffer].valid())
265 {
266 return angle::Result::Continue;
267 }
268
269 VkDescriptorPoolSize setSizes[2] = {
270 {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
271 {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
272 };
273
274 return ensureResourcesInitialized(context, Function::ConvertVertexBuffer, setSizes,
275 ArraySize(setSizes), sizeof(ConvertVertexShaderParams));
276}
277
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100278angle::Result UtilsVk::ensureImageClearResourcesInitialized(vk::Context *context)
279{
280 if (mPipelineLayouts[Function::ImageClear].valid())
281 {
282 return angle::Result::Continue;
283 }
284
285 // The shader does not use any descriptor sets.
286 return ensureResourcesInitialized(context, Function::ImageClear, nullptr, 0,
287 sizeof(ImageClearShaderParams));
288}
289
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100290angle::Result UtilsVk::ensureImageCopyResourcesInitialized(vk::Context *context)
291{
292 if (mPipelineLayouts[Function::ImageCopy].valid())
293 {
294 return angle::Result::Continue;
295 }
296
297 VkDescriptorPoolSize setSizes[1] = {
298 {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1},
299 };
300
301 return ensureResourcesInitialized(context, Function::ImageCopy, setSizes, ArraySize(setSizes),
302 sizeof(ImageCopyShaderParams));
303}
304
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100305angle::Result UtilsVk::setupProgram(vk::Context *context,
306 Function function,
307 vk::RefCounted<vk::ShaderAndSerial> *fsCsShader,
308 vk::RefCounted<vk::ShaderAndSerial> *vsShader,
309 vk::ShaderProgramHelper *program,
310 const vk::GraphicsPipelineDesc *pipelineDesc,
311 const VkDescriptorSet descriptorSet,
312 const void *pushConstants,
313 size_t pushConstantsSize,
314 vk::CommandBuffer *commandBuffer)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100315{
316 RendererVk *renderer = context->getRenderer();
317
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100318 bool isCompute = function >= Function::ComputeStartIndex;
319 VkPipelineBindPoint bindPoint =
320 isCompute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
321 VkShaderStageFlags pushConstantsShaderStage =
322 isCompute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
323
324 // If compute, vsShader and pipelineDesc should be nullptr, and if not compute they shouldn't
325 // be.
326 ASSERT(isCompute != (vsShader && pipelineDesc));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100327
328 const vk::BindingPointer<vk::PipelineLayout> &pipelineLayout = mPipelineLayouts[function];
329
Jamie Madilldbc605c2019-01-04 16:39:14 -0500330 Serial serial = renderer->getCurrentQueueSerial();
331
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100332 if (isCompute)
333 {
Jamie Madill3f0c4a52019-01-10 10:20:35 -0500334 vk::PipelineAndSerial *pipelineAndSerial;
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100335 program->setShader(gl::ShaderType::Compute, fsCsShader);
336 ANGLE_TRY(program->getComputePipeline(context, pipelineLayout.get(), &pipelineAndSerial));
Jamie Madill3f0c4a52019-01-10 10:20:35 -0500337 pipelineAndSerial->updateSerial(serial);
338 commandBuffer->bindPipeline(bindPoint, pipelineAndSerial->get());
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100339 }
340 else
341 {
342 program->setShader(gl::ShaderType::Vertex, vsShader);
343 program->setShader(gl::ShaderType::Fragment, fsCsShader);
Jamie Madilldbc605c2019-01-04 16:39:14 -0500344
Jamie Madill3f0c4a52019-01-10 10:20:35 -0500345 // This value is not used but is passed to getGraphicsPipeline to avoid a nullptr check.
346 const vk::GraphicsPipelineDesc *descPtr;
347 vk::PipelineHelper *helper;
348
Jamie Madilldbc605c2019-01-04 16:39:14 -0500349 ANGLE_TRY(program->getGraphicsPipeline(
350 context, &renderer->getRenderPassCache(), renderer->getPipelineCache(), serial,
Jamie Madill3f0c4a52019-01-10 10:20:35 -0500351 pipelineLayout.get(), *pipelineDesc, gl::AttributesMask(), &descPtr, &helper));
352 helper->updateSerial(serial);
353 commandBuffer->bindPipeline(bindPoint, helper->getPipeline());
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100354 }
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100355
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100356 if (descriptorSet != VK_NULL_HANDLE)
357 {
358 commandBuffer->bindDescriptorSets(bindPoint, pipelineLayout.get(), 0, 1, &descriptorSet, 0,
359 nullptr);
360 }
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100361
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100362 commandBuffer->pushConstants(pipelineLayout.get(), pushConstantsShaderStage, 0,
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100363 pushConstantsSize, pushConstants);
364
365 return angle::Result::Continue;
366}
367
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100368angle::Result UtilsVk::clearBuffer(vk::Context *context,
369 vk::BufferHelper *dest,
370 const ClearParameters &params)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500371{
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100372 RendererVk *renderer = context->getRenderer();
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500373
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100374 ANGLE_TRY(ensureBufferClearResourcesInitialized(context));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500375
376 vk::CommandBuffer *commandBuffer;
377 ANGLE_TRY(dest->recordCommands(context, &commandBuffer));
378
379 // Tell dest it's being written to.
380 dest->onWrite(VK_ACCESS_SHADER_WRITE_BIT);
381
382 const vk::Format &destFormat = dest->getViewFormat();
383
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100384 uint32_t flags = BufferUtils_comp::kIsClear | GetBufferUtilsFlags(params.size, destFormat);
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500385
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100386 BufferUtilsShaderParams shaderParams;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500387 shaderParams.destOffset = params.offset;
388 shaderParams.size = params.size;
389 shaderParams.clearValue = params.clearValue;
390
391 VkDescriptorSet descriptorSet;
392 vk::SharedDescriptorPoolBinding descriptorPoolBinding;
393 ANGLE_TRY(mDescriptorPools[Function::BufferClear].allocateSets(
394 context, mDescriptorSetLayouts[Function::BufferClear][kSetIndex].get().ptr(), 1,
395 &descriptorPoolBinding, &descriptorSet));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100396 descriptorPoolBinding.get().updateSerial(context->getRenderer()->getCurrentQueueSerial());
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500397
398 VkWriteDescriptorSet writeInfo = {};
399
400 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
401 writeInfo.dstSet = descriptorSet;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100402 writeInfo.dstBinding = kBufferClearOutputBinding;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500403 writeInfo.descriptorCount = 1;
404 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
405 writeInfo.pTexelBufferView = dest->getBufferView().ptr();
406
407 vkUpdateDescriptorSets(context->getDevice(), 1, &writeInfo, 0, nullptr);
408
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100409 vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
410 ANGLE_TRY(renderer->getShaderLibrary().getBufferUtils_comp(context, flags, &shader));
411
412 ANGLE_TRY(setupProgram(context, Function::BufferClear, shader, nullptr,
413 &mBufferUtilsPrograms[flags], nullptr, descriptorSet, &shaderParams,
414 sizeof(shaderParams), commandBuffer));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500415
416 commandBuffer->dispatch(UnsignedCeilDivide(params.size, 64), 1, 1);
417
418 descriptorPoolBinding.reset();
419
Jamie Madill7c985f52018-11-29 18:16:17 -0500420 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500421}
422
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100423angle::Result UtilsVk::copyBuffer(vk::Context *context,
424 vk::BufferHelper *dest,
425 vk::BufferHelper *src,
426 const CopyParameters &params)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500427{
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100428 RendererVk *renderer = context->getRenderer();
429
430 ANGLE_TRY(ensureBufferCopyResourcesInitialized(context));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500431
432 vk::CommandBuffer *commandBuffer;
433 ANGLE_TRY(dest->recordCommands(context, &commandBuffer));
434
435 // Tell src we are going to read from it.
436 src->onRead(dest, VK_ACCESS_SHADER_READ_BIT);
437 // Tell dest it's being written to.
438 dest->onWrite(VK_ACCESS_SHADER_WRITE_BIT);
439
440 const vk::Format &destFormat = dest->getViewFormat();
441 const vk::Format &srcFormat = src->getViewFormat();
442
443 ASSERT(destFormat.vkFormatIsInt == srcFormat.vkFormatIsInt);
444 ASSERT(destFormat.vkFormatIsUnsigned == srcFormat.vkFormatIsUnsigned);
445
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100446 uint32_t flags = BufferUtils_comp::kIsCopy | GetBufferUtilsFlags(params.size, destFormat);
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500447
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100448 BufferUtilsShaderParams shaderParams;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500449 shaderParams.destOffset = params.destOffset;
450 shaderParams.size = params.size;
451 shaderParams.srcOffset = params.srcOffset;
452
453 VkDescriptorSet descriptorSet;
454 vk::SharedDescriptorPoolBinding descriptorPoolBinding;
455 ANGLE_TRY(mDescriptorPools[Function::BufferCopy].allocateSets(
456 context, mDescriptorSetLayouts[Function::BufferCopy][kSetIndex].get().ptr(), 1,
457 &descriptorPoolBinding, &descriptorSet));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100458 descriptorPoolBinding.get().updateSerial(context->getRenderer()->getCurrentQueueSerial());
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500459
460 VkWriteDescriptorSet writeInfo[2] = {};
461
462 writeInfo[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
463 writeInfo[0].dstSet = descriptorSet;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100464 writeInfo[0].dstBinding = kBufferCopyDestinationBinding;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500465 writeInfo[0].descriptorCount = 1;
466 writeInfo[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
467 writeInfo[0].pTexelBufferView = dest->getBufferView().ptr();
468
469 writeInfo[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
470 writeInfo[1].dstSet = descriptorSet;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100471 writeInfo[1].dstBinding = kBufferCopySourceBinding;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500472 writeInfo[1].descriptorCount = 1;
473 writeInfo[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
474 writeInfo[1].pTexelBufferView = src->getBufferView().ptr();
475
476 vkUpdateDescriptorSets(context->getDevice(), 2, writeInfo, 0, nullptr);
477
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100478 vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
479 ANGLE_TRY(renderer->getShaderLibrary().getBufferUtils_comp(context, flags, &shader));
480
481 ANGLE_TRY(setupProgram(context, Function::BufferCopy, shader, nullptr,
482 &mBufferUtilsPrograms[flags], nullptr, descriptorSet, &shaderParams,
483 sizeof(shaderParams), commandBuffer));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500484
485 commandBuffer->dispatch(UnsignedCeilDivide(params.size, 64), 1, 1);
486
487 descriptorPoolBinding.reset();
488
Jamie Madill7c985f52018-11-29 18:16:17 -0500489 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500490}
491
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100492angle::Result UtilsVk::convertVertexBuffer(vk::Context *context,
493 vk::BufferHelper *dest,
494 vk::BufferHelper *src,
495 const ConvertVertexParameters &params)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100496{
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100497 RendererVk *renderer = context->getRenderer();
498
499 ANGLE_TRY(ensureConvertVertexResourcesInitialized(context));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100500
501 vk::CommandBuffer *commandBuffer;
502 ANGLE_TRY(dest->recordCommands(context, &commandBuffer));
503
504 // Tell src we are going to read from it.
505 src->onRead(dest, VK_ACCESS_SHADER_READ_BIT);
506 // Tell dest it's being written to.
507 dest->onWrite(VK_ACCESS_SHADER_WRITE_BIT);
508
509 ConvertVertexShaderParams shaderParams;
510 shaderParams.Ns = params.srcFormat->channelCount();
511 shaderParams.Bs = params.srcFormat->pixelBytes / params.srcFormat->channelCount();
512 shaderParams.Ss = params.srcStride;
513 shaderParams.Nd = params.destFormat->channelCount();
514 shaderParams.Bd = params.destFormat->pixelBytes / params.destFormat->channelCount();
515 shaderParams.Sd = shaderParams.Nd * shaderParams.Bd;
516 // The component size is expected to either be 1, 2 or 4 bytes.
517 ASSERT(4 % shaderParams.Bs == 0);
518 ASSERT(4 % shaderParams.Bd == 0);
519 shaderParams.Es = 4 / shaderParams.Bs;
520 shaderParams.Ed = 4 / shaderParams.Bd;
521 // Total number of output components is simply the number of vertices by number of components in
522 // each.
523 shaderParams.componentCount = params.vertexCount * shaderParams.Nd;
524 // Total number of 4-byte outputs is the number of components divided by how many components can
525 // fit in a 4-byte value. Note that this value is also the invocation size of the shader.
526 shaderParams.outputCount = shaderParams.componentCount / shaderParams.Ed;
527 shaderParams.srcOffset = params.srcOffset;
528 shaderParams.destOffset = params.destOffset;
529
530 uint32_t flags = GetConvertVertexFlags(params);
531
532 bool isAligned =
533 shaderParams.outputCount % 64 == 0 && shaderParams.componentCount % shaderParams.Ed == 0;
534 flags |= isAligned ? ConvertVertex_comp::kIsAligned : 0;
535
536 VkDescriptorSet descriptorSet;
537 vk::SharedDescriptorPoolBinding descriptorPoolBinding;
538 ANGLE_TRY(mDescriptorPools[Function::ConvertVertexBuffer].allocateSets(
539 context, mDescriptorSetLayouts[Function::ConvertVertexBuffer][kSetIndex].get().ptr(), 1,
540 &descriptorPoolBinding, &descriptorSet));
541 descriptorPoolBinding.get().updateSerial(context->getRenderer()->getCurrentQueueSerial());
542
543 VkWriteDescriptorSet writeInfo = {};
544 VkDescriptorBufferInfo buffers[2] = {
545 {dest->getBuffer().getHandle(), 0, VK_WHOLE_SIZE},
546 {src->getBuffer().getHandle(), 0, VK_WHOLE_SIZE},
547 };
548 static_assert(kConvertVertexDestinationBinding + 1 == kConvertVertexSourceBinding,
549 "Update write info");
550
551 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
552 writeInfo.dstSet = descriptorSet;
553 writeInfo.dstBinding = kConvertVertexDestinationBinding;
554 writeInfo.descriptorCount = 2;
555 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
556 writeInfo.pBufferInfo = buffers;
557
558 vkUpdateDescriptorSets(context->getDevice(), 1, &writeInfo, 0, nullptr);
559
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100560 vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
561 ANGLE_TRY(renderer->getShaderLibrary().getConvertVertex_comp(context, flags, &shader));
562
563 ANGLE_TRY(setupProgram(context, Function::ConvertVertexBuffer, shader, nullptr,
564 &mConvertVertexPrograms[flags], nullptr, descriptorSet, &shaderParams,
565 sizeof(shaderParams), commandBuffer));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100566
567 commandBuffer->dispatch(UnsignedCeilDivide(shaderParams.outputCount, 64), 1, 1);
568
569 descriptorPoolBinding.reset();
570
571 return angle::Result::Continue;
572}
573
Jamie Madill85ca1892019-01-16 13:27:15 -0500574angle::Result UtilsVk::startRenderPass(ContextVk *contextVk,
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100575 vk::ImageHelper *image,
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500576 const vk::ImageView *imageView,
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100577 const vk::RenderPassDesc &renderPassDesc,
578 const gl::Rectangle &renderArea,
579 vk::CommandBuffer **commandBufferOut)
580{
Jamie Madill85ca1892019-01-16 13:27:15 -0500581 RendererVk *renderer = contextVk->getRenderer();
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100582
583 vk::RenderPass *renderPass = nullptr;
Jamie Madill85ca1892019-01-16 13:27:15 -0500584 ANGLE_TRY(renderer->getCompatibleRenderPass(contextVk, renderPassDesc, &renderPass));
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100585
586 VkFramebufferCreateInfo framebufferInfo = {};
587
588 framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
589 framebufferInfo.flags = 0;
590 framebufferInfo.renderPass = renderPass->getHandle();
591 framebufferInfo.attachmentCount = 1;
592 framebufferInfo.pAttachments = imageView->ptr();
593 framebufferInfo.width = renderArea.x + renderArea.width;
594 framebufferInfo.height = renderArea.y + renderArea.height;
595 framebufferInfo.layers = 1;
596
597 vk::Framebuffer framebuffer;
Jamie Madill85ca1892019-01-16 13:27:15 -0500598 ANGLE_VK_TRY(contextVk, framebuffer.init(contextVk->getDevice(), framebufferInfo));
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100599
600 // TODO(jmadill): Proper clear value implementation. http://anglebug.com/2361
601 std::vector<VkClearValue> clearValues = {{}};
602 ASSERT(clearValues.size() == 1);
603
Jamie Madill85ca1892019-01-16 13:27:15 -0500604 ANGLE_TRY(image->beginRenderPass(contextVk, framebuffer, renderArea, renderPassDesc,
605 clearValues, commandBufferOut));
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100606
607 renderer->releaseObject(renderer->getCurrentQueueSerial(), &framebuffer);
608
609 return angle::Result::Continue;
610}
611
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100612angle::Result UtilsVk::clearImage(ContextVk *contextVk,
613 FramebufferVk *framebuffer,
614 const ClearImageParameters &params)
615{
616 RendererVk *renderer = contextVk->getRenderer();
617
618 ANGLE_TRY(ensureImageClearResourcesInitialized(contextVk));
619
620 vk::CommandBuffer *commandBuffer;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500621 if (!framebuffer->appendToStartedRenderPass(renderer->getCurrentQueueSerial(), &commandBuffer))
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100622 {
Jamie Madillc09ae152019-02-01 14:16:32 -0500623 ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, &commandBuffer));
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100624 }
625
626 ImageClearShaderParams shaderParams;
627 shaderParams.clearValue = params.clearValue;
628
629 vk::GraphicsPipelineDesc pipelineDesc;
630 pipelineDesc.initDefaults();
Jamie Madill3f0c4a52019-01-10 10:20:35 -0500631 pipelineDesc.setColorWriteMask(params.colorMaskFlags, *params.alphaMask);
632 pipelineDesc.setRenderPassDesc(*params.renderPassDesc);
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100633
Jamie Madill633d5e62018-12-23 19:58:01 -0500634 const gl::Rectangle &renderArea = framebuffer->getFramebuffer()->getRenderPassRenderArea();
635 bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO();
636
637 VkViewport viewport;
638 gl_vk::GetViewport(renderArea, 0.0f, 1.0f, invertViewport, params.renderAreaHeight, &viewport);
639 pipelineDesc.setViewport(viewport);
640
641 VkRect2D scissor;
642 const gl::State &glState = contextVk->getState();
643 gl_vk::GetScissor(glState, invertViewport, renderArea, &scissor);
644 pipelineDesc.setScissor(scissor);
645
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100646 vk::ShaderLibrary &shaderLibrary = renderer->getShaderLibrary();
647 vk::RefCounted<vk::ShaderAndSerial> *vertexShader = nullptr;
648 vk::RefCounted<vk::ShaderAndSerial> *fragmentShader = nullptr;
649 ANGLE_TRY(shaderLibrary.getFullScreenQuad_vert(contextVk, 0, &vertexShader));
650 ANGLE_TRY(shaderLibrary.getImageClear_frag(contextVk, 0, &fragmentShader));
651
652 ANGLE_TRY(setupProgram(contextVk, Function::ImageClear, fragmentShader, vertexShader,
653 &mImageClearProgram, &pipelineDesc, VK_NULL_HANDLE, &shaderParams,
654 sizeof(shaderParams), commandBuffer));
655
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100656 commandBuffer->draw(6, 1, 0, 0);
657
658 return angle::Result::Continue;
659}
660
Jamie Madill85ca1892019-01-16 13:27:15 -0500661angle::Result UtilsVk::copyImage(ContextVk *contextVk,
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100662 vk::ImageHelper *dest,
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500663 const vk::ImageView *destView,
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100664 vk::ImageHelper *src,
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500665 const vk::ImageView *srcView,
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100666 const CopyImageParameters &params)
667{
Jamie Madill85ca1892019-01-16 13:27:15 -0500668 RendererVk *renderer = contextVk->getRenderer();
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100669
Jamie Madill85ca1892019-01-16 13:27:15 -0500670 ANGLE_TRY(ensureImageCopyResourcesInitialized(contextVk));
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100671
672 const vk::Format &srcFormat = src->getFormat();
673 const vk::Format &destFormat = dest->getFormat();
674
675 ImageCopyShaderParams shaderParams;
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500676 shaderParams.flipY = params.srcFlipY || params.destFlipY;
677 shaderParams.premultiplyAlpha = params.srcPremultiplyAlpha;
678 shaderParams.unmultiplyAlpha = params.srcUnmultiplyAlpha;
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100679 shaderParams.destHasLuminance = destFormat.angleFormat().luminanceBits > 0;
680 shaderParams.destIsAlpha =
681 destFormat.angleFormat().isLUMA() && destFormat.angleFormat().alphaBits > 0;
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500682 shaderParams.destDefaultChannelsMask = GetFormatDefaultChannelMask(destFormat);
683 shaderParams.srcMip = params.srcMip;
684 shaderParams.srcLayer = params.srcLayer;
685 shaderParams.srcOffset[0] = params.srcOffset[0];
686 shaderParams.srcOffset[1] = params.srcOffset[1];
687 shaderParams.destOffset[0] = params.destOffset[0];
688 shaderParams.destOffset[1] = params.destOffset[1];
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100689
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500690 ASSERT(!(params.srcFlipY && params.destFlipY));
691 if (params.srcFlipY)
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100692 {
693 // If viewport is flipped, the shader expects srcOffset[1] to have the
694 // last row's index instead of the first's.
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500695 shaderParams.srcOffset[1] = params.srcHeight - params.srcOffset[1] - 1;
696 }
697 else if (params.destFlipY)
698 {
699 // If image is flipped during copy, the shader uses the same code path as above,
700 // with srcOffset being set to the last row's index instead of the first's.
701 shaderParams.srcOffset[1] = params.srcOffset[1] + params.srcExtents[1] - 1;
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100702 }
703
704 uint32_t flags = GetImageCopyFlags(srcFormat, destFormat);
Shahbaz Youssefi4f3b2072019-01-01 14:48:25 -0500705 flags |= src->getLayerCount() > 1 ? ImageCopy_frag::kSrcIsArray : 0;
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100706
707 VkDescriptorSet descriptorSet;
708 vk::SharedDescriptorPoolBinding descriptorPoolBinding;
709 ANGLE_TRY(mDescriptorPools[Function::ImageCopy].allocateSets(
Jamie Madill85ca1892019-01-16 13:27:15 -0500710 contextVk, mDescriptorSetLayouts[Function::ImageCopy][kSetIndex].get().ptr(), 1,
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100711 &descriptorPoolBinding, &descriptorSet));
Jamie Madill85ca1892019-01-16 13:27:15 -0500712 descriptorPoolBinding.get().updateSerial(contextVk->getRenderer()->getCurrentQueueSerial());
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100713
714 vk::RenderPassDesc renderPassDesc;
715 renderPassDesc.setSamples(dest->getSamples());
716 renderPassDesc.packAttachment(destFormat);
717
718 vk::GraphicsPipelineDesc pipelineDesc;
719 pipelineDesc.initDefaults();
Jamie Madill3f0c4a52019-01-10 10:20:35 -0500720 pipelineDesc.setRenderPassDesc(renderPassDesc);
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100721
722 gl::Rectangle renderArea;
723 renderArea.x = params.destOffset[0];
724 renderArea.y = params.destOffset[1];
725 renderArea.width = params.srcExtents[0];
726 renderArea.height = params.srcExtents[1];
727
Jamie Madill633d5e62018-12-23 19:58:01 -0500728 VkViewport viewport;
729 gl_vk::GetViewport(renderArea, 0.0f, 1.0f, false, dest->getExtents().height, &viewport);
730 pipelineDesc.setViewport(viewport);
731
732 VkRect2D scissor = gl_vk::GetRect(renderArea);
733 pipelineDesc.setScissor(scissor);
734
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100735 // Change source layout outside render pass
Shahbaz Youssefib5ba5492019-01-02 15:19:22 -0500736 if (src->getCurrentLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
737 {
738 vk::CommandBuffer *srcLayoutChange;
Jamie Madill85ca1892019-01-16 13:27:15 -0500739 ANGLE_TRY(src->recordCommands(contextVk, &srcLayoutChange));
Shahbaz Youssefib5ba5492019-01-02 15:19:22 -0500740 src->changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT,
741 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
742 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
743 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, srcLayoutChange);
744 }
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100745
746 // Change destination layout outside render pass as well
747 vk::CommandBuffer *destLayoutChange;
Jamie Madill85ca1892019-01-16 13:27:15 -0500748 ANGLE_TRY(dest->recordCommands(contextVk, &destLayoutChange));
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100749
750 dest->changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT,
751 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
752 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
753 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, destLayoutChange);
754
755 vk::CommandBuffer *commandBuffer;
Jamie Madill85ca1892019-01-16 13:27:15 -0500756 ANGLE_TRY(
757 startRenderPass(contextVk, dest, destView, renderPassDesc, renderArea, &commandBuffer));
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100758
759 // Source's layout change should happen before rendering
760 src->addReadDependency(dest);
761
762 VkDescriptorImageInfo imageInfo = {};
763 imageInfo.imageView = srcView->getHandle();
764 imageInfo.imageLayout = src->getCurrentLayout();
765
766 VkWriteDescriptorSet writeInfo = {};
767 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
768 writeInfo.dstSet = descriptorSet;
769 writeInfo.dstBinding = kImageCopySourceBinding;
770 writeInfo.descriptorCount = 1;
771 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
772 writeInfo.pImageInfo = &imageInfo;
773
Jamie Madill85ca1892019-01-16 13:27:15 -0500774 vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfo, 0, nullptr);
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100775
776 vk::ShaderLibrary &shaderLibrary = renderer->getShaderLibrary();
777 vk::RefCounted<vk::ShaderAndSerial> *vertexShader = nullptr;
778 vk::RefCounted<vk::ShaderAndSerial> *fragmentShader = nullptr;
Jamie Madill85ca1892019-01-16 13:27:15 -0500779 ANGLE_TRY(shaderLibrary.getFullScreenQuad_vert(contextVk, 0, &vertexShader));
780 ANGLE_TRY(shaderLibrary.getImageCopy_frag(contextVk, flags, &fragmentShader));
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100781
Jamie Madill85ca1892019-01-16 13:27:15 -0500782 ANGLE_TRY(setupProgram(contextVk, Function::ImageCopy, fragmentShader, vertexShader,
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100783 &mImageCopyPrograms[flags], &pipelineDesc, descriptorSet, &shaderParams,
784 sizeof(shaderParams), commandBuffer));
785
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100786 commandBuffer->draw(6, 1, 0, 0);
787
788 descriptorPoolBinding.reset();
789
790 return angle::Result::Continue;
791}
792
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500793} // namespace rx