Make image descriptor fields unsigned

All Vulkan width/height/depth variables are unsigned, while our
descriptor and sampling code used signed integers in various places.
While this was benign it added confusion about whether some of these
values could be negative and need special handling.

Note that the results produced by the 32-bit SamplerCore::address()
method are signed, because negative values represent out-of-bounds
sampling. So these are left unchanged and the image dimensions are
explicitly cast to signed where necessary.

The Mipmap::onePitchP field is also still signed, because it is used
in MulAdd() intrinsics which multiply pairs of signed 16-bit fields
and produce a 32-bit signed result (there is no unsigned PMADDWD
instruction variant). Note that multiplications which produce a result
of the same bit width as the operands are indifferent to signedness
(just like addition and subtraction).

Some assert_cast<>'s were used to catch unexpected overflows, and uses
of `auto` in the descriptor writing code were replaced with explicit
types to aid readability.

Bug: b/210880838
Bug: b/200806413
Change-Id: I8d8cb1b17cfd2d40b0ad3153e75c69a086e2ae40
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/61248
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Device/Sampler.hpp b/src/Device/Sampler.hpp
index 983db10..7402b5c 100644
--- a/src/Device/Sampler.hpp
+++ b/src/Device/Sampler.hpp
@@ -25,17 +25,17 @@
 {
 	const void *buffer;
 
-	short4 uHalf;
-	short4 vHalf;
-	short4 wHalf;
-	int4 width;
-	int4 height;
-	int4 depth;
+	ushort4 uHalf;
+	ushort4 vHalf;
+	ushort4 wHalf;
+	uint4 width;
+	uint4 height;
+	uint4 depth;
 	short4 onePitchP;
-	int4 pitchP;
-	int4 sliceP;
-	int4 samplePitchP;
-	int4 sampleMax;
+	uint4 pitchP;
+	uint4 sliceP;
+	uint4 samplePitchP;
+	uint4 sampleMax;
 };
 
 struct Texture
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 9ffddb9..37aa93a 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -480,8 +480,8 @@
 		if(!gather)  // Blend
 		{
 			// Fractions
-			UShort4 f0u = As<UShort4>(uuuu0) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width)));
-			UShort4 f0v = As<UShort4>(vvvv0) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height)));
+			UShort4 f0u = As<UShort4>(uuuu0) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, width)));
+			UShort4 f0v = As<UShort4>(vvvv0) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, height)));
 
 			UShort4 f1u = ~f0u;
 			UShort4 f1v = ~f0v;
@@ -687,9 +687,9 @@
 		}
 
 		// Fractions
-		UShort4 f0u = As<UShort4>(u[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width)));
-		UShort4 f0v = As<UShort4>(v[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height)));
-		UShort4 f0s = As<UShort4>(s[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)));
+		UShort4 f0u = As<UShort4>(u[0][0][0]) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, width)));
+		UShort4 f0v = As<UShort4>(v[0][0][0]) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, height)));
+		UShort4 f0s = As<UShort4>(s[0][0][0]) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, depth)));
 
 		UShort4 f1u = ~f0u;
 		UShort4 f1v = ~f0v;
@@ -906,7 +906,7 @@
 	address(u, x0, x1, fu, mipmap, offset.x, filter, OFFSET(Mipmap, width), state.addressingModeU);
 	address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV);
 
-	Int4 pitchP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, pitchP), 16);
+	Int4 pitchP = As<Int4>(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, pitchP), 16));
 	y0 *= pitchP;
 
 	Int4 z;
@@ -999,8 +999,8 @@
 	address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV);
 	address(w, z0, z1, fw, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW);
 
-	Int4 pitchP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, pitchP), 16);
-	Int4 sliceP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, sliceP), 16);
+	Int4 pitchP = As<Int4>(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, pitchP), 16));
+	Int4 sliceP = As<Int4>(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, sliceP), 16));
 	y0 *= pitchP;
 	z0 *= sliceP;
 
