blob: 5356880fe1339df63e910ef8044747341a6547e5 [file] [log] [blame]
Alexis Hetuc8176632019-01-22 17:01:28 -05001// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "VkDescriptorSetLayout.hpp"
Nicolas Capens7d867272019-04-08 22:51:08 -040016
Ben Clayton225a1302019-04-02 12:28:22 +010017#include "VkDescriptorSet.hpp"
Nicolas Capens7d867272019-04-08 22:51:08 -040018#include "VkSampler.hpp"
19#include "VkImageView.hpp"
Chris Forbesbfbdd892019-04-27 12:11:29 -070020#include "VkBuffer.hpp"
Chris Forbes58228822019-04-17 12:51:29 -070021#include "VkBufferView.hpp"
Ben Clayton76e9bc02019-02-26 15:02:18 +000022#include "System/Types.hpp"
23
Alexis Hetu048974f2019-02-15 15:28:37 -050024#include <algorithm>
Alexis Hetuc8176632019-01-22 17:01:28 -050025#include <cstring>
26
27namespace
28{
29
30static bool UsesImmutableSamplers(const VkDescriptorSetLayoutBinding& binding)
31{
32 return (((binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
33 (binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)) &&
34 (binding.pImmutableSamplers != nullptr));
35}
36
37}
38
39namespace vk
40{
41
42DescriptorSetLayout::DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo* pCreateInfo, void* mem) :
43 flags(pCreateInfo->flags), bindingCount(pCreateInfo->bindingCount), bindings(reinterpret_cast<VkDescriptorSetLayoutBinding*>(mem))
44{
Alexis Hetu048974f2019-02-15 15:28:37 -050045 uint8_t* hostMemory = static_cast<uint8_t*>(mem) + bindingCount * sizeof(VkDescriptorSetLayoutBinding);
46 bindingOffsets = reinterpret_cast<size_t*>(hostMemory);
47 hostMemory += bindingCount * sizeof(size_t);
Alexis Hetuc8176632019-01-22 17:01:28 -050048
Alexis Hetu048974f2019-02-15 15:28:37 -050049 size_t offset = 0;
Alexis Hetuc8176632019-01-22 17:01:28 -050050 for(uint32_t i = 0; i < bindingCount; i++)
51 {
52 bindings[i] = pCreateInfo->pBindings[i];
53 if(UsesImmutableSamplers(bindings[i]))
54 {
55 size_t immutableSamplersSize = bindings[i].descriptorCount * sizeof(VkSampler);
Alexis Hetu048974f2019-02-15 15:28:37 -050056 bindings[i].pImmutableSamplers = reinterpret_cast<const VkSampler*>(hostMemory);
57 hostMemory += immutableSamplersSize;
Alexis Hetuc8176632019-01-22 17:01:28 -050058 memcpy(const_cast<VkSampler*>(bindings[i].pImmutableSamplers),
59 pCreateInfo->pBindings[i].pImmutableSamplers,
60 immutableSamplersSize);
61 }
62 else
63 {
64 bindings[i].pImmutableSamplers = nullptr;
65 }
Alexis Hetu048974f2019-02-15 15:28:37 -050066 bindingOffsets[i] = offset;
67 offset += bindings[i].descriptorCount * GetDescriptorSize(bindings[i].descriptorType);
Alexis Hetuc8176632019-01-22 17:01:28 -050068 }
Chris Forbesbfbdd892019-04-27 12:11:29 -070069 ASSERT_MSG(offset == getDescriptorSetDataSize(), "offset: %d, size: %d", int(offset), int(getDescriptorSetDataSize()));
Alexis Hetuc8176632019-01-22 17:01:28 -050070}
71
72void DescriptorSetLayout::destroy(const VkAllocationCallbacks* pAllocator)
73{
Alexis Hetud9c82562019-03-15 11:41:04 -040074 vk::deallocate(bindings, pAllocator); // This allocation also contains pImmutableSamplers
Alexis Hetuc8176632019-01-22 17:01:28 -050075}
76
77size_t DescriptorSetLayout::ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo* pCreateInfo)
78{
Alexis Hetu048974f2019-02-15 15:28:37 -050079 size_t allocationSize = pCreateInfo->bindingCount * (sizeof(VkDescriptorSetLayoutBinding) + sizeof(size_t));
Alexis Hetuc8176632019-01-22 17:01:28 -050080
81 for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++)
82 {
83 if(UsesImmutableSamplers(pCreateInfo->pBindings[i]))
84 {
85 allocationSize += pCreateInfo->pBindings[i].descriptorCount * sizeof(VkSampler);
86 }
87 }
88
89 return allocationSize;
90}
91
92size_t DescriptorSetLayout::GetDescriptorSize(VkDescriptorType type)
93{
94 switch(type)
95 {
96 case VK_DESCRIPTOR_TYPE_SAMPLER:
97 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
98 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
Chris Forbesbfbdd892019-04-27 12:11:29 -070099 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
100 return sizeof(SampledImageDescriptor);
Alexis Hetuc8176632019-01-22 17:01:28 -0500101 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
Chris Forbes58228822019-04-17 12:51:29 -0700102 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
Alexis Hetu048974f2019-02-15 15:28:37 -0500103 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
Chris Forbesbfbdd892019-04-27 12:11:29 -0700104 return sizeof(StorageImageDescriptor);
Alexis Hetuc8176632019-01-22 17:01:28 -0500105 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
106 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
107 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
108 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
Chris Forbesbfbdd892019-04-27 12:11:29 -0700109 return sizeof(BufferDescriptor);
Alexis Hetuc8176632019-01-22 17:01:28 -0500110 default:
111 UNIMPLEMENTED("Unsupported Descriptor Type");
Nicolas Capensbd54e072019-04-25 23:28:28 -0400112 return 0;
Alexis Hetuc8176632019-01-22 17:01:28 -0500113 }
Alexis Hetuc8176632019-01-22 17:01:28 -0500114}
115
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400116size_t DescriptorSetLayout::getDescriptorSetAllocationSize() const
117{
118 // vk::DescriptorSet has a layout member field.
Chris Forbesbfbdd892019-04-27 12:11:29 -0700119 return sw::align<alignof(DescriptorSet)>(OFFSET(DescriptorSet, data) + getDescriptorSetDataSize());
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400120}
121
122size_t DescriptorSetLayout::getDescriptorSetDataSize() const
Alexis Hetuc8176632019-01-22 17:01:28 -0500123{
124 size_t size = 0;
125 for(uint32_t i = 0; i < bindingCount; i++)
126 {
127 size += bindings[i].descriptorCount * GetDescriptorSize(bindings[i].descriptorType);
128 }
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400129
Alexis Hetuc8176632019-01-22 17:01:28 -0500130 return size;
131}
132
Alexis Hetu048974f2019-02-15 15:28:37 -0500133uint32_t DescriptorSetLayout::getBindingIndex(uint32_t binding) const
134{
135 for(uint32_t i = 0; i < bindingCount; i++)
136 {
137 if(binding == bindings[i].binding)
138 {
139 return i;
140 }
141 }
142
Ben Clayton225a1302019-04-02 12:28:22 +0100143 DABORT("Invalid DescriptorSetLayout binding: %d", int(binding));
Alexis Hetu048974f2019-02-15 15:28:37 -0500144 return 0;
145}
146
147void DescriptorSetLayout::initialize(VkDescriptorSet vkDescriptorSet)
148{
149 // Use a pointer to this descriptor set layout as the descriptor set's header
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400150 DescriptorSet* descriptorSet = vk::Cast(vkDescriptorSet);
Nicolas Capensbd54e072019-04-25 23:28:28 -0400151 descriptorSet->header.layout = this;
Alexis Hetu048974f2019-02-15 15:28:37 -0500152 uint8_t* mem = descriptorSet->data;
153
154 for(uint32_t i = 0; i < bindingCount; i++)
155 {
156 size_t typeSize = GetDescriptorSize(bindings[i].descriptorType);
157 if(UsesImmutableSamplers(bindings[i]))
158 {
159 for(uint32_t j = 0; j < bindings[i].descriptorCount; j++)
160 {
Nicolas Capens7d867272019-04-08 22:51:08 -0400161 SampledImageDescriptor* imageSamplerDescriptor = reinterpret_cast<SampledImageDescriptor*>(mem);
Nicolas Capensa94ca182019-04-24 13:42:53 -0400162 imageSamplerDescriptor->updateSampler(vk::Cast(bindings[i].pImmutableSamplers[j]));
Alexis Hetu048974f2019-02-15 15:28:37 -0500163 mem += typeSize;
164 }
165 }
166 else
167 {
168 mem += bindings[i].descriptorCount * typeSize;
169 }
170 }
171}
172
Ben Clayton225a1302019-04-02 12:28:22 +0100173size_t DescriptorSetLayout::getBindingCount() const
174{
175 return bindingCount;
176}
177
Ben Clayton8c56e8d2019-04-25 08:24:01 +0100178bool DescriptorSetLayout::hasBinding(uint32_t binding) const
179{
180 for(uint32_t i = 0; i < bindingCount; i++)
181 {
182 if(binding == bindings[i].binding)
183 {
184 return true;
185 }
186 }
187 return false;
188}
189
Chris Forbes0b092cd2019-04-19 09:02:14 -0700190size_t DescriptorSetLayout::getBindingStride(uint32_t binding) const
191{
192 uint32_t index = getBindingIndex(binding);
193 return GetDescriptorSize(bindings[index].descriptorType);
194}
195
Alexis Hetu5078d482019-04-10 15:00:25 -0400196size_t DescriptorSetLayout::getBindingOffset(uint32_t binding, size_t arrayElement) const
Ben Clayton76e9bc02019-02-26 15:02:18 +0000197{
198 uint32_t index = getBindingIndex(binding);
Ben Clayton225a1302019-04-02 12:28:22 +0100199 auto typeSize = GetDescriptorSize(bindings[index].descriptorType);
200 return bindingOffsets[index] + OFFSET(DescriptorSet, data[0]) + (typeSize * arrayElement);
201}
202
203bool DescriptorSetLayout::isDynamic(VkDescriptorType type)
204{
205 return type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
206 type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
207}
208
209bool DescriptorSetLayout::isBindingDynamic(uint32_t binding) const
210{
211 uint32_t index = getBindingIndex(binding);
212 return isDynamic(bindings[index].descriptorType);
213}
214
Alexis Hetu5078d482019-04-10 15:00:25 -0400215uint32_t DescriptorSetLayout::getDynamicDescriptorCount() const
Ben Clayton225a1302019-04-02 12:28:22 +0100216{
Alexis Hetu5078d482019-04-10 15:00:25 -0400217 uint32_t count = 0;
Ben Clayton225a1302019-04-02 12:28:22 +0100218 for (size_t i = 0; i < bindingCount; i++)
219 {
220 if (isDynamic(bindings[i].descriptorType))
221 {
222 count += bindings[i].descriptorCount;
223 }
224 }
225 return count;
226}
227
Alexis Hetu5078d482019-04-10 15:00:25 -0400228uint32_t DescriptorSetLayout::getDynamicDescriptorOffset(uint32_t binding) const
Ben Clayton225a1302019-04-02 12:28:22 +0100229{
230 uint32_t n = getBindingIndex(binding);
231 ASSERT(isDynamic(bindings[n].descriptorType));
232
Alexis Hetu5078d482019-04-10 15:00:25 -0400233 uint32_t index = 0;
Ben Clayton225a1302019-04-02 12:28:22 +0100234 for (uint32_t i = 0; i < n; i++)
235 {
236 if (isDynamic(bindings[i].descriptorType))
237 {
238 index += bindings[i].descriptorCount;
239 }
240 }
241 return index;
242}
243
244VkDescriptorSetLayoutBinding const & DescriptorSetLayout::getBindingLayout(uint32_t binding) const
245{
Ben Clayton72438f12019-04-04 12:30:46 +0100246 uint32_t index = getBindingIndex(binding);
247 return bindings[index];
Ben Clayton76e9bc02019-02-26 15:02:18 +0000248}
249
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400250uint8_t* DescriptorSetLayout::getOffsetPointer(DescriptorSet *descriptorSet, uint32_t binding, uint32_t arrayElement, uint32_t count, size_t* typeSize) const
Alexis Hetu048974f2019-02-15 15:28:37 -0500251{
252 uint32_t index = getBindingIndex(binding);
253 *typeSize = GetDescriptorSize(bindings[index].descriptorType);
254 size_t byteOffset = bindingOffsets[index] + (*typeSize * arrayElement);
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400255 ASSERT(((*typeSize * count) + byteOffset) <= getDescriptorSetDataSize()); // Make sure the operation will not go out of bounds
256 return &descriptorSet->data[byteOffset];
Alexis Hetu048974f2019-02-15 15:28:37 -0500257}
258
Nicolas Capensa94ca182019-04-24 13:42:53 -0400259void SampledImageDescriptor::updateSampler(const vk::Sampler *sampler)
260{
Nicolas Capens1e7120e2019-04-30 17:33:26 -0400261 if(sampler)
Chris Forbesbfbdd892019-04-27 12:11:29 -0700262 {
Nicolas Capens1e7120e2019-04-30 17:33:26 -0400263 memcpy(&this->sampler, sampler, sizeof(this->sampler));
Chris Forbesbfbdd892019-04-27 12:11:29 -0700264 }
Nicolas Capensfa7d1362019-05-01 20:26:14 -0400265 else
266 {
267 // Descriptor ID's start at 1, allowing to detect descriptor update
268 // bugs by checking for 0. Also avoid reading random values.
269 memset(&this->sampler, 0, sizeof(this->sampler));
270 }
Nicolas Capensa94ca182019-04-24 13:42:53 -0400271}
272
Chris Forbesbc694e22019-04-19 15:12:49 -0700273void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src)
Alexis Hetu048974f2019-02-15 15:28:37 -0500274{
Nicolas Capensbd54e072019-04-25 23:28:28 -0400275 DescriptorSetLayout* dstLayout = dstSet->header.layout;
Nicolas Capens9e735102019-04-18 15:03:06 -0400276 auto &binding = dstLayout->bindings[dstLayout->getBindingIndex(entry.dstBinding)];
Alexis Hetu048974f2019-02-15 15:28:37 -0500277 ASSERT(dstLayout);
Nicolas Capens9e735102019-04-18 15:03:06 -0400278 ASSERT(binding.descriptorType == entry.descriptorType);
Alexis Hetu048974f2019-02-15 15:28:37 -0500279
280 size_t typeSize = 0;
Chris Forbesbc694e22019-04-19 15:12:49 -0700281 uint8_t* memToWrite = dstLayout->getOffsetPointer(dstSet, entry.dstBinding, entry.dstArrayElement, entry.descriptorCount, &typeSize);
Alexis Hetu048974f2019-02-15 15:28:37 -0500282
Nicolas Capensbd54e072019-04-25 23:28:28 -0400283 ASSERT(reinterpret_cast<intptr_t>(memToWrite) % 16 == 0); // Each descriptor must be 16-byte aligned.
284
Chris Forbesbfbdd892019-04-27 12:11:29 -0700285 if (entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
286 {
287 SampledImageDescriptor *imageSampler = reinterpret_cast<SampledImageDescriptor*>(memToWrite);
288
289 for(uint32_t i = 0; i < entry.descriptorCount; i++)
290 {
291 auto update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
292 // "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
293 // descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
294 if (!binding.pImmutableSamplers)
295 {
296 imageSampler[i].updateSampler(vk::Cast(update->sampler));
297 }
298 }
299 }
300 else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
301 {
Chris Forbes3e6a9712019-05-08 14:05:56 -0700302 SampledImageDescriptor *imageSampler = reinterpret_cast<SampledImageDescriptor*>(memToWrite);
303
304 for (uint32_t i = 0; i < entry.descriptorCount; i++)
305 {
306 auto update = reinterpret_cast<VkBufferView const *>(src + entry.offset + entry.stride * i);
307 auto bufferView = Cast(*update);
308
309 imageSampler[i].type = VK_IMAGE_VIEW_TYPE_1D;
Chris Forbes246cc502019-05-09 09:25:09 -0700310 imageSampler[i].imageViewId = bufferView->id;
Chris Forbes3e6a9712019-05-08 14:05:56 -0700311 imageSampler[i].swizzle = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
312 imageSampler[i].format = bufferView->getFormat();
313
314 auto numElements = bufferView->getElementCount();
315 imageSampler[i].extent = { numElements, 1, 1 };
316 imageSampler[i].arrayLayers = 1;
317 imageSampler[i].texture.widthWidthHeightHeight = sw::vector(numElements, numElements, 1, 1);
318 imageSampler[i].texture.width = sw::replicate(numElements);
319 imageSampler[i].texture.height = sw::replicate(1);
320 imageSampler[i].texture.depth = sw::replicate(1);
321
322 sw::Mipmap &mipmap = imageSampler[i].texture.mipmap[0];
323 mipmap.buffer[0] = bufferView->getPointer();
324 mipmap.width[0] = mipmap.width[1] = mipmap.width[2] = mipmap.width[3] = static_cast<short>(numElements);
325 mipmap.height[0] = mipmap.height[1] = mipmap.height[2] = mipmap.height[3] = 1;
326 mipmap.depth[0] = mipmap.depth[1] = mipmap.depth[2] = mipmap.depth[3] = 1;
327 mipmap.pitchP.x = mipmap.pitchP.y = mipmap.pitchP.z = mipmap.pitchP.w = numElements;
328 mipmap.sliceP.x = mipmap.sliceP.y = mipmap.sliceP.z = mipmap.sliceP.w = 0;
329 mipmap.onePitchP[0] = mipmap.onePitchP[2] = 1;
330 mipmap.onePitchP[1] = mipmap.onePitchP[3] = static_cast<short>(numElements);
331 }
Chris Forbesbfbdd892019-04-27 12:11:29 -0700332 }
333 else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
334 entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
Nicolas Capens7d867272019-04-08 22:51:08 -0400335 {
336 SampledImageDescriptor *imageSampler = reinterpret_cast<SampledImageDescriptor*>(memToWrite);
337
Chris Forbesbc694e22019-04-19 15:12:49 -0700338 for(uint32_t i = 0; i < entry.descriptorCount; i++)
Nicolas Capens7d867272019-04-08 22:51:08 -0400339 {
Chris Forbesbc694e22019-04-19 15:12:49 -0700340 auto update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
Chris Forbesbc694e22019-04-19 15:12:49 -0700341 vk::ImageView *imageView = vk::Cast(update->imageView);
Nicolas Capens7d867272019-04-08 22:51:08 -0400342 sw::Texture *texture = &imageSampler[i].texture;
Nicolas Capens9e735102019-04-18 15:03:06 -0400343
344 // "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
345 // descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
346 if(!binding.pImmutableSamplers)
347 {
Nicolas Capensa94ca182019-04-24 13:42:53 -0400348 imageSampler[i].updateSampler(vk::Cast(update->sampler));
Nicolas Capens9e735102019-04-18 15:03:06 -0400349 }
350
Chris Forbes45f9a932019-05-08 13:30:38 -0700351 imageSampler[i].imageViewId = imageView->id;
Ben Clayton0264d8e2019-05-08 15:39:40 +0100352 imageSampler[i].extent = imageView->getMipLevelExtent(0);
353 imageSampler[i].arrayLayers = imageView->getSubresourceRange().layerCount;
Chris Forbes45f9a932019-05-08 13:30:38 -0700354 imageSampler[i].type = imageView->getType();
355 imageSampler[i].swizzle = imageView->getComponentMapping();
356 imageSampler[i].format = imageView->getFormat(ImageView::SAMPLING);
Nicolas Capens9e735102019-04-18 15:03:06 -0400357
Nicolas Capens7d867272019-04-08 22:51:08 -0400358 auto &subresourceRange = imageView->getSubresourceRange();
359 int baseLevel = subresourceRange.baseMipLevel;
360
361 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
362 {
363 int level = mipmapLevel - baseLevel; // Level within the image view
Nicolas Capens9e735102019-04-18 15:03:06 -0400364 level = sw::clamp(level, 0, (int)subresourceRange.levelCount - 1);
Nicolas Capens7d867272019-04-08 22:51:08 -0400365
Nicolas Capens7d867272019-04-08 22:51:08 -0400366 VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT;
Nicolas Capens7d867272019-04-08 22:51:08 -0400367 sw::Mipmap &mipmap = texture->mipmap[mipmapLevel];
Nicolas Capensa195abb2019-04-25 17:15:56 -0400368
369 if(imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE)
370 {
371 for(int face = 0; face < 6; face++)
372 {
373 // Obtain the pointer to the corner of the level including the border, for seamless sampling.
374 // This is taken into account in the sampling routine, which can't handle negative texel coordinates.
375 VkOffset3D offset = {-1, -1, 0};
376
377 // TODO(b/129523279): Implement as 6 consecutive layers instead of separate pointers.
Alexis Hetuac873342019-04-17 15:59:03 -0400378 mipmap.buffer[face] = imageView->getOffsetPointer(offset, aspect, level, face, ImageView::SAMPLING);
Nicolas Capensa195abb2019-04-25 17:15:56 -0400379 }
380 }
381 else
382 {
383 VkOffset3D offset = {0, 0, 0};
Alexis Hetuac873342019-04-17 15:59:03 -0400384 mipmap.buffer[0] = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
Nicolas Capensa195abb2019-04-25 17:15:56 -0400385 }
Nicolas Capens7d867272019-04-08 22:51:08 -0400386
387 VkExtent3D extent = imageView->getMipLevelExtent(level);
Alexis Hetuac873342019-04-17 15:59:03 -0400388 Format format = imageView->getFormat(ImageView::SAMPLING);
Chris Forbesf40cff92019-04-27 11:17:28 -0700389 int layers = imageView->getSubresourceRange().layerCount;
390 // TODO(b/129523279): Untangle depth vs layers throughout the sampler
Nicolas Capens7d867272019-04-08 22:51:08 -0400391 int width = extent.width;
392 int height = extent.height;
Chris Forbesf40cff92019-04-27 11:17:28 -0700393 int depth = layers > 1 ? layers : extent.depth;
Alexis Hetuac873342019-04-17 15:59:03 -0400394 int pitchP = imageView->rowPitchBytes(aspect, level, ImageView::SAMPLING) / format.bytes();
395 int sliceP = (layers > 1 ? imageView->layerPitchBytes(aspect, ImageView::SAMPLING) : imageView->slicePitchBytes(aspect, level, ImageView::SAMPLING)) / format.bytes();
Nicolas Capens7d867272019-04-08 22:51:08 -0400396
Nicolas Capens7d867272019-04-08 22:51:08 -0400397 if(mipmapLevel == 0)
398 {
Nicolas Capens1e7120e2019-04-30 17:33:26 -0400399 texture->widthWidthHeightHeight[0] = width;
400 texture->widthWidthHeightHeight[1] = width;
401 texture->widthWidthHeightHeight[2] = height;
402 texture->widthWidthHeightHeight[3] = height;
Nicolas Capens7d867272019-04-08 22:51:08 -0400403
Nicolas Capens1e7120e2019-04-30 17:33:26 -0400404 texture->width[0] = width;
405 texture->width[1] = width;
406 texture->width[2] = width;
407 texture->width[3] = width;
Nicolas Capens7d867272019-04-08 22:51:08 -0400408
Nicolas Capens1e7120e2019-04-30 17:33:26 -0400409 texture->height[0] = height;
410 texture->height[1] = height;
411 texture->height[2] = height;
412 texture->height[3] = height;
Nicolas Capens7d867272019-04-08 22:51:08 -0400413
Nicolas Capens1e7120e2019-04-30 17:33:26 -0400414 texture->depth[0] = depth;
415 texture->depth[1] = depth;
416 texture->depth[2] = depth;
417 texture->depth[3] = depth;
Nicolas Capens7d867272019-04-08 22:51:08 -0400418 }
419
420 if(format.isFloatFormat())
421 {
422 mipmap.fWidth[0] = (float)width / 65536.0f;
423 mipmap.fWidth[1] = (float)width / 65536.0f;
424 mipmap.fWidth[2] = (float)width / 65536.0f;
425 mipmap.fWidth[3] = (float)width / 65536.0f;
426
427 mipmap.fHeight[0] = (float)height / 65536.0f;
428 mipmap.fHeight[1] = (float)height / 65536.0f;
429 mipmap.fHeight[2] = (float)height / 65536.0f;
430 mipmap.fHeight[3] = (float)height / 65536.0f;
431
432 mipmap.fDepth[0] = (float)depth / 65536.0f;
433 mipmap.fDepth[1] = (float)depth / 65536.0f;
434 mipmap.fDepth[2] = (float)depth / 65536.0f;
435 mipmap.fDepth[3] = (float)depth / 65536.0f;
436 }
437
438 short halfTexelU = 0x8000 / width;
439 short halfTexelV = 0x8000 / height;
440 short halfTexelW = 0x8000 / depth;
441
442 mipmap.uHalf[0] = halfTexelU;
443 mipmap.uHalf[1] = halfTexelU;
444 mipmap.uHalf[2] = halfTexelU;
445 mipmap.uHalf[3] = halfTexelU;
446
447 mipmap.vHalf[0] = halfTexelV;
448 mipmap.vHalf[1] = halfTexelV;
449 mipmap.vHalf[2] = halfTexelV;
450 mipmap.vHalf[3] = halfTexelV;
451
452 mipmap.wHalf[0] = halfTexelW;
453 mipmap.wHalf[1] = halfTexelW;
454 mipmap.wHalf[2] = halfTexelW;
455 mipmap.wHalf[3] = halfTexelW;
456
457 mipmap.width[0] = width;
458 mipmap.width[1] = width;
459 mipmap.width[2] = width;
460 mipmap.width[3] = width;
461
462 mipmap.height[0] = height;
463 mipmap.height[1] = height;
464 mipmap.height[2] = height;
465 mipmap.height[3] = height;
466
467 mipmap.depth[0] = depth;
468 mipmap.depth[1] = depth;
469 mipmap.depth[2] = depth;
470 mipmap.depth[3] = depth;
471
472 mipmap.onePitchP[0] = 1;
473 mipmap.onePitchP[1] = pitchP;
474 mipmap.onePitchP[2] = 1;
475 mipmap.onePitchP[3] = pitchP;
476
477 mipmap.pitchP[0] = pitchP;
478 mipmap.pitchP[1] = pitchP;
479 mipmap.pitchP[2] = pitchP;
480 mipmap.pitchP[3] = pitchP;
481
482 mipmap.sliceP[0] = sliceP;
483 mipmap.sliceP[1] = sliceP;
484 mipmap.sliceP[2] = sliceP;
485 mipmap.sliceP[3] = sliceP;
486
487 // TODO(b/129523279)
488 if(false/*format == FORMAT_YV12_BT601 ||
489 format == FORMAT_YV12_BT709 ||
490 format == FORMAT_YV12_JFIF*/)
491 {
492 unsigned int YStride = pitchP;
493 unsigned int YSize = YStride * height;
494 unsigned int CStride = sw::align<16>(YStride / 2);
495 unsigned int CSize = CStride * height / 2;
496
497 mipmap.buffer[1] = (sw::byte*)mipmap.buffer[0] + YSize;
498 mipmap.buffer[2] = (sw::byte*)mipmap.buffer[1] + CSize;
499
500 texture->mipmap[1].width[0] = width / 2;
501 texture->mipmap[1].width[1] = width / 2;
502 texture->mipmap[1].width[2] = width / 2;
503 texture->mipmap[1].width[3] = width / 2;
504 texture->mipmap[1].height[0] = height / 2;
505 texture->mipmap[1].height[1] = height / 2;
506 texture->mipmap[1].height[2] = height / 2;
507 texture->mipmap[1].height[3] = height / 2;
508 texture->mipmap[1].onePitchP[0] = 1;
509 texture->mipmap[1].onePitchP[1] = CStride;
510 texture->mipmap[1].onePitchP[2] = 1;
511 texture->mipmap[1].onePitchP[3] = CStride;
512 }
513 }
514 }
515 }
Chris Forbesa1614932019-04-22 08:52:59 -0700516 else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
517 entry.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
Chris Forbes58228822019-04-17 12:51:29 -0700518 {
519 auto descriptor = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
Chris Forbesbc694e22019-04-19 15:12:49 -0700520 for(uint32_t i = 0; i < entry.descriptorCount; i++)
Chris Forbes58228822019-04-17 12:51:29 -0700521 {
Chris Forbesbc694e22019-04-19 15:12:49 -0700522 auto update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
523 auto imageView = Cast(update->imageView);
Nicolas Capensa195abb2019-04-25 17:15:56 -0400524 descriptor[i].ptr = imageView->getOffsetPointer({0, 0, 0}, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
Chris Forbes58228822019-04-17 12:51:29 -0700525 descriptor[i].extent = imageView->getMipLevelExtent(0);
526 descriptor[i].rowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
Chris Forbes52a3bba2019-05-03 15:11:41 -0700527 descriptor[i].samplePitchBytes = imageView->getSubresourceRange().layerCount > 1
528 ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT)
529 : imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
530 descriptor[i].slicePitchBytes = descriptor[i].samplePitchBytes * imageView->getSampleCount();
Chris Forbes58228822019-04-17 12:51:29 -0700531 descriptor[i].arrayLayers = imageView->getSubresourceRange().layerCount;
Ben Clayton9e4bc1b2019-04-16 16:52:02 -0400532 descriptor[i].sizeInBytes = imageView->getImageSizeInBytes();
Chris Forbes011744e2019-05-06 14:21:45 -0700533
534 if (imageView->getFormat().isStencil())
535 {
536 descriptor[i].stencilPtr = imageView->getOffsetPointer({0, 0, 0}, VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0);
537 descriptor[i].stencilRowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
538 descriptor[i].stencilSamplePitchBytes = imageView->getSubresourceRange().layerCount > 1
539 ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT)
540 : imageView->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
541 descriptor[i].stencilSlicePitchBytes = descriptor[i].stencilSamplePitchBytes * imageView->getSampleCount();
542 }
Chris Forbes58228822019-04-17 12:51:29 -0700543 }
544 }
Chris Forbesbc694e22019-04-19 15:12:49 -0700545 else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
Chris Forbes58228822019-04-17 12:51:29 -0700546 {
547 auto descriptor = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
Chris Forbesbc694e22019-04-19 15:12:49 -0700548 for (uint32_t i = 0; i < entry.descriptorCount; i++)
Chris Forbes58228822019-04-17 12:51:29 -0700549 {
Chris Forbesbc694e22019-04-19 15:12:49 -0700550 auto update = reinterpret_cast<VkBufferView const *>(src + entry.offset + entry.stride * i);
551 auto bufferView = Cast(*update);
Chris Forbes58228822019-04-17 12:51:29 -0700552 descriptor[i].ptr = bufferView->getPointer();
553 descriptor[i].extent = {bufferView->getElementCount(), 1, 1};
554 descriptor[i].rowPitchBytes = 0;
555 descriptor[i].slicePitchBytes = 0;
Chris Forbes52a3bba2019-05-03 15:11:41 -0700556 descriptor[i].samplePitchBytes = 0;
Chris Forbes58228822019-04-17 12:51:29 -0700557 descriptor[i].arrayLayers = 1;
Ben Clayton9e4bc1b2019-04-16 16:52:02 -0400558 descriptor[i].sizeInBytes = bufferView->getRangeInBytes();
Chris Forbes58228822019-04-17 12:51:29 -0700559 }
560 }
Chris Forbesbfbdd892019-04-27 12:11:29 -0700561 else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
562 entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
563 entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
564 entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
Nicolas Capens7d867272019-04-08 22:51:08 -0400565 {
Chris Forbesbfbdd892019-04-27 12:11:29 -0700566 auto descriptor = reinterpret_cast<BufferDescriptor *>(memToWrite);
567 for (uint32_t i = 0; i < entry.descriptorCount; i++)
568 {
569 auto update = reinterpret_cast<VkDescriptorBufferInfo const *>(src + entry.offset + entry.stride * i);
570 auto buffer = Cast(update->buffer);
571 descriptor[i].ptr = buffer->getOffsetPointer(update->offset);
572 descriptor[i].sizeInBytes = (update->range == VK_WHOLE_SIZE) ? buffer->getSize() - update->offset : update->range;
573 descriptor[i].robustnessSize = buffer->getSize() - update->offset;
574 }
Nicolas Capens7d867272019-04-08 22:51:08 -0400575 }
Alexis Hetu048974f2019-02-15 15:28:37 -0500576}
577
Chris Forbesbc694e22019-04-19 15:12:49 -0700578void DescriptorSetLayout::WriteDescriptorSet(const VkWriteDescriptorSet& writeDescriptorSet)
579{
580 DescriptorSet* dstSet = vk::Cast(writeDescriptorSet.dstSet);
581 VkDescriptorUpdateTemplateEntry e;
582 e.descriptorType = writeDescriptorSet.descriptorType;
583 e.dstBinding = writeDescriptorSet.dstBinding;
584 e.dstArrayElement = writeDescriptorSet.dstArrayElement;
585 e.descriptorCount = writeDescriptorSet.descriptorCount;
586 e.offset = 0;
587 void const *ptr = nullptr;
588 switch (writeDescriptorSet.descriptorType)
589 {
590 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
591 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
592 ptr = writeDescriptorSet.pTexelBufferView;
Chris Forbesbfbdd892019-04-27 12:11:29 -0700593 e.stride = sizeof(VkBufferView);
Chris Forbesbc694e22019-04-19 15:12:49 -0700594 break;
595
596 case VK_DESCRIPTOR_TYPE_SAMPLER:
597 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
598 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
599 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
600 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
601 ptr = writeDescriptorSet.pImageInfo;
602 e.stride = sizeof(VkDescriptorImageInfo);
603 break;
604
605 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
606 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
607 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
608 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
609 ptr = writeDescriptorSet.pBufferInfo;
610 e.stride = sizeof(VkDescriptorBufferInfo);
611 break;
612
613 default:
614 UNIMPLEMENTED("descriptor type %u", writeDescriptorSet.descriptorType);
615 }
616
617 WriteDescriptorSet(dstSet, e, reinterpret_cast<char const *>(ptr));
618}
619
Alexis Hetu048974f2019-02-15 15:28:37 -0500620void DescriptorSetLayout::CopyDescriptorSet(const VkCopyDescriptorSet& descriptorCopies)
621{
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400622 DescriptorSet* srcSet = vk::Cast(descriptorCopies.srcSet);
Nicolas Capensbd54e072019-04-25 23:28:28 -0400623 DescriptorSetLayout* srcLayout = srcSet->header.layout;
Alexis Hetu048974f2019-02-15 15:28:37 -0500624 ASSERT(srcLayout);
625
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400626 DescriptorSet* dstSet = vk::Cast(descriptorCopies.dstSet);
Nicolas Capensbd54e072019-04-25 23:28:28 -0400627 DescriptorSetLayout* dstLayout = dstSet->header.layout;
Alexis Hetu048974f2019-02-15 15:28:37 -0500628 ASSERT(dstLayout);
629
630 size_t srcTypeSize = 0;
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400631 uint8_t* memToRead = srcLayout->getOffsetPointer(srcSet, descriptorCopies.srcBinding, descriptorCopies.srcArrayElement, descriptorCopies.descriptorCount, &srcTypeSize);
Alexis Hetu048974f2019-02-15 15:28:37 -0500632
633 size_t dstTypeSize = 0;
Nicolas Capensa94a95c2019-03-29 06:22:17 -0400634 uint8_t* memToWrite = dstLayout->getOffsetPointer(dstSet, descriptorCopies.dstBinding, descriptorCopies.dstArrayElement, descriptorCopies.descriptorCount, &dstTypeSize);
Alexis Hetu048974f2019-02-15 15:28:37 -0500635
636 ASSERT(srcTypeSize == dstTypeSize);
637 size_t writeSize = dstTypeSize * descriptorCopies.descriptorCount;
638 memcpy(memToWrite, memToRead, writeSize);
639}
640
Chris Forbesf149d952019-04-28 15:57:44 -0700641} // namespace vk