blob: 8b449255795084c1ceb432858126e749443d385f [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 Youssefi8f1b7a62018-11-14 16:02:54 -050021
22namespace
23{
24// All internal shaders assume there is only one descriptor set, indexed at 0
25constexpr uint32_t kSetIndex = 0;
26
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010027constexpr uint32_t kBufferClearOutputBinding = 0;
28constexpr uint32_t kBufferCopyDestinationBinding = 0;
29constexpr uint32_t kBufferCopySourceBinding = 1;
30constexpr uint32_t kConvertVertexDestinationBinding = 0;
31constexpr uint32_t kConvertVertexSourceBinding = 1;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050032
33uint32_t GetBufferUtilsFlags(size_t dispatchSize, const vk::Format &format)
34{
35 uint32_t flags = dispatchSize % 64 == 0 ? BufferUtils_comp::kIsAligned : 0;
36 const angle::Format &bufferFormat = format.bufferFormat();
37
38 flags |= bufferFormat.componentType == GL_INT
39 ? BufferUtils_comp::kIsInt
40 : bufferFormat.componentType == GL_UNSIGNED_INT ? BufferUtils_comp::kIsUint
41 : BufferUtils_comp::kIsFloat;
42
43 return flags;
44}
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010045
Shahbaz Youssefie3219402018-12-08 16:54:14 +010046uint32_t GetConvertVertexFlags(const UtilsVk::ConvertVertexParameters &params)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010047{
48 bool srcIsInt = params.srcFormat->componentType == GL_INT;
49 bool srcIsUint = params.srcFormat->componentType == GL_UNSIGNED_INT;
50 bool srcIsSnorm = params.srcFormat->componentType == GL_SIGNED_NORMALIZED;
51 bool srcIsUnorm = params.srcFormat->componentType == GL_UNSIGNED_NORMALIZED;
52 bool srcIsFixed = params.srcFormat->isFixed;
53 bool srcIsFloat = params.srcFormat->componentType == GL_FLOAT;
54
55 bool destIsInt = params.destFormat->componentType == GL_INT;
56 bool destIsUint = params.destFormat->componentType == GL_UNSIGNED_INT;
57 bool destIsFloat = params.destFormat->componentType == GL_FLOAT;
58
59 // Assert on the types to make sure the shader supports its. These are based on
60 // ConvertVertex_comp::Conversion values.
61 ASSERT(!destIsInt || srcIsInt); // If destination is int, src must be int too
62 ASSERT(!destIsUint || srcIsUint); // If destination is uint, src must be uint too
63 ASSERT(!srcIsFixed || destIsFloat); // If source is fixed, dest must be float
64 // One of each bool set must be true
65 ASSERT(srcIsInt || srcIsUint || srcIsSnorm || srcIsUnorm || srcIsFixed || srcIsFloat);
66 ASSERT(destIsInt || destIsUint || destIsFloat);
67
68 // We currently don't have any big-endian devices in the list of supported platforms. The
69 // shader is capable of supporting big-endian architectures, but the relevant flag (IsBigEndian)
70 // is not added to the build configuration file (to reduce binary size). If necessary, add
71 // IsBigEndian to ConvertVertex.comp.json and select the appropriate flag based on the
72 // endian-ness test here.
73 uint32_t endiannessTest = 0;
74 *reinterpret_cast<uint8_t *>(&endiannessTest) = 1;
75 ASSERT(endiannessTest == 1);
76
77 uint32_t flags = 0;
78
79 if (srcIsInt && destIsInt)
80 {
81 flags |= ConvertVertex_comp::kIntToInt;
82 }
83 else if (srcIsUint && destIsUint)
84 {
85 flags |= ConvertVertex_comp::kUintToUint;
86 }
87 else if (srcIsInt)
88 {
89 flags |= ConvertVertex_comp::kIntToFloat;
90 }
91 else if (srcIsUint)
92 {
93 flags |= ConvertVertex_comp::kUintToFloat;
94 }
95 else if (srcIsSnorm)
96 {
97 flags |= ConvertVertex_comp::kSnormToFloat;
98 }
99 else if (srcIsUnorm)
100 {
101 flags |= ConvertVertex_comp::kUnormToFloat;
102 }
103 else if (srcIsFixed)
104 {
105 flags |= ConvertVertex_comp::kFixedToFloat;
106 }
107 else if (srcIsFloat)
108 {
109 flags |= ConvertVertex_comp::kFloatToFloat;
110 }
111 else
112 {
113 UNREACHABLE();
114 }
115
116 return flags;
117}
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500118} // namespace
119
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100120UtilsVk::UtilsVk() = default;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500121
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100122UtilsVk::~UtilsVk() = default;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500123
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100124void UtilsVk::destroy(VkDevice device)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500125{
126 for (Function f : angle::AllEnums<Function>())
127 {
128 for (auto &descriptorSetLayout : mDescriptorSetLayouts[f])
129 {
130 descriptorSetLayout.reset();
131 }
132 mPipelineLayouts[f].reset();
133 mDescriptorPools[f].destroy(device);
134 }
135
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100136 for (vk::ShaderProgramHelper &program : mBufferUtilsPrograms)
137 {
138 program.destroy(device);
139 }
140 for (vk::ShaderProgramHelper &program : mConvertVertexPrograms)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500141 {
142 program.destroy(device);
143 }
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100144 mImageClearProgram.destroy(device);
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500145}
146
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100147angle::Result UtilsVk::ensureResourcesInitialized(vk::Context *context,
148 Function function,
149 VkDescriptorPoolSize *setSizes,
150 size_t setSizesCount,
151 size_t pushConstantsSize)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500152{
153 RendererVk *renderer = context->getRenderer();
154
155 vk::DescriptorSetLayoutDesc descriptorSetDesc;
156
157 uint32_t currentBinding = 0;
158 for (size_t i = 0; i < setSizesCount; ++i)
159 {
160 descriptorSetDesc.update(currentBinding, setSizes[i].type, setSizes[i].descriptorCount);
161 currentBinding += setSizes[i].descriptorCount;
162 }
163
164 ANGLE_TRY(renderer->getDescriptorSetLayout(context, descriptorSetDesc,
165 &mDescriptorSetLayouts[function][kSetIndex]));
166
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100167 gl::ShaderType pushConstantsShaderStage = function >= Function::ComputeStartIndex
168 ? gl::ShaderType::Compute
169 : gl::ShaderType::Fragment;
170
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500171 // Corresponding pipeline layouts:
172 vk::PipelineLayoutDesc pipelineLayoutDesc;
173
174 pipelineLayoutDesc.updateDescriptorSetLayout(kSetIndex, descriptorSetDesc);
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100175 pipelineLayoutDesc.updatePushConstantRange(pushConstantsShaderStage, 0, pushConstantsSize);
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500176
177 ANGLE_TRY(renderer->getPipelineLayout(
178 context, pipelineLayoutDesc, mDescriptorSetLayouts[function], &mPipelineLayouts[function]));
179
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100180 if (setSizesCount > 0)
181 {
182 ANGLE_TRY(mDescriptorPools[function].init(context, setSizes, setSizesCount));
183 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500184
Jamie Madill7c985f52018-11-29 18:16:17 -0500185 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500186}
187
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100188angle::Result UtilsVk::ensureBufferClearResourcesInitialized(vk::Context *context)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500189{
190 if (mPipelineLayouts[Function::BufferClear].valid())
191 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500192 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500193 }
194
195 VkDescriptorPoolSize setSizes[1] = {
196 {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1},
197 };
198
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100199 return ensureResourcesInitialized(context, Function::BufferClear, setSizes, ArraySize(setSizes),
200 sizeof(BufferUtilsShaderParams));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500201}
202
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100203angle::Result UtilsVk::ensureBufferCopyResourcesInitialized(vk::Context *context)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500204{
205 if (mPipelineLayouts[Function::BufferCopy].valid())
206 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500207 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500208 }
209
210 VkDescriptorPoolSize setSizes[2] = {
211 {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1},
212 {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1},
213 };
214
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100215 return ensureResourcesInitialized(context, Function::BufferCopy, setSizes, ArraySize(setSizes),
216 sizeof(BufferUtilsShaderParams));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500217}
218
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100219angle::Result UtilsVk::ensureConvertVertexResourcesInitialized(vk::Context *context)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100220{
221 if (mPipelineLayouts[Function::ConvertVertexBuffer].valid())
222 {
223 return angle::Result::Continue;
224 }
225
226 VkDescriptorPoolSize setSizes[2] = {
227 {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
228 {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
229 };
230
231 return ensureResourcesInitialized(context, Function::ConvertVertexBuffer, setSizes,
232 ArraySize(setSizes), sizeof(ConvertVertexShaderParams));
233}
234
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100235angle::Result UtilsVk::ensureImageClearResourcesInitialized(vk::Context *context)
236{
237 if (mPipelineLayouts[Function::ImageClear].valid())
238 {
239 return angle::Result::Continue;
240 }
241
242 // The shader does not use any descriptor sets.
243 return ensureResourcesInitialized(context, Function::ImageClear, nullptr, 0,
244 sizeof(ImageClearShaderParams));
245}
246
247angle::Result UtilsVk::setupProgram(vk::Context *context,
248 Function function,
249 vk::RefCounted<vk::ShaderAndSerial> *fsCsShader,
250 vk::RefCounted<vk::ShaderAndSerial> *vsShader,
251 vk::ShaderProgramHelper *program,
252 const vk::GraphicsPipelineDesc *pipelineDesc,
253 const VkDescriptorSet descriptorSet,
254 const void *pushConstants,
255 size_t pushConstantsSize,
256 vk::CommandBuffer *commandBuffer)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100257{
258 RendererVk *renderer = context->getRenderer();
259
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100260 bool isCompute = function >= Function::ComputeStartIndex;
261 VkPipelineBindPoint bindPoint =
262 isCompute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
263 VkShaderStageFlags pushConstantsShaderStage =
264 isCompute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
265
266 // If compute, vsShader and pipelineDesc should be nullptr, and if not compute they shouldn't
267 // be.
268 ASSERT(isCompute != (vsShader && pipelineDesc));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100269
270 const vk::BindingPointer<vk::PipelineLayout> &pipelineLayout = mPipelineLayouts[function];
271
272 vk::PipelineAndSerial *pipelineAndSerial;
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100273 if (isCompute)
274 {
275 program->setShader(gl::ShaderType::Compute, fsCsShader);
276 ANGLE_TRY(program->getComputePipeline(context, pipelineLayout.get(), &pipelineAndSerial));
277 }
278 else
279 {
280 program->setShader(gl::ShaderType::Vertex, vsShader);
281 program->setShader(gl::ShaderType::Fragment, fsCsShader);
282 ANGLE_TRY(program->getGraphicsPipeline(context, pipelineLayout.get(), *pipelineDesc,
283 gl::AttributesMask(), &pipelineAndSerial));
284 }
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100285
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100286 commandBuffer->bindPipeline(bindPoint, pipelineAndSerial->get());
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100287 pipelineAndSerial->updateSerial(renderer->getCurrentQueueSerial());
288
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100289 if (descriptorSet != VK_NULL_HANDLE)
290 {
291 commandBuffer->bindDescriptorSets(bindPoint, pipelineLayout.get(), 0, 1, &descriptorSet, 0,
292 nullptr);
293 }
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100294
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100295 commandBuffer->pushConstants(pipelineLayout.get(), pushConstantsShaderStage, 0,
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100296 pushConstantsSize, pushConstants);
297
298 return angle::Result::Continue;
299}
300
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100301angle::Result UtilsVk::clearBuffer(vk::Context *context,
302 vk::BufferHelper *dest,
303 const ClearParameters &params)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500304{
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100305 RendererVk *renderer = context->getRenderer();
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500306
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100307 ANGLE_TRY(ensureBufferClearResourcesInitialized(context));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500308
309 vk::CommandBuffer *commandBuffer;
310 ANGLE_TRY(dest->recordCommands(context, &commandBuffer));
311
312 // Tell dest it's being written to.
313 dest->onWrite(VK_ACCESS_SHADER_WRITE_BIT);
314
315 const vk::Format &destFormat = dest->getViewFormat();
316
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100317 uint32_t flags = BufferUtils_comp::kIsClear | GetBufferUtilsFlags(params.size, destFormat);
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500318
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100319 BufferUtilsShaderParams shaderParams;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500320 shaderParams.destOffset = params.offset;
321 shaderParams.size = params.size;
322 shaderParams.clearValue = params.clearValue;
323
324 VkDescriptorSet descriptorSet;
325 vk::SharedDescriptorPoolBinding descriptorPoolBinding;
326 ANGLE_TRY(mDescriptorPools[Function::BufferClear].allocateSets(
327 context, mDescriptorSetLayouts[Function::BufferClear][kSetIndex].get().ptr(), 1,
328 &descriptorPoolBinding, &descriptorSet));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100329 descriptorPoolBinding.get().updateSerial(context->getRenderer()->getCurrentQueueSerial());
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500330
331 VkWriteDescriptorSet writeInfo = {};
332
333 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
334 writeInfo.dstSet = descriptorSet;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100335 writeInfo.dstBinding = kBufferClearOutputBinding;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500336 writeInfo.descriptorCount = 1;
337 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
338 writeInfo.pTexelBufferView = dest->getBufferView().ptr();
339
340 vkUpdateDescriptorSets(context->getDevice(), 1, &writeInfo, 0, nullptr);
341
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100342 vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
343 ANGLE_TRY(renderer->getShaderLibrary().getBufferUtils_comp(context, flags, &shader));
344
345 ANGLE_TRY(setupProgram(context, Function::BufferClear, shader, nullptr,
346 &mBufferUtilsPrograms[flags], nullptr, descriptorSet, &shaderParams,
347 sizeof(shaderParams), commandBuffer));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500348
349 commandBuffer->dispatch(UnsignedCeilDivide(params.size, 64), 1, 1);
350
351 descriptorPoolBinding.reset();
352
Jamie Madill7c985f52018-11-29 18:16:17 -0500353 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500354}
355
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100356angle::Result UtilsVk::copyBuffer(vk::Context *context,
357 vk::BufferHelper *dest,
358 vk::BufferHelper *src,
359 const CopyParameters &params)
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500360{
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100361 RendererVk *renderer = context->getRenderer();
362
363 ANGLE_TRY(ensureBufferCopyResourcesInitialized(context));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500364
365 vk::CommandBuffer *commandBuffer;
366 ANGLE_TRY(dest->recordCommands(context, &commandBuffer));
367
368 // Tell src we are going to read from it.
369 src->onRead(dest, VK_ACCESS_SHADER_READ_BIT);
370 // Tell dest it's being written to.
371 dest->onWrite(VK_ACCESS_SHADER_WRITE_BIT);
372
373 const vk::Format &destFormat = dest->getViewFormat();
374 const vk::Format &srcFormat = src->getViewFormat();
375
376 ASSERT(destFormat.vkFormatIsInt == srcFormat.vkFormatIsInt);
377 ASSERT(destFormat.vkFormatIsUnsigned == srcFormat.vkFormatIsUnsigned);
378
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100379 uint32_t flags = BufferUtils_comp::kIsCopy | GetBufferUtilsFlags(params.size, destFormat);
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500380
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100381 BufferUtilsShaderParams shaderParams;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500382 shaderParams.destOffset = params.destOffset;
383 shaderParams.size = params.size;
384 shaderParams.srcOffset = params.srcOffset;
385
386 VkDescriptorSet descriptorSet;
387 vk::SharedDescriptorPoolBinding descriptorPoolBinding;
388 ANGLE_TRY(mDescriptorPools[Function::BufferCopy].allocateSets(
389 context, mDescriptorSetLayouts[Function::BufferCopy][kSetIndex].get().ptr(), 1,
390 &descriptorPoolBinding, &descriptorSet));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100391 descriptorPoolBinding.get().updateSerial(context->getRenderer()->getCurrentQueueSerial());
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500392
393 VkWriteDescriptorSet writeInfo[2] = {};
394
395 writeInfo[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
396 writeInfo[0].dstSet = descriptorSet;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100397 writeInfo[0].dstBinding = kBufferCopyDestinationBinding;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500398 writeInfo[0].descriptorCount = 1;
399 writeInfo[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
400 writeInfo[0].pTexelBufferView = dest->getBufferView().ptr();
401
402 writeInfo[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
403 writeInfo[1].dstSet = descriptorSet;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100404 writeInfo[1].dstBinding = kBufferCopySourceBinding;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500405 writeInfo[1].descriptorCount = 1;
406 writeInfo[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
407 writeInfo[1].pTexelBufferView = src->getBufferView().ptr();
408
409 vkUpdateDescriptorSets(context->getDevice(), 2, writeInfo, 0, nullptr);
410
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100411 vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
412 ANGLE_TRY(renderer->getShaderLibrary().getBufferUtils_comp(context, flags, &shader));
413
414 ANGLE_TRY(setupProgram(context, Function::BufferCopy, shader, nullptr,
415 &mBufferUtilsPrograms[flags], nullptr, descriptorSet, &shaderParams,
416 sizeof(shaderParams), commandBuffer));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500417
418 commandBuffer->dispatch(UnsignedCeilDivide(params.size, 64), 1, 1);
419
420 descriptorPoolBinding.reset();
421
Jamie Madill7c985f52018-11-29 18:16:17 -0500422 return angle::Result::Continue;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500423}
424
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100425angle::Result UtilsVk::convertVertexBuffer(vk::Context *context,
426 vk::BufferHelper *dest,
427 vk::BufferHelper *src,
428 const ConvertVertexParameters &params)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100429{
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100430 RendererVk *renderer = context->getRenderer();
431
432 ANGLE_TRY(ensureConvertVertexResourcesInitialized(context));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100433
434 vk::CommandBuffer *commandBuffer;
435 ANGLE_TRY(dest->recordCommands(context, &commandBuffer));
436
437 // Tell src we are going to read from it.
438 src->onRead(dest, VK_ACCESS_SHADER_READ_BIT);
439 // Tell dest it's being written to.
440 dest->onWrite(VK_ACCESS_SHADER_WRITE_BIT);
441
442 ConvertVertexShaderParams shaderParams;
443 shaderParams.Ns = params.srcFormat->channelCount();
444 shaderParams.Bs = params.srcFormat->pixelBytes / params.srcFormat->channelCount();
445 shaderParams.Ss = params.srcStride;
446 shaderParams.Nd = params.destFormat->channelCount();
447 shaderParams.Bd = params.destFormat->pixelBytes / params.destFormat->channelCount();
448 shaderParams.Sd = shaderParams.Nd * shaderParams.Bd;
449 // The component size is expected to either be 1, 2 or 4 bytes.
450 ASSERT(4 % shaderParams.Bs == 0);
451 ASSERT(4 % shaderParams.Bd == 0);
452 shaderParams.Es = 4 / shaderParams.Bs;
453 shaderParams.Ed = 4 / shaderParams.Bd;
454 // Total number of output components is simply the number of vertices by number of components in
455 // each.
456 shaderParams.componentCount = params.vertexCount * shaderParams.Nd;
457 // Total number of 4-byte outputs is the number of components divided by how many components can
458 // fit in a 4-byte value. Note that this value is also the invocation size of the shader.
459 shaderParams.outputCount = shaderParams.componentCount / shaderParams.Ed;
460 shaderParams.srcOffset = params.srcOffset;
461 shaderParams.destOffset = params.destOffset;
462
463 uint32_t flags = GetConvertVertexFlags(params);
464
465 bool isAligned =
466 shaderParams.outputCount % 64 == 0 && shaderParams.componentCount % shaderParams.Ed == 0;
467 flags |= isAligned ? ConvertVertex_comp::kIsAligned : 0;
468
469 VkDescriptorSet descriptorSet;
470 vk::SharedDescriptorPoolBinding descriptorPoolBinding;
471 ANGLE_TRY(mDescriptorPools[Function::ConvertVertexBuffer].allocateSets(
472 context, mDescriptorSetLayouts[Function::ConvertVertexBuffer][kSetIndex].get().ptr(), 1,
473 &descriptorPoolBinding, &descriptorSet));
474 descriptorPoolBinding.get().updateSerial(context->getRenderer()->getCurrentQueueSerial());
475
476 VkWriteDescriptorSet writeInfo = {};
477 VkDescriptorBufferInfo buffers[2] = {
478 {dest->getBuffer().getHandle(), 0, VK_WHOLE_SIZE},
479 {src->getBuffer().getHandle(), 0, VK_WHOLE_SIZE},
480 };
481 static_assert(kConvertVertexDestinationBinding + 1 == kConvertVertexSourceBinding,
482 "Update write info");
483
484 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
485 writeInfo.dstSet = descriptorSet;
486 writeInfo.dstBinding = kConvertVertexDestinationBinding;
487 writeInfo.descriptorCount = 2;
488 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
489 writeInfo.pBufferInfo = buffers;
490
491 vkUpdateDescriptorSets(context->getDevice(), 1, &writeInfo, 0, nullptr);
492
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100493 vk::RefCounted<vk::ShaderAndSerial> *shader = nullptr;
494 ANGLE_TRY(renderer->getShaderLibrary().getConvertVertex_comp(context, flags, &shader));
495
496 ANGLE_TRY(setupProgram(context, Function::ConvertVertexBuffer, shader, nullptr,
497 &mConvertVertexPrograms[flags], nullptr, descriptorSet, &shaderParams,
498 sizeof(shaderParams), commandBuffer));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100499
500 commandBuffer->dispatch(UnsignedCeilDivide(shaderParams.outputCount, 64), 1, 1);
501
502 descriptorPoolBinding.reset();
503
504 return angle::Result::Continue;
505}
506
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100507angle::Result UtilsVk::clearImage(ContextVk *contextVk,
508 FramebufferVk *framebuffer,
509 const ClearImageParameters &params)
510{
511 RendererVk *renderer = contextVk->getRenderer();
512
513 ANGLE_TRY(ensureImageClearResourcesInitialized(contextVk));
514
515 vk::CommandBuffer *commandBuffer;
516 if (!framebuffer->appendToStartedRenderPass(contextVk->getRenderer(), &commandBuffer))
517 {
518 ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, &commandBuffer))
519 }
520
521 ImageClearShaderParams shaderParams;
522 shaderParams.clearValue = params.clearValue;
523
524 vk::GraphicsPipelineDesc pipelineDesc;
525 pipelineDesc.initDefaults();
526 pipelineDesc.updateColorWriteMask(params.colorMaskFlags, *params.alphaMask);
527 pipelineDesc.updateRenderPassDesc(*params.renderPassDesc);
528
529 vk::ShaderLibrary &shaderLibrary = renderer->getShaderLibrary();
530 vk::RefCounted<vk::ShaderAndSerial> *vertexShader = nullptr;
531 vk::RefCounted<vk::ShaderAndSerial> *fragmentShader = nullptr;
532 ANGLE_TRY(shaderLibrary.getFullScreenQuad_vert(contextVk, 0, &vertexShader));
533 ANGLE_TRY(shaderLibrary.getImageClear_frag(contextVk, 0, &fragmentShader));
534
535 ANGLE_TRY(setupProgram(contextVk, Function::ImageClear, fragmentShader, vertexShader,
536 &mImageClearProgram, &pipelineDesc, VK_NULL_HANDLE, &shaderParams,
537 sizeof(shaderParams), commandBuffer));
538
539 VkViewport viewport;
540 const gl::Rectangle &renderArea = framebuffer->getFramebuffer()->getRenderPassRenderArea();
541 bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO();
542 gl_vk::GetViewport(renderArea, 0.0f, 1.0f, invertViewport, params.renderAreaHeight, &viewport);
543
544 VkRect2D scissor;
545 const gl::State &glState = contextVk->getGLState();
546 gl_vk::GetScissor(glState, invertViewport, renderArea, &scissor);
547
548 commandBuffer->setViewport(0, 1, &viewport);
549 commandBuffer->setScissor(0, 1, &scissor);
550 commandBuffer->draw(6, 1, 0, 0);
551
552 return angle::Result::Continue;
553}
554
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500555} // namespace rx