blob: f23778cef17563243cf6c2dc144260b340f93cd5 [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 Madille1f3ad42017-10-28 23:00:42 -040065 ANGLE_TRY(AllocateBufferMemory(vk::GetImpl(context), blockSize, &storageOut->buffer,
Jamie Madill76e471e2017-10-21 09:56:01 -040066 &storageOut->memory, requiredSizeOut));
67
68 return gl::NoError();
69}
70
71template <typename T>
72void UpdateDefaultUniformBlock(GLsizei count,
73 int componentCount,
74 const T *v,
75 const sh::BlockMemberInfo &layoutInfo,
76 angle::MemoryBuffer *uniformData)
77{
78 // Assume an offset of -1 means the block is unused.
79 if (layoutInfo.offset == -1)
80 {
81 return;
82 }
83
84 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
96vk::Error SyncDefaultUniformBlock(VkDevice device,
97 vk::DeviceMemory *bufferMemory,
98 const angle::MemoryBuffer &bufferData)
99{
100 ASSERT(bufferMemory->valid() && !bufferData.empty());
101 uint8_t *mapPointer = nullptr;
102 ANGLE_TRY(bufferMemory->map(device, 0, bufferData.size(), 0, &mapPointer));
103 memcpy(mapPointer, bufferData.data(), bufferData.size());
104 bufferMemory->unmap(device);
105 return vk::NoError();
106}
107
108enum ShaderIndex : uint32_t
109{
110 MinShaderIndex = 0,
111 VertexShader = MinShaderIndex,
112 FragmentShader = 1,
113 MaxShaderIndex = 2,
114};
115
116gl::Shader *GetShader(const gl::ProgramState &programState, uint32_t shaderIndex)
117{
118 switch (shaderIndex)
119 {
120 case VertexShader:
121 return programState.getAttachedVertexShader();
122 case FragmentShader:
123 return programState.getAttachedFragmentShader();
124 default:
125 UNREACHABLE();
126 return nullptr;
127 }
128}
129
130} // anonymous namespace
131
132ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
133 : storage(), uniformData(), uniformsDirty(false), uniformLayout()
134{
135}
136
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500137ProgramVk::DefaultUniformBlock::~DefaultUniformBlock()
138{
139}
140
Jamie Madill76e471e2017-10-21 09:56:01 -0400141ProgramVk::ProgramVk(const gl::ProgramState &state)
Jamie Madill8c3988c2017-12-21 14:44:56 -0500142 : ProgramImpl(state), mDefaultUniformBlocks(), mUsedDescriptorSetRange(), mDirtyTextures(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400143{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500144 mUsedDescriptorSetRange.invalidate();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400145}
146
147ProgramVk::~ProgramVk()
148{
149}
150
Jamie Madillc564c072017-06-01 12:45:42 -0400151void ProgramVk::destroy(const gl::Context *contextImpl)
Jamie Madill5deea722017-02-16 10:44:46 -0500152{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400153 VkDevice device = vk::GetImpl(contextImpl)->getDevice();
Jamie Madillc5143482017-10-15 20:20:06 -0400154 reset(device);
155}
Jamie Madill5deea722017-02-16 10:44:46 -0500156
Jamie Madillc5143482017-10-15 20:20:06 -0400157void ProgramVk::reset(VkDevice device)
158{
Jamie Madill76e471e2017-10-21 09:56:01 -0400159 for (auto &uniformBlock : mDefaultUniformBlocks)
160 {
161 uniformBlock.storage.memory.destroy(device);
162 uniformBlock.storage.buffer.destroy(device);
163 }
164
165 mEmptyUniformBlockStorage.memory.destroy(device);
166 mEmptyUniformBlockStorage.buffer.destroy(device);
167
Jamie Madill5deea722017-02-16 10:44:46 -0500168 mLinkedFragmentModule.destroy(device);
169 mLinkedVertexModule.destroy(device);
Jamie Madillf2f6d372018-01-10 21:37:23 -0500170 mVertexModuleSerial = Serial();
171 mFragmentModuleSerial = Serial();
Jamie Madill76e471e2017-10-21 09:56:01 -0400172
173 // Descriptor Sets are pool allocated, so do not need to be explicitly freed.
Jamie Madill5547b382017-10-23 18:16:01 -0400174 mDescriptorSets.clear();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500175 mUsedDescriptorSetRange.invalidate();
Jamie Madill5547b382017-10-23 18:16:01 -0400176 mDirtyTextures = false;
Jamie Madill5deea722017-02-16 10:44:46 -0500177}
178
Jamie Madill9cf9e872017-06-05 12:59:25 -0400179gl::LinkResult ProgramVk::load(const gl::Context *contextImpl,
180 gl::InfoLog &infoLog,
181 gl::BinaryInputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400182{
183 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500184 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400185}
186
Jamie Madill27a60632017-06-30 15:12:01 -0400187void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400188{
189 UNIMPLEMENTED();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400190}
191
192void ProgramVk::setBinaryRetrievableHint(bool retrievable)
193{
194 UNIMPLEMENTED();
195}
196
Yunchao He61afff12017-03-14 15:34:03 +0800197void ProgramVk::setSeparable(bool separable)
198{
199 UNIMPLEMENTED();
200}
201
Jamie Madill9cf9e872017-06-05 12:59:25 -0400202gl::LinkResult ProgramVk::link(const gl::Context *glContext,
Jamie Madillc9727f32017-11-07 12:37:07 -0500203 const gl::ProgramLinkedResources &resources,
Jamie Madill9cf9e872017-06-05 12:59:25 -0400204 gl::InfoLog &infoLog)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400205{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400206 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madillc5143482017-10-15 20:20:06 -0400207 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500208 GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
Jamie Madillc5143482017-10-15 20:20:06 -0400209 VkDevice device = renderer->getDevice();
210
211 reset(device);
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500212
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500213 std::vector<uint32_t> vertexCode;
214 std::vector<uint32_t> fragmentCode;
215 bool linkSuccess = false;
Jamie Madill4dd167f2017-11-09 13:08:31 -0500216 ANGLE_TRY_RESULT(
217 glslangWrapper->linkProgram(glContext, mState, resources, &vertexCode, &fragmentCode),
218 linkSuccess);
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500219 if (!linkSuccess)
220 {
221 return false;
222 }
223
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500224 {
225 VkShaderModuleCreateInfo vertexShaderInfo;
226 vertexShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
227 vertexShaderInfo.pNext = nullptr;
228 vertexShaderInfo.flags = 0;
229 vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t);
230 vertexShaderInfo.pCode = vertexCode.data();
Jamie Madillc5143482017-10-15 20:20:06 -0400231
232 ANGLE_TRY(mLinkedVertexModule.init(device, vertexShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500233 mVertexModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500234 }
235
236 {
237 VkShaderModuleCreateInfo fragmentShaderInfo;
238 fragmentShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
239 fragmentShaderInfo.pNext = nullptr;
240 fragmentShaderInfo.flags = 0;
241 fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t);
242 fragmentShaderInfo.pCode = fragmentCode.data();
243
Jamie Madillc5143482017-10-15 20:20:06 -0400244 ANGLE_TRY(mLinkedFragmentModule.init(device, fragmentShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500245 mFragmentModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500246 }
247
Jamie Madill76e471e2017-10-21 09:56:01 -0400248 ANGLE_TRY(initDescriptorSets(contextVk));
249 ANGLE_TRY(initDefaultUniformBlocks(glContext));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500250
Jamie Madill8c3988c2017-12-21 14:44:56 -0500251 if (!mState.getSamplerUniformRange().empty())
252 {
253 // Ensure the descriptor set range includes the textures at position 1.
254 mUsedDescriptorSetRange.extend(1);
255 mDirtyTextures = true;
256 }
257
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500258 return true;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400259}
260
Jamie Madill76e471e2017-10-21 09:56:01 -0400261gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
262{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400263 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madill76e471e2017-10-21 09:56:01 -0400264 VkDevice device = contextVk->getDevice();
265
266 // Process vertex and fragment uniforms into std140 packing.
267 std::array<sh::BlockLayoutMap, 2> layoutMap;
268 std::array<size_t, 2> requiredBufferSize = {{0, 0}};
269
270 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
271 {
272 ANGLE_TRY(InitDefaultUniformBlock(glContext, device, GetShader(mState, shaderIndex),
273 &mDefaultUniformBlocks[shaderIndex].storage,
274 &layoutMap[shaderIndex],
275 &requiredBufferSize[shaderIndex]));
276 }
277
278 // Init the default block layout info.
279 const auto &locations = mState.getUniformLocations();
280 const auto &uniforms = mState.getUniforms();
281 for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex)
282 {
283 std::array<sh::BlockMemberInfo, 2> layoutInfo;
284
285 const auto &location = locations[locationIndex];
286 if (location.used() && !location.ignored)
287 {
Jamie Madillde03e002017-10-21 14:04:20 -0400288 const auto &uniform = uniforms[location.index];
289
290 if (uniform.isSampler())
291 continue;
292
Jamie Madill76e471e2017-10-21 09:56:01 -0400293 std::string uniformName = uniform.name;
294 if (uniform.isArray())
295 {
Olli Etuaho1734e172017-10-27 15:30:27 +0300296 uniformName += ArrayString(location.arrayIndex);
Jamie Madill76e471e2017-10-21 09:56:01 -0400297 }
298
299 bool found = false;
300
301 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
302 {
303 auto it = layoutMap[shaderIndex].find(uniformName);
304 if (it != layoutMap[shaderIndex].end())
305 {
306 found = true;
307 layoutInfo[shaderIndex] = it->second;
308 }
309 }
310
311 ASSERT(found);
312 }
313
314 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
315 {
316 mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]);
317 }
318 }
319
320 bool anyDirty = false;
321 bool allDirty = true;
322
323 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
324 {
325 if (requiredBufferSize[shaderIndex] > 0)
326 {
327 if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize(
328 requiredBufferSize[shaderIndex]))
329 {
330 return gl::OutOfMemory() << "Memory allocation failure.";
331 }
332 mDefaultUniformBlocks[shaderIndex].uniformData.fill(0);
333 mDefaultUniformBlocks[shaderIndex].uniformsDirty = true;
334
335 anyDirty = true;
336 }
337 else
338 {
339 allDirty = false;
340 }
341 }
342
343 if (anyDirty)
344 {
345 // Initialize the "empty" uniform block if necessary.
346 if (!allDirty)
347 {
348 VkBufferCreateInfo uniformBufferInfo;
349 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
350 uniformBufferInfo.pNext = nullptr;
351 uniformBufferInfo.flags = 0;
352 uniformBufferInfo.size = 1;
353 uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
354 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
355 uniformBufferInfo.queueFamilyIndexCount = 0;
356 uniformBufferInfo.pQueueFamilyIndices = nullptr;
357
358 ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo));
359
360 size_t requiredSize = 0;
361 ANGLE_TRY(AllocateBufferMemory(contextVk, 1, &mEmptyUniformBlockStorage.buffer,
362 &mEmptyUniformBlockStorage.memory, &requiredSize));
363 }
364
365 ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk));
Jamie Madill8c3988c2017-12-21 14:44:56 -0500366
367 // Ensure the descriptor set range includes the uniform buffers at position 0.
368 mUsedDescriptorSetRange.extend(0);
Jamie Madill5547b382017-10-23 18:16:01 -0400369 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400370
371 return gl::NoError();
372}
373
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400374GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
375{
376 UNIMPLEMENTED();
377 return GLboolean();
378}
379
Jamie Madill76e471e2017-10-21 09:56:01 -0400380template <typename T>
381void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType)
382{
383 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
384 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
385
386 if (linkedUniform.type == entryPointType)
387 {
388 for (auto &uniformBlock : mDefaultUniformBlocks)
389 {
390 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
391 UpdateDefaultUniformBlock(count, linkedUniform.typeInfo->componentCount, v, layoutInfo,
392 &uniformBlock.uniformData);
393 }
394 }
395 else
396 {
397 ASSERT(linkedUniform.type == gl::VariableBoolVectorType(entryPointType));
398 UNIMPLEMENTED();
399 }
400}
401
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400402void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
403{
Jamie Madill76e471e2017-10-21 09:56:01 -0400404 setUniformImpl(location, count, v, GL_FLOAT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400405}
406
407void ProgramVk::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
408{
Jamie Madill76e471e2017-10-21 09:56:01 -0400409 setUniformImpl(location, count, v, GL_FLOAT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400410}
411
412void ProgramVk::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
413{
Jamie Madill76e471e2017-10-21 09:56:01 -0400414 setUniformImpl(location, count, v, GL_FLOAT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400415}
416
417void ProgramVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
418{
Jamie Madill76e471e2017-10-21 09:56:01 -0400419 setUniformImpl(location, count, v, GL_FLOAT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400420}
421
422void ProgramVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
423{
424 UNIMPLEMENTED();
425}
426
427void ProgramVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
428{
429 UNIMPLEMENTED();
430}
431
432void ProgramVk::setUniform3iv(GLint location, GLsizei count, const GLint *v)
433{
434 UNIMPLEMENTED();
435}
436
437void ProgramVk::setUniform4iv(GLint location, GLsizei count, const GLint *v)
438{
439 UNIMPLEMENTED();
440}
441
442void ProgramVk::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
443{
444 UNIMPLEMENTED();
445}
446
447void ProgramVk::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
448{
449 UNIMPLEMENTED();
450}
451
452void ProgramVk::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
453{
454 UNIMPLEMENTED();
455}
456
457void ProgramVk::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
458{
459 UNIMPLEMENTED();
460}
461
462void ProgramVk::setUniformMatrix2fv(GLint location,
463 GLsizei count,
464 GLboolean transpose,
465 const GLfloat *value)
466{
467 UNIMPLEMENTED();
468}
469
470void ProgramVk::setUniformMatrix3fv(GLint location,
471 GLsizei count,
472 GLboolean transpose,
473 const GLfloat *value)
474{
475 UNIMPLEMENTED();
476}
477
478void ProgramVk::setUniformMatrix4fv(GLint location,
479 GLsizei count,
480 GLboolean transpose,
481 const GLfloat *value)
482{
483 UNIMPLEMENTED();
484}
485
486void ProgramVk::setUniformMatrix2x3fv(GLint location,
487 GLsizei count,
488 GLboolean transpose,
489 const GLfloat *value)
490{
491 UNIMPLEMENTED();
492}
493
494void ProgramVk::setUniformMatrix3x2fv(GLint location,
495 GLsizei count,
496 GLboolean transpose,
497 const GLfloat *value)
498{
499 UNIMPLEMENTED();
500}
501
502void ProgramVk::setUniformMatrix2x4fv(GLint location,
503 GLsizei count,
504 GLboolean transpose,
505 const GLfloat *value)
506{
507 UNIMPLEMENTED();
508}
509
510void ProgramVk::setUniformMatrix4x2fv(GLint location,
511 GLsizei count,
512 GLboolean transpose,
513 const GLfloat *value)
514{
515 UNIMPLEMENTED();
516}
517
518void ProgramVk::setUniformMatrix3x4fv(GLint location,
519 GLsizei count,
520 GLboolean transpose,
521 const GLfloat *value)
522{
523 UNIMPLEMENTED();
524}
525
526void ProgramVk::setUniformMatrix4x3fv(GLint location,
527 GLsizei count,
528 GLboolean transpose,
529 const GLfloat *value)
530{
531 UNIMPLEMENTED();
532}
533
534void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
535{
536 UNIMPLEMENTED();
537}
538
Sami Väisänen46eaa942016-06-29 10:26:37 +0300539void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
540 GLenum genMode,
541 GLint components,
542 const GLfloat *coeffs)
543{
544 UNIMPLEMENTED();
545}
546
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500547const vk::ShaderModule &ProgramVk::getLinkedVertexModule() const
548{
549 ASSERT(mLinkedVertexModule.getHandle() != VK_NULL_HANDLE);
550 return mLinkedVertexModule;
551}
552
Jamie Madillf2f6d372018-01-10 21:37:23 -0500553Serial ProgramVk::getVertexModuleSerial() const
554{
555 return mVertexModuleSerial;
556}
557
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500558const vk::ShaderModule &ProgramVk::getLinkedFragmentModule() const
559{
560 ASSERT(mLinkedFragmentModule.getHandle() != VK_NULL_HANDLE);
561 return mLinkedFragmentModule;
562}
563
Jamie Madillf2f6d372018-01-10 21:37:23 -0500564Serial ProgramVk::getFragmentModuleSerial() const
565{
566 return mFragmentModuleSerial;
567}
568
Jamie Madill76e471e2017-10-21 09:56:01 -0400569vk::Error ProgramVk::initDescriptorSets(ContextVk *contextVk)
570{
Jamie Madill5547b382017-10-23 18:16:01 -0400571 ASSERT(mDescriptorSets.empty());
Jamie Madill76e471e2017-10-21 09:56:01 -0400572
Jamie Madill8c3988c2017-12-21 14:44:56 -0500573 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400574 VkDevice device = contextVk->getDevice();
575
576 // Write out to a new a descriptor set.
577 // TODO(jmadill): Handle descriptor set lifetime.
578 vk::DescriptorPool *descriptorPool = contextVk->getDescriptorPool();
579
Jamie Madill8c3988c2017-12-21 14:44:56 -0500580 const auto &descriptorSetLayouts = renderer->getGraphicsDescriptorSetLayouts();
581
582 uint32_t descriptorSetCount = static_cast<uint32_t>(descriptorSetLayouts.size());
Jamie Madill76e471e2017-10-21 09:56:01 -0400583
Jamie Madill5547b382017-10-23 18:16:01 -0400584 VkDescriptorSetAllocateInfo allocInfo;
585 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
586 allocInfo.pNext = nullptr;
587 allocInfo.descriptorPool = descriptorPool->getHandle();
588 allocInfo.descriptorSetCount = descriptorSetCount;
Jamie Madill8c3988c2017-12-21 14:44:56 -0500589 allocInfo.pSetLayouts = descriptorSetLayouts[0].ptr();
Jamie Madill76e471e2017-10-21 09:56:01 -0400590
Jamie Madill5547b382017-10-23 18:16:01 -0400591 mDescriptorSets.resize(descriptorSetCount, VK_NULL_HANDLE);
592 ANGLE_TRY(descriptorPool->allocateDescriptorSets(device, allocInfo, &mDescriptorSets[0]));
Jamie Madill76e471e2017-10-21 09:56:01 -0400593 return vk::NoError();
594}
595
Jamie Madill54164b02017-08-28 15:17:37 -0400596void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
597{
598 UNIMPLEMENTED();
599}
600
601void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
602{
603 UNIMPLEMENTED();
604}
605
606void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
607{
608 UNIMPLEMENTED();
609}
610
Jamie Madill76e471e2017-10-21 09:56:01 -0400611vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
612{
613 if (!mDefaultUniformBlocks[VertexShader].uniformsDirty &&
614 !mDefaultUniformBlocks[FragmentShader].uniformsDirty)
615 {
616 return vk::NoError();
617 }
618
Jamie Madill8c3988c2017-12-21 14:44:56 -0500619 ASSERT(mUsedDescriptorSetRange.contains(0));
Jamie Madill5547b382017-10-23 18:16:01 -0400620
Jamie Madill76e471e2017-10-21 09:56:01 -0400621 VkDevice device = contextVk->getDevice();
622
623 // Update buffer memory by immediate mapping. This immediate update only works once.
624 // TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers.
625 for (auto &uniformBlock : mDefaultUniformBlocks)
626 {
627 if (uniformBlock.uniformsDirty)
628 {
629 ANGLE_TRY(SyncDefaultUniformBlock(device, &uniformBlock.storage.memory,
630 uniformBlock.uniformData));
631 uniformBlock.uniformsDirty = false;
632 }
633 }
634
635 return vk::NoError();
636}
637
638vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
639{
640 std::array<VkDescriptorBufferInfo, 2> descriptorBufferInfo;
641 std::array<VkWriteDescriptorSet, 2> writeDescriptorInfo;
642 uint32_t bufferCount = 0;
643
644 for (auto &uniformBlock : mDefaultUniformBlocks)
645 {
646 auto &bufferInfo = descriptorBufferInfo[bufferCount];
647
648 if (!uniformBlock.uniformData.empty())
649 {
650 bufferInfo.buffer = uniformBlock.storage.buffer.getHandle();
651 }
652 else
653 {
654 bufferInfo.buffer = mEmptyUniformBlockStorage.buffer.getHandle();
655 }
656
657 bufferInfo.offset = 0;
658 bufferInfo.range = VK_WHOLE_SIZE;
659
660 auto &writeInfo = writeDescriptorInfo[bufferCount];
661
662 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
663 writeInfo.pNext = nullptr;
Jamie Madill5547b382017-10-23 18:16:01 -0400664 writeInfo.dstSet = mDescriptorSets[0];
Jamie Madill76e471e2017-10-21 09:56:01 -0400665 writeInfo.dstBinding = bufferCount;
666 writeInfo.dstArrayElement = 0;
667 writeInfo.descriptorCount = 1;
668 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
669 writeInfo.pImageInfo = nullptr;
670 writeInfo.pBufferInfo = &bufferInfo;
671 writeInfo.pTexelBufferView = nullptr;
672
673 bufferCount++;
674 }
675
676 VkDevice device = contextVk->getDevice();
677
678 vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr);
679
680 return vk::NoError();
681}
682
Jamie Madill5547b382017-10-23 18:16:01 -0400683const std::vector<VkDescriptorSet> &ProgramVk::getDescriptorSets() const
Jamie Madill76e471e2017-10-21 09:56:01 -0400684{
Jamie Madill5547b382017-10-23 18:16:01 -0400685 return mDescriptorSets;
686}
687
Jamie Madill8c3988c2017-12-21 14:44:56 -0500688const gl::RangeUI &ProgramVk::getUsedDescriptorSetRange() const
Jamie Madill5547b382017-10-23 18:16:01 -0400689{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500690 return mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400691}
692
693void ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
694{
695 if (mState.getSamplerBindings().empty() || !mDirtyTextures)
696 {
697 return;
698 }
699
Jamie Madill8c3988c2017-12-21 14:44:56 -0500700 ASSERT(mUsedDescriptorSetRange.contains(1));
701 VkDescriptorSet descriptorSet = mDescriptorSets[1];
Jamie Madill5547b382017-10-23 18:16:01 -0400702
703 // TODO(jmadill): Don't hard-code the texture limit.
704 ShaderTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
705 ShaderTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
706 uint32_t imageCount = 0;
707
708 const gl::State &glState = contextVk->getGLState();
709 const auto &completeTextures = glState.getCompleteTextureCache();
710
711 for (const auto &samplerBinding : mState.getSamplerBindings())
712 {
713 ASSERT(!samplerBinding.unreferenced);
714
715 // TODO(jmadill): Sampler arrays
716 ASSERT(samplerBinding.boundTextureUnits.size() == 1);
717
718 GLuint textureUnit = samplerBinding.boundTextureUnits[0];
719 const gl::Texture *texture = completeTextures[textureUnit];
720
721 // TODO(jmadill): Incomplete textures handling.
722 ASSERT(texture);
723
Jamie Madille1f3ad42017-10-28 23:00:42 -0400724 TextureVk *textureVk = vk::GetImpl(texture);
Jamie Madill5547b382017-10-23 18:16:01 -0400725 const vk::Image &image = textureVk->getImage();
726
727 VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];
728
729 imageInfo.sampler = textureVk->getSampler().getHandle();
730 imageInfo.imageView = textureVk->getImageView().getHandle();
731 imageInfo.imageLayout = image.getCurrentLayout();
732
733 auto &writeInfo = writeDescriptorInfo[imageCount];
734
735 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
736 writeInfo.pNext = nullptr;
737 writeInfo.dstSet = descriptorSet;
738 writeInfo.dstBinding = imageCount;
739 writeInfo.dstArrayElement = 0;
740 writeInfo.descriptorCount = 1;
741 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
742 writeInfo.pImageInfo = &imageInfo;
743 writeInfo.pBufferInfo = nullptr;
744 writeInfo.pTexelBufferView = nullptr;
745
746 imageCount++;
747 }
748
749 VkDevice device = contextVk->getDevice();
750
751 ASSERT(imageCount > 0);
752 vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);
753
754 mDirtyTextures = false;
755}
756
757void ProgramVk::invalidateTextures()
758{
759 mDirtyTextures = true;
Jamie Madill76e471e2017-10-21 09:56:01 -0400760}
761
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400762} // namespace rx