blob: c9d9a0195b334bfcdda246f4fb61f63025df6f0f [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 {
434 UNIMPLEMENTED();
435 return;
436 }
437
Luc Ferron24a31372018-04-04 11:49:14 -0400438 if (linkedUniform.typeInfo->type == entryPointType)
Jamie Madill76e471e2017-10-21 09:56:01 -0400439 {
Luc Ferron24a31372018-04-04 11:49:14 -0400440 for (auto &uniformBlock : mDefaultUniformBlocks)
Jamie Madill76e471e2017-10-21 09:56:01 -0400441 {
Luc Ferron24a31372018-04-04 11:49:14 -0400442 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
Luc Ferron62059a52018-03-29 07:01:35 -0400443
Luc Ferron24a31372018-04-04 11:49:14 -0400444 // Assume an offset of -1 means the block is unused.
445 if (layoutInfo.offset == -1)
446 {
447 continue;
448 }
449
450 const GLint componentCount = linkedUniform.typeInfo->componentCount;
Luc Ferron62059a52018-03-29 07:01:35 -0400451 UpdateDefaultUniformBlock(count, locationInfo.arrayIndex, componentCount, v, layoutInfo,
452 &uniformBlock.uniformData);
Luc Ferron24a31372018-04-04 11:49:14 -0400453 uniformBlock.uniformsDirty = true;
Luc Ferron62059a52018-03-29 07:01:35 -0400454 }
Luc Ferron24a31372018-04-04 11:49:14 -0400455 }
456 else
457 {
458 for (auto &uniformBlock : mDefaultUniformBlocks)
Luc Ferron62059a52018-03-29 07:01:35 -0400459 {
Luc Ferron24a31372018-04-04 11:49:14 -0400460 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
461
462 // Assume an offset of -1 means the block is unused.
463 if (layoutInfo.offset == -1)
464 {
465 continue;
466 }
467
468 const GLint componentCount = linkedUniform.typeInfo->componentCount;
469
Luc Ferron62059a52018-03-29 07:01:35 -0400470 ASSERT(linkedUniform.typeInfo->type == gl::VariableBoolVectorType(entryPointType));
471
472 GLint initialArrayOffset = locationInfo.arrayIndex * layoutInfo.arrayStride;
473 for (GLint i = 0; i < count; i++)
474 {
475 GLint elementOffset = i * layoutInfo.arrayStride + initialArrayOffset;
476 GLint *dest =
477 reinterpret_cast<GLint *>(uniformBlock.uniformData.data() + elementOffset);
478 const T *source = v + i * componentCount;
479
480 for (int c = 0; c < componentCount; c++)
481 {
482 dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
483 }
484 }
Luc Ferron24a31372018-04-04 11:49:14 -0400485 uniformBlock.uniformsDirty = true;
Luc Ferron62059a52018-03-29 07:01:35 -0400486 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400487 }
488}
489
Luc Ferron7cec3352018-03-13 13:29:34 -0400490template <typename T>
491void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) const
492{
493 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
494 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
495
496 if (linkedUniform.isSampler())
497 {
498 UNIMPLEMENTED();
499 return;
500 }
501
Olli Etuaho107c7242018-03-20 15:45:35 +0200502 const gl::ShaderType shaderType = linkedUniform.getFirstShaderTypeWhereActive();
Jiawei Shao385b3e02018-03-21 09:43:28 +0800503 ASSERT(shaderType != gl::ShaderType::InvalidEnum);
Luc Ferron7cec3352018-03-13 13:29:34 -0400504
Jiawei Shao385b3e02018-03-21 09:43:28 +0800505 const DefaultUniformBlock &uniformBlock =
506 mDefaultUniformBlocks[static_cast<GLuint>(shaderType)];
Luc Ferron7cec3352018-03-13 13:29:34 -0400507 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
Luc Ferron62059a52018-03-29 07:01:35 -0400508
509 ASSERT(linkedUniform.typeInfo->componentType == entryPointType ||
510 linkedUniform.typeInfo->componentType == gl::VariableBoolVectorType(entryPointType));
Luc Ferron2371aca2018-03-27 16:03:03 -0400511 ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, locationInfo.arrayIndex, v,
512 layoutInfo, &uniformBlock.uniformData);
Luc Ferron7cec3352018-03-13 13:29:34 -0400513}
514
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400515void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
516{
Jamie Madill76e471e2017-10-21 09:56:01 -0400517 setUniformImpl(location, count, v, GL_FLOAT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400518}
519
520void ProgramVk::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
521{
Jamie Madill76e471e2017-10-21 09:56:01 -0400522 setUniformImpl(location, count, v, GL_FLOAT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400523}
524
525void ProgramVk::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
526{
Jamie Madill76e471e2017-10-21 09:56:01 -0400527 setUniformImpl(location, count, v, GL_FLOAT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400528}
529
530void ProgramVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
531{
Jamie Madill76e471e2017-10-21 09:56:01 -0400532 setUniformImpl(location, count, v, GL_FLOAT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400533}
534
535void ProgramVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
536{
Luc Ferron7cec3352018-03-13 13:29:34 -0400537 setUniformImpl(location, count, v, GL_INT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400538}
539
540void ProgramVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
541{
Luc Ferron489243f2018-03-28 16:55:28 -0400542 setUniformImpl(location, count, v, GL_INT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400543}
544
545void ProgramVk::setUniform3iv(GLint location, GLsizei count, const GLint *v)
546{
Luc Ferron489243f2018-03-28 16:55:28 -0400547 setUniformImpl(location, count, v, GL_INT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400548}
549
550void ProgramVk::setUniform4iv(GLint location, GLsizei count, const GLint *v)
551{
Luc Ferron489243f2018-03-28 16:55:28 -0400552 setUniformImpl(location, count, v, GL_INT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400553}
554
555void ProgramVk::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
556{
557 UNIMPLEMENTED();
558}
559
560void ProgramVk::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
561{
562 UNIMPLEMENTED();
563}
564
565void ProgramVk::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
566{
567 UNIMPLEMENTED();
568}
569
570void ProgramVk::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
571{
572 UNIMPLEMENTED();
573}
574
575void ProgramVk::setUniformMatrix2fv(GLint location,
576 GLsizei count,
577 GLboolean transpose,
578 const GLfloat *value)
579{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400580 if (transpose == GL_TRUE)
581 {
582 UNIMPLEMENTED();
583 return;
584 }
585
586 setUniformImpl(location, count, value, GL_FLOAT_MAT2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400587}
588
589void ProgramVk::setUniformMatrix3fv(GLint location,
590 GLsizei count,
591 GLboolean transpose,
592 const GLfloat *value)
593{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400594 if (transpose == GL_TRUE)
595 {
596 UNIMPLEMENTED();
597 return;
598 }
599 setUniformImpl(location, count, value, GL_FLOAT_MAT3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400600}
601
602void ProgramVk::setUniformMatrix4fv(GLint location,
603 GLsizei count,
604 GLboolean transpose,
605 const GLfloat *value)
606{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400607 if (transpose == GL_TRUE)
608 {
609 UNIMPLEMENTED();
610 return;
611 }
612
613 setUniformImpl(location, count, value, GL_FLOAT_MAT4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400614}
615
616void ProgramVk::setUniformMatrix2x3fv(GLint location,
617 GLsizei count,
618 GLboolean transpose,
619 const GLfloat *value)
620{
621 UNIMPLEMENTED();
622}
623
624void ProgramVk::setUniformMatrix3x2fv(GLint location,
625 GLsizei count,
626 GLboolean transpose,
627 const GLfloat *value)
628{
629 UNIMPLEMENTED();
630}
631
632void ProgramVk::setUniformMatrix2x4fv(GLint location,
633 GLsizei count,
634 GLboolean transpose,
635 const GLfloat *value)
636{
637 UNIMPLEMENTED();
638}
639
640void ProgramVk::setUniformMatrix4x2fv(GLint location,
641 GLsizei count,
642 GLboolean transpose,
643 const GLfloat *value)
644{
645 UNIMPLEMENTED();
646}
647
648void ProgramVk::setUniformMatrix3x4fv(GLint location,
649 GLsizei count,
650 GLboolean transpose,
651 const GLfloat *value)
652{
653 UNIMPLEMENTED();
654}
655
656void ProgramVk::setUniformMatrix4x3fv(GLint location,
657 GLsizei count,
658 GLboolean transpose,
659 const GLfloat *value)
660{
661 UNIMPLEMENTED();
662}
663
664void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
665{
666 UNIMPLEMENTED();
667}
668
Sami Väisänen46eaa942016-06-29 10:26:37 +0300669void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
670 GLenum genMode,
671 GLint components,
672 const GLfloat *coeffs)
673{
674 UNIMPLEMENTED();
675}
676
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500677const vk::ShaderModule &ProgramVk::getLinkedVertexModule() const
678{
679 ASSERT(mLinkedVertexModule.getHandle() != VK_NULL_HANDLE);
680 return mLinkedVertexModule;
681}
682
Jamie Madillf2f6d372018-01-10 21:37:23 -0500683Serial ProgramVk::getVertexModuleSerial() const
684{
685 return mVertexModuleSerial;
686}
687
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500688const vk::ShaderModule &ProgramVk::getLinkedFragmentModule() const
689{
690 ASSERT(mLinkedFragmentModule.getHandle() != VK_NULL_HANDLE);
691 return mLinkedFragmentModule;
692}
693
Jamie Madillf2f6d372018-01-10 21:37:23 -0500694Serial ProgramVk::getFragmentModuleSerial() const
695{
696 return mFragmentModuleSerial;
697}
698
Luc Ferron6ea1b412018-03-21 16:13:01 -0400699vk::Error ProgramVk::allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex)
Jamie Madill76e471e2017-10-21 09:56:01 -0400700{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500701 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400702
703 // Write out to a new a descriptor set.
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400704 vk::DynamicDescriptorPool *dynamicDescriptorPool = contextVk->getDynamicDescriptorPool();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500705 const auto &descriptorSetLayouts = renderer->getGraphicsDescriptorSetLayouts();
Jamie Madill76e471e2017-10-21 09:56:01 -0400706
Luc Ferron6ea1b412018-03-21 16:13:01 -0400707 uint32_t potentialNewCount = descriptorSetIndex + 1;
708 if (potentialNewCount > mDescriptorSets.size())
709 {
710 mDescriptorSets.resize(potentialNewCount, VK_NULL_HANDLE);
711 }
Luc Ferron7a06ac12018-03-15 10:17:04 -0400712
Luc Ferron6ea1b412018-03-21 16:13:01 -0400713 const VkDescriptorSetLayout *descriptorSetLayout =
714 descriptorSetLayouts[descriptorSetIndex].ptr();
715
716 ANGLE_TRY(dynamicDescriptorPool->allocateDescriptorSets(contextVk, descriptorSetLayout, 1,
717 &mDescriptorSets[descriptorSetIndex]));
Jamie Madill76e471e2017-10-21 09:56:01 -0400718 return vk::NoError();
719}
720
Jamie Madill54164b02017-08-28 15:17:37 -0400721void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
722{
Luc Ferron7cec3352018-03-13 13:29:34 -0400723 getUniformImpl(location, params, GL_FLOAT);
Jamie Madill54164b02017-08-28 15:17:37 -0400724}
725
726void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
727{
Luc Ferron7cec3352018-03-13 13:29:34 -0400728 getUniformImpl(location, params, GL_INT);
Jamie Madill54164b02017-08-28 15:17:37 -0400729}
730
731void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
732{
733 UNIMPLEMENTED();
734}
735
Jamie Madill76e471e2017-10-21 09:56:01 -0400736vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
737{
738 if (!mDefaultUniformBlocks[VertexShader].uniformsDirty &&
739 !mDefaultUniformBlocks[FragmentShader].uniformsDirty)
740 {
741 return vk::NoError();
742 }
743
Jamie Madill8c3988c2017-12-21 14:44:56 -0500744 ASSERT(mUsedDescriptorSetRange.contains(0));
Jamie Madill5547b382017-10-23 18:16:01 -0400745
Jamie Madill76e471e2017-10-21 09:56:01 -0400746 // Update buffer memory by immediate mapping. This immediate update only works once.
747 // TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers.
Luc Ferron7a06ac12018-03-15 10:17:04 -0400748 bool anyNewBufferAllocated = false;
749 for (size_t index = 0; index < mDefaultUniformBlocks.size(); index++)
Jamie Madill76e471e2017-10-21 09:56:01 -0400750 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400751 DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[index];
752
Jamie Madill76e471e2017-10-21 09:56:01 -0400753 if (uniformBlock.uniformsDirty)
754 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400755 bool bufferModified = false;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400756 ANGLE_TRY(SyncDefaultUniformBlock(contextVk->getRenderer(), &uniformBlock.storage,
Luc Ferron7a06ac12018-03-15 10:17:04 -0400757 uniformBlock.uniformData,
758 &mUniformBlocksOffsets[index], &bufferModified));
Jamie Madill76e471e2017-10-21 09:56:01 -0400759 uniformBlock.uniformsDirty = false;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400760
761 if (bufferModified)
762 {
763 anyNewBufferAllocated = true;
764 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400765 }
766 }
767
Luc Ferron7a06ac12018-03-15 10:17:04 -0400768 if (anyNewBufferAllocated)
769 {
770 // We need to reinitialize the descriptor sets if we newly allocated buffers since we can't
771 // modify the descriptor sets once initialized.
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400772 ANGLE_TRY(allocateDescriptorSet(contextVk, vk::UniformBufferIndex));
Luc Ferron7a06ac12018-03-15 10:17:04 -0400773 ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk));
774 }
775
Jamie Madill76e471e2017-10-21 09:56:01 -0400776 return vk::NoError();
777}
778
779vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
780{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400781 std::array<VkDescriptorBufferInfo, MaxShaderIndex> descriptorBufferInfo;
782 std::array<VkWriteDescriptorSet, MaxShaderIndex> writeDescriptorInfo;
Jamie Madill76e471e2017-10-21 09:56:01 -0400783 uint32_t bufferCount = 0;
784
785 for (auto &uniformBlock : mDefaultUniformBlocks)
786 {
787 auto &bufferInfo = descriptorBufferInfo[bufferCount];
Luc Ferron7a06ac12018-03-15 10:17:04 -0400788 auto &writeInfo = writeDescriptorInfo[bufferCount];
Jamie Madill76e471e2017-10-21 09:56:01 -0400789
790 if (!uniformBlock.uniformData.empty())
791 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400792 bufferInfo.buffer = uniformBlock.storage.getCurrentBufferHandle();
Jamie Madill76e471e2017-10-21 09:56:01 -0400793 }
794 else
795 {
796 bufferInfo.buffer = mEmptyUniformBlockStorage.buffer.getHandle();
797 }
798
799 bufferInfo.offset = 0;
800 bufferInfo.range = VK_WHOLE_SIZE;
801
Jamie Madill76e471e2017-10-21 09:56:01 -0400802 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
803 writeInfo.pNext = nullptr;
Jamie Madill5547b382017-10-23 18:16:01 -0400804 writeInfo.dstSet = mDescriptorSets[0];
Jamie Madill76e471e2017-10-21 09:56:01 -0400805 writeInfo.dstBinding = bufferCount;
806 writeInfo.dstArrayElement = 0;
807 writeInfo.descriptorCount = 1;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400808 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
Jamie Madill76e471e2017-10-21 09:56:01 -0400809 writeInfo.pImageInfo = nullptr;
810 writeInfo.pBufferInfo = &bufferInfo;
811 writeInfo.pTexelBufferView = nullptr;
812
813 bufferCount++;
814 }
815
816 VkDevice device = contextVk->getDevice();
817
818 vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr);
819
820 return vk::NoError();
821}
822
Jamie Madill5547b382017-10-23 18:16:01 -0400823const std::vector<VkDescriptorSet> &ProgramVk::getDescriptorSets() const
Jamie Madill76e471e2017-10-21 09:56:01 -0400824{
Jamie Madill5547b382017-10-23 18:16:01 -0400825 return mDescriptorSets;
826}
827
Luc Ferron7a06ac12018-03-15 10:17:04 -0400828const uint32_t *ProgramVk::getDynamicOffsets()
829{
830 // If we have no descriptor set being used, we do not need to specify any offsets when binding
831 // the descriptor sets.
832 if (!mUsedDescriptorSetRange.contains(0))
833 return nullptr;
834
835 return mUniformBlocksOffsets.data();
836}
837
838uint32_t ProgramVk::getDynamicOffsetsCount()
839{
840 if (!mUsedDescriptorSetRange.contains(0))
841 return 0;
842
843 return static_cast<uint32_t>(mUniformBlocksOffsets.size());
844}
845
Jamie Madill8c3988c2017-12-21 14:44:56 -0500846const gl::RangeUI &ProgramVk::getUsedDescriptorSetRange() const
Jamie Madill5547b382017-10-23 18:16:01 -0400847{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500848 return mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400849}
850
Luc Ferron6ea1b412018-03-21 16:13:01 -0400851vk::Error ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
Jamie Madill5547b382017-10-23 18:16:01 -0400852{
853 if (mState.getSamplerBindings().empty() || !mDirtyTextures)
854 {
Luc Ferron6ea1b412018-03-21 16:13:01 -0400855 return vk::NoError();
Jamie Madill5547b382017-10-23 18:16:01 -0400856 }
857
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400858 ANGLE_TRY(allocateDescriptorSet(contextVk, vk::TextureIndex));
Luc Ferron6ea1b412018-03-21 16:13:01 -0400859
Jamie Madill8c3988c2017-12-21 14:44:56 -0500860 ASSERT(mUsedDescriptorSetRange.contains(1));
861 VkDescriptorSet descriptorSet = mDescriptorSets[1];
Jamie Madill5547b382017-10-23 18:16:01 -0400862
863 // TODO(jmadill): Don't hard-code the texture limit.
864 ShaderTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
865 ShaderTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
866 uint32_t imageCount = 0;
867
868 const gl::State &glState = contextVk->getGLState();
869 const auto &completeTextures = glState.getCompleteTextureCache();
870
Jamie Madill858c1cc2018-03-31 14:19:13 -0400871 for (const gl::SamplerBinding &samplerBinding : mState.getSamplerBindings())
Jamie Madill5547b382017-10-23 18:16:01 -0400872 {
873 ASSERT(!samplerBinding.unreferenced);
874
875 // TODO(jmadill): Sampler arrays
876 ASSERT(samplerBinding.boundTextureUnits.size() == 1);
877
878 GLuint textureUnit = samplerBinding.boundTextureUnits[0];
879 const gl::Texture *texture = completeTextures[textureUnit];
880
881 // TODO(jmadill): Incomplete textures handling.
882 ASSERT(texture);
883
Jamie Madille1f3ad42017-10-28 23:00:42 -0400884 TextureVk *textureVk = vk::GetImpl(texture);
Jamie Madill858c1cc2018-03-31 14:19:13 -0400885 const vk::ImageHelper &image = textureVk->getImage();
Jamie Madill5547b382017-10-23 18:16:01 -0400886
887 VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];
888
889 imageInfo.sampler = textureVk->getSampler().getHandle();
890 imageInfo.imageView = textureVk->getImageView().getHandle();
891 imageInfo.imageLayout = image.getCurrentLayout();
892
893 auto &writeInfo = writeDescriptorInfo[imageCount];
894
895 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
896 writeInfo.pNext = nullptr;
897 writeInfo.dstSet = descriptorSet;
898 writeInfo.dstBinding = imageCount;
899 writeInfo.dstArrayElement = 0;
900 writeInfo.descriptorCount = 1;
901 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
902 writeInfo.pImageInfo = &imageInfo;
903 writeInfo.pBufferInfo = nullptr;
904 writeInfo.pTexelBufferView = nullptr;
905
906 imageCount++;
907 }
908
909 VkDevice device = contextVk->getDevice();
910
911 ASSERT(imageCount > 0);
912 vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);
913
914 mDirtyTextures = false;
Luc Ferron6ea1b412018-03-21 16:13:01 -0400915 return vk::NoError();
Jamie Madill5547b382017-10-23 18:16:01 -0400916}
917
918void ProgramVk::invalidateTextures()
919{
920 mDirtyTextures = true;
Jamie Madill76e471e2017-10-21 09:56:01 -0400921}
922
Luc Ferron7a06ac12018-03-15 10:17:04 -0400923void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
924{
925 for (DefaultUniformBlock &block : mDefaultUniformBlocks)
926 {
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400927 block.storage.setMinimumSizeForTesting(minSize);
Luc Ferron7a06ac12018-03-15 10:17:04 -0400928 }
929}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400930} // namespace rx