blob: facd0757b3cf04084f35ec052c3b0aa1126cf55b [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
2// Copyright 2016 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//
6// ProgramVk.cpp:
7// Implements the class methods for ProgramVk.
8//
9
10#include "libANGLE/renderer/vulkan/ProgramVk.h"
11
12#include "common/debug.h"
Jamie Madill76e471e2017-10-21 09:56:01 -040013#include "common/utilities.h"
Jamie Madillc564c072017-06-01 12:45:42 -040014#include "libANGLE/Context.h"
Jamie Madill8ecf7f92017-01-13 17:29:52 -050015#include "libANGLE/renderer/vulkan/ContextVk.h"
Luc Ferrondaedf4d2018-03-16 09:28:53 -040016#include "libANGLE/renderer/vulkan/DynamicDescriptorPool.h"
Jamie Madill8ecf7f92017-01-13 17:29:52 -050017#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
18#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill5547b382017-10-23 18:16:01 -040019#include "libANGLE/renderer/vulkan/TextureVk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040020
21namespace rx
22{
23
Jamie Madill76e471e2017-10-21 09:56:01 -040024namespace
25{
26
27gl::Error InitDefaultUniformBlock(const gl::Context *context,
28 VkDevice device,
29 gl::Shader *shader,
30 vk::BufferAndMemory *storageOut,
31 sh::BlockLayoutMap *blockLayoutMapOut,
32 size_t *requiredSizeOut)
33{
34 const auto &uniforms = shader->getUniforms(context);
35
36 if (uniforms.empty())
37 {
38 *requiredSizeOut = 0;
39 return gl::NoError();
40 }
41
42 sh::Std140BlockEncoder blockEncoder;
Olli Etuaho3de27032017-11-30 12:16:47 +020043 sh::GetUniformBlockInfo(uniforms, "", &blockEncoder, blockLayoutMapOut);
Jamie Madill76e471e2017-10-21 09:56:01 -040044
45 size_t blockSize = blockEncoder.getBlockSize();
46
47 // TODO(jmadill): I think we still need a valid block for the pipeline even if zero sized.
48 if (blockSize == 0)
49 {
50 *requiredSizeOut = 0;
51 return gl::NoError();
52 }
53
54 VkBufferCreateInfo uniformBufferInfo;
55 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
56 uniformBufferInfo.pNext = nullptr;
57 uniformBufferInfo.flags = 0;
58 uniformBufferInfo.size = blockSize;
59 uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
60 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
61 uniformBufferInfo.queueFamilyIndexCount = 0;
62 uniformBufferInfo.pQueueFamilyIndices = nullptr;
63
64 ANGLE_TRY(storageOut->buffer.init(device, uniformBufferInfo));
65
Jamie Madill57dd97a2018-02-06 17:10:49 -050066 // Assume host vislble/coherent memory available.
67 VkMemoryPropertyFlags flags =
68 (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Jamie Madill57fbfd82018-02-14 12:45:34 -050069
70 ContextVk *contextVk = vk::GetImpl(context);
71
72 ANGLE_TRY(AllocateBufferMemory(contextVk->getRenderer(), flags, &storageOut->buffer,
Jamie Madill76e471e2017-10-21 09:56:01 -040073 &storageOut->memory, requiredSizeOut));
74
75 return gl::NoError();
76}
77
78template <typename T>
79void UpdateDefaultUniformBlock(GLsizei count,
80 int componentCount,
81 const T *v,
82 const sh::BlockMemberInfo &layoutInfo,
83 angle::MemoryBuffer *uniformData)
84{
Jamie Madill76e471e2017-10-21 09:56:01 -040085 int elementSize = sizeof(T) * componentCount;
86 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
87 {
88 uint8_t *writePtr = uniformData->data() + layoutInfo.offset;
89 memcpy(writePtr, v, elementSize * count);
90 }
91 else
92 {
93 UNIMPLEMENTED();
94 }
95}
96
Luc Ferron7cec3352018-03-13 13:29:34 -040097template <typename T>
98void ReadFromDefaultUniformBlock(int componentCount,
99 T *dst,
100 const sh::BlockMemberInfo &layoutInfo,
101 const angle::MemoryBuffer *uniformData)
102{
103 ASSERT(layoutInfo.offset != -1);
104
105 int elementSize = sizeof(T) * componentCount;
106 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
107 {
108 const uint8_t *readPtr = uniformData->data() + layoutInfo.offset;
109 memcpy(dst, readPtr, elementSize);
110 }
111 else
112 {
113 UNIMPLEMENTED();
114 }
115}
116
Jamie Madill76e471e2017-10-21 09:56:01 -0400117vk::Error SyncDefaultUniformBlock(VkDevice device,
118 vk::DeviceMemory *bufferMemory,
119 const angle::MemoryBuffer &bufferData)
120{
121 ASSERT(bufferMemory->valid() && !bufferData.empty());
122 uint8_t *mapPointer = nullptr;
123 ANGLE_TRY(bufferMemory->map(device, 0, bufferData.size(), 0, &mapPointer));
124 memcpy(mapPointer, bufferData.data(), bufferData.size());
125 bufferMemory->unmap(device);
126 return vk::NoError();
127}
128
129enum ShaderIndex : uint32_t
130{
131 MinShaderIndex = 0,
132 VertexShader = MinShaderIndex,
133 FragmentShader = 1,
134 MaxShaderIndex = 2,
135};
136
137gl::Shader *GetShader(const gl::ProgramState &programState, uint32_t shaderIndex)
138{
139 switch (shaderIndex)
140 {
141 case VertexShader:
142 return programState.getAttachedVertexShader();
143 case FragmentShader:
144 return programState.getAttachedFragmentShader();
145 default:
146 UNREACHABLE();
147 return nullptr;
148 }
149}
150
151} // anonymous namespace
152
153ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
154 : storage(), uniformData(), uniformsDirty(false), uniformLayout()
155{
156}
157
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500158ProgramVk::DefaultUniformBlock::~DefaultUniformBlock()
159{
160}
161
Jamie Madill76e471e2017-10-21 09:56:01 -0400162ProgramVk::ProgramVk(const gl::ProgramState &state)
Jamie Madill8c3988c2017-12-21 14:44:56 -0500163 : ProgramImpl(state), mDefaultUniformBlocks(), mUsedDescriptorSetRange(), mDirtyTextures(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400164{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500165 mUsedDescriptorSetRange.invalidate();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400166}
167
168ProgramVk::~ProgramVk()
169{
170}
171
Jamie Madillb7d924a2018-03-10 11:16:54 -0500172gl::Error ProgramVk::destroy(const gl::Context *contextImpl)
Jamie Madill5deea722017-02-16 10:44:46 -0500173{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500174 ContextVk *contextVk = vk::GetImpl(contextImpl);
Jamie Madillb7d924a2018-03-10 11:16:54 -0500175 return reset(contextVk);
Jamie Madillc5143482017-10-15 20:20:06 -0400176}
Jamie Madill5deea722017-02-16 10:44:46 -0500177
Jamie Madillb7d924a2018-03-10 11:16:54 -0500178vk::Error ProgramVk::reset(ContextVk *contextVk)
Jamie Madillc5143482017-10-15 20:20:06 -0400179{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500180 // TODO(jmadill): Handle re-linking a program that is in-use. http://anglebug.com/2397
181
182 VkDevice device = contextVk->getDevice();
183
Jamie Madill76e471e2017-10-21 09:56:01 -0400184 for (auto &uniformBlock : mDefaultUniformBlocks)
185 {
186 uniformBlock.storage.memory.destroy(device);
187 uniformBlock.storage.buffer.destroy(device);
188 }
189
190 mEmptyUniformBlockStorage.memory.destroy(device);
191 mEmptyUniformBlockStorage.buffer.destroy(device);
192
Jamie Madill5deea722017-02-16 10:44:46 -0500193 mLinkedFragmentModule.destroy(device);
194 mLinkedVertexModule.destroy(device);
Jamie Madillf2f6d372018-01-10 21:37:23 -0500195 mVertexModuleSerial = Serial();
196 mFragmentModuleSerial = Serial();
Jamie Madill76e471e2017-10-21 09:56:01 -0400197
Jamie Madill5547b382017-10-23 18:16:01 -0400198 mDescriptorSets.clear();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500199 mUsedDescriptorSetRange.invalidate();
Jamie Madill5547b382017-10-23 18:16:01 -0400200 mDirtyTextures = false;
Jamie Madillb7d924a2018-03-10 11:16:54 -0500201
202 return vk::NoError();
Jamie Madill5deea722017-02-16 10:44:46 -0500203}
204
Jamie Madill9cf9e872017-06-05 12:59:25 -0400205gl::LinkResult ProgramVk::load(const gl::Context *contextImpl,
206 gl::InfoLog &infoLog,
207 gl::BinaryInputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400208{
209 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500210 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400211}
212
Jamie Madill27a60632017-06-30 15:12:01 -0400213void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400214{
215 UNIMPLEMENTED();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400216}
217
218void ProgramVk::setBinaryRetrievableHint(bool retrievable)
219{
220 UNIMPLEMENTED();
221}
222
Yunchao He61afff12017-03-14 15:34:03 +0800223void ProgramVk::setSeparable(bool separable)
224{
225 UNIMPLEMENTED();
226}
227
Jamie Madill9cf9e872017-06-05 12:59:25 -0400228gl::LinkResult ProgramVk::link(const gl::Context *glContext,
Jamie Madillc9727f32017-11-07 12:37:07 -0500229 const gl::ProgramLinkedResources &resources,
Jamie Madill9cf9e872017-06-05 12:59:25 -0400230 gl::InfoLog &infoLog)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400231{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400232 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madillc5143482017-10-15 20:20:06 -0400233 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500234 GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
Jamie Madillc5143482017-10-15 20:20:06 -0400235 VkDevice device = renderer->getDevice();
236
Jamie Madillb7d924a2018-03-10 11:16:54 -0500237 ANGLE_TRY(reset(contextVk));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500238
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500239 std::vector<uint32_t> vertexCode;
240 std::vector<uint32_t> fragmentCode;
241 bool linkSuccess = false;
Jamie Madill4dd167f2017-11-09 13:08:31 -0500242 ANGLE_TRY_RESULT(
243 glslangWrapper->linkProgram(glContext, mState, resources, &vertexCode, &fragmentCode),
244 linkSuccess);
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500245 if (!linkSuccess)
246 {
247 return false;
248 }
249
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500250 {
251 VkShaderModuleCreateInfo vertexShaderInfo;
252 vertexShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
253 vertexShaderInfo.pNext = nullptr;
254 vertexShaderInfo.flags = 0;
255 vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t);
256 vertexShaderInfo.pCode = vertexCode.data();
Jamie Madillc5143482017-10-15 20:20:06 -0400257
258 ANGLE_TRY(mLinkedVertexModule.init(device, vertexShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500259 mVertexModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500260 }
261
262 {
263 VkShaderModuleCreateInfo fragmentShaderInfo;
264 fragmentShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
265 fragmentShaderInfo.pNext = nullptr;
266 fragmentShaderInfo.flags = 0;
267 fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t);
268 fragmentShaderInfo.pCode = fragmentCode.data();
269
Jamie Madillc5143482017-10-15 20:20:06 -0400270 ANGLE_TRY(mLinkedFragmentModule.init(device, fragmentShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500271 mFragmentModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500272 }
273
Jamie Madill76e471e2017-10-21 09:56:01 -0400274 ANGLE_TRY(initDescriptorSets(contextVk));
275 ANGLE_TRY(initDefaultUniformBlocks(glContext));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500276
Jamie Madill8c3988c2017-12-21 14:44:56 -0500277 if (!mState.getSamplerUniformRange().empty())
278 {
279 // Ensure the descriptor set range includes the textures at position 1.
280 mUsedDescriptorSetRange.extend(1);
281 mDirtyTextures = true;
282 }
283
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500284 return true;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400285}
286
Jamie Madill76e471e2017-10-21 09:56:01 -0400287gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
288{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400289 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madill57fbfd82018-02-14 12:45:34 -0500290 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400291 VkDevice device = contextVk->getDevice();
292
293 // Process vertex and fragment uniforms into std140 packing.
294 std::array<sh::BlockLayoutMap, 2> layoutMap;
295 std::array<size_t, 2> requiredBufferSize = {{0, 0}};
296
297 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
298 {
299 ANGLE_TRY(InitDefaultUniformBlock(glContext, device, GetShader(mState, shaderIndex),
300 &mDefaultUniformBlocks[shaderIndex].storage,
301 &layoutMap[shaderIndex],
302 &requiredBufferSize[shaderIndex]));
303 }
304
305 // Init the default block layout info.
306 const auto &locations = mState.getUniformLocations();
307 const auto &uniforms = mState.getUniforms();
308 for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex)
309 {
310 std::array<sh::BlockMemberInfo, 2> layoutInfo;
311
312 const auto &location = locations[locationIndex];
313 if (location.used() && !location.ignored)
314 {
Jamie Madillde03e002017-10-21 14:04:20 -0400315 const auto &uniform = uniforms[location.index];
316
317 if (uniform.isSampler())
318 continue;
319
Jamie Madill76e471e2017-10-21 09:56:01 -0400320 std::string uniformName = uniform.name;
321 if (uniform.isArray())
322 {
Olli Etuaho1734e172017-10-27 15:30:27 +0300323 uniformName += ArrayString(location.arrayIndex);
Jamie Madill76e471e2017-10-21 09:56:01 -0400324 }
325
326 bool found = false;
327
328 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
329 {
330 auto it = layoutMap[shaderIndex].find(uniformName);
331 if (it != layoutMap[shaderIndex].end())
332 {
333 found = true;
334 layoutInfo[shaderIndex] = it->second;
335 }
336 }
337
338 ASSERT(found);
339 }
340
341 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
342 {
343 mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]);
344 }
345 }
346
347 bool anyDirty = false;
348 bool allDirty = true;
349
350 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
351 {
352 if (requiredBufferSize[shaderIndex] > 0)
353 {
354 if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize(
355 requiredBufferSize[shaderIndex]))
356 {
357 return gl::OutOfMemory() << "Memory allocation failure.";
358 }
359 mDefaultUniformBlocks[shaderIndex].uniformData.fill(0);
360 mDefaultUniformBlocks[shaderIndex].uniformsDirty = true;
361
362 anyDirty = true;
363 }
364 else
365 {
366 allDirty = false;
367 }
368 }
369
370 if (anyDirty)
371 {
372 // Initialize the "empty" uniform block if necessary.
373 if (!allDirty)
374 {
375 VkBufferCreateInfo uniformBufferInfo;
376 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
377 uniformBufferInfo.pNext = nullptr;
378 uniformBufferInfo.flags = 0;
379 uniformBufferInfo.size = 1;
380 uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
381 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
382 uniformBufferInfo.queueFamilyIndexCount = 0;
383 uniformBufferInfo.pQueueFamilyIndices = nullptr;
384
385 ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo));
386
Jamie Madill57dd97a2018-02-06 17:10:49 -0500387 // Assume host vislble/coherent memory available.
388 VkMemoryPropertyFlags flags =
389 (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Jamie Madill76e471e2017-10-21 09:56:01 -0400390 size_t requiredSize = 0;
Jamie Madill57fbfd82018-02-14 12:45:34 -0500391 ANGLE_TRY(AllocateBufferMemory(renderer, flags, &mEmptyUniformBlockStorage.buffer,
Jamie Madill76e471e2017-10-21 09:56:01 -0400392 &mEmptyUniformBlockStorage.memory, &requiredSize));
393 }
394
395 ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk));
Jamie Madill8c3988c2017-12-21 14:44:56 -0500396
397 // Ensure the descriptor set range includes the uniform buffers at position 0.
398 mUsedDescriptorSetRange.extend(0);
Jamie Madill5547b382017-10-23 18:16:01 -0400399 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400400
401 return gl::NoError();
402}
403
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400404GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
405{
406 UNIMPLEMENTED();
407 return GLboolean();
408}
409
Jamie Madill76e471e2017-10-21 09:56:01 -0400410template <typename T>
411void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType)
412{
413 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
414 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
415
Luc Ferron7cec3352018-03-13 13:29:34 -0400416 if (linkedUniform.isSampler())
417 {
418 UNIMPLEMENTED();
419 return;
420 }
421
Jamie Madill76e471e2017-10-21 09:56:01 -0400422 if (linkedUniform.type == entryPointType)
423 {
424 for (auto &uniformBlock : mDefaultUniformBlocks)
425 {
426 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
Jamie Madill5eaddbd2018-03-14 16:16:03 -0400427
428 // Assume an offset of -1 means the block is unused.
429 if (layoutInfo.offset == -1)
430 {
431 continue;
432 }
433
Jamie Madill76e471e2017-10-21 09:56:01 -0400434 UpdateDefaultUniformBlock(count, linkedUniform.typeInfo->componentCount, v, layoutInfo,
435 &uniformBlock.uniformData);
Jamie Madill5eaddbd2018-03-14 16:16:03 -0400436
437 uniformBlock.uniformsDirty = true;
Jamie Madill76e471e2017-10-21 09:56:01 -0400438 }
439 }
440 else
441 {
442 ASSERT(linkedUniform.type == gl::VariableBoolVectorType(entryPointType));
443 UNIMPLEMENTED();
444 }
445}
446
Luc Ferron7cec3352018-03-13 13:29:34 -0400447template <typename T>
448void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) const
449{
450 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
451 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
452
453 if (linkedUniform.isSampler())
454 {
455 UNIMPLEMENTED();
456 return;
457 }
458
459 ASSERT(linkedUniform.typeInfo->componentType == entryPointType);
460 const gl::ShaderType shaderType = linkedUniform.getFirstStaticUseShaderType();
461 ASSERT(shaderType != gl::ShaderType::SHADER_TYPE_INVALID);
462
463 const DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
464 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
465 ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, v, layoutInfo,
466 &uniformBlock.uniformData);
467}
468
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400469void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
470{
Jamie Madill76e471e2017-10-21 09:56:01 -0400471 setUniformImpl(location, count, v, GL_FLOAT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400472}
473
474void ProgramVk::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
475{
Jamie Madill76e471e2017-10-21 09:56:01 -0400476 setUniformImpl(location, count, v, GL_FLOAT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400477}
478
479void ProgramVk::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
480{
Jamie Madill76e471e2017-10-21 09:56:01 -0400481 setUniformImpl(location, count, v, GL_FLOAT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400482}
483
484void ProgramVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
485{
Jamie Madill76e471e2017-10-21 09:56:01 -0400486 setUniformImpl(location, count, v, GL_FLOAT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400487}
488
489void ProgramVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
490{
Luc Ferron7cec3352018-03-13 13:29:34 -0400491 setUniformImpl(location, count, v, GL_INT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400492}
493
494void ProgramVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
495{
496 UNIMPLEMENTED();
497}
498
499void ProgramVk::setUniform3iv(GLint location, GLsizei count, const GLint *v)
500{
501 UNIMPLEMENTED();
502}
503
504void ProgramVk::setUniform4iv(GLint location, GLsizei count, const GLint *v)
505{
506 UNIMPLEMENTED();
507}
508
509void ProgramVk::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
510{
511 UNIMPLEMENTED();
512}
513
514void ProgramVk::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
515{
516 UNIMPLEMENTED();
517}
518
519void ProgramVk::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
520{
521 UNIMPLEMENTED();
522}
523
524void ProgramVk::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
525{
526 UNIMPLEMENTED();
527}
528
529void ProgramVk::setUniformMatrix2fv(GLint location,
530 GLsizei count,
531 GLboolean transpose,
532 const GLfloat *value)
533{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400534 if (transpose == GL_TRUE)
535 {
536 UNIMPLEMENTED();
537 return;
538 }
539
540 setUniformImpl(location, count, value, GL_FLOAT_MAT2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400541}
542
543void ProgramVk::setUniformMatrix3fv(GLint location,
544 GLsizei count,
545 GLboolean transpose,
546 const GLfloat *value)
547{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400548 if (transpose == GL_TRUE)
549 {
550 UNIMPLEMENTED();
551 return;
552 }
553 setUniformImpl(location, count, value, GL_FLOAT_MAT3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400554}
555
556void ProgramVk::setUniformMatrix4fv(GLint location,
557 GLsizei count,
558 GLboolean transpose,
559 const GLfloat *value)
560{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400561 if (transpose == GL_TRUE)
562 {
563 UNIMPLEMENTED();
564 return;
565 }
566
567 setUniformImpl(location, count, value, GL_FLOAT_MAT4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400568}
569
570void ProgramVk::setUniformMatrix2x3fv(GLint location,
571 GLsizei count,
572 GLboolean transpose,
573 const GLfloat *value)
574{
575 UNIMPLEMENTED();
576}
577
578void ProgramVk::setUniformMatrix3x2fv(GLint location,
579 GLsizei count,
580 GLboolean transpose,
581 const GLfloat *value)
582{
583 UNIMPLEMENTED();
584}
585
586void ProgramVk::setUniformMatrix2x4fv(GLint location,
587 GLsizei count,
588 GLboolean transpose,
589 const GLfloat *value)
590{
591 UNIMPLEMENTED();
592}
593
594void ProgramVk::setUniformMatrix4x2fv(GLint location,
595 GLsizei count,
596 GLboolean transpose,
597 const GLfloat *value)
598{
599 UNIMPLEMENTED();
600}
601
602void ProgramVk::setUniformMatrix3x4fv(GLint location,
603 GLsizei count,
604 GLboolean transpose,
605 const GLfloat *value)
606{
607 UNIMPLEMENTED();
608}
609
610void ProgramVk::setUniformMatrix4x3fv(GLint location,
611 GLsizei count,
612 GLboolean transpose,
613 const GLfloat *value)
614{
615 UNIMPLEMENTED();
616}
617
618void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
619{
620 UNIMPLEMENTED();
621}
622
Sami Väisänen46eaa942016-06-29 10:26:37 +0300623void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
624 GLenum genMode,
625 GLint components,
626 const GLfloat *coeffs)
627{
628 UNIMPLEMENTED();
629}
630
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500631const vk::ShaderModule &ProgramVk::getLinkedVertexModule() const
632{
633 ASSERT(mLinkedVertexModule.getHandle() != VK_NULL_HANDLE);
634 return mLinkedVertexModule;
635}
636
Jamie Madillf2f6d372018-01-10 21:37:23 -0500637Serial ProgramVk::getVertexModuleSerial() const
638{
639 return mVertexModuleSerial;
640}
641
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500642const vk::ShaderModule &ProgramVk::getLinkedFragmentModule() const
643{
644 ASSERT(mLinkedFragmentModule.getHandle() != VK_NULL_HANDLE);
645 return mLinkedFragmentModule;
646}
647
Jamie Madillf2f6d372018-01-10 21:37:23 -0500648Serial ProgramVk::getFragmentModuleSerial() const
649{
650 return mFragmentModuleSerial;
651}
652
Jamie Madill76e471e2017-10-21 09:56:01 -0400653vk::Error ProgramVk::initDescriptorSets(ContextVk *contextVk)
654{
Jamie Madill5547b382017-10-23 18:16:01 -0400655 ASSERT(mDescriptorSets.empty());
Jamie Madill76e471e2017-10-21 09:56:01 -0400656
Jamie Madill8c3988c2017-12-21 14:44:56 -0500657 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400658
659 // Write out to a new a descriptor set.
Luc Ferrondaedf4d2018-03-16 09:28:53 -0400660 DynamicDescriptorPool *dynamicDescriptorPool = contextVk->getDynamicDescriptorPool();
Jamie Madill76e471e2017-10-21 09:56:01 -0400661
Jamie Madill8c3988c2017-12-21 14:44:56 -0500662 const auto &descriptorSetLayouts = renderer->getGraphicsDescriptorSetLayouts();
663
664 uint32_t descriptorSetCount = static_cast<uint32_t>(descriptorSetLayouts.size());
Jamie Madill76e471e2017-10-21 09:56:01 -0400665
Jamie Madill5547b382017-10-23 18:16:01 -0400666 mDescriptorSets.resize(descriptorSetCount, VK_NULL_HANDLE);
Luc Ferrondaedf4d2018-03-16 09:28:53 -0400667 ANGLE_TRY(dynamicDescriptorPool->allocateDescriptorSets(
668 contextVk, descriptorSetLayouts[0].ptr(), descriptorSetCount, &mDescriptorSets[0]));
Jamie Madill76e471e2017-10-21 09:56:01 -0400669 return vk::NoError();
670}
671
Jamie Madill54164b02017-08-28 15:17:37 -0400672void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
673{
Luc Ferron7cec3352018-03-13 13:29:34 -0400674 getUniformImpl(location, params, GL_FLOAT);
Jamie Madill54164b02017-08-28 15:17:37 -0400675}
676
677void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
678{
Luc Ferron7cec3352018-03-13 13:29:34 -0400679 getUniformImpl(location, params, GL_INT);
Jamie Madill54164b02017-08-28 15:17:37 -0400680}
681
682void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
683{
684 UNIMPLEMENTED();
685}
686
Jamie Madill76e471e2017-10-21 09:56:01 -0400687vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
688{
689 if (!mDefaultUniformBlocks[VertexShader].uniformsDirty &&
690 !mDefaultUniformBlocks[FragmentShader].uniformsDirty)
691 {
692 return vk::NoError();
693 }
694
Jamie Madill8c3988c2017-12-21 14:44:56 -0500695 ASSERT(mUsedDescriptorSetRange.contains(0));
Jamie Madill5547b382017-10-23 18:16:01 -0400696
Jamie Madill76e471e2017-10-21 09:56:01 -0400697 VkDevice device = contextVk->getDevice();
698
699 // Update buffer memory by immediate mapping. This immediate update only works once.
700 // TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers.
701 for (auto &uniformBlock : mDefaultUniformBlocks)
702 {
703 if (uniformBlock.uniformsDirty)
704 {
705 ANGLE_TRY(SyncDefaultUniformBlock(device, &uniformBlock.storage.memory,
706 uniformBlock.uniformData));
707 uniformBlock.uniformsDirty = false;
708 }
709 }
710
711 return vk::NoError();
712}
713
714vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
715{
716 std::array<VkDescriptorBufferInfo, 2> descriptorBufferInfo;
717 std::array<VkWriteDescriptorSet, 2> writeDescriptorInfo;
718 uint32_t bufferCount = 0;
719
720 for (auto &uniformBlock : mDefaultUniformBlocks)
721 {
722 auto &bufferInfo = descriptorBufferInfo[bufferCount];
723
724 if (!uniformBlock.uniformData.empty())
725 {
726 bufferInfo.buffer = uniformBlock.storage.buffer.getHandle();
727 }
728 else
729 {
730 bufferInfo.buffer = mEmptyUniformBlockStorage.buffer.getHandle();
731 }
732
733 bufferInfo.offset = 0;
734 bufferInfo.range = VK_WHOLE_SIZE;
735
736 auto &writeInfo = writeDescriptorInfo[bufferCount];
737
738 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
739 writeInfo.pNext = nullptr;
Jamie Madill5547b382017-10-23 18:16:01 -0400740 writeInfo.dstSet = mDescriptorSets[0];
Jamie Madill76e471e2017-10-21 09:56:01 -0400741 writeInfo.dstBinding = bufferCount;
742 writeInfo.dstArrayElement = 0;
743 writeInfo.descriptorCount = 1;
744 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
745 writeInfo.pImageInfo = nullptr;
746 writeInfo.pBufferInfo = &bufferInfo;
747 writeInfo.pTexelBufferView = nullptr;
748
749 bufferCount++;
750 }
751
752 VkDevice device = contextVk->getDevice();
753
754 vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr);
755
756 return vk::NoError();
757}
758
Jamie Madill5547b382017-10-23 18:16:01 -0400759const std::vector<VkDescriptorSet> &ProgramVk::getDescriptorSets() const
Jamie Madill76e471e2017-10-21 09:56:01 -0400760{
Jamie Madill5547b382017-10-23 18:16:01 -0400761 return mDescriptorSets;
762}
763
Jamie Madill8c3988c2017-12-21 14:44:56 -0500764const gl::RangeUI &ProgramVk::getUsedDescriptorSetRange() const
Jamie Madill5547b382017-10-23 18:16:01 -0400765{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500766 return mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400767}
768
769void ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
770{
771 if (mState.getSamplerBindings().empty() || !mDirtyTextures)
772 {
773 return;
774 }
775
Jamie Madill8c3988c2017-12-21 14:44:56 -0500776 ASSERT(mUsedDescriptorSetRange.contains(1));
777 VkDescriptorSet descriptorSet = mDescriptorSets[1];
Jamie Madill5547b382017-10-23 18:16:01 -0400778
779 // TODO(jmadill): Don't hard-code the texture limit.
780 ShaderTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
781 ShaderTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
782 uint32_t imageCount = 0;
783
784 const gl::State &glState = contextVk->getGLState();
785 const auto &completeTextures = glState.getCompleteTextureCache();
786
787 for (const auto &samplerBinding : mState.getSamplerBindings())
788 {
789 ASSERT(!samplerBinding.unreferenced);
790
791 // TODO(jmadill): Sampler arrays
792 ASSERT(samplerBinding.boundTextureUnits.size() == 1);
793
794 GLuint textureUnit = samplerBinding.boundTextureUnits[0];
795 const gl::Texture *texture = completeTextures[textureUnit];
796
797 // TODO(jmadill): Incomplete textures handling.
798 ASSERT(texture);
799
Jamie Madille1f3ad42017-10-28 23:00:42 -0400800 TextureVk *textureVk = vk::GetImpl(texture);
Jamie Madill5547b382017-10-23 18:16:01 -0400801 const vk::Image &image = textureVk->getImage();
802
803 VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];
804
805 imageInfo.sampler = textureVk->getSampler().getHandle();
806 imageInfo.imageView = textureVk->getImageView().getHandle();
807 imageInfo.imageLayout = image.getCurrentLayout();
808
809 auto &writeInfo = writeDescriptorInfo[imageCount];
810
811 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
812 writeInfo.pNext = nullptr;
813 writeInfo.dstSet = descriptorSet;
814 writeInfo.dstBinding = imageCount;
815 writeInfo.dstArrayElement = 0;
816 writeInfo.descriptorCount = 1;
817 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
818 writeInfo.pImageInfo = &imageInfo;
819 writeInfo.pBufferInfo = nullptr;
820 writeInfo.pTexelBufferView = nullptr;
821
822 imageCount++;
823 }
824
825 VkDevice device = contextVk->getDevice();
826
827 ASSERT(imageCount > 0);
828 vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);
829
830 mDirtyTextures = false;
831}
832
833void ProgramVk::invalidateTextures()
834{
835 mDirtyTextures = true;
Jamie Madill76e471e2017-10-21 09:56:01 -0400836}
837
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400838} // namespace rx