@@ -1315,22 +1315,22 @@
 
 void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, const Short4 &layerIndex, Vector4i &offset, const Int4 &sample, const Pointer<Byte> &mipmap)
 {
-	uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width))));
+	uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, width))));
 
 	if(function.offset)
 	{
-		uuuu = applyOffset(uuuu, offset.x, *Pointer<Int4>(mipmap + OFFSET(Mipmap, width)), state.addressingModeU);
+		uuuu = applyOffset(uuuu, offset.x, *Pointer<UInt4>(mipmap + OFFSET(Mipmap, width)), state.addressingModeU);
 	}
 
 	UInt4 indices = Int4(uuuu);
 
 	if(state.is2D() || state.is3D() || state.isCube())
 	{
-		vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height))));
+		vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, height))));
 
 		if(function.offset)
 		{
-			vvvv = applyOffset(vvvv, offset.y, *Pointer<Int4>(mipmap + OFFSET(Mipmap, height)), state.addressingModeV);
+			vvvv = applyOffset(vvvv, offset.y, *Pointer<UInt4>(mipmap + OFFSET(Mipmap, height)), state.addressingModeV);
 		}
 
 		Short4 uv0uv1 = As<Short4>(UnpackLow(uuuu, vvvv));
@@ -2245,7 +2245,7 @@
 		return;
 	}
 
-	Int4 dim = *Pointer<Int4>(mipmap + whd, 16);
+	Int4 dim = As<Int4>(*Pointer<UInt4>(mipmap + whd, 16));
 	Int4 maxXYZ = dim - Int4(1);
 
 	if(function == Fetch)  // Unnormalized coordinates
diff --git a/src/Reactor/Reactor.cpp b/src/Reactor/Reactor.cpp
index 3bbaca1..f959b95 100644
--- a/src/Reactor/Reactor.cpp
+++ b/src/Reactor/Reactor.cpp
@@ -1776,6 +1776,11 @@
 	storeValue(swizzle);
 }
 
+Short4::Short4(RValue<UInt4> cast)
+    : Short4(As<Int4>(cast))
+{
+}
+
 //	Short4::Short4(RValue<Float> cast)
 //	{
 //	}
@@ -2005,6 +2010,11 @@
 	return RValue<Short>(Nucleus::createExtractElement(val.value(), Short::type(), i));
 }
 
+UShort4::UShort4(RValue<UInt4> cast)
+    : UShort4(As<Int4>(cast))
+{
+}
+
 UShort4::UShort4(RValue<Int4> cast)
 {
 	*this = Short4(cast);
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 55ca984..3b3d08b 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -879,6 +879,7 @@
 public:
 	explicit Short4(RValue<Int> cast);
 	explicit Short4(RValue<Int4> cast);
+	explicit Short4(RValue<UInt4> cast);
 	//	explicit Short4(RValue<Float> cast);
 	explicit Short4(RValue<Float4> cast);
 
@@ -956,6 +957,7 @@
 class UShort4 : public LValue<UShort4>
 {
 public:
+	explicit UShort4(RValue<UInt4> cast);
 	explicit UShort4(RValue<Int4> cast);
 	explicit UShort4(RValue<Float4> cast, bool saturate = false);
 
diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp
index 9c364b4..c8d5f25 100644
--- a/src/Vulkan/VkDescriptorSetLayout.cpp
+++ b/src/Vulkan/VkDescriptorSetLayout.cpp
@@ -59,8 +59,8 @@
 
 	for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++)
 	{
-		const auto &srcBinding = pCreateInfo->pBindings[i];
-		auto &dstBinding = bindings[srcBinding.binding];
+		const VkDescriptorSetLayoutBinding &srcBinding = pCreateInfo->pBindings[i];
+		vk::DescriptorSetLayout::Binding &dstBinding = bindings[srcBinding.binding];
 
 		dstBinding.descriptorType = srcBinding.descriptorType;
 		dstBinding.descriptorCount = srcBinding.descriptorCount;
@@ -277,10 +277,49 @@
 	return &descriptorSet->data[byteOffset];
 }
 
-void DescriptorSetLayout::WriteDescriptorSet(Device *device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src)
+static void WriteTextureLevelInfo(sw::Texture *texture, uint32_t level, uint32_t width, uint32_t height, uint32_t depth, uint32_t pitchP, uint32_t sliceP, uint32_t samplePitchP, uint32_t sampleMax)
+{
+	if(level == 0)
+	{
+		texture->widthWidthHeightHeight[0] = static_cast<float>(width);
+		texture->widthWidthHeightHeight[1] = static_cast<float>(width);
+		texture->widthWidthHeightHeight[2] = static_cast<float>(height);
+		texture->widthWidthHeightHeight[3] = static_cast<float>(height);
+
+		texture->width = sw::float4(static_cast<float>(width));
+		texture->height = sw::float4(static_cast<float>(height));
+		texture->depth = sw::float4(static_cast<float>(depth));
+	}
+
+	sw::Mipmap &mipmap = texture->mipmap[level];
+
+	uint16_t halfTexelU = 0x8000 / width;
+	uint16_t halfTexelV = 0x8000 / height;
+	uint16_t halfTexelW = 0x8000 / depth;
+
+	mipmap.uHalf = sw::ushort4(halfTexelU);
+	mipmap.vHalf = sw::ushort4(halfTexelV);
+	mipmap.wHalf = sw::ushort4(halfTexelW);
+
+	mipmap.width = sw::uint4(width);
+	mipmap.height = sw::uint4(height);
+	mipmap.depth = sw::uint4(depth);
+
+	mipmap.onePitchP[0] = 1;
+	mipmap.onePitchP[1] = sw::assert_cast<short>(pitchP);
+	mipmap.onePitchP[2] = 1;
+	mipmap.onePitchP[3] = sw::assert_cast<short>(pitchP);
+
+	mipmap.pitchP = sw::uint4(pitchP);
+	mipmap.sliceP = sw::uint4(sliceP);
+	mipmap.samplePitchP = sw::uint4(samplePitchP);
+	mipmap.sampleMax = sw::uint4(sampleMax);
+}
+
+void DescriptorSetLayout::WriteDescriptorSet(Device *device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, const char *src)
 {
 	DescriptorSetLayout *dstLayout = dstSet->header.layout;
-	auto &binding = dstLayout->bindings[entry.dstBinding];
+	const DescriptorSetLayout::Binding &binding = dstLayout->bindings[entry.dstBinding];
 	ASSERT(dstLayout);
 	ASSERT(binding.descriptorType == entry.descriptorType);
 
@@ -295,7 +334,8 @@
 
 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
 		{
-			auto update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
+			const VkDescriptorImageInfo *update = reinterpret_cast<const VkDescriptorImageInfo *>(src + entry.offset + entry.stride * i);
+
 			// "All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a
 			//  descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers."
 			if(!binding.immutableSamplers)
@@ -310,12 +350,12 @@
 
 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
 		{
-			auto update = reinterpret_cast<VkBufferView const *>(src + entry.offset + entry.stride * i);
-			auto bufferView = vk::Cast(*update);
+			const VkBufferView *update = reinterpret_cast<const VkBufferView *>(src + entry.offset + entry.stride * i);
+			const vk::BufferView *bufferView = vk::Cast(*update);
 
 			sampledImage[i].imageViewId = bufferView->id;
 
-			auto numElements = bufferView->getElementCount();
+			uint32_t numElements = bufferView->getElementCount();
 			sampledImage[i].width = numElements;
 			sampledImage[i].height = 1;
 			sampledImage[i].depth = 1;
@@ -344,7 +384,7 @@
 
 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
 		{
-			auto *update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
+			const VkDescriptorImageInfo *update = reinterpret_cast<const VkDescriptorImageInfo *>(src + entry.offset + entry.stride * i);
 
 			vk::ImageView *imageView = vk::Cast(update->imageView);
 			Format format = imageView->getFormat(ImageView::SAMPLING);
@@ -391,17 +431,17 @@
 
 				VkExtent2D extent = imageView->getMipLevelExtent(0);
 
-				int width = extent.width;
-				int height = extent.height;
-				int pitchP0 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_0_BIT, level, ImageView::SAMPLING) /
-				              imageView->getFormat(VK_IMAGE_ASPECT_PLANE_0_BIT).bytes();
+				uint32_t width = extent.width;
+				uint32_t height = extent.height;
+				uint32_t pitchP0 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_0_BIT, level, ImageView::SAMPLING) /
+				                   imageView->getFormat(VK_IMAGE_ASPECT_PLANE_0_BIT).bytes();
 
 				// Write plane 0 parameters to mipmap level 0.
 				WriteTextureLevelInfo(texture, 0, width, height, 1, pitchP0, 0, 0, 0);
 
 				// Plane 2, if present, has equal parameters to plane 1, so we use mipmap level 1 for both.
-				int pitchP1 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_1_BIT, level, ImageView::SAMPLING) /
-				              imageView->getFormat(VK_IMAGE_ASPECT_PLANE_1_BIT).bytes();
+				uint32_t pitchP1 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_1_BIT, level, ImageView::SAMPLING) /
+				                   imageView->getFormat(VK_IMAGE_ASPECT_PLANE_1_BIT).bytes();
 
 				WriteTextureLevelInfo(texture, 1, width / 2, height / 2, 1, pitchP1, 0, 0, 0);
 			}
@@ -430,15 +470,15 @@
 
 					VkExtent2D extent = imageView->getMipLevelExtent(level);
 
-					int width = extent.width;
-					int height = extent.height;
-					int layerCount = imageView->getSubresourceRange().layerCount;
-					int depth = imageView->getDepthOrLayerCount(level);
-					int bytes = format.bytes();
-					int pitchP = imageView->rowPitchBytes(aspect, level, ImageView::SAMPLING) / bytes;
-					int sliceP = (layerCount > 1 ? imageView->layerPitchBytes(aspect, ImageView::SAMPLING) : imageView->slicePitchBytes(aspect, level, ImageView::SAMPLING)) / bytes;
-					int samplePitchP = imageView->getMipLevelSize(aspect, level, ImageView::SAMPLING) / bytes;
-					int sampleMax = imageView->getSampleCount() - 1;
+					uint32_t width = extent.width;
+					uint32_t height = extent.height;
+					uint32_t layerCount = imageView->getSubresourceRange().layerCount;
+					uint32_t depth = imageView->getDepthOrLayerCount(level);
+					uint32_t bytes = format.bytes();
+					uint32_t pitchP = imageView->rowPitchBytes(aspect, level, ImageView::SAMPLING) / bytes;
+					uint32_t sliceP = (layerCount > 1 ? imageView->layerPitchBytes(aspect, ImageView::SAMPLING) : imageView->slicePitchBytes(aspect, level, ImageView::SAMPLING)) / bytes;
+					uint32_t samplePitchP = imageView->getMipLevelSize(aspect, level, ImageView::SAMPLING) / bytes;
+					uint32_t sampleMax = imageView->getSampleCount() - 1;
 
 					WriteTextureLevelInfo(texture, mipmapLevel, width, height, depth, pitchP, sliceP, samplePitchP, sampleMax);
 				}
@@ -448,13 +488,14 @@
 	else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
 	        entry.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
 	{
-		auto storageImage = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
+		StorageImageDescriptor *storageImage = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
+
 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
 		{
-			auto *update = reinterpret_cast<VkDescriptorImageInfo const *>(src + entry.offset + entry.stride * i);
-			auto *imageView = vk::Cast(update->imageView);
+			const VkDescriptorImageInfo *update = reinterpret_cast<const VkDescriptorImageInfo *>(src + entry.offset + entry.stride * i);
+			vk::ImageView *imageView = vk::Cast(update->imageView);
 			const auto &extent = imageView->getMipLevelExtent(0);
-			auto layerCount = imageView->getSubresourceRange().layerCount;
+			uint32_t layerCount = imageView->getSubresourceRange().layerCount;
 
 			storageImage[i].imageViewId = imageView->id;
 			storageImage[i].ptr = imageView->getOffsetPointer({ 0, 0, 0 }, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
@@ -483,11 +524,12 @@
 	}
 	else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
 	{
-		auto *storageImage = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
+		StorageImageDescriptor *storageImage = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
+
 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
 		{
-			auto update = reinterpret_cast<VkBufferView const *>(src + entry.offset + entry.stride * i);
-			auto bufferView = vk::Cast(*update);
+			const VkBufferView *update = reinterpret_cast<const VkBufferView *>(src + entry.offset + entry.stride * i);
+			const vk::BufferView *bufferView = vk::Cast(*update);
 
 			storageImage[i].imageViewId = bufferView->id;
 			storageImage[i].ptr = bufferView->getPointer();
@@ -506,11 +548,12 @@
 	        entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
 	        entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
 	{
-		auto *bufferDescriptor = reinterpret_cast<BufferDescriptor *>(memToWrite);
+		BufferDescriptor *bufferDescriptor = reinterpret_cast<BufferDescriptor *>(memToWrite);
+
 		for(uint32_t i = 0; i < entry.descriptorCount; i++)
 		{
-			auto update = reinterpret_cast<VkDescriptorBufferInfo const *>(src + entry.offset + entry.stride * i);
-			auto buffer = vk::Cast(update->buffer);
+			const VkDescriptorBufferInfo *update = reinterpret_cast<const VkDescriptorBufferInfo *>(src + entry.offset + entry.stride * i);
+			const vk::Buffer *buffer = vk::Cast(update->buffer);
 			bufferDescriptor[i].ptr = buffer->getOffsetPointer(update->offset);
 			bufferDescriptor[i].sizeInBytes = static_cast<int>((update->range == VK_WHOLE_SIZE) ? buffer->getSize() - update->offset : update->range);
 
@@ -521,45 +564,6 @@
 	}
 }
 
-void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP, int samplePitchP, int sampleMax)
-{
-	if(level == 0)
-	{
-		texture->widthWidthHeightHeight[0] = static_cast<float>(width);
-		texture->widthWidthHeightHeight[1] = static_cast<float>(width);
-		texture->widthWidthHeightHeight[2] = static_cast<float>(height);
-		texture->widthWidthHeightHeight[3] = static_cast<float>(height);
-
-		texture->width = sw::float4(static_cast<float>(width));
-		texture->height = sw::float4(static_cast<float>(height));
-		texture->depth = sw::float4(static_cast<float>(depth));
-	}
-
-	sw::Mipmap &mipmap = texture->mipmap[level];
-
-	short halfTexelU = 0x8000 / width;
-	short halfTexelV = 0x8000 / height;
-	short halfTexelW = 0x8000 / depth;
-
-	mipmap.uHalf = sw::short4(halfTexelU);
-	mipmap.vHalf = sw::short4(halfTexelV);
-	mipmap.wHalf = sw::short4(halfTexelW);
-
-	mipmap.width = sw::int4(width);
-	mipmap.height = sw::int4(height);
-	mipmap.depth = sw::int4(depth);
-
-	mipmap.onePitchP[0] = 1;
-	mipmap.onePitchP[1] = static_cast<short>(pitchP);
-	mipmap.onePitchP[2] = 1;
-	mipmap.onePitchP[3] = static_cast<short>(pitchP);
-
-	mipmap.pitchP = sw::int4(pitchP);
-	mipmap.sliceP = sw::int4(sliceP);
-	mipmap.samplePitchP = sw::int4(samplePitchP);
-	mipmap.sampleMax = sw::int4(sampleMax);
-}
-
 void DescriptorSetLayout::WriteDescriptorSet(Device *device, const VkWriteDescriptorSet &writeDescriptorSet)
 {
 	DescriptorSet *dstSet = vk::Cast(writeDescriptorSet.dstSet);
@@ -569,7 +573,8 @@
 	e.dstArrayElement = writeDescriptorSet.dstArrayElement;
 	e.descriptorCount = writeDescriptorSet.descriptorCount;
 	e.offset = 0;
-	void const *ptr = nullptr;
+	const void *ptr = nullptr;
+
 	switch(writeDescriptorSet.descriptorType)
 	{
 	case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
@@ -599,7 +604,7 @@
 		UNSUPPORTED("descriptor type %u", writeDescriptorSet.descriptorType);
 	}
 
-	WriteDescriptorSet(device, dstSet, e, reinterpret_cast<char const *>(ptr));
+	WriteDescriptorSet(device, dstSet, e, reinterpret_cast<const char *>(ptr));
 }
 
 void DescriptorSetLayout::CopyDescriptorSet(const VkCopyDescriptorSet &descriptorCopies)
diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp
index 591562c..80786a9 100644
--- a/src/Vulkan/VkDescriptorSetLayout.hpp
+++ b/src/Vulkan/VkDescriptorSetLayout.hpp
@@ -105,7 +105,6 @@
 	static void CopyDescriptorSet(const VkCopyDescriptorSet &descriptorCopies);
 
 	static void WriteDescriptorSet(Device *device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src);
-	static void WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP, int samplePitchP, int sampleMax);
 
 	void initialize(DescriptorSet *descriptorSet);
 
diff --git a/src/Vulkan/VkImageView.cpp b/src/Vulkan/VkImageView.cpp
index a468569..c555695 100644
--- a/src/Vulkan/VkImageView.cpp
+++ b/src/Vulkan/VkImageView.cpp
@@ -17,6 +17,7 @@
 #include "VkImage.hpp"
 #include "VkStructConversion.hpp"
 #include "System/Math.hpp"
+#include "System/Types.hpp"
 
 #include <climits>
 
@@ -321,24 +322,24 @@
 	return imageFormat.getAspectFormat(subresourceRange.aspectMask);
 }
 
-int ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
+uint32_t ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
 {
-	return getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
+	return sw::assert_cast<uint32_t>(getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel));
 }
 
-int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
+uint32_t ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
 {
-	return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
+	return sw::assert_cast<uint32_t>(getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel));
 }
 
-int ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
+uint32_t ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
 {
-	return getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel);
+	return sw::assert_cast<uint32_t>(getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel));
 }
 
-int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
+uint32_t ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
 {
-	return static_cast<int>(getImage(usage)->getLayerSize(aspect));
+	return sw::assert_cast<uint32_t>(getImage(usage)->getLayerSize(aspect));
 }
 
 VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel) const
@@ -352,12 +353,12 @@
 	return Extent2D(image->getMipLevelExtent(aspect, subresourceRange.baseMipLevel + mipLevel));
 }
 
-int ImageView::getDepthOrLayerCount(uint32_t mipLevel) const
+uint32_t ImageView::getDepthOrLayerCount(uint32_t mipLevel) const
 {
 	VkExtent3D extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
 	                                             subresourceRange.baseMipLevel + mipLevel);
-	int layers = subresourceRange.layerCount;
-	int depthOrLayers = layers > 1 ? layers : extent.depth;
+	uint32_t layers = subresourceRange.layerCount;
+	uint32_t depthOrLayers = layers > 1 ? layers : extent.depth;
 
 	// For cube images the number of whole cubes is returned
 	if(viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
diff --git a/src/Vulkan/VkImageView.hpp b/src/Vulkan/VkImageView.hpp
index 2121c5b..ede2bb1 100644
--- a/src/Vulkan/VkImageView.hpp
+++ b/src/Vulkan/VkImageView.hpp
@@ -103,13 +103,13 @@
 	VkImageViewType getType() const { return viewType; }
 	Format getFormat(Usage usage = RAW) const;
 	Format getFormat(VkImageAspectFlagBits aspect) const { return image->getFormat(aspect); }
-	int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
-	int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
-	int getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
-	int layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage = RAW) const;
+	uint32_t rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
+	uint32_t slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
+	uint32_t getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
+	uint32_t layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage = RAW) const;
 	VkExtent2D getMipLevelExtent(uint32_t mipLevel) const;
 	VkExtent2D getMipLevelExtent(uint32_t mipLevel, VkImageAspectFlagBits aspect) const;
-	int getDepthOrLayerCount(uint32_t mipLevel) const;
+	uint32_t getDepthOrLayerCount(uint32_t mipLevel) const;
 
 	int getSampleCount() const
 	{