blob: c3d736737e546fd44530f2ad7b41ca97c181e730 [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
2// Copyright 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// ProgramVk.cpp:
7// Implements the class methods for ProgramVk.
8//
9
10#include "libANGLE/renderer/vulkan/ProgramVk.h"
11
12#include "common/debug.h"
Jamie Madill76e471e2017-10-21 09:56:01 -040013#include "common/utilities.h"
Jamie Madillc564c072017-06-01 12:45:42 -040014#include "libANGLE/Context.h"
Jamie Madill8ecf7f92017-01-13 17:29:52 -050015#include "libANGLE/renderer/vulkan/ContextVk.h"
Luc Ferrondaedf4d2018-03-16 09:28:53 -040016#include "libANGLE/renderer/vulkan/DynamicDescriptorPool.h"
Jamie Madill8ecf7f92017-01-13 17:29:52 -050017#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
18#include "libANGLE/renderer/vulkan/RendererVk.h"
Luc Ferron7a06ac12018-03-15 10:17:04 -040019#include "libANGLE/renderer/vulkan/StreamingBuffer.h"
Jamie Madill5547b382017-10-23 18:16:01 -040020#include "libANGLE/renderer/vulkan/TextureVk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040021
22namespace rx
23{
24
Jamie Madill76e471e2017-10-21 09:56:01 -040025namespace
26{
27
Luc Ferron7a06ac12018-03-15 10:17:04 -040028constexpr size_t kUniformBlockStreamingBufferMinSize = 256 * 128;
29
Jamie Madill76e471e2017-10-21 09:56:01 -040030gl::Error InitDefaultUniformBlock(const gl::Context *context,
Jamie Madill76e471e2017-10-21 09:56:01 -040031 gl::Shader *shader,
Jamie Madill76e471e2017-10-21 09:56:01 -040032 sh::BlockLayoutMap *blockLayoutMapOut,
Luc Ferron7a06ac12018-03-15 10:17:04 -040033 size_t *blockSizeOut)
Jamie Madill76e471e2017-10-21 09:56:01 -040034{
35 const auto &uniforms = shader->getUniforms(context);
36
37 if (uniforms.empty())
38 {
Luc Ferron7a06ac12018-03-15 10:17:04 -040039 *blockSizeOut = 0;
Jamie Madill76e471e2017-10-21 09:56:01 -040040 return gl::NoError();
41 }
42
43 sh::Std140BlockEncoder blockEncoder;
Olli Etuaho3de27032017-11-30 12:16:47 +020044 sh::GetUniformBlockInfo(uniforms, "", &blockEncoder, blockLayoutMapOut);
Jamie Madill76e471e2017-10-21 09:56:01 -040045
46 size_t blockSize = blockEncoder.getBlockSize();
47
48 // TODO(jmadill): I think we still need a valid block for the pipeline even if zero sized.
49 if (blockSize == 0)
50 {
Luc Ferron7a06ac12018-03-15 10:17:04 -040051 *blockSizeOut = 0;
Jamie Madill76e471e2017-10-21 09:56:01 -040052 return gl::NoError();
53 }
54
Luc Ferron7a06ac12018-03-15 10:17:04 -040055 *blockSizeOut = blockSize;
Jamie Madill76e471e2017-10-21 09:56:01 -040056 return gl::NoError();
57}
58
59template <typename T>
60void UpdateDefaultUniformBlock(GLsizei count,
Luc Ferron2371aca2018-03-27 16:03:03 -040061 uint32_t arrayIndex,
Jamie Madill76e471e2017-10-21 09:56:01 -040062 int componentCount,
63 const T *v,
64 const sh::BlockMemberInfo &layoutInfo,
65 angle::MemoryBuffer *uniformData)
66{
Luc Ferron2371aca2018-03-27 16:03:03 -040067 const int elementSize = sizeof(T) * componentCount;
68
69 uint8_t *dst = uniformData->data() + layoutInfo.offset;
Jamie Madill76e471e2017-10-21 09:56:01 -040070 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
71 {
Luc Ferron2371aca2018-03-27 16:03:03 -040072 uint32_t arrayOffset = arrayIndex * layoutInfo.arrayStride;
73 uint8_t *writePtr = dst + arrayOffset;
Jamie Madill76e471e2017-10-21 09:56:01 -040074 memcpy(writePtr, v, elementSize * count);
75 }
76 else
77 {
Luc Ferron2371aca2018-03-27 16:03:03 -040078 // Have to respect the arrayStride between each element of the array.
79 int maxIndex = arrayIndex + count;
80 for (int writeIndex = arrayIndex, readIndex = 0; writeIndex < maxIndex;
81 writeIndex++, readIndex++)
82 {
83 const int arrayOffset = writeIndex * layoutInfo.arrayStride;
84 uint8_t *writePtr = dst + arrayOffset;
85 const T *readPtr = v + readIndex;
86 memcpy(writePtr, readPtr, elementSize);
87 }
Jamie Madill76e471e2017-10-21 09:56:01 -040088 }
89}
90
Luc Ferron7cec3352018-03-13 13:29:34 -040091template <typename T>
92void ReadFromDefaultUniformBlock(int componentCount,
Luc Ferron2371aca2018-03-27 16:03:03 -040093 uint32_t arrayIndex,
Luc Ferron7cec3352018-03-13 13:29:34 -040094 T *dst,
95 const sh::BlockMemberInfo &layoutInfo,
96 const angle::MemoryBuffer *uniformData)
97{
98 ASSERT(layoutInfo.offset != -1);
99
Luc Ferron2371aca2018-03-27 16:03:03 -0400100 const int elementSize = sizeof(T) * componentCount;
101 const uint8_t *source = uniformData->data() + layoutInfo.offset;
102
Luc Ferron7cec3352018-03-13 13:29:34 -0400103 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
104 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400105 const uint8_t *readPtr = source + arrayIndex * layoutInfo.arrayStride;
Luc Ferron7cec3352018-03-13 13:29:34 -0400106 memcpy(dst, readPtr, elementSize);
107 }
108 else
109 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400110 // Have to respect the arrayStride between each element of the array.
111 const int arrayOffset = arrayIndex * layoutInfo.arrayStride;
112 const uint8_t *readPtr = source + arrayOffset;
113 memcpy(dst, readPtr, elementSize);
Luc Ferron7cec3352018-03-13 13:29:34 -0400114 }
115}
116
Luc Ferron7a06ac12018-03-15 10:17:04 -0400117vk::Error SyncDefaultUniformBlock(ContextVk *contextVk,
118 StreamingBuffer &streamingBuffer,
119 const angle::MemoryBuffer &bufferData,
120 uint32_t *outOffset,
121 bool *outBufferModified)
Jamie Madill76e471e2017-10-21 09:56:01 -0400122{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400123 ASSERT(!bufferData.empty());
124 uint8_t *data = nullptr;
125 VkBuffer *outBuffer = nullptr;
126 uint32_t offset;
127 ANGLE_TRY(streamingBuffer.allocate(contextVk, bufferData.size(), &data, outBuffer, &offset,
128 outBufferModified));
129 *outOffset = offset;
130 memcpy(data, bufferData.data(), bufferData.size());
131 ANGLE_TRY(streamingBuffer.flush(contextVk));
Jamie Madill76e471e2017-10-21 09:56:01 -0400132 return vk::NoError();
133}
134
Jiawei Shao385b3e02018-03-21 09:43:28 +0800135// TODO(jiawei.shao@intel.com): Fully remove this enum by gl::ShaderType. (BUG=angleproject:2169)
Jamie Madill76e471e2017-10-21 09:56:01 -0400136enum ShaderIndex : uint32_t
137{
138 MinShaderIndex = 0,
139 VertexShader = MinShaderIndex,
140 FragmentShader = 1,
Luc Ferron7a06ac12018-03-15 10:17:04 -0400141 MaxShaderIndex = kShaderTypeCount,
Jamie Madill76e471e2017-10-21 09:56:01 -0400142};
143
144gl::Shader *GetShader(const gl::ProgramState &programState, uint32_t shaderIndex)
145{
146 switch (shaderIndex)
147 {
148 case VertexShader:
Jiawei Shao385b3e02018-03-21 09:43:28 +0800149 return programState.getAttachedShader(gl::ShaderType::Vertex);
Jamie Madill76e471e2017-10-21 09:56:01 -0400150 case FragmentShader:
Jiawei Shao385b3e02018-03-21 09:43:28 +0800151 return programState.getAttachedShader(gl::ShaderType::Fragment);
Jamie Madill76e471e2017-10-21 09:56:01 -0400152 default:
153 UNREACHABLE();
154 return nullptr;
155 }
156}
157
158} // anonymous namespace
159
160ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
Luc Ferron7a06ac12018-03-15 10:17:04 -0400161 : storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
162 kUniformBlockStreamingBufferMinSize),
163 uniformData(),
164 uniformsDirty(false),
165 uniformLayout()
Jamie Madill76e471e2017-10-21 09:56:01 -0400166{
167}
168
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500169ProgramVk::DefaultUniformBlock::~DefaultUniformBlock()
170{
171}
172
Jamie Madill76e471e2017-10-21 09:56:01 -0400173ProgramVk::ProgramVk(const gl::ProgramState &state)
Luc Ferron7a06ac12018-03-15 10:17:04 -0400174 : ProgramImpl(state),
175 mDefaultUniformBlocks(),
176 mUniformBlocksOffsets(),
177 mUsedDescriptorSetRange(),
178 mDirtyTextures(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400179{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400180 mUniformBlocksOffsets.fill(0);
Jamie Madill8c3988c2017-12-21 14:44:56 -0500181 mUsedDescriptorSetRange.invalidate();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400182}
183
184ProgramVk::~ProgramVk()
185{
186}
187
Jamie Madillb7d924a2018-03-10 11:16:54 -0500188gl::Error ProgramVk::destroy(const gl::Context *contextImpl)
Jamie Madill5deea722017-02-16 10:44:46 -0500189{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500190 ContextVk *contextVk = vk::GetImpl(contextImpl);
Jamie Madillb7d924a2018-03-10 11:16:54 -0500191 return reset(contextVk);
Jamie Madillc5143482017-10-15 20:20:06 -0400192}
Jamie Madill5deea722017-02-16 10:44:46 -0500193
Jamie Madillb7d924a2018-03-10 11:16:54 -0500194vk::Error ProgramVk::reset(ContextVk *contextVk)
Jamie Madillc5143482017-10-15 20:20:06 -0400195{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500196 // TODO(jmadill): Handle re-linking a program that is in-use. http://anglebug.com/2397
197
198 VkDevice device = contextVk->getDevice();
199
Jamie Madill76e471e2017-10-21 09:56:01 -0400200 for (auto &uniformBlock : mDefaultUniformBlocks)
201 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400202 uniformBlock.storage.destroy(device);
Jamie Madill76e471e2017-10-21 09:56:01 -0400203 }
204
205 mEmptyUniformBlockStorage.memory.destroy(device);
206 mEmptyUniformBlockStorage.buffer.destroy(device);
207
Jamie Madill5deea722017-02-16 10:44:46 -0500208 mLinkedFragmentModule.destroy(device);
209 mLinkedVertexModule.destroy(device);
Jamie Madillf2f6d372018-01-10 21:37:23 -0500210 mVertexModuleSerial = Serial();
211 mFragmentModuleSerial = Serial();
Jamie Madill76e471e2017-10-21 09:56:01 -0400212
Jamie Madill5547b382017-10-23 18:16:01 -0400213 mDescriptorSets.clear();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500214 mUsedDescriptorSetRange.invalidate();
Jamie Madill5547b382017-10-23 18:16:01 -0400215 mDirtyTextures = false;
Jamie Madillb7d924a2018-03-10 11:16:54 -0500216
217 return vk::NoError();
Jamie Madill5deea722017-02-16 10:44:46 -0500218}
219
Jamie Madill9cf9e872017-06-05 12:59:25 -0400220gl::LinkResult ProgramVk::load(const gl::Context *contextImpl,
221 gl::InfoLog &infoLog,
222 gl::BinaryInputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400223{
224 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500225 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400226}
227
Jamie Madill27a60632017-06-30 15:12:01 -0400228void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400229{
230 UNIMPLEMENTED();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400231}
232
233void ProgramVk::setBinaryRetrievableHint(bool retrievable)
234{
235 UNIMPLEMENTED();
236}
237
Yunchao He61afff12017-03-14 15:34:03 +0800238void ProgramVk::setSeparable(bool separable)
239{
240 UNIMPLEMENTED();
241}
242
Jamie Madill9cf9e872017-06-05 12:59:25 -0400243gl::LinkResult ProgramVk::link(const gl::Context *glContext,
Jamie Madillc9727f32017-11-07 12:37:07 -0500244 const gl::ProgramLinkedResources &resources,
Jamie Madill9cf9e872017-06-05 12:59:25 -0400245 gl::InfoLog &infoLog)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400246{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400247 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madillc5143482017-10-15 20:20:06 -0400248 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500249 GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
Jamie Madillc5143482017-10-15 20:20:06 -0400250 VkDevice device = renderer->getDevice();
251
Jamie Madillb7d924a2018-03-10 11:16:54 -0500252 ANGLE_TRY(reset(contextVk));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500253
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500254 std::vector<uint32_t> vertexCode;
255 std::vector<uint32_t> fragmentCode;
256 bool linkSuccess = false;
Jamie Madill4dd167f2017-11-09 13:08:31 -0500257 ANGLE_TRY_RESULT(
258 glslangWrapper->linkProgram(glContext, mState, resources, &vertexCode, &fragmentCode),
259 linkSuccess);
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500260 if (!linkSuccess)
261 {
262 return false;
263 }
264
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500265 {
266 VkShaderModuleCreateInfo vertexShaderInfo;
267 vertexShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
268 vertexShaderInfo.pNext = nullptr;
269 vertexShaderInfo.flags = 0;
270 vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t);
271 vertexShaderInfo.pCode = vertexCode.data();
Jamie Madillc5143482017-10-15 20:20:06 -0400272
273 ANGLE_TRY(mLinkedVertexModule.init(device, vertexShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500274 mVertexModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500275 }
276
277 {
278 VkShaderModuleCreateInfo fragmentShaderInfo;
279 fragmentShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
280 fragmentShaderInfo.pNext = nullptr;
281 fragmentShaderInfo.flags = 0;
282 fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t);
283 fragmentShaderInfo.pCode = fragmentCode.data();
284
Jamie Madillc5143482017-10-15 20:20:06 -0400285 ANGLE_TRY(mLinkedFragmentModule.init(device, fragmentShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500286 mFragmentModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500287 }
288
Jamie Madill76e471e2017-10-21 09:56:01 -0400289 ANGLE_TRY(initDefaultUniformBlocks(glContext));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500290
Jamie Madill8c3988c2017-12-21 14:44:56 -0500291 if (!mState.getSamplerUniformRange().empty())
292 {
293 // Ensure the descriptor set range includes the textures at position 1.
294 mUsedDescriptorSetRange.extend(1);
295 mDirtyTextures = true;
296 }
297
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500298 return true;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400299}
300
Jamie Madill76e471e2017-10-21 09:56:01 -0400301gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
302{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400303 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madill57fbfd82018-02-14 12:45:34 -0500304 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400305 VkDevice device = contextVk->getDevice();
306
307 // Process vertex and fragment uniforms into std140 packing.
Luc Ferron7a06ac12018-03-15 10:17:04 -0400308 std::array<sh::BlockLayoutMap, MaxShaderIndex> layoutMap;
309 std::array<size_t, MaxShaderIndex> requiredBufferSize = {{0, 0}};
Jamie Madill76e471e2017-10-21 09:56:01 -0400310
311 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
312 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400313 ANGLE_TRY(InitDefaultUniformBlock(glContext, GetShader(mState, shaderIndex),
Jamie Madill76e471e2017-10-21 09:56:01 -0400314 &layoutMap[shaderIndex],
315 &requiredBufferSize[shaderIndex]));
316 }
317
318 // Init the default block layout info.
319 const auto &locations = mState.getUniformLocations();
320 const auto &uniforms = mState.getUniforms();
321 for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex)
322 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400323 std::array<sh::BlockMemberInfo, MaxShaderIndex> layoutInfo;
Jamie Madill76e471e2017-10-21 09:56:01 -0400324
325 const auto &location = locations[locationIndex];
326 if (location.used() && !location.ignored)
327 {
Jamie Madillde03e002017-10-21 14:04:20 -0400328 const auto &uniform = uniforms[location.index];
329
330 if (uniform.isSampler())
331 continue;
332
Jamie Madill76e471e2017-10-21 09:56:01 -0400333 std::string uniformName = uniform.name;
334 if (uniform.isArray())
335 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400336 // Gets the uniform name without the [0] at the end.
337 uniformName = gl::ParseResourceName(uniformName, nullptr);
Jamie Madill76e471e2017-10-21 09:56:01 -0400338 }
339
340 bool found = false;
341
342 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
343 {
344 auto it = layoutMap[shaderIndex].find(uniformName);
345 if (it != layoutMap[shaderIndex].end())
346 {
347 found = true;
348 layoutInfo[shaderIndex] = it->second;
349 }
350 }
351
352 ASSERT(found);
353 }
354
355 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
356 {
357 mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]);
358 }
359 }
360
361 bool anyDirty = false;
362 bool allDirty = true;
363
364 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
365 {
366 if (requiredBufferSize[shaderIndex] > 0)
367 {
368 if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize(
369 requiredBufferSize[shaderIndex]))
370 {
371 return gl::OutOfMemory() << "Memory allocation failure.";
372 }
Luc Ferron7a06ac12018-03-15 10:17:04 -0400373 size_t minAlignment = static_cast<size_t>(
374 renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
375
376 mDefaultUniformBlocks[shaderIndex].storage.init(minAlignment);
377
378 // Initialize uniform buffer memory to zero by default.
Jamie Madill76e471e2017-10-21 09:56:01 -0400379 mDefaultUniformBlocks[shaderIndex].uniformData.fill(0);
380 mDefaultUniformBlocks[shaderIndex].uniformsDirty = true;
381
382 anyDirty = true;
383 }
384 else
385 {
386 allDirty = false;
387 }
388 }
389
390 if (anyDirty)
391 {
392 // Initialize the "empty" uniform block if necessary.
393 if (!allDirty)
394 {
395 VkBufferCreateInfo uniformBufferInfo;
396 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
397 uniformBufferInfo.pNext = nullptr;
398 uniformBufferInfo.flags = 0;
399 uniformBufferInfo.size = 1;
400 uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
401 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
402 uniformBufferInfo.queueFamilyIndexCount = 0;
403 uniformBufferInfo.pQueueFamilyIndices = nullptr;
404
405 ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo));
406
Luc Ferron7a06ac12018-03-15 10:17:04 -0400407 // Assume host visible/coherent memory available.
Jamie Madill57dd97a2018-02-06 17:10:49 -0500408 VkMemoryPropertyFlags flags =
409 (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Jamie Madill76e471e2017-10-21 09:56:01 -0400410 size_t requiredSize = 0;
Jamie Madill57fbfd82018-02-14 12:45:34 -0500411 ANGLE_TRY(AllocateBufferMemory(renderer, flags, &mEmptyUniformBlockStorage.buffer,
Jamie Madill76e471e2017-10-21 09:56:01 -0400412 &mEmptyUniformBlockStorage.memory, &requiredSize));
413 }
414
Jamie Madill8c3988c2017-12-21 14:44:56 -0500415 // Ensure the descriptor set range includes the uniform buffers at position 0.
416 mUsedDescriptorSetRange.extend(0);
Jamie Madill5547b382017-10-23 18:16:01 -0400417 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400418
419 return gl::NoError();
420}
421
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400422GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
423{
424 UNIMPLEMENTED();
425 return GLboolean();
426}
427
Jamie Madill76e471e2017-10-21 09:56:01 -0400428template <typename T>
429void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType)
430{
431 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
432 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
433
Luc Ferron7cec3352018-03-13 13:29:34 -0400434 if (linkedUniform.isSampler())
435 {
436 UNIMPLEMENTED();
437 return;
438 }
439
Luc Ferron24a31372018-04-04 11:49:14 -0400440 if (linkedUniform.typeInfo->type == entryPointType)
Jamie Madill76e471e2017-10-21 09:56:01 -0400441 {
Luc Ferron24a31372018-04-04 11:49:14 -0400442 for (auto &uniformBlock : mDefaultUniformBlocks)
Jamie Madill76e471e2017-10-21 09:56:01 -0400443 {
Luc Ferron24a31372018-04-04 11:49:14 -0400444 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
Luc Ferron62059a52018-03-29 07:01:35 -0400445
Luc Ferron24a31372018-04-04 11:49:14 -0400446 // Assume an offset of -1 means the block is unused.
447 if (layoutInfo.offset == -1)
448 {
449 continue;
450 }
451
452 const GLint componentCount = linkedUniform.typeInfo->componentCount;
Luc Ferron62059a52018-03-29 07:01:35 -0400453 UpdateDefaultUniformBlock(count, locationInfo.arrayIndex, componentCount, v, layoutInfo,
454 &uniformBlock.uniformData);
Luc Ferron24a31372018-04-04 11:49:14 -0400455 uniformBlock.uniformsDirty = true;
Luc Ferron62059a52018-03-29 07:01:35 -0400456 }
Luc Ferron24a31372018-04-04 11:49:14 -0400457 }
458 else
459 {
460 for (auto &uniformBlock : mDefaultUniformBlocks)
Luc Ferron62059a52018-03-29 07:01:35 -0400461 {
Luc Ferron24a31372018-04-04 11:49:14 -0400462 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
463
464 // Assume an offset of -1 means the block is unused.
465 if (layoutInfo.offset == -1)
466 {
467 continue;
468 }
469
470 const GLint componentCount = linkedUniform.typeInfo->componentCount;
471
Luc Ferron62059a52018-03-29 07:01:35 -0400472 ASSERT(linkedUniform.typeInfo->type == gl::VariableBoolVectorType(entryPointType));
473
474 GLint initialArrayOffset = locationInfo.arrayIndex * layoutInfo.arrayStride;
475 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.
Luc Ferrondaedf4d2018-03-16 09:28:53 -0400706 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;
758 ANGLE_TRY(SyncDefaultUniformBlock(contextVk, uniformBlock.storage,
759 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.
Luc Ferron6ea1b412018-03-21 16:13:01 -0400774 ANGLE_TRY(allocateDescriptorSet(contextVk, 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
Luc Ferron6ea1b412018-03-21 16:13:01 -0400860 ANGLE_TRY(allocateDescriptorSet(contextVk, TextureIndex));
861
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 {
929 block.storage.setMinimumSize(minSize);
930 }
931}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400932} // namespace rx