blob: 989232f70d839443530d78e1a3fb3e5ea84f2461 [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
Jamie Madillf3614372018-03-31 14:19:14 -040026constexpr size_t kUniformBlockDynamicBufferMinSize = 256 * 128;
Luc Ferron7a06ac12018-03-15 10:17:04 -040027
Jamie Madill76e471e2017-10-21 09:56:01 -040028gl::Error InitDefaultUniformBlock(const gl::Context *context,
Jamie Madill76e471e2017-10-21 09:56:01 -040029 gl::Shader *shader,
Jamie Madill76e471e2017-10-21 09:56:01 -040030 sh::BlockLayoutMap *blockLayoutMapOut,
Luc Ferron7a06ac12018-03-15 10:17:04 -040031 size_t *blockSizeOut)
Jamie Madill76e471e2017-10-21 09:56:01 -040032{
33 const auto &uniforms = shader->getUniforms(context);
34
35 if (uniforms.empty())
36 {
Luc Ferron7a06ac12018-03-15 10:17:04 -040037 *blockSizeOut = 0;
Jamie Madill76e471e2017-10-21 09:56:01 -040038 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 {
Luc Ferron7a06ac12018-03-15 10:17:04 -040049 *blockSizeOut = 0;
Jamie Madill76e471e2017-10-21 09:56:01 -040050 return gl::NoError();
51 }
52
Luc Ferron7a06ac12018-03-15 10:17:04 -040053 *blockSizeOut = blockSize;
Jamie Madill76e471e2017-10-21 09:56:01 -040054 return gl::NoError();
55}
56
57template <typename T>
58void UpdateDefaultUniformBlock(GLsizei count,
Luc Ferron2371aca2018-03-27 16:03:03 -040059 uint32_t arrayIndex,
Jamie Madill76e471e2017-10-21 09:56:01 -040060 int componentCount,
61 const T *v,
62 const sh::BlockMemberInfo &layoutInfo,
63 angle::MemoryBuffer *uniformData)
64{
Luc Ferron2371aca2018-03-27 16:03:03 -040065 const int elementSize = sizeof(T) * componentCount;
66
67 uint8_t *dst = uniformData->data() + layoutInfo.offset;
Jamie Madill76e471e2017-10-21 09:56:01 -040068 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
69 {
Luc Ferron2371aca2018-03-27 16:03:03 -040070 uint32_t arrayOffset = arrayIndex * layoutInfo.arrayStride;
71 uint8_t *writePtr = dst + arrayOffset;
Jamie Madill76e471e2017-10-21 09:56:01 -040072 memcpy(writePtr, v, elementSize * count);
73 }
74 else
75 {
Luc Ferron2371aca2018-03-27 16:03:03 -040076 // Have to respect the arrayStride between each element of the array.
77 int maxIndex = arrayIndex + count;
78 for (int writeIndex = arrayIndex, readIndex = 0; writeIndex < maxIndex;
79 writeIndex++, readIndex++)
80 {
81 const int arrayOffset = writeIndex * layoutInfo.arrayStride;
82 uint8_t *writePtr = dst + arrayOffset;
83 const T *readPtr = v + readIndex;
84 memcpy(writePtr, readPtr, elementSize);
85 }
Jamie Madill76e471e2017-10-21 09:56:01 -040086 }
87}
88
Luc Ferron7cec3352018-03-13 13:29:34 -040089template <typename T>
90void ReadFromDefaultUniformBlock(int componentCount,
Luc Ferron2371aca2018-03-27 16:03:03 -040091 uint32_t arrayIndex,
Luc Ferron7cec3352018-03-13 13:29:34 -040092 T *dst,
93 const sh::BlockMemberInfo &layoutInfo,
94 const angle::MemoryBuffer *uniformData)
95{
96 ASSERT(layoutInfo.offset != -1);
97
Luc Ferron2371aca2018-03-27 16:03:03 -040098 const int elementSize = sizeof(T) * componentCount;
99 const uint8_t *source = uniformData->data() + layoutInfo.offset;
100
Luc Ferron7cec3352018-03-13 13:29:34 -0400101 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
102 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400103 const uint8_t *readPtr = source + arrayIndex * layoutInfo.arrayStride;
Luc Ferron7cec3352018-03-13 13:29:34 -0400104 memcpy(dst, readPtr, elementSize);
105 }
106 else
107 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400108 // Have to respect the arrayStride between each element of the array.
109 const int arrayOffset = arrayIndex * layoutInfo.arrayStride;
110 const uint8_t *readPtr = source + arrayOffset;
111 memcpy(dst, readPtr, elementSize);
Luc Ferron7cec3352018-03-13 13:29:34 -0400112 }
113}
114
Jamie Madillc3755fc2018-04-05 08:39:13 -0400115vk::Error SyncDefaultUniformBlock(RendererVk *renderer,
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400116 vk::DynamicBuffer *dynamicBuffer,
Luc Ferron7a06ac12018-03-15 10:17:04 -0400117 const angle::MemoryBuffer &bufferData,
118 uint32_t *outOffset,
119 bool *outBufferModified)
Jamie Madill76e471e2017-10-21 09:56:01 -0400120{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400121 ASSERT(!bufferData.empty());
122 uint8_t *data = nullptr;
123 VkBuffer *outBuffer = nullptr;
124 uint32_t offset;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400125 ANGLE_TRY(dynamicBuffer->allocate(renderer, bufferData.size(), &data, outBuffer, &offset,
126 outBufferModified));
Luc Ferron7a06ac12018-03-15 10:17:04 -0400127 *outOffset = offset;
128 memcpy(data, bufferData.data(), bufferData.size());
Jamie Madillc3755fc2018-04-05 08:39:13 -0400129 ANGLE_TRY(dynamicBuffer->flush(renderer->getDevice()));
Jamie Madill76e471e2017-10-21 09:56:01 -0400130 return vk::NoError();
131}
132
Jiawei Shao385b3e02018-03-21 09:43:28 +0800133// TODO(jiawei.shao@intel.com): Fully remove this enum by gl::ShaderType. (BUG=angleproject:2169)
Jamie Madill76e471e2017-10-21 09:56:01 -0400134enum ShaderIndex : uint32_t
135{
136 MinShaderIndex = 0,
137 VertexShader = MinShaderIndex,
138 FragmentShader = 1,
Luc Ferron7a06ac12018-03-15 10:17:04 -0400139 MaxShaderIndex = kShaderTypeCount,
Jamie Madill76e471e2017-10-21 09:56:01 -0400140};
141
142gl::Shader *GetShader(const gl::ProgramState &programState, uint32_t shaderIndex)
143{
144 switch (shaderIndex)
145 {
146 case VertexShader:
Jiawei Shao385b3e02018-03-21 09:43:28 +0800147 return programState.getAttachedShader(gl::ShaderType::Vertex);
Jamie Madill76e471e2017-10-21 09:56:01 -0400148 case FragmentShader:
Jiawei Shao385b3e02018-03-21 09:43:28 +0800149 return programState.getAttachedShader(gl::ShaderType::Fragment);
Jamie Madill76e471e2017-10-21 09:56:01 -0400150 default:
151 UNREACHABLE();
152 return nullptr;
153 }
154}
155
156} // anonymous namespace
157
158ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
Luc Ferron7a06ac12018-03-15 10:17:04 -0400159 : storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
Jamie Madillf3614372018-03-31 14:19:14 -0400160 kUniformBlockDynamicBufferMinSize),
Luc Ferron7a06ac12018-03-15 10:17:04 -0400161 uniformData(),
162 uniformsDirty(false),
163 uniformLayout()
Jamie Madill76e471e2017-10-21 09:56:01 -0400164{
165}
166
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500167ProgramVk::DefaultUniformBlock::~DefaultUniformBlock()
168{
169}
170
Jamie Madill76e471e2017-10-21 09:56:01 -0400171ProgramVk::ProgramVk(const gl::ProgramState &state)
Luc Ferron7a06ac12018-03-15 10:17:04 -0400172 : ProgramImpl(state),
173 mDefaultUniformBlocks(),
174 mUniformBlocksOffsets(),
175 mUsedDescriptorSetRange(),
176 mDirtyTextures(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400177{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400178 mUniformBlocksOffsets.fill(0);
Jamie Madill8c3988c2017-12-21 14:44:56 -0500179 mUsedDescriptorSetRange.invalidate();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400180}
181
182ProgramVk::~ProgramVk()
183{
184}
185
Jamie Madillb7d924a2018-03-10 11:16:54 -0500186gl::Error ProgramVk::destroy(const gl::Context *contextImpl)
Jamie Madill5deea722017-02-16 10:44:46 -0500187{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500188 ContextVk *contextVk = vk::GetImpl(contextImpl);
Jamie Madillb7d924a2018-03-10 11:16:54 -0500189 return reset(contextVk);
Jamie Madillc5143482017-10-15 20:20:06 -0400190}
Jamie Madill5deea722017-02-16 10:44:46 -0500191
Jamie Madillb7d924a2018-03-10 11:16:54 -0500192vk::Error ProgramVk::reset(ContextVk *contextVk)
Jamie Madillc5143482017-10-15 20:20:06 -0400193{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500194 // TODO(jmadill): Handle re-linking a program that is in-use. http://anglebug.com/2397
195
196 VkDevice device = contextVk->getDevice();
197
Jamie Madill76e471e2017-10-21 09:56:01 -0400198 for (auto &uniformBlock : mDefaultUniformBlocks)
199 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400200 uniformBlock.storage.destroy(device);
Jamie Madill76e471e2017-10-21 09:56:01 -0400201 }
202
203 mEmptyUniformBlockStorage.memory.destroy(device);
204 mEmptyUniformBlockStorage.buffer.destroy(device);
205
Jamie Madill5deea722017-02-16 10:44:46 -0500206 mLinkedFragmentModule.destroy(device);
207 mLinkedVertexModule.destroy(device);
Jamie Madillf2f6d372018-01-10 21:37:23 -0500208 mVertexModuleSerial = Serial();
209 mFragmentModuleSerial = Serial();
Jamie Madill76e471e2017-10-21 09:56:01 -0400210
Jamie Madill5547b382017-10-23 18:16:01 -0400211 mDescriptorSets.clear();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500212 mUsedDescriptorSetRange.invalidate();
Jamie Madill5547b382017-10-23 18:16:01 -0400213 mDirtyTextures = false;
Jamie Madillb7d924a2018-03-10 11:16:54 -0500214
215 return vk::NoError();
Jamie Madill5deea722017-02-16 10:44:46 -0500216}
217
Jamie Madill9cf9e872017-06-05 12:59:25 -0400218gl::LinkResult ProgramVk::load(const gl::Context *contextImpl,
219 gl::InfoLog &infoLog,
220 gl::BinaryInputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400221{
222 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500223 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400224}
225
Jamie Madill27a60632017-06-30 15:12:01 -0400226void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400227{
228 UNIMPLEMENTED();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400229}
230
231void ProgramVk::setBinaryRetrievableHint(bool retrievable)
232{
233 UNIMPLEMENTED();
234}
235
Yunchao He61afff12017-03-14 15:34:03 +0800236void ProgramVk::setSeparable(bool separable)
237{
238 UNIMPLEMENTED();
239}
240
Jamie Madill9cf9e872017-06-05 12:59:25 -0400241gl::LinkResult ProgramVk::link(const gl::Context *glContext,
Jamie Madillc9727f32017-11-07 12:37:07 -0500242 const gl::ProgramLinkedResources &resources,
Jamie Madill9cf9e872017-06-05 12:59:25 -0400243 gl::InfoLog &infoLog)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400244{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400245 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madillc5143482017-10-15 20:20:06 -0400246 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500247 GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
Jamie Madillc5143482017-10-15 20:20:06 -0400248 VkDevice device = renderer->getDevice();
249
Jamie Madillb7d924a2018-03-10 11:16:54 -0500250 ANGLE_TRY(reset(contextVk));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500251
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500252 std::vector<uint32_t> vertexCode;
253 std::vector<uint32_t> fragmentCode;
254 bool linkSuccess = false;
Jamie Madill4dd167f2017-11-09 13:08:31 -0500255 ANGLE_TRY_RESULT(
256 glslangWrapper->linkProgram(glContext, mState, resources, &vertexCode, &fragmentCode),
257 linkSuccess);
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500258 if (!linkSuccess)
259 {
260 return false;
261 }
262
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500263 {
264 VkShaderModuleCreateInfo vertexShaderInfo;
265 vertexShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
266 vertexShaderInfo.pNext = nullptr;
267 vertexShaderInfo.flags = 0;
268 vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t);
269 vertexShaderInfo.pCode = vertexCode.data();
Jamie Madillc5143482017-10-15 20:20:06 -0400270
271 ANGLE_TRY(mLinkedVertexModule.init(device, vertexShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500272 mVertexModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500273 }
274
275 {
276 VkShaderModuleCreateInfo fragmentShaderInfo;
277 fragmentShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
278 fragmentShaderInfo.pNext = nullptr;
279 fragmentShaderInfo.flags = 0;
280 fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t);
281 fragmentShaderInfo.pCode = fragmentCode.data();
282
Jamie Madillc5143482017-10-15 20:20:06 -0400283 ANGLE_TRY(mLinkedFragmentModule.init(device, fragmentShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500284 mFragmentModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500285 }
286
Jamie Madill76e471e2017-10-21 09:56:01 -0400287 ANGLE_TRY(initDefaultUniformBlocks(glContext));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500288
Jamie Madill8c3988c2017-12-21 14:44:56 -0500289 if (!mState.getSamplerUniformRange().empty())
290 {
291 // Ensure the descriptor set range includes the textures at position 1.
292 mUsedDescriptorSetRange.extend(1);
293 mDirtyTextures = true;
294 }
295
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500296 return true;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400297}
298
Jamie Madill76e471e2017-10-21 09:56:01 -0400299gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
300{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400301 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madill57fbfd82018-02-14 12:45:34 -0500302 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400303 VkDevice device = contextVk->getDevice();
304
305 // Process vertex and fragment uniforms into std140 packing.
Luc Ferron7a06ac12018-03-15 10:17:04 -0400306 std::array<sh::BlockLayoutMap, MaxShaderIndex> layoutMap;
307 std::array<size_t, MaxShaderIndex> requiredBufferSize = {{0, 0}};
Jamie Madill76e471e2017-10-21 09:56:01 -0400308
309 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
310 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400311 ANGLE_TRY(InitDefaultUniformBlock(glContext, GetShader(mState, shaderIndex),
Jamie Madill76e471e2017-10-21 09:56:01 -0400312 &layoutMap[shaderIndex],
313 &requiredBufferSize[shaderIndex]));
314 }
315
316 // Init the default block layout info.
317 const auto &locations = mState.getUniformLocations();
318 const auto &uniforms = mState.getUniforms();
319 for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex)
320 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400321 std::array<sh::BlockMemberInfo, MaxShaderIndex> layoutInfo;
Jamie Madill76e471e2017-10-21 09:56:01 -0400322
323 const auto &location = locations[locationIndex];
324 if (location.used() && !location.ignored)
325 {
Jamie Madillde03e002017-10-21 14:04:20 -0400326 const auto &uniform = uniforms[location.index];
327
328 if (uniform.isSampler())
329 continue;
330
Jamie Madill76e471e2017-10-21 09:56:01 -0400331 std::string uniformName = uniform.name;
332 if (uniform.isArray())
333 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400334 // Gets the uniform name without the [0] at the end.
335 uniformName = gl::ParseResourceName(uniformName, nullptr);
Jamie Madill76e471e2017-10-21 09:56:01 -0400336 }
337
338 bool found = false;
339
340 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
341 {
342 auto it = layoutMap[shaderIndex].find(uniformName);
343 if (it != layoutMap[shaderIndex].end())
344 {
345 found = true;
346 layoutInfo[shaderIndex] = it->second;
347 }
348 }
349
350 ASSERT(found);
351 }
352
353 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
354 {
355 mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]);
356 }
357 }
358
359 bool anyDirty = false;
360 bool allDirty = true;
361
362 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
363 {
364 if (requiredBufferSize[shaderIndex] > 0)
365 {
366 if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize(
367 requiredBufferSize[shaderIndex]))
368 {
369 return gl::OutOfMemory() << "Memory allocation failure.";
370 }
Luc Ferron7a06ac12018-03-15 10:17:04 -0400371 size_t minAlignment = static_cast<size_t>(
372 renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
373
374 mDefaultUniformBlocks[shaderIndex].storage.init(minAlignment);
375
376 // Initialize uniform buffer memory to zero by default.
Jamie Madill76e471e2017-10-21 09:56:01 -0400377 mDefaultUniformBlocks[shaderIndex].uniformData.fill(0);
378 mDefaultUniformBlocks[shaderIndex].uniformsDirty = true;
379
380 anyDirty = true;
381 }
382 else
383 {
384 allDirty = false;
385 }
386 }
387
388 if (anyDirty)
389 {
390 // Initialize the "empty" uniform block if necessary.
391 if (!allDirty)
392 {
393 VkBufferCreateInfo uniformBufferInfo;
394 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
395 uniformBufferInfo.pNext = nullptr;
396 uniformBufferInfo.flags = 0;
397 uniformBufferInfo.size = 1;
398 uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
399 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
400 uniformBufferInfo.queueFamilyIndexCount = 0;
401 uniformBufferInfo.pQueueFamilyIndices = nullptr;
402
403 ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo));
404
Luc Ferron7a06ac12018-03-15 10:17:04 -0400405 // Assume host visible/coherent memory available.
Jamie Madill57dd97a2018-02-06 17:10:49 -0500406 VkMemoryPropertyFlags flags =
407 (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Jamie Madill76e471e2017-10-21 09:56:01 -0400408 size_t requiredSize = 0;
Jamie Madill57fbfd82018-02-14 12:45:34 -0500409 ANGLE_TRY(AllocateBufferMemory(renderer, flags, &mEmptyUniformBlockStorage.buffer,
Jamie Madill76e471e2017-10-21 09:56:01 -0400410 &mEmptyUniformBlockStorage.memory, &requiredSize));
411 }
412
Jamie Madill8c3988c2017-12-21 14:44:56 -0500413 // Ensure the descriptor set range includes the uniform buffers at position 0.
414 mUsedDescriptorSetRange.extend(0);
Jamie Madill5547b382017-10-23 18:16:01 -0400415 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400416
417 return gl::NoError();
418}
419
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400420GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
421{
422 UNIMPLEMENTED();
423 return GLboolean();
424}
425
Jamie Madill76e471e2017-10-21 09:56:01 -0400426template <typename T>
427void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType)
428{
429 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
430 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
431
Luc Ferron7cec3352018-03-13 13:29:34 -0400432 if (linkedUniform.isSampler())
433 {
Jamie Madill0cb6dc42018-04-16 10:36:39 -0400434 // We could potentially cache some indexing here. For now this is a no-op since the mapping
435 // is handled entirely in ContextVk.
Luc Ferron7cec3352018-03-13 13:29:34 -0400436 return;
437 }
438
Luc Ferron24a31372018-04-04 11:49:14 -0400439 if (linkedUniform.typeInfo->type == entryPointType)
Jamie Madill76e471e2017-10-21 09:56:01 -0400440 {
Luc Ferron24a31372018-04-04 11:49:14 -0400441 for (auto &uniformBlock : mDefaultUniformBlocks)
Jamie Madill76e471e2017-10-21 09:56:01 -0400442 {
Luc Ferron24a31372018-04-04 11:49:14 -0400443 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
Luc Ferron62059a52018-03-29 07:01:35 -0400444
Luc Ferron24a31372018-04-04 11:49:14 -0400445 // Assume an offset of -1 means the block is unused.
446 if (layoutInfo.offset == -1)
447 {
448 continue;
449 }
450
451 const GLint componentCount = linkedUniform.typeInfo->componentCount;
Luc Ferron62059a52018-03-29 07:01:35 -0400452 UpdateDefaultUniformBlock(count, locationInfo.arrayIndex, componentCount, v, layoutInfo,
453 &uniformBlock.uniformData);
Luc Ferron24a31372018-04-04 11:49:14 -0400454 uniformBlock.uniformsDirty = true;
Luc Ferron62059a52018-03-29 07:01:35 -0400455 }
Luc Ferron24a31372018-04-04 11:49:14 -0400456 }
457 else
458 {
459 for (auto &uniformBlock : mDefaultUniformBlocks)
Luc Ferron62059a52018-03-29 07:01:35 -0400460 {
Luc Ferron24a31372018-04-04 11:49:14 -0400461 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
462
463 // Assume an offset of -1 means the block is unused.
464 if (layoutInfo.offset == -1)
465 {
466 continue;
467 }
468
469 const GLint componentCount = linkedUniform.typeInfo->componentCount;
470
Luc Ferron62059a52018-03-29 07:01:35 -0400471 ASSERT(linkedUniform.typeInfo->type == gl::VariableBoolVectorType(entryPointType));
472
Luc Ferrond91c3792018-04-06 09:36:36 -0400473 GLint initialArrayOffset =
474 locationInfo.arrayIndex * layoutInfo.arrayStride + layoutInfo.offset;
Luc Ferron62059a52018-03-29 07:01:35 -0400475 for (GLint i = 0; i < count; i++)
476 {
477 GLint elementOffset = i * layoutInfo.arrayStride + initialArrayOffset;
478 GLint *dest =
479 reinterpret_cast<GLint *>(uniformBlock.uniformData.data() + elementOffset);
480 const T *source = v + i * componentCount;
481
482 for (int c = 0; c < componentCount; c++)
483 {
484 dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
485 }
486 }
Luc Ferron24a31372018-04-04 11:49:14 -0400487 uniformBlock.uniformsDirty = true;
Luc Ferron62059a52018-03-29 07:01:35 -0400488 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400489 }
490}
491
Luc Ferron7cec3352018-03-13 13:29:34 -0400492template <typename T>
493void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) const
494{
495 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
496 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
497
498 if (linkedUniform.isSampler())
499 {
500 UNIMPLEMENTED();
501 return;
502 }
503
Olli Etuaho107c7242018-03-20 15:45:35 +0200504 const gl::ShaderType shaderType = linkedUniform.getFirstShaderTypeWhereActive();
Jiawei Shao385b3e02018-03-21 09:43:28 +0800505 ASSERT(shaderType != gl::ShaderType::InvalidEnum);
Luc Ferron7cec3352018-03-13 13:29:34 -0400506
Jiawei Shao385b3e02018-03-21 09:43:28 +0800507 const DefaultUniformBlock &uniformBlock =
508 mDefaultUniformBlocks[static_cast<GLuint>(shaderType)];
Luc Ferron7cec3352018-03-13 13:29:34 -0400509 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
Luc Ferron62059a52018-03-29 07:01:35 -0400510
511 ASSERT(linkedUniform.typeInfo->componentType == entryPointType ||
512 linkedUniform.typeInfo->componentType == gl::VariableBoolVectorType(entryPointType));
Luc Ferron2371aca2018-03-27 16:03:03 -0400513 ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, locationInfo.arrayIndex, v,
514 layoutInfo, &uniformBlock.uniformData);
Luc Ferron7cec3352018-03-13 13:29:34 -0400515}
516
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400517void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
518{
Jamie Madill76e471e2017-10-21 09:56:01 -0400519 setUniformImpl(location, count, v, GL_FLOAT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400520}
521
522void ProgramVk::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
523{
Jamie Madill76e471e2017-10-21 09:56:01 -0400524 setUniformImpl(location, count, v, GL_FLOAT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400525}
526
527void ProgramVk::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
528{
Jamie Madill76e471e2017-10-21 09:56:01 -0400529 setUniformImpl(location, count, v, GL_FLOAT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400530}
531
532void ProgramVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
533{
Jamie Madill76e471e2017-10-21 09:56:01 -0400534 setUniformImpl(location, count, v, GL_FLOAT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400535}
536
537void ProgramVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
538{
Luc Ferron7cec3352018-03-13 13:29:34 -0400539 setUniformImpl(location, count, v, GL_INT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400540}
541
542void ProgramVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
543{
Luc Ferron489243f2018-03-28 16:55:28 -0400544 setUniformImpl(location, count, v, GL_INT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400545}
546
547void ProgramVk::setUniform3iv(GLint location, GLsizei count, const GLint *v)
548{
Luc Ferron489243f2018-03-28 16:55:28 -0400549 setUniformImpl(location, count, v, GL_INT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400550}
551
552void ProgramVk::setUniform4iv(GLint location, GLsizei count, const GLint *v)
553{
Luc Ferron489243f2018-03-28 16:55:28 -0400554 setUniformImpl(location, count, v, GL_INT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400555}
556
557void ProgramVk::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
558{
559 UNIMPLEMENTED();
560}
561
562void ProgramVk::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
563{
564 UNIMPLEMENTED();
565}
566
567void ProgramVk::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
568{
569 UNIMPLEMENTED();
570}
571
572void ProgramVk::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
573{
574 UNIMPLEMENTED();
575}
576
577void ProgramVk::setUniformMatrix2fv(GLint location,
578 GLsizei count,
579 GLboolean transpose,
580 const GLfloat *value)
581{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400582 if (transpose == GL_TRUE)
583 {
584 UNIMPLEMENTED();
585 return;
586 }
587
588 setUniformImpl(location, count, value, GL_FLOAT_MAT2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400589}
590
591void ProgramVk::setUniformMatrix3fv(GLint location,
592 GLsizei count,
593 GLboolean transpose,
594 const GLfloat *value)
595{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400596 if (transpose == GL_TRUE)
597 {
598 UNIMPLEMENTED();
599 return;
600 }
601 setUniformImpl(location, count, value, GL_FLOAT_MAT3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400602}
603
604void ProgramVk::setUniformMatrix4fv(GLint location,
605 GLsizei count,
606 GLboolean transpose,
607 const GLfloat *value)
608{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400609 if (transpose == GL_TRUE)
610 {
611 UNIMPLEMENTED();
612 return;
613 }
614
615 setUniformImpl(location, count, value, GL_FLOAT_MAT4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400616}
617
618void ProgramVk::setUniformMatrix2x3fv(GLint location,
619 GLsizei count,
620 GLboolean transpose,
621 const GLfloat *value)
622{
623 UNIMPLEMENTED();
624}
625
626void ProgramVk::setUniformMatrix3x2fv(GLint location,
627 GLsizei count,
628 GLboolean transpose,
629 const GLfloat *value)
630{
631 UNIMPLEMENTED();
632}
633
634void ProgramVk::setUniformMatrix2x4fv(GLint location,
635 GLsizei count,
636 GLboolean transpose,
637 const GLfloat *value)
638{
639 UNIMPLEMENTED();
640}
641
642void ProgramVk::setUniformMatrix4x2fv(GLint location,
643 GLsizei count,
644 GLboolean transpose,
645 const GLfloat *value)
646{
647 UNIMPLEMENTED();
648}
649
650void ProgramVk::setUniformMatrix3x4fv(GLint location,
651 GLsizei count,
652 GLboolean transpose,
653 const GLfloat *value)
654{
655 UNIMPLEMENTED();
656}
657
658void ProgramVk::setUniformMatrix4x3fv(GLint location,
659 GLsizei count,
660 GLboolean transpose,
661 const GLfloat *value)
662{
663 UNIMPLEMENTED();
664}
665
666void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
667{
668 UNIMPLEMENTED();
669}
670
Sami Väisänen46eaa942016-06-29 10:26:37 +0300671void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
672 GLenum genMode,
673 GLint components,
674 const GLfloat *coeffs)
675{
676 UNIMPLEMENTED();
677}
678
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500679const vk::ShaderModule &ProgramVk::getLinkedVertexModule() const
680{
681 ASSERT(mLinkedVertexModule.getHandle() != VK_NULL_HANDLE);
682 return mLinkedVertexModule;
683}
684
Jamie Madillf2f6d372018-01-10 21:37:23 -0500685Serial ProgramVk::getVertexModuleSerial() const
686{
687 return mVertexModuleSerial;
688}
689
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500690const vk::ShaderModule &ProgramVk::getLinkedFragmentModule() const
691{
692 ASSERT(mLinkedFragmentModule.getHandle() != VK_NULL_HANDLE);
693 return mLinkedFragmentModule;
694}
695
Jamie Madillf2f6d372018-01-10 21:37:23 -0500696Serial ProgramVk::getFragmentModuleSerial() const
697{
698 return mFragmentModuleSerial;
699}
700
Luc Ferron6ea1b412018-03-21 16:13:01 -0400701vk::Error ProgramVk::allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex)
Jamie Madill76e471e2017-10-21 09:56:01 -0400702{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500703 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400704
705 // Write out to a new a descriptor set.
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400706 vk::DynamicDescriptorPool *dynamicDescriptorPool = contextVk->getDynamicDescriptorPool();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500707 const auto &descriptorSetLayouts = renderer->getGraphicsDescriptorSetLayouts();
Jamie Madill76e471e2017-10-21 09:56:01 -0400708
Luc Ferron6ea1b412018-03-21 16:13:01 -0400709 uint32_t potentialNewCount = descriptorSetIndex + 1;
710 if (potentialNewCount > mDescriptorSets.size())
711 {
712 mDescriptorSets.resize(potentialNewCount, VK_NULL_HANDLE);
713 }
Luc Ferron7a06ac12018-03-15 10:17:04 -0400714
Luc Ferron6ea1b412018-03-21 16:13:01 -0400715 const VkDescriptorSetLayout *descriptorSetLayout =
716 descriptorSetLayouts[descriptorSetIndex].ptr();
717
718 ANGLE_TRY(dynamicDescriptorPool->allocateDescriptorSets(contextVk, descriptorSetLayout, 1,
719 &mDescriptorSets[descriptorSetIndex]));
Jamie Madill76e471e2017-10-21 09:56:01 -0400720 return vk::NoError();
721}
722
Jamie Madill54164b02017-08-28 15:17:37 -0400723void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
724{
Luc Ferron7cec3352018-03-13 13:29:34 -0400725 getUniformImpl(location, params, GL_FLOAT);
Jamie Madill54164b02017-08-28 15:17:37 -0400726}
727
728void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
729{
Luc Ferron7cec3352018-03-13 13:29:34 -0400730 getUniformImpl(location, params, GL_INT);
Jamie Madill54164b02017-08-28 15:17:37 -0400731}
732
733void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
734{
735 UNIMPLEMENTED();
736}
737
Jamie Madill76e471e2017-10-21 09:56:01 -0400738vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
739{
740 if (!mDefaultUniformBlocks[VertexShader].uniformsDirty &&
741 !mDefaultUniformBlocks[FragmentShader].uniformsDirty)
742 {
743 return vk::NoError();
744 }
745
Jamie Madill8c3988c2017-12-21 14:44:56 -0500746 ASSERT(mUsedDescriptorSetRange.contains(0));
Jamie Madill5547b382017-10-23 18:16:01 -0400747
Jamie Madill76e471e2017-10-21 09:56:01 -0400748 // Update buffer memory by immediate mapping. This immediate update only works once.
749 // TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers.
Luc Ferron7a06ac12018-03-15 10:17:04 -0400750 bool anyNewBufferAllocated = false;
751 for (size_t index = 0; index < mDefaultUniformBlocks.size(); index++)
Jamie Madill76e471e2017-10-21 09:56:01 -0400752 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400753 DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[index];
754
Jamie Madill76e471e2017-10-21 09:56:01 -0400755 if (uniformBlock.uniformsDirty)
756 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400757 bool bufferModified = false;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400758 ANGLE_TRY(SyncDefaultUniformBlock(contextVk->getRenderer(), &uniformBlock.storage,
Luc Ferron7a06ac12018-03-15 10:17:04 -0400759 uniformBlock.uniformData,
760 &mUniformBlocksOffsets[index], &bufferModified));
Jamie Madill76e471e2017-10-21 09:56:01 -0400761 uniformBlock.uniformsDirty = false;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400762
763 if (bufferModified)
764 {
765 anyNewBufferAllocated = true;
766 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400767 }
768 }
769
Luc Ferron7a06ac12018-03-15 10:17:04 -0400770 if (anyNewBufferAllocated)
771 {
772 // We need to reinitialize the descriptor sets if we newly allocated buffers since we can't
773 // modify the descriptor sets once initialized.
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400774 ANGLE_TRY(allocateDescriptorSet(contextVk, vk::UniformBufferIndex));
Luc Ferron7a06ac12018-03-15 10:17:04 -0400775 ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk));
776 }
777
Jamie Madill76e471e2017-10-21 09:56:01 -0400778 return vk::NoError();
779}
780
781vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
782{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400783 std::array<VkDescriptorBufferInfo, MaxShaderIndex> descriptorBufferInfo;
784 std::array<VkWriteDescriptorSet, MaxShaderIndex> writeDescriptorInfo;
Jamie Madill76e471e2017-10-21 09:56:01 -0400785 uint32_t bufferCount = 0;
786
787 for (auto &uniformBlock : mDefaultUniformBlocks)
788 {
789 auto &bufferInfo = descriptorBufferInfo[bufferCount];
Luc Ferron7a06ac12018-03-15 10:17:04 -0400790 auto &writeInfo = writeDescriptorInfo[bufferCount];
Jamie Madill76e471e2017-10-21 09:56:01 -0400791
792 if (!uniformBlock.uniformData.empty())
793 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400794 bufferInfo.buffer = uniformBlock.storage.getCurrentBufferHandle();
Jamie Madill76e471e2017-10-21 09:56:01 -0400795 }
796 else
797 {
798 bufferInfo.buffer = mEmptyUniformBlockStorage.buffer.getHandle();
799 }
800
801 bufferInfo.offset = 0;
802 bufferInfo.range = VK_WHOLE_SIZE;
803
Jamie Madill76e471e2017-10-21 09:56:01 -0400804 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
805 writeInfo.pNext = nullptr;
Jamie Madill5547b382017-10-23 18:16:01 -0400806 writeInfo.dstSet = mDescriptorSets[0];
Jamie Madill76e471e2017-10-21 09:56:01 -0400807 writeInfo.dstBinding = bufferCount;
808 writeInfo.dstArrayElement = 0;
809 writeInfo.descriptorCount = 1;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400810 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
Jamie Madill76e471e2017-10-21 09:56:01 -0400811 writeInfo.pImageInfo = nullptr;
812 writeInfo.pBufferInfo = &bufferInfo;
813 writeInfo.pTexelBufferView = nullptr;
814
815 bufferCount++;
816 }
817
818 VkDevice device = contextVk->getDevice();
819
820 vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr);
821
822 return vk::NoError();
823}
824
Jamie Madill5547b382017-10-23 18:16:01 -0400825const std::vector<VkDescriptorSet> &ProgramVk::getDescriptorSets() const
Jamie Madill76e471e2017-10-21 09:56:01 -0400826{
Jamie Madill5547b382017-10-23 18:16:01 -0400827 return mDescriptorSets;
828}
829
Luc Ferron7a06ac12018-03-15 10:17:04 -0400830const uint32_t *ProgramVk::getDynamicOffsets()
831{
832 // If we have no descriptor set being used, we do not need to specify any offsets when binding
833 // the descriptor sets.
834 if (!mUsedDescriptorSetRange.contains(0))
835 return nullptr;
836
837 return mUniformBlocksOffsets.data();
838}
839
840uint32_t ProgramVk::getDynamicOffsetsCount()
841{
842 if (!mUsedDescriptorSetRange.contains(0))
843 return 0;
844
845 return static_cast<uint32_t>(mUniformBlocksOffsets.size());
846}
847
Jamie Madill8c3988c2017-12-21 14:44:56 -0500848const gl::RangeUI &ProgramVk::getUsedDescriptorSetRange() const
Jamie Madill5547b382017-10-23 18:16:01 -0400849{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500850 return mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400851}
852
Luc Ferron6ea1b412018-03-21 16:13:01 -0400853vk::Error ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
Jamie Madill5547b382017-10-23 18:16:01 -0400854{
855 if (mState.getSamplerBindings().empty() || !mDirtyTextures)
856 {
Luc Ferron6ea1b412018-03-21 16:13:01 -0400857 return vk::NoError();
Jamie Madill5547b382017-10-23 18:16:01 -0400858 }
859
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400860 ANGLE_TRY(allocateDescriptorSet(contextVk, vk::TextureIndex));
Luc Ferron6ea1b412018-03-21 16:13:01 -0400861
Jamie Madill8c3988c2017-12-21 14:44:56 -0500862 ASSERT(mUsedDescriptorSetRange.contains(1));
863 VkDescriptorSet descriptorSet = mDescriptorSets[1];
Jamie Madill5547b382017-10-23 18:16:01 -0400864
865 // TODO(jmadill): Don't hard-code the texture limit.
866 ShaderTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
867 ShaderTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
868 uint32_t imageCount = 0;
869
870 const gl::State &glState = contextVk->getGLState();
871 const auto &completeTextures = glState.getCompleteTextureCache();
872
Jamie Madill858c1cc2018-03-31 14:19:13 -0400873 for (const gl::SamplerBinding &samplerBinding : mState.getSamplerBindings())
Jamie Madill5547b382017-10-23 18:16:01 -0400874 {
875 ASSERT(!samplerBinding.unreferenced);
876
877 // TODO(jmadill): Sampler arrays
878 ASSERT(samplerBinding.boundTextureUnits.size() == 1);
879
880 GLuint textureUnit = samplerBinding.boundTextureUnits[0];
881 const gl::Texture *texture = completeTextures[textureUnit];
882
883 // TODO(jmadill): Incomplete textures handling.
884 ASSERT(texture);
885
Jamie Madille1f3ad42017-10-28 23:00:42 -0400886 TextureVk *textureVk = vk::GetImpl(texture);
Jamie Madill858c1cc2018-03-31 14:19:13 -0400887 const vk::ImageHelper &image = textureVk->getImage();
Jamie Madill5547b382017-10-23 18:16:01 -0400888
889 VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];
890
891 imageInfo.sampler = textureVk->getSampler().getHandle();
892 imageInfo.imageView = textureVk->getImageView().getHandle();
893 imageInfo.imageLayout = image.getCurrentLayout();
894
895 auto &writeInfo = writeDescriptorInfo[imageCount];
896
897 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
898 writeInfo.pNext = nullptr;
899 writeInfo.dstSet = descriptorSet;
900 writeInfo.dstBinding = imageCount;
901 writeInfo.dstArrayElement = 0;
902 writeInfo.descriptorCount = 1;
903 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
904 writeInfo.pImageInfo = &imageInfo;
905 writeInfo.pBufferInfo = nullptr;
906 writeInfo.pTexelBufferView = nullptr;
907
908 imageCount++;
909 }
910
911 VkDevice device = contextVk->getDevice();
912
913 ASSERT(imageCount > 0);
914 vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);
915
916 mDirtyTextures = false;
Luc Ferron6ea1b412018-03-21 16:13:01 -0400917 return vk::NoError();
Jamie Madill5547b382017-10-23 18:16:01 -0400918}
919
920void ProgramVk::invalidateTextures()
921{
922 mDirtyTextures = true;
Jamie Madill76e471e2017-10-21 09:56:01 -0400923}
924
Luc Ferron7a06ac12018-03-15 10:17:04 -0400925void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
926{
927 for (DefaultUniformBlock &block : mDefaultUniformBlocks)
928 {
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400929 block.storage.setMinimumSizeForTesting(minSize);
Luc Ferron7a06ac12018-03-15 10:17:04 -0400930 }
931}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400932} // namespace rx