blob: a3a7c36000af940ddc9c070122c82a40576c3ec1 [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"
Jamie Madill5547b382017-10-23 18:16:01 -040019#include "libANGLE/renderer/vulkan/TextureVk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040020
21namespace rx
22{
23
Jamie Madill76e471e2017-10-21 09:56:01 -040024namespace
25{
26
Jamie Madillf3614372018-03-31 14:19:14 -040027constexpr size_t kUniformBlockDynamicBufferMinSize = 256 * 128;
Luc Ferron7a06ac12018-03-15 10:17:04 -040028
Jamie Madill76e471e2017-10-21 09:56:01 -040029gl::Error InitDefaultUniformBlock(const gl::Context *context,
Jamie Madill76e471e2017-10-21 09:56:01 -040030 gl::Shader *shader,
Jamie Madill76e471e2017-10-21 09:56:01 -040031 sh::BlockLayoutMap *blockLayoutMapOut,
Luc Ferron7a06ac12018-03-15 10:17:04 -040032 size_t *blockSizeOut)
Jamie Madill76e471e2017-10-21 09:56:01 -040033{
34 const auto &uniforms = shader->getUniforms(context);
35
36 if (uniforms.empty())
37 {
Luc Ferron7a06ac12018-03-15 10:17:04 -040038 *blockSizeOut = 0;
Jamie Madill76e471e2017-10-21 09:56:01 -040039 return gl::NoError();
40 }
41
42 sh::Std140BlockEncoder blockEncoder;
Olli Etuaho3de27032017-11-30 12:16:47 +020043 sh::GetUniformBlockInfo(uniforms, "", &blockEncoder, blockLayoutMapOut);
Jamie Madill76e471e2017-10-21 09:56:01 -040044
45 size_t blockSize = blockEncoder.getBlockSize();
46
47 // TODO(jmadill): I think we still need a valid block for the pipeline even if zero sized.
48 if (blockSize == 0)
49 {
Luc Ferron7a06ac12018-03-15 10:17:04 -040050 *blockSizeOut = 0;
Jamie Madill76e471e2017-10-21 09:56:01 -040051 return gl::NoError();
52 }
53
Luc Ferron7a06ac12018-03-15 10:17:04 -040054 *blockSizeOut = blockSize;
Jamie Madill76e471e2017-10-21 09:56:01 -040055 return gl::NoError();
56}
57
58template <typename T>
59void UpdateDefaultUniformBlock(GLsizei count,
Luc Ferron2371aca2018-03-27 16:03:03 -040060 uint32_t arrayIndex,
Jamie Madill76e471e2017-10-21 09:56:01 -040061 int componentCount,
62 const T *v,
63 const sh::BlockMemberInfo &layoutInfo,
64 angle::MemoryBuffer *uniformData)
65{
Luc Ferron2371aca2018-03-27 16:03:03 -040066 const int elementSize = sizeof(T) * componentCount;
67
68 uint8_t *dst = uniformData->data() + layoutInfo.offset;
Jamie Madill76e471e2017-10-21 09:56:01 -040069 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
70 {
Luc Ferron2371aca2018-03-27 16:03:03 -040071 uint32_t arrayOffset = arrayIndex * layoutInfo.arrayStride;
72 uint8_t *writePtr = dst + arrayOffset;
Jamie Madill76e471e2017-10-21 09:56:01 -040073 memcpy(writePtr, v, elementSize * count);
74 }
75 else
76 {
Luc Ferron2371aca2018-03-27 16:03:03 -040077 // Have to respect the arrayStride between each element of the array.
78 int maxIndex = arrayIndex + count;
79 for (int writeIndex = arrayIndex, readIndex = 0; writeIndex < maxIndex;
80 writeIndex++, readIndex++)
81 {
82 const int arrayOffset = writeIndex * layoutInfo.arrayStride;
83 uint8_t *writePtr = dst + arrayOffset;
84 const T *readPtr = v + readIndex;
85 memcpy(writePtr, readPtr, elementSize);
86 }
Jamie Madill76e471e2017-10-21 09:56:01 -040087 }
88}
89
Luc Ferron7cec3352018-03-13 13:29:34 -040090template <typename T>
91void ReadFromDefaultUniformBlock(int componentCount,
Luc Ferron2371aca2018-03-27 16:03:03 -040092 uint32_t arrayIndex,
Luc Ferron7cec3352018-03-13 13:29:34 -040093 T *dst,
94 const sh::BlockMemberInfo &layoutInfo,
95 const angle::MemoryBuffer *uniformData)
96{
97 ASSERT(layoutInfo.offset != -1);
98
Luc Ferron2371aca2018-03-27 16:03:03 -040099 const int elementSize = sizeof(T) * componentCount;
100 const uint8_t *source = uniformData->data() + layoutInfo.offset;
101
Luc Ferron7cec3352018-03-13 13:29:34 -0400102 if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
103 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400104 const uint8_t *readPtr = source + arrayIndex * layoutInfo.arrayStride;
Luc Ferron7cec3352018-03-13 13:29:34 -0400105 memcpy(dst, readPtr, elementSize);
106 }
107 else
108 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400109 // Have to respect the arrayStride between each element of the array.
110 const int arrayOffset = arrayIndex * layoutInfo.arrayStride;
111 const uint8_t *readPtr = source + arrayOffset;
112 memcpy(dst, readPtr, elementSize);
Luc Ferron7cec3352018-03-13 13:29:34 -0400113 }
114}
115
Jamie Madillc3755fc2018-04-05 08:39:13 -0400116vk::Error SyncDefaultUniformBlock(RendererVk *renderer,
117 DynamicBuffer *dynamicBuffer,
Luc Ferron7a06ac12018-03-15 10:17:04 -0400118 const angle::MemoryBuffer &bufferData,
119 uint32_t *outOffset,
120 bool *outBufferModified)
Jamie Madill76e471e2017-10-21 09:56:01 -0400121{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400122 ASSERT(!bufferData.empty());
123 uint8_t *data = nullptr;
124 VkBuffer *outBuffer = nullptr;
125 uint32_t offset;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400126 ANGLE_TRY(dynamicBuffer->allocate(renderer, bufferData.size(), &data, outBuffer, &offset,
127 outBufferModified));
Luc Ferron7a06ac12018-03-15 10:17:04 -0400128 *outOffset = offset;
129 memcpy(data, bufferData.data(), bufferData.size());
Jamie Madillc3755fc2018-04-05 08:39:13 -0400130 ANGLE_TRY(dynamicBuffer->flush(renderer->getDevice()));
Jamie Madill76e471e2017-10-21 09:56:01 -0400131 return vk::NoError();
132}
133
Jiawei Shao385b3e02018-03-21 09:43:28 +0800134// TODO(jiawei.shao@intel.com): Fully remove this enum by gl::ShaderType. (BUG=angleproject:2169)
Jamie Madill76e471e2017-10-21 09:56:01 -0400135enum ShaderIndex : uint32_t
136{
137 MinShaderIndex = 0,
138 VertexShader = MinShaderIndex,
139 FragmentShader = 1,
Luc Ferron7a06ac12018-03-15 10:17:04 -0400140 MaxShaderIndex = kShaderTypeCount,
Jamie Madill76e471e2017-10-21 09:56:01 -0400141};
142
143gl::Shader *GetShader(const gl::ProgramState &programState, uint32_t shaderIndex)
144{
145 switch (shaderIndex)
146 {
147 case VertexShader:
Jiawei Shao385b3e02018-03-21 09:43:28 +0800148 return programState.getAttachedShader(gl::ShaderType::Vertex);
Jamie Madill76e471e2017-10-21 09:56:01 -0400149 case FragmentShader:
Jiawei Shao385b3e02018-03-21 09:43:28 +0800150 return programState.getAttachedShader(gl::ShaderType::Fragment);
Jamie Madill76e471e2017-10-21 09:56:01 -0400151 default:
152 UNREACHABLE();
153 return nullptr;
154 }
155}
156
157} // anonymous namespace
158
159ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
Luc Ferron7a06ac12018-03-15 10:17:04 -0400160 : storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
Jamie Madillf3614372018-03-31 14:19:14 -0400161 kUniformBlockDynamicBufferMinSize),
Luc Ferron7a06ac12018-03-15 10:17:04 -0400162 uniformData(),
163 uniformsDirty(false),
164 uniformLayout()
Jamie Madill76e471e2017-10-21 09:56:01 -0400165{
166}
167
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500168ProgramVk::DefaultUniformBlock::~DefaultUniformBlock()
169{
170}
171
Jamie Madill76e471e2017-10-21 09:56:01 -0400172ProgramVk::ProgramVk(const gl::ProgramState &state)
Luc Ferron7a06ac12018-03-15 10:17:04 -0400173 : ProgramImpl(state),
174 mDefaultUniformBlocks(),
175 mUniformBlocksOffsets(),
176 mUsedDescriptorSetRange(),
177 mDirtyTextures(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400178{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400179 mUniformBlocksOffsets.fill(0);
Jamie Madill8c3988c2017-12-21 14:44:56 -0500180 mUsedDescriptorSetRange.invalidate();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400181}
182
183ProgramVk::~ProgramVk()
184{
185}
186
Jamie Madillb7d924a2018-03-10 11:16:54 -0500187gl::Error ProgramVk::destroy(const gl::Context *contextImpl)
Jamie Madill5deea722017-02-16 10:44:46 -0500188{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500189 ContextVk *contextVk = vk::GetImpl(contextImpl);
Jamie Madillb7d924a2018-03-10 11:16:54 -0500190 return reset(contextVk);
Jamie Madillc5143482017-10-15 20:20:06 -0400191}
Jamie Madill5deea722017-02-16 10:44:46 -0500192
Jamie Madillb7d924a2018-03-10 11:16:54 -0500193vk::Error ProgramVk::reset(ContextVk *contextVk)
Jamie Madillc5143482017-10-15 20:20:06 -0400194{
Jamie Madill67ae6c52018-03-09 11:49:01 -0500195 // TODO(jmadill): Handle re-linking a program that is in-use. http://anglebug.com/2397
196
197 VkDevice device = contextVk->getDevice();
198
Jamie Madill76e471e2017-10-21 09:56:01 -0400199 for (auto &uniformBlock : mDefaultUniformBlocks)
200 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400201 uniformBlock.storage.destroy(device);
Jamie Madill76e471e2017-10-21 09:56:01 -0400202 }
203
204 mEmptyUniformBlockStorage.memory.destroy(device);
205 mEmptyUniformBlockStorage.buffer.destroy(device);
206
Jamie Madill5deea722017-02-16 10:44:46 -0500207 mLinkedFragmentModule.destroy(device);
208 mLinkedVertexModule.destroy(device);
Jamie Madillf2f6d372018-01-10 21:37:23 -0500209 mVertexModuleSerial = Serial();
210 mFragmentModuleSerial = Serial();
Jamie Madill76e471e2017-10-21 09:56:01 -0400211
Jamie Madill5547b382017-10-23 18:16:01 -0400212 mDescriptorSets.clear();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500213 mUsedDescriptorSetRange.invalidate();
Jamie Madill5547b382017-10-23 18:16:01 -0400214 mDirtyTextures = false;
Jamie Madillb7d924a2018-03-10 11:16:54 -0500215
216 return vk::NoError();
Jamie Madill5deea722017-02-16 10:44:46 -0500217}
218
Jamie Madill9cf9e872017-06-05 12:59:25 -0400219gl::LinkResult ProgramVk::load(const gl::Context *contextImpl,
220 gl::InfoLog &infoLog,
221 gl::BinaryInputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400222{
223 UNIMPLEMENTED();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500224 return gl::InternalError();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400225}
226
Jamie Madill27a60632017-06-30 15:12:01 -0400227void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400228{
229 UNIMPLEMENTED();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400230}
231
232void ProgramVk::setBinaryRetrievableHint(bool retrievable)
233{
234 UNIMPLEMENTED();
235}
236
Yunchao He61afff12017-03-14 15:34:03 +0800237void ProgramVk::setSeparable(bool separable)
238{
239 UNIMPLEMENTED();
240}
241
Jamie Madill9cf9e872017-06-05 12:59:25 -0400242gl::LinkResult ProgramVk::link(const gl::Context *glContext,
Jamie Madillc9727f32017-11-07 12:37:07 -0500243 const gl::ProgramLinkedResources &resources,
Jamie Madill9cf9e872017-06-05 12:59:25 -0400244 gl::InfoLog &infoLog)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400245{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400246 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madillc5143482017-10-15 20:20:06 -0400247 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500248 GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
Jamie Madillc5143482017-10-15 20:20:06 -0400249 VkDevice device = renderer->getDevice();
250
Jamie Madillb7d924a2018-03-10 11:16:54 -0500251 ANGLE_TRY(reset(contextVk));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500252
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500253 std::vector<uint32_t> vertexCode;
254 std::vector<uint32_t> fragmentCode;
255 bool linkSuccess = false;
Jamie Madill4dd167f2017-11-09 13:08:31 -0500256 ANGLE_TRY_RESULT(
257 glslangWrapper->linkProgram(glContext, mState, resources, &vertexCode, &fragmentCode),
258 linkSuccess);
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500259 if (!linkSuccess)
260 {
261 return false;
262 }
263
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500264 {
265 VkShaderModuleCreateInfo vertexShaderInfo;
266 vertexShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
267 vertexShaderInfo.pNext = nullptr;
268 vertexShaderInfo.flags = 0;
269 vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t);
270 vertexShaderInfo.pCode = vertexCode.data();
Jamie Madillc5143482017-10-15 20:20:06 -0400271
272 ANGLE_TRY(mLinkedVertexModule.init(device, vertexShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500273 mVertexModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500274 }
275
276 {
277 VkShaderModuleCreateInfo fragmentShaderInfo;
278 fragmentShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
279 fragmentShaderInfo.pNext = nullptr;
280 fragmentShaderInfo.flags = 0;
281 fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t);
282 fragmentShaderInfo.pCode = fragmentCode.data();
283
Jamie Madillc5143482017-10-15 20:20:06 -0400284 ANGLE_TRY(mLinkedFragmentModule.init(device, fragmentShaderInfo));
Jamie Madillf2f6d372018-01-10 21:37:23 -0500285 mFragmentModuleSerial = renderer->issueProgramSerial();
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500286 }
287
Jamie Madill76e471e2017-10-21 09:56:01 -0400288 ANGLE_TRY(initDefaultUniformBlocks(glContext));
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500289
Jamie Madill8c3988c2017-12-21 14:44:56 -0500290 if (!mState.getSamplerUniformRange().empty())
291 {
292 // Ensure the descriptor set range includes the textures at position 1.
293 mUsedDescriptorSetRange.extend(1);
294 mDirtyTextures = true;
295 }
296
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500297 return true;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400298}
299
Jamie Madill76e471e2017-10-21 09:56:01 -0400300gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
301{
Jamie Madille1f3ad42017-10-28 23:00:42 -0400302 ContextVk *contextVk = vk::GetImpl(glContext);
Jamie Madill57fbfd82018-02-14 12:45:34 -0500303 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400304 VkDevice device = contextVk->getDevice();
305
306 // Process vertex and fragment uniforms into std140 packing.
Luc Ferron7a06ac12018-03-15 10:17:04 -0400307 std::array<sh::BlockLayoutMap, MaxShaderIndex> layoutMap;
308 std::array<size_t, MaxShaderIndex> requiredBufferSize = {{0, 0}};
Jamie Madill76e471e2017-10-21 09:56:01 -0400309
310 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
311 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400312 ANGLE_TRY(InitDefaultUniformBlock(glContext, GetShader(mState, shaderIndex),
Jamie Madill76e471e2017-10-21 09:56:01 -0400313 &layoutMap[shaderIndex],
314 &requiredBufferSize[shaderIndex]));
315 }
316
317 // Init the default block layout info.
318 const auto &locations = mState.getUniformLocations();
319 const auto &uniforms = mState.getUniforms();
320 for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex)
321 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400322 std::array<sh::BlockMemberInfo, MaxShaderIndex> layoutInfo;
Jamie Madill76e471e2017-10-21 09:56:01 -0400323
324 const auto &location = locations[locationIndex];
325 if (location.used() && !location.ignored)
326 {
Jamie Madillde03e002017-10-21 14:04:20 -0400327 const auto &uniform = uniforms[location.index];
328
329 if (uniform.isSampler())
330 continue;
331
Jamie Madill76e471e2017-10-21 09:56:01 -0400332 std::string uniformName = uniform.name;
333 if (uniform.isArray())
334 {
Luc Ferron2371aca2018-03-27 16:03:03 -0400335 // Gets the uniform name without the [0] at the end.
336 uniformName = gl::ParseResourceName(uniformName, nullptr);
Jamie Madill76e471e2017-10-21 09:56:01 -0400337 }
338
339 bool found = false;
340
341 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
342 {
343 auto it = layoutMap[shaderIndex].find(uniformName);
344 if (it != layoutMap[shaderIndex].end())
345 {
346 found = true;
347 layoutInfo[shaderIndex] = it->second;
348 }
349 }
350
351 ASSERT(found);
352 }
353
354 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
355 {
356 mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]);
357 }
358 }
359
360 bool anyDirty = false;
361 bool allDirty = true;
362
363 for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
364 {
365 if (requiredBufferSize[shaderIndex] > 0)
366 {
367 if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize(
368 requiredBufferSize[shaderIndex]))
369 {
370 return gl::OutOfMemory() << "Memory allocation failure.";
371 }
Luc Ferron7a06ac12018-03-15 10:17:04 -0400372 size_t minAlignment = static_cast<size_t>(
373 renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
374
375 mDefaultUniformBlocks[shaderIndex].storage.init(minAlignment);
376
377 // Initialize uniform buffer memory to zero by default.
Jamie Madill76e471e2017-10-21 09:56:01 -0400378 mDefaultUniformBlocks[shaderIndex].uniformData.fill(0);
379 mDefaultUniformBlocks[shaderIndex].uniformsDirty = true;
380
381 anyDirty = true;
382 }
383 else
384 {
385 allDirty = false;
386 }
387 }
388
389 if (anyDirty)
390 {
391 // Initialize the "empty" uniform block if necessary.
392 if (!allDirty)
393 {
394 VkBufferCreateInfo uniformBufferInfo;
395 uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
396 uniformBufferInfo.pNext = nullptr;
397 uniformBufferInfo.flags = 0;
398 uniformBufferInfo.size = 1;
399 uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
400 uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
401 uniformBufferInfo.queueFamilyIndexCount = 0;
402 uniformBufferInfo.pQueueFamilyIndices = nullptr;
403
404 ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo));
405
Luc Ferron7a06ac12018-03-15 10:17:04 -0400406 // Assume host visible/coherent memory available.
Jamie Madill57dd97a2018-02-06 17:10:49 -0500407 VkMemoryPropertyFlags flags =
408 (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
Jamie Madill76e471e2017-10-21 09:56:01 -0400409 size_t requiredSize = 0;
Jamie Madill57fbfd82018-02-14 12:45:34 -0500410 ANGLE_TRY(AllocateBufferMemory(renderer, flags, &mEmptyUniformBlockStorage.buffer,
Jamie Madill76e471e2017-10-21 09:56:01 -0400411 &mEmptyUniformBlockStorage.memory, &requiredSize));
412 }
413
Jamie Madill8c3988c2017-12-21 14:44:56 -0500414 // Ensure the descriptor set range includes the uniform buffers at position 0.
415 mUsedDescriptorSetRange.extend(0);
Jamie Madill5547b382017-10-23 18:16:01 -0400416 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400417
418 return gl::NoError();
419}
420
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400421GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
422{
423 UNIMPLEMENTED();
424 return GLboolean();
425}
426
Jamie Madill76e471e2017-10-21 09:56:01 -0400427template <typename T>
428void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType)
429{
430 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
431 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
432
Luc Ferron7cec3352018-03-13 13:29:34 -0400433 if (linkedUniform.isSampler())
434 {
435 UNIMPLEMENTED();
436 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
473 GLint initialArrayOffset = locationInfo.arrayIndex * layoutInfo.arrayStride;
474 for (GLint i = 0; i < count; i++)
475 {
476 GLint elementOffset = i * layoutInfo.arrayStride + initialArrayOffset;
477 GLint *dest =
478 reinterpret_cast<GLint *>(uniformBlock.uniformData.data() + elementOffset);
479 const T *source = v + i * componentCount;
480
481 for (int c = 0; c < componentCount; c++)
482 {
483 dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
484 }
485 }
Luc Ferron24a31372018-04-04 11:49:14 -0400486 uniformBlock.uniformsDirty = true;
Luc Ferron62059a52018-03-29 07:01:35 -0400487 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400488 }
489}
490
Luc Ferron7cec3352018-03-13 13:29:34 -0400491template <typename T>
492void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) const
493{
494 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
495 const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
496
497 if (linkedUniform.isSampler())
498 {
499 UNIMPLEMENTED();
500 return;
501 }
502
Olli Etuaho107c7242018-03-20 15:45:35 +0200503 const gl::ShaderType shaderType = linkedUniform.getFirstShaderTypeWhereActive();
Jiawei Shao385b3e02018-03-21 09:43:28 +0800504 ASSERT(shaderType != gl::ShaderType::InvalidEnum);
Luc Ferron7cec3352018-03-13 13:29:34 -0400505
Jiawei Shao385b3e02018-03-21 09:43:28 +0800506 const DefaultUniformBlock &uniformBlock =
507 mDefaultUniformBlocks[static_cast<GLuint>(shaderType)];
Luc Ferron7cec3352018-03-13 13:29:34 -0400508 const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
Luc Ferron62059a52018-03-29 07:01:35 -0400509
510 ASSERT(linkedUniform.typeInfo->componentType == entryPointType ||
511 linkedUniform.typeInfo->componentType == gl::VariableBoolVectorType(entryPointType));
Luc Ferron2371aca2018-03-27 16:03:03 -0400512 ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, locationInfo.arrayIndex, v,
513 layoutInfo, &uniformBlock.uniformData);
Luc Ferron7cec3352018-03-13 13:29:34 -0400514}
515
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400516void ProgramVk::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
517{
Jamie Madill76e471e2017-10-21 09:56:01 -0400518 setUniformImpl(location, count, v, GL_FLOAT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400519}
520
521void ProgramVk::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
522{
Jamie Madill76e471e2017-10-21 09:56:01 -0400523 setUniformImpl(location, count, v, GL_FLOAT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400524}
525
526void ProgramVk::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
527{
Jamie Madill76e471e2017-10-21 09:56:01 -0400528 setUniformImpl(location, count, v, GL_FLOAT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400529}
530
531void ProgramVk::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
532{
Jamie Madill76e471e2017-10-21 09:56:01 -0400533 setUniformImpl(location, count, v, GL_FLOAT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400534}
535
536void ProgramVk::setUniform1iv(GLint location, GLsizei count, const GLint *v)
537{
Luc Ferron7cec3352018-03-13 13:29:34 -0400538 setUniformImpl(location, count, v, GL_INT);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400539}
540
541void ProgramVk::setUniform2iv(GLint location, GLsizei count, const GLint *v)
542{
Luc Ferron489243f2018-03-28 16:55:28 -0400543 setUniformImpl(location, count, v, GL_INT_VEC2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400544}
545
546void ProgramVk::setUniform3iv(GLint location, GLsizei count, const GLint *v)
547{
Luc Ferron489243f2018-03-28 16:55:28 -0400548 setUniformImpl(location, count, v, GL_INT_VEC3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400549}
550
551void ProgramVk::setUniform4iv(GLint location, GLsizei count, const GLint *v)
552{
Luc Ferron489243f2018-03-28 16:55:28 -0400553 setUniformImpl(location, count, v, GL_INT_VEC4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400554}
555
556void ProgramVk::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
557{
558 UNIMPLEMENTED();
559}
560
561void ProgramVk::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
562{
563 UNIMPLEMENTED();
564}
565
566void ProgramVk::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
567{
568 UNIMPLEMENTED();
569}
570
571void ProgramVk::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
572{
573 UNIMPLEMENTED();
574}
575
576void ProgramVk::setUniformMatrix2fv(GLint location,
577 GLsizei count,
578 GLboolean transpose,
579 const GLfloat *value)
580{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400581 if (transpose == GL_TRUE)
582 {
583 UNIMPLEMENTED();
584 return;
585 }
586
587 setUniformImpl(location, count, value, GL_FLOAT_MAT2);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400588}
589
590void ProgramVk::setUniformMatrix3fv(GLint location,
591 GLsizei count,
592 GLboolean transpose,
593 const GLfloat *value)
594{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400595 if (transpose == GL_TRUE)
596 {
597 UNIMPLEMENTED();
598 return;
599 }
600 setUniformImpl(location, count, value, GL_FLOAT_MAT3);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400601}
602
603void ProgramVk::setUniformMatrix4fv(GLint location,
604 GLsizei count,
605 GLboolean transpose,
606 const GLfloat *value)
607{
Luc Ferron5b64aca2018-03-14 14:55:58 -0400608 if (transpose == GL_TRUE)
609 {
610 UNIMPLEMENTED();
611 return;
612 }
613
614 setUniformImpl(location, count, value, GL_FLOAT_MAT4);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400615}
616
617void ProgramVk::setUniformMatrix2x3fv(GLint location,
618 GLsizei count,
619 GLboolean transpose,
620 const GLfloat *value)
621{
622 UNIMPLEMENTED();
623}
624
625void ProgramVk::setUniformMatrix3x2fv(GLint location,
626 GLsizei count,
627 GLboolean transpose,
628 const GLfloat *value)
629{
630 UNIMPLEMENTED();
631}
632
633void ProgramVk::setUniformMatrix2x4fv(GLint location,
634 GLsizei count,
635 GLboolean transpose,
636 const GLfloat *value)
637{
638 UNIMPLEMENTED();
639}
640
641void ProgramVk::setUniformMatrix4x2fv(GLint location,
642 GLsizei count,
643 GLboolean transpose,
644 const GLfloat *value)
645{
646 UNIMPLEMENTED();
647}
648
649void ProgramVk::setUniformMatrix3x4fv(GLint location,
650 GLsizei count,
651 GLboolean transpose,
652 const GLfloat *value)
653{
654 UNIMPLEMENTED();
655}
656
657void ProgramVk::setUniformMatrix4x3fv(GLint location,
658 GLsizei count,
659 GLboolean transpose,
660 const GLfloat *value)
661{
662 UNIMPLEMENTED();
663}
664
665void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
666{
667 UNIMPLEMENTED();
668}
669
Sami Väisänen46eaa942016-06-29 10:26:37 +0300670void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
671 GLenum genMode,
672 GLint components,
673 const GLfloat *coeffs)
674{
675 UNIMPLEMENTED();
676}
677
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500678const vk::ShaderModule &ProgramVk::getLinkedVertexModule() const
679{
680 ASSERT(mLinkedVertexModule.getHandle() != VK_NULL_HANDLE);
681 return mLinkedVertexModule;
682}
683
Jamie Madillf2f6d372018-01-10 21:37:23 -0500684Serial ProgramVk::getVertexModuleSerial() const
685{
686 return mVertexModuleSerial;
687}
688
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500689const vk::ShaderModule &ProgramVk::getLinkedFragmentModule() const
690{
691 ASSERT(mLinkedFragmentModule.getHandle() != VK_NULL_HANDLE);
692 return mLinkedFragmentModule;
693}
694
Jamie Madillf2f6d372018-01-10 21:37:23 -0500695Serial ProgramVk::getFragmentModuleSerial() const
696{
697 return mFragmentModuleSerial;
698}
699
Luc Ferron6ea1b412018-03-21 16:13:01 -0400700vk::Error ProgramVk::allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex)
Jamie Madill76e471e2017-10-21 09:56:01 -0400701{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500702 RendererVk *renderer = contextVk->getRenderer();
Jamie Madill76e471e2017-10-21 09:56:01 -0400703
704 // Write out to a new a descriptor set.
Luc Ferrondaedf4d2018-03-16 09:28:53 -0400705 DynamicDescriptorPool *dynamicDescriptorPool = contextVk->getDynamicDescriptorPool();
Jamie Madill8c3988c2017-12-21 14:44:56 -0500706 const auto &descriptorSetLayouts = renderer->getGraphicsDescriptorSetLayouts();
Jamie Madill76e471e2017-10-21 09:56:01 -0400707
Luc Ferron6ea1b412018-03-21 16:13:01 -0400708 uint32_t potentialNewCount = descriptorSetIndex + 1;
709 if (potentialNewCount > mDescriptorSets.size())
710 {
711 mDescriptorSets.resize(potentialNewCount, VK_NULL_HANDLE);
712 }
Luc Ferron7a06ac12018-03-15 10:17:04 -0400713
Luc Ferron6ea1b412018-03-21 16:13:01 -0400714 const VkDescriptorSetLayout *descriptorSetLayout =
715 descriptorSetLayouts[descriptorSetIndex].ptr();
716
717 ANGLE_TRY(dynamicDescriptorPool->allocateDescriptorSets(contextVk, descriptorSetLayout, 1,
718 &mDescriptorSets[descriptorSetIndex]));
Jamie Madill76e471e2017-10-21 09:56:01 -0400719 return vk::NoError();
720}
721
Jamie Madill54164b02017-08-28 15:17:37 -0400722void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
723{
Luc Ferron7cec3352018-03-13 13:29:34 -0400724 getUniformImpl(location, params, GL_FLOAT);
Jamie Madill54164b02017-08-28 15:17:37 -0400725}
726
727void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
728{
Luc Ferron7cec3352018-03-13 13:29:34 -0400729 getUniformImpl(location, params, GL_INT);
Jamie Madill54164b02017-08-28 15:17:37 -0400730}
731
732void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
733{
734 UNIMPLEMENTED();
735}
736
Jamie Madill76e471e2017-10-21 09:56:01 -0400737vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
738{
739 if (!mDefaultUniformBlocks[VertexShader].uniformsDirty &&
740 !mDefaultUniformBlocks[FragmentShader].uniformsDirty)
741 {
742 return vk::NoError();
743 }
744
Jamie Madill8c3988c2017-12-21 14:44:56 -0500745 ASSERT(mUsedDescriptorSetRange.contains(0));
Jamie Madill5547b382017-10-23 18:16:01 -0400746
Jamie Madill76e471e2017-10-21 09:56:01 -0400747 // Update buffer memory by immediate mapping. This immediate update only works once.
748 // TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers.
Luc Ferron7a06ac12018-03-15 10:17:04 -0400749 bool anyNewBufferAllocated = false;
750 for (size_t index = 0; index < mDefaultUniformBlocks.size(); index++)
Jamie Madill76e471e2017-10-21 09:56:01 -0400751 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400752 DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[index];
753
Jamie Madill76e471e2017-10-21 09:56:01 -0400754 if (uniformBlock.uniformsDirty)
755 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400756 bool bufferModified = false;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400757 ANGLE_TRY(SyncDefaultUniformBlock(contextVk->getRenderer(), &uniformBlock.storage,
Luc Ferron7a06ac12018-03-15 10:17:04 -0400758 uniformBlock.uniformData,
759 &mUniformBlocksOffsets[index], &bufferModified));
Jamie Madill76e471e2017-10-21 09:56:01 -0400760 uniformBlock.uniformsDirty = false;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400761
762 if (bufferModified)
763 {
764 anyNewBufferAllocated = true;
765 }
Jamie Madill76e471e2017-10-21 09:56:01 -0400766 }
767 }
768
Luc Ferron7a06ac12018-03-15 10:17:04 -0400769 if (anyNewBufferAllocated)
770 {
771 // We need to reinitialize the descriptor sets if we newly allocated buffers since we can't
772 // modify the descriptor sets once initialized.
Luc Ferron6ea1b412018-03-21 16:13:01 -0400773 ANGLE_TRY(allocateDescriptorSet(contextVk, UniformBufferIndex));
Luc Ferron7a06ac12018-03-15 10:17:04 -0400774 ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk));
775 }
776
Jamie Madill76e471e2017-10-21 09:56:01 -0400777 return vk::NoError();
778}
779
780vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
781{
Luc Ferron7a06ac12018-03-15 10:17:04 -0400782 std::array<VkDescriptorBufferInfo, MaxShaderIndex> descriptorBufferInfo;
783 std::array<VkWriteDescriptorSet, MaxShaderIndex> writeDescriptorInfo;
Jamie Madill76e471e2017-10-21 09:56:01 -0400784 uint32_t bufferCount = 0;
785
786 for (auto &uniformBlock : mDefaultUniformBlocks)
787 {
788 auto &bufferInfo = descriptorBufferInfo[bufferCount];
Luc Ferron7a06ac12018-03-15 10:17:04 -0400789 auto &writeInfo = writeDescriptorInfo[bufferCount];
Jamie Madill76e471e2017-10-21 09:56:01 -0400790
791 if (!uniformBlock.uniformData.empty())
792 {
Luc Ferron7a06ac12018-03-15 10:17:04 -0400793 bufferInfo.buffer = uniformBlock.storage.getCurrentBufferHandle();
Jamie Madill76e471e2017-10-21 09:56:01 -0400794 }
795 else
796 {
797 bufferInfo.buffer = mEmptyUniformBlockStorage.buffer.getHandle();
798 }
799
800 bufferInfo.offset = 0;
801 bufferInfo.range = VK_WHOLE_SIZE;
802
Jamie Madill76e471e2017-10-21 09:56:01 -0400803 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
804 writeInfo.pNext = nullptr;
Jamie Madill5547b382017-10-23 18:16:01 -0400805 writeInfo.dstSet = mDescriptorSets[0];
Jamie Madill76e471e2017-10-21 09:56:01 -0400806 writeInfo.dstBinding = bufferCount;
807 writeInfo.dstArrayElement = 0;
808 writeInfo.descriptorCount = 1;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400809 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
Jamie Madill76e471e2017-10-21 09:56:01 -0400810 writeInfo.pImageInfo = nullptr;
811 writeInfo.pBufferInfo = &bufferInfo;
812 writeInfo.pTexelBufferView = nullptr;
813
814 bufferCount++;
815 }
816
817 VkDevice device = contextVk->getDevice();
818
819 vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr);
820
821 return vk::NoError();
822}
823
Jamie Madill5547b382017-10-23 18:16:01 -0400824const std::vector<VkDescriptorSet> &ProgramVk::getDescriptorSets() const
Jamie Madill76e471e2017-10-21 09:56:01 -0400825{
Jamie Madill5547b382017-10-23 18:16:01 -0400826 return mDescriptorSets;
827}
828
Luc Ferron7a06ac12018-03-15 10:17:04 -0400829const uint32_t *ProgramVk::getDynamicOffsets()
830{
831 // If we have no descriptor set being used, we do not need to specify any offsets when binding
832 // the descriptor sets.
833 if (!mUsedDescriptorSetRange.contains(0))
834 return nullptr;
835
836 return mUniformBlocksOffsets.data();
837}
838
839uint32_t ProgramVk::getDynamicOffsetsCount()
840{
841 if (!mUsedDescriptorSetRange.contains(0))
842 return 0;
843
844 return static_cast<uint32_t>(mUniformBlocksOffsets.size());
845}
846
Jamie Madill8c3988c2017-12-21 14:44:56 -0500847const gl::RangeUI &ProgramVk::getUsedDescriptorSetRange() const
Jamie Madill5547b382017-10-23 18:16:01 -0400848{
Jamie Madill8c3988c2017-12-21 14:44:56 -0500849 return mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400850}
851
Luc Ferron6ea1b412018-03-21 16:13:01 -0400852vk::Error ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
Jamie Madill5547b382017-10-23 18:16:01 -0400853{
854 if (mState.getSamplerBindings().empty() || !mDirtyTextures)
855 {
Luc Ferron6ea1b412018-03-21 16:13:01 -0400856 return vk::NoError();
Jamie Madill5547b382017-10-23 18:16:01 -0400857 }
858
Luc Ferron6ea1b412018-03-21 16:13:01 -0400859 ANGLE_TRY(allocateDescriptorSet(contextVk, TextureIndex));
860
Jamie Madill8c3988c2017-12-21 14:44:56 -0500861 ASSERT(mUsedDescriptorSetRange.contains(1));
862 VkDescriptorSet descriptorSet = mDescriptorSets[1];
Jamie Madill5547b382017-10-23 18:16:01 -0400863
864 // TODO(jmadill): Don't hard-code the texture limit.
865 ShaderTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
866 ShaderTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
867 uint32_t imageCount = 0;
868
869 const gl::State &glState = contextVk->getGLState();
870 const auto &completeTextures = glState.getCompleteTextureCache();
871
Jamie Madill858c1cc2018-03-31 14:19:13 -0400872 for (const gl::SamplerBinding &samplerBinding : mState.getSamplerBindings())
Jamie Madill5547b382017-10-23 18:16:01 -0400873 {
874 ASSERT(!samplerBinding.unreferenced);
875
876 // TODO(jmadill): Sampler arrays
877 ASSERT(samplerBinding.boundTextureUnits.size() == 1);
878
879 GLuint textureUnit = samplerBinding.boundTextureUnits[0];
880 const gl::Texture *texture = completeTextures[textureUnit];
881
882 // TODO(jmadill): Incomplete textures handling.
883 ASSERT(texture);
884
Jamie Madille1f3ad42017-10-28 23:00:42 -0400885 TextureVk *textureVk = vk::GetImpl(texture);
Jamie Madill858c1cc2018-03-31 14:19:13 -0400886 const vk::ImageHelper &image = textureVk->getImage();
Jamie Madill5547b382017-10-23 18:16:01 -0400887
888 VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];
889
890 imageInfo.sampler = textureVk->getSampler().getHandle();
891 imageInfo.imageView = textureVk->getImageView().getHandle();
892 imageInfo.imageLayout = image.getCurrentLayout();
893
894 auto &writeInfo = writeDescriptorInfo[imageCount];
895
896 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
897 writeInfo.pNext = nullptr;
898 writeInfo.dstSet = descriptorSet;
899 writeInfo.dstBinding = imageCount;
900 writeInfo.dstArrayElement = 0;
901 writeInfo.descriptorCount = 1;
902 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
903 writeInfo.pImageInfo = &imageInfo;
904 writeInfo.pBufferInfo = nullptr;
905 writeInfo.pTexelBufferView = nullptr;
906
907 imageCount++;
908 }
909
910 VkDevice device = contextVk->getDevice();
911
912 ASSERT(imageCount > 0);
913 vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);
914
915 mDirtyTextures = false;
Luc Ferron6ea1b412018-03-21 16:13:01 -0400916 return vk::NoError();
Jamie Madill5547b382017-10-23 18:16:01 -0400917}
918
919void ProgramVk::invalidateTextures()
920{
921 mDirtyTextures = true;
Jamie Madill76e471e2017-10-21 09:56:01 -0400922}
923
Luc Ferron7a06ac12018-03-15 10:17:04 -0400924void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
925{
926 for (DefaultUniformBlock &block : mDefaultUniformBlocks)
927 {
928 block.storage.setMinimumSize(minSize);
929 }
930}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400931} // namespace rx