blob: e8e1cb9a716bc7184122ee4c197d0e24602d6f67 [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"
16#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
17#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill5547b382017-10-23 18:16:01 -040018#include "libANGLE/renderer/vulkan/TextureVk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040019
20namespace rx
21{
22
Jamie Madill76e471e2017-10-21 09:56:01 -040023namespace
24{
25
26gl::Error InitDefaultUniformBlock(const gl::Context *context,
27 VkDevice device,
28 gl::Shader *shader,
29 vk::BufferAndMemory *storageOut,
30 sh::BlockLayoutMap *blockLayoutMapOut,
31 size_t *requiredSizeOut)
32{
33 const auto &uniforms = shader->getUniforms(context);
34
35 if (uniforms.empty())
36 {
37 *requiredSizeOut = 0;
38 return gl::NoError();
39 }
40
41 sh::Std140BlockEncoder blockEncoder;
Olli Etuaho3de27032017-11-30 12:16:47 +020042 sh::GetUniformBlockInfo(uniforms, "", &blockEncoder, blockLayoutMapOut);
Jamie Madill76e471e2017-10-21 09:56:01 -040043
44 size_t blockSize = blockEncoder.getBlockSize();
45
46 // TODO(jmadill): I think we still need a valid block for the pipeline even if zero sized.
47 if (blockSize == 0)
48 {
49 *requiredSizeOut = 0;
50 return gl::NoError();
51 }
52
53 VkBufferCreateInfo uniformBufferInfo;
54 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
55 uniformBufferInfo.pNext = nullptr;
56 uniformBufferInfo.flags = 0;
57 uniformBufferInfo.size = blockSize;
58 uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
59 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
60 uniformBufferInfo.queueFamilyIndexCount = 0;
61 uniformBufferInfo.pQueueFamilyIndices = nullptr;
62
63 ANGLE_TRY(storageOut->buffer.init(device, uniformBufferInfo));
64
Jamie Madill57dd97a2018-02-06 17:10:49 -050065 // Assume host vislble/coherent memory available.
66 VkMemoryPropertyFlags flags =
67 (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Jamie Madill57fbfd82018-02-14 12:45:34 -050068
69 ContextVk *contextVk = vk::GetImpl(context);
70
71 ANGLE_TRY(AllocateBufferMemory(contextVk->getRenderer(), flags, &storageOut->buffer,
Jamie Madill76e471e2017-10-21 09:56:01 -040072 &storageOut->memory, requiredSizeOut));
73
74 return gl::NoError();
75}
76
77template <typename T>
78void UpdateDefaultUniformBlock(GLsizei count,
79 int componentCount,
80 const T *v,
81 const sh::BlockMemberInfo &layoutInfo,
82 angle::MemoryBuffer *uniformData)
83{
Jamie Madill76e471e2017-10-21 09:56:01 -040084 int elementSize = sizeof(T) * componentCount;
85 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
86 {
87 uint8_t *writePtr = uniformData->data() + layoutInfo.offset;
88 memcpy(writePtr, v, elementSize * count);
89 }
90 else
91 {
92 UNIMPLEMENTED();
93 }
94}
95
Luc Ferron7cec3352018-03-13 13:29:34 -040096template <typename T>
97void ReadFromDefaultUniformBlock(int componentCount,
98 T *dst,
99 const sh::BlockMemberInfo &layoutInfo,
100 const angle::MemoryBuffer *uniformData)
101{
102 ASSERT(layoutInfo.offset != -1);
103
104 int elementSize = sizeof(T) * componentCount;
105 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
106 {
107 const uint8_t *readPtr = uniformData->data() + layoutInfo.offset;
108 memcpy(dst, readPtr, elementSize);
109 }
110 else
111 {
112 UNIMPLEMENTED();
113 }
114}
115
Jamie Madill76e471e2017-10-21 09:56:01 -0400116vk::Error SyncDefaultUniformBlock(VkDevice device,
117 vk::DeviceMemory *bufferMemory,
118 const angle::MemoryBuffer &bufferData)
119{
120 ASSERT(bufferMemory->valid() && !bufferData.empty());
121 uint8_t *mapPointer = nullptr;
122 ANGLE_TRY(bufferMemory->map(device, 0, bufferData.size(), 0, &mapPointer));
123 memcpy(mapPointer, bufferData.data(), bufferData.size());
124 bufferMemory->unmap(device);
125 return vk::NoError();
126}
127
128enum ShaderIndex : uint32_t
129{
130 MinShaderIndex = 0,
131 VertexShader = MinShaderIndex,
132 FragmentShader = 1,
133 MaxShaderIndex = 2,
134};
135
136gl::Shader *GetShader(const gl::ProgramState &programState, uint32_t shaderIndex)
137{
138 switch (shaderIndex)
139 {
140 case VertexShader:
141 return programState.getAttachedVertexShader();
142 case FragmentShader:
143 return programState.getAttachedFragmentShader();
144 default:
145 UNREACHABLE();
146 return nullptr;
147 }
148}
149
150} // anonymous namespace
151
152ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
153 : storage(), uniformData(), uniformsDirty(false), uniformLayout()
154{
155}
156
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500157ProgramVk::DefaultUniformBlock::~DefaultUniformBlock()
158{
159}
160
Jamie Madill76e471e2017-10-21 09:56:01 -0400161ProgramVk::ProgramVk(const gl::ProgramState &state)
Jamie Madill8c3988c2017-12-21 14:44:56 -0500162 : ProgramImpl(state), mDefaultUniformBlocks(), mUsedDescriptorSetRange(), mDirtyTextures(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400163{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500164 mUsedDescriptorSetRange.invalidate();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400165}
166
167ProgramVk::~ProgramVk()
168{
169}
170
Jamie Madillb7d924a2018-03-10 11:16:54 -0500171gl::Error ProgramVk::destroy(const gl::Context *contextImpl)
Jamie Madill5deea722017-02-16 10:44:46 -0500172{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500173 ContextVk *contextVk = vk::GetImpl(contextImpl);
Jamie Madillb7d924a2018-03-10 11:16:54 -0500174 return reset(contextVk);
Jamie Madillc5143482017-10-15 20:20:06 -0400175}
Jamie Madill5deea722017-02-16 10:44:46 -0500176
Jamie Madillb7d924a2018-03-10 11:16:54 -0500177vk::Error ProgramVk::reset(ContextVk *contextVk)
Jamie Madillc5143482017-10-15 20:20:06 -0400178{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500179 // TODO(jmadill): Handle re-linking a program that is in-use. http://anglebug.com/2397
180
181 VkDevice device = contextVk->getDevice();
182
Jamie Madill76e471e2017-10-21 09:56:01 -0400183 for (auto &uniformBlock : mDefaultUniformBlocks)
184 {
185 uniformBlock.storage.memory.destroy(device);
186 uniformBlock.storage.buffer.destroy(device);
187 }
188
189 mEmptyUniformBlockStorage.memory.destroy(device);
190 mEmptyUniformBlockStorage.buffer.destroy(device);
191
Jamie Madill5deea722017-02-16 10:44:46 -0500192 mLinkedFragmentModule.destroy(device);
193 mLinkedVertexModule.destroy(device);
Jamie Madillf2f6d372018-01-10 21:37:23 -0500194 mVertexModuleSerial = Serial();
195 mFragmentModuleSerial = Serial();
Jamie Madill76e471e2017-10-21 09:56:01 -0400196
Jamie Madill67ae6c52018-03-09 11:49:01 -0500197 // Free our descriptor set handles.
198 if (!mDescriptorSets.empty())
199 {
200 vk::DescriptorPool *descriptorPool = contextVk->getDescriptorPool();
Jamie Madillb7d924a2018-03-10 11:16:54 -0500201 ANGLE_TRY(descriptorPool->freeDescriptorSets(
202 device, static_cast<uint32_t>(mDescriptorSets.size()), mDescriptorSets.data()));
Jamie Madill67ae6c52018-03-09 11:49:01 -0500203 }
Jamie Madill5547b382017-10-23 18:16:01 -0400204 mDescriptorSets.clear();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500205 mUsedDescriptorSetRange.invalidate();
Jamie Madill5547b382017-10-23 18:16:01 -0400206 mDirtyTextures = false;
Jamie Madillb7d924a2018-03-10 11:16:54 -0500207
208 return vk::NoError();
Jamie Madill5deea722017-02-16 10:44:46 -0500209}
210
Jamie Madill9cf9e872017-06-05 12:59:25 -0400211gl::LinkResult ProgramVk::load(const gl::Context *contextImpl,
212 gl::InfoLog &infoLog,
213 gl::BinaryInputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400214{
215 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500216 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400217}
218
Jamie Madill27a60632017-06-30 15:12:01 -0400219void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400220{
221 UNIMPLEMENTED();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400222}
223
224void ProgramVk::setBinaryRetrievableHint(bool retrievable)
225{
226 UNIMPLEMENTED();
227}
228
Yunchao He61afff12017-03-14 15:34:03 +0800229void ProgramVk::setSeparable(bool separable)
230{
231 UNIMPLEMENTED();
232}
233
Jamie Madill9cf9e872017-06-05 12:59:25 -0400234gl::LinkResult ProgramVk::link(const gl::Context *glContext,
Jamie Madillc9727f32017-11-07 12:37:07 -0500235 const gl::ProgramLinkedResources &resources,
Jamie Madill9cf9e872017-06-05 12:59:25 -0400236 gl::InfoLog &infoLog)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400237{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400238 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madillc5143482017-10-15 20:20:06 -0400239 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500240 GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
Jamie Madillc5143482017-10-15 20:20:06 -0400241 VkDevice device = renderer->getDevice();
242
Jamie Madillb7d924a2018-03-10 11:16:54 -0500243 ANGLE_TRY(reset(contextVk));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500244
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500245 std::vector<uint32_t> vertexCode;
246 std::vector<uint32_t> fragmentCode;
247 bool linkSuccess = false;
Jamie Madill4dd167f2017-11-09 13:08:31 -0500248 ANGLE_TRY_RESULT(
249 glslangWrapper->linkProgram(glContext, mState, resources, &vertexCode, &fragmentCode),
250 linkSuccess);
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500251 if (!linkSuccess)
252 {
253 return false;
254 }
255
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500256 {
257 VkShaderModuleCreateInfo vertexShaderInfo;
258 vertexShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
259 vertexShaderInfo.pNext = nullptr;
260 vertexShaderInfo.flags = 0;
261 vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t);
262 vertexShaderInfo.pCode = vertexCode.data();
Jamie Madillc5143482017-10-15 20:20:06 -0400263
264 ANGLE_TRY(mLinkedVertexModule.init(device, vertexShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500265 mVertexModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500266 }
267
268 {
269 VkShaderModuleCreateInfo fragmentShaderInfo;
270 fragmentShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
271 fragmentShaderInfo.pNext = nullptr;
272 fragmentShaderInfo.flags = 0;
273 fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t);
274 fragmentShaderInfo.pCode = fragmentCode.data();
275
Jamie Madillc5143482017-10-15 20:20:06 -0400276 ANGLE_TRY(mLinkedFragmentModule.init(device, fragmentShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500277 mFragmentModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500278 }
279
Jamie Madill76e471e2017-10-21 09:56:01 -0400280 ANGLE_TRY(initDescriptorSets(contextVk));
281 ANGLE_TRY(initDefaultUniformBlocks(glContext));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500282
Jamie Madill8c3988c2017-12-21 14:44:56 -0500283 if (!mState.getSamplerUniformRange().empty())
284 {
285 // Ensure the descriptor set range includes the textures at position 1.
286 mUsedDescriptorSetRange.extend(1);
287 mDirtyTextures = true;
288 }
289
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500290 return true;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400291}
292
Jamie Madill76e471e2017-10-21 09:56:01 -0400293gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
294{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400295 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madill57fbfd82018-02-14 12:45:34 -0500296 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400297 VkDevice device = contextVk->getDevice();
298
299 // Process vertex and fragment uniforms into std140 packing.
300 std::array<sh::BlockLayoutMap, 2> layoutMap;
301 std::array<size_t, 2> requiredBufferSize = {{0, 0}};
302
303 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
304 {
305 ANGLE_TRY(InitDefaultUniformBlock(glContext, device, GetShader(mState, shaderIndex),
306 &mDefaultUniformBlocks[shaderIndex].storage,
307 &layoutMap[shaderIndex],
308 &requiredBufferSize[shaderIndex]));
309 }
310
311 // Init the default block layout info.
312 const auto &locations = mState.getUniformLocations();
313 const auto &uniforms = mState.getUniforms();
314 for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex)
315 {
316 std::array<sh::BlockMemberInfo, 2> layoutInfo;
317
318 const auto &location = locations[locationIndex];
319 if (location.used() && !location.ignored)
320 {
Jamie Madillde03e002017-10-21 14:04:20 -0400321 const auto &uniform = uniforms[location.index];
322
323 if (uniform.isSampler())
324 continue;
325
Jamie Madill76e471e2017-10-21 09:56:01 -0400326 std::string uniformName = uniform.name;
327 if (uniform.isArray())
328 {
Olli Etuaho1734e172017-10-27 15:30:27 +0300329 uniformName += ArrayString(location.arrayIndex);
Jamie Madill76e471e2017-10-21 09:56:01 -0400330 }
331
332 bool found = false;
333
334 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
335 {
336 auto it = layoutMap[shaderIndex].find(uniformName);
337 if (it != layoutMap[shaderIndex].end())
338 {
339 found = true;
340 layoutInfo[shaderIndex] = it->second;
341 }
342 }
343
344 ASSERT(found);
345 }
346
347 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
348 {
349 mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]);
350 }
351 }
352
353 bool anyDirty = false;
354 bool allDirty = true;
355
356 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
357 {
358 if (requiredBufferSize[shaderIndex] > 0)
359 {
360 if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize(
361 requiredBufferSize[shaderIndex]))
362 {
363 return gl::OutOfMemory() << "Memory allocation failure.";
364 }
365 mDefaultUniformBlocks[shaderIndex].uniformData.fill(0);
366 mDefaultUniformBlocks[shaderIndex].uniformsDirty = true;
367
368 anyDirty = true;
369 }
370 else
371 {
372 allDirty = false;
373 }
374 }
375
376 if (anyDirty)
377 {
378 // Initialize the "empty" uniform block if necessary.
379 if (!allDirty)
380 {
381 VkBufferCreateInfo uniformBufferInfo;
382 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
383 uniformBufferInfo.pNext = nullptr;
384 uniformBufferInfo.flags = 0;
385 uniformBufferInfo.size = 1;
386 uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
387 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
388 uniformBufferInfo.queueFamilyIndexCount = 0;
389 uniformBufferInfo.pQueueFamilyIndices = nullptr;
390
391 ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo));
392
Jamie Madill57dd97a2018-02-06 17:10:49 -0500393 // Assume host vislble/coherent memory available.
394 VkMemoryPropertyFlags flags =
395 (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Jamie Madill76e471e2017-10-21 09:56:01 -0400396 size_t requiredSize = 0;
Jamie Madill57fbfd82018-02-14 12:45:34 -0500397 ANGLE_TRY(AllocateBufferMemory(renderer, flags, &mEmptyUniformBlockStorage.buffer,
Jamie Madill76e471e2017-10-21 09:56:01 -0400398 &mEmptyUniformBlockStorage.memory, &requiredSize));
399 }
400
401 ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk));
Jamie Madill8c3988c2017-12-21 14:44:56 -0500402
403 // Ensure the descriptor set range includes the uniform buffers at position 0.
404 mUsedDescriptorSetRange.extend(0);
Jamie Madill5547b382017-10-23 18:16:01 -0400405 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400406
407 return gl::NoError();
408}
409
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400410GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
411{
412 UNIMPLEMENTED();
413 return GLboolean();
414}
415
Jamie Madill76e471e2017-10-21 09:56:01 -0400416template <typename T>
417void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType)
418{
419 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
420 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
421
Luc Ferron7cec3352018-03-13 13:29:34 -0400422 if (linkedUniform.isSampler())
423 {
424 UNIMPLEMENTED();
425 return;
426 }
427
Jamie Madill76e471e2017-10-21 09:56:01 -0400428 if (linkedUniform.type == entryPointType)
429 {
430 for (auto &uniformBlock : mDefaultUniformBlocks)
431 {
432 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
Jamie Madill5eaddbd2018-03-14 16:16:03 -0400433
434 // Assume an offset of -1 means the block is unused.
435 if (layoutInfo.offset == -1)
436 {
437 continue;
438 }
439
Jamie Madill76e471e2017-10-21 09:56:01 -0400440 UpdateDefaultUniformBlock(count, linkedUniform.typeInfo->componentCount, v, layoutInfo,
441 &uniformBlock.uniformData);
Jamie Madill5eaddbd2018-03-14 16:16:03 -0400442
443 uniformBlock.uniformsDirty = true;
Jamie Madill76e471e2017-10-21 09:56:01 -0400444 }
445 }
446 else
447 {
448 ASSERT(linkedUniform.type == gl::VariableBoolVectorType(entryPointType));
449 UNIMPLEMENTED();
450 }
451}
452
Luc Ferron7cec3352018-03-13 13:29:34 -0400453template <typename T>
454void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) const
455{
456 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
457 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
458
459 if (linkedUniform.isSampler())
460 {
461 UNIMPLEMENTED();
462 return;
463 }
464
465 ASSERT(linkedUniform.typeInfo->componentType == entryPointType);
466 const gl::ShaderType shaderType = linkedUniform.getFirstStaticUseShaderType();
467 ASSERT(shaderType != gl::ShaderType::SHADER_TYPE_INVALID);
468
469 const DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
470 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
471 ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, v, layoutInfo,
472 &uniformBlock.uniformData);
473}
474
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400475void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
476{
Jamie Madill76e471e2017-10-21 09:56:01 -0400477 setUniformImpl(location, count, v, GL_FLOAT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400478}
479
480void ProgramVk::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
481{
Jamie Madill76e471e2017-10-21 09:56:01 -0400482 setUniformImpl(location, count, v, GL_FLOAT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400483}
484
485void ProgramVk::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
486{
Jamie Madill76e471e2017-10-21 09:56:01 -0400487 setUniformImpl(location, count, v, GL_FLOAT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400488}
489
490void ProgramVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
491{
Jamie Madill76e471e2017-10-21 09:56:01 -0400492 setUniformImpl(location, count, v, GL_FLOAT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400493}
494
495void ProgramVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
496{
Luc Ferron7cec3352018-03-13 13:29:34 -0400497 setUniformImpl(location, count, v, GL_INT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400498}
499
500void ProgramVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
501{
502 UNIMPLEMENTED();
503}
504
505void ProgramVk::setUniform3iv(GLint location, GLsizei count, const GLint *v)
506{
507 UNIMPLEMENTED();
508}
509
510void ProgramVk::setUniform4iv(GLint location, GLsizei count, const GLint *v)
511{
512 UNIMPLEMENTED();
513}
514
515void ProgramVk::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
516{
517 UNIMPLEMENTED();
518}
519
520void ProgramVk::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
521{
522 UNIMPLEMENTED();
523}
524
525void ProgramVk::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
526{
527 UNIMPLEMENTED();
528}
529
530void ProgramVk::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
531{
532 UNIMPLEMENTED();
533}
534
535void ProgramVk::setUniformMatrix2fv(GLint location,
536 GLsizei count,
537 GLboolean transpose,
538 const GLfloat *value)
539{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400540 if (transpose == GL_TRUE)
541 {
542 UNIMPLEMENTED();
543 return;
544 }
545
546 setUniformImpl(location, count, value, GL_FLOAT_MAT2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400547}
548
549void ProgramVk::setUniformMatrix3fv(GLint location,
550 GLsizei count,
551 GLboolean transpose,
552 const GLfloat *value)
553{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400554 if (transpose == GL_TRUE)
555 {
556 UNIMPLEMENTED();
557 return;
558 }
559 setUniformImpl(location, count, value, GL_FLOAT_MAT3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400560}
561
562void ProgramVk::setUniformMatrix4fv(GLint location,
563 GLsizei count,
564 GLboolean transpose,
565 const GLfloat *value)
566{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400567 if (transpose == GL_TRUE)
568 {
569 UNIMPLEMENTED();
570 return;
571 }
572
573 setUniformImpl(location, count, value, GL_FLOAT_MAT4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400574}
575
576void ProgramVk::setUniformMatrix2x3fv(GLint location,
577 GLsizei count,
578 GLboolean transpose,
579 const GLfloat *value)
580{
581 UNIMPLEMENTED();
582}
583
584void ProgramVk::setUniformMatrix3x2fv(GLint location,
585 GLsizei count,
586 GLboolean transpose,
587 const GLfloat *value)
588{
589 UNIMPLEMENTED();
590}
591
592void ProgramVk::setUniformMatrix2x4fv(GLint location,
593 GLsizei count,
594 GLboolean transpose,
595 const GLfloat *value)
596{
597 UNIMPLEMENTED();
598}
599
600void ProgramVk::setUniformMatrix4x2fv(GLint location,
601 GLsizei count,
602 GLboolean transpose,
603 const GLfloat *value)
604{
605 UNIMPLEMENTED();
606}
607
608void ProgramVk::setUniformMatrix3x4fv(GLint location,
609 GLsizei count,
610 GLboolean transpose,
611 const GLfloat *value)
612{
613 UNIMPLEMENTED();
614}
615
616void ProgramVk::setUniformMatrix4x3fv(GLint location,
617 GLsizei count,
618 GLboolean transpose,
619 const GLfloat *value)
620{
621 UNIMPLEMENTED();
622}
623
624void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
625{
626 UNIMPLEMENTED();
627}
628
Sami Väisänen46eaa942016-06-29 10:26:37 +0300629void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
630 GLenum genMode,
631 GLint components,
632 const GLfloat *coeffs)
633{
634 UNIMPLEMENTED();
635}
636
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500637const vk::ShaderModule &ProgramVk::getLinkedVertexModule() const
638{
639 ASSERT(mLinkedVertexModule.getHandle() != VK_NULL_HANDLE);
640 return mLinkedVertexModule;
641}
642
Jamie Madillf2f6d372018-01-10 21:37:23 -0500643Serial ProgramVk::getVertexModuleSerial() const
644{
645 return mVertexModuleSerial;
646}
647
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500648const vk::ShaderModule &ProgramVk::getLinkedFragmentModule() const
649{
650 ASSERT(mLinkedFragmentModule.getHandle() != VK_NULL_HANDLE);
651 return mLinkedFragmentModule;
652}
653
Jamie Madillf2f6d372018-01-10 21:37:23 -0500654Serial ProgramVk::getFragmentModuleSerial() const
655{
656 return mFragmentModuleSerial;
657}
658
Jamie Madill76e471e2017-10-21 09:56:01 -0400659vk::Error ProgramVk::initDescriptorSets(ContextVk *contextVk)
660{
Jamie Madill5547b382017-10-23 18:16:01 -0400661 ASSERT(mDescriptorSets.empty());
Jamie Madill76e471e2017-10-21 09:56:01 -0400662
Jamie Madill8c3988c2017-12-21 14:44:56 -0500663 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400664 VkDevice device = contextVk->getDevice();
665
666 // Write out to a new a descriptor set.
667 // TODO(jmadill): Handle descriptor set lifetime.
668 vk::DescriptorPool *descriptorPool = contextVk->getDescriptorPool();
669
Jamie Madill8c3988c2017-12-21 14:44:56 -0500670 const auto &descriptorSetLayouts = renderer->getGraphicsDescriptorSetLayouts();
671
672 uint32_t descriptorSetCount = static_cast<uint32_t>(descriptorSetLayouts.size());
Jamie Madill76e471e2017-10-21 09:56:01 -0400673
Jamie Madill5547b382017-10-23 18:16:01 -0400674 VkDescriptorSetAllocateInfo allocInfo;
675 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
676 allocInfo.pNext = nullptr;
677 allocInfo.descriptorPool = descriptorPool->getHandle();
678 allocInfo.descriptorSetCount = descriptorSetCount;
Jamie Madill8c3988c2017-12-21 14:44:56 -0500679 allocInfo.pSetLayouts = descriptorSetLayouts[0].ptr();
Jamie Madill76e471e2017-10-21 09:56:01 -0400680
Jamie Madill5547b382017-10-23 18:16:01 -0400681 mDescriptorSets.resize(descriptorSetCount, VK_NULL_HANDLE);
682 ANGLE_TRY(descriptorPool->allocateDescriptorSets(device, allocInfo, &mDescriptorSets[0]));
Jamie Madill76e471e2017-10-21 09:56:01 -0400683 return vk::NoError();
684}
685
Jamie Madill54164b02017-08-28 15:17:37 -0400686void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
687{
Luc Ferron7cec3352018-03-13 13:29:34 -0400688 getUniformImpl(location, params, GL_FLOAT);
Jamie Madill54164b02017-08-28 15:17:37 -0400689}
690
691void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
692{
Luc Ferron7cec3352018-03-13 13:29:34 -0400693 getUniformImpl(location, params, GL_INT);
Jamie Madill54164b02017-08-28 15:17:37 -0400694}
695
696void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
697{
698 UNIMPLEMENTED();
699}
700
Jamie Madill76e471e2017-10-21 09:56:01 -0400701vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
702{
703 if (!mDefaultUniformBlocks[VertexShader].uniformsDirty &&
704 !mDefaultUniformBlocks[FragmentShader].uniformsDirty)
705 {
706 return vk::NoError();
707 }
708
Jamie Madill8c3988c2017-12-21 14:44:56 -0500709 ASSERT(mUsedDescriptorSetRange.contains(0));
Jamie Madill5547b382017-10-23 18:16:01 -0400710
Jamie Madill76e471e2017-10-21 09:56:01 -0400711 VkDevice device = contextVk->getDevice();
712
713 // Update buffer memory by immediate mapping. This immediate update only works once.
714 // TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers.
715 for (auto &uniformBlock : mDefaultUniformBlocks)
716 {
717 if (uniformBlock.uniformsDirty)
718 {
719 ANGLE_TRY(SyncDefaultUniformBlock(device, &uniformBlock.storage.memory,
720 uniformBlock.uniformData));
721 uniformBlock.uniformsDirty = false;
722 }
723 }
724
725 return vk::NoError();
726}
727
728vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
729{
730 std::array<VkDescriptorBufferInfo, 2> descriptorBufferInfo;
731 std::array<VkWriteDescriptorSet, 2> writeDescriptorInfo;
732 uint32_t bufferCount = 0;
733
734 for (auto &uniformBlock : mDefaultUniformBlocks)
735 {
736 auto &bufferInfo = descriptorBufferInfo[bufferCount];
737
738 if (!uniformBlock.uniformData.empty())
739 {
740 bufferInfo.buffer = uniformBlock.storage.buffer.getHandle();
741 }
742 else
743 {
744 bufferInfo.buffer = mEmptyUniformBlockStorage.buffer.getHandle();
745 }
746
747 bufferInfo.offset = 0;
748 bufferInfo.range = VK_WHOLE_SIZE;
749
750 auto &writeInfo = writeDescriptorInfo[bufferCount];
751
752 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
753 writeInfo.pNext = nullptr;
Jamie Madill5547b382017-10-23 18:16:01 -0400754 writeInfo.dstSet = mDescriptorSets[0];
Jamie Madill76e471e2017-10-21 09:56:01 -0400755 writeInfo.dstBinding = bufferCount;
756 writeInfo.dstArrayElement = 0;
757 writeInfo.descriptorCount = 1;
758 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
759 writeInfo.pImageInfo = nullptr;
760 writeInfo.pBufferInfo = &bufferInfo;
761 writeInfo.pTexelBufferView = nullptr;
762
763 bufferCount++;
764 }
765
766 VkDevice device = contextVk->getDevice();
767
768 vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr);
769
770 return vk::NoError();
771}
772
Jamie Madill5547b382017-10-23 18:16:01 -0400773const std::vector<VkDescriptorSet> &ProgramVk::getDescriptorSets() const
Jamie Madill76e471e2017-10-21 09:56:01 -0400774{
Jamie Madill5547b382017-10-23 18:16:01 -0400775 return mDescriptorSets;
776}
777
Jamie Madill8c3988c2017-12-21 14:44:56 -0500778const gl::RangeUI &ProgramVk::getUsedDescriptorSetRange() const
Jamie Madill5547b382017-10-23 18:16:01 -0400779{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500780 return mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400781}
782
783void ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
784{
785 if (mState.getSamplerBindings().empty() || !mDirtyTextures)
786 {
787 return;
788 }
789
Jamie Madill8c3988c2017-12-21 14:44:56 -0500790 ASSERT(mUsedDescriptorSetRange.contains(1));
791 VkDescriptorSet descriptorSet = mDescriptorSets[1];
Jamie Madill5547b382017-10-23 18:16:01 -0400792
793 // TODO(jmadill): Don't hard-code the texture limit.
794 ShaderTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
795 ShaderTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
796 uint32_t imageCount = 0;
797
798 const gl::State &glState = contextVk->getGLState();
799 const auto &completeTextures = glState.getCompleteTextureCache();
800
801 for (const auto &samplerBinding : mState.getSamplerBindings())
802 {
803 ASSERT(!samplerBinding.unreferenced);
804
805 // TODO(jmadill): Sampler arrays
806 ASSERT(samplerBinding.boundTextureUnits.size() == 1);
807
808 GLuint textureUnit = samplerBinding.boundTextureUnits[0];
809 const gl::Texture *texture = completeTextures[textureUnit];
810
811 // TODO(jmadill): Incomplete textures handling.
812 ASSERT(texture);
813
Jamie Madille1f3ad42017-10-28 23:00:42 -0400814 TextureVk *textureVk = vk::GetImpl(texture);
Jamie Madill5547b382017-10-23 18:16:01 -0400815 const vk::Image &image = textureVk->getImage();
816
817 VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];
818
819 imageInfo.sampler = textureVk->getSampler().getHandle();
820 imageInfo.imageView = textureVk->getImageView().getHandle();
821 imageInfo.imageLayout = image.getCurrentLayout();
822
823 auto &writeInfo = writeDescriptorInfo[imageCount];
824
825 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
826 writeInfo.pNext = nullptr;
827 writeInfo.dstSet = descriptorSet;
828 writeInfo.dstBinding = imageCount;
829 writeInfo.dstArrayElement = 0;
830 writeInfo.descriptorCount = 1;
831 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
832 writeInfo.pImageInfo = &imageInfo;
833 writeInfo.pBufferInfo = nullptr;
834 writeInfo.pTexelBufferView = nullptr;
835
836 imageCount++;
837 }
838
839 VkDevice device = contextVk->getDevice();
840
841 ASSERT(imageCount > 0);
842 vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);
843
844 mDirtyTextures = false;
845}
846
847void ProgramVk::invalidateTextures()
848{
849 mDirtyTextures = true;
Jamie Madill76e471e2017-10-21 09:56:01 -0400850}
851
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400852} // namespace rx