Moved many Cast functions to libVulkan.cpp

We should be changing to the internal object representation ASAP
in the API and not carry around handles when it's trivial not to.

Bug: b/116336664

Change-Id: I21de3421fd3e72f3402f2d7cefe1a3dd22c87045
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/32850
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkBuffer.cpp b/src/Vulkan/VkBuffer.cpp
index 287ff22..7c09a42 100644
--- a/src/Vulkan/VkBuffer.cpp
+++ b/src/Vulkan/VkBuffer.cpp
@@ -68,9 +68,9 @@
 	return memoryRequirements;
 }
 
-void Buffer::bind(VkDeviceMemory pDeviceMemory, VkDeviceSize pMemoryOffset)
+void Buffer::bind(DeviceMemory* pDeviceMemory, VkDeviceSize pMemoryOffset)
 {
-	memory = Cast(pDeviceMemory)->getOffsetPointer(pMemoryOffset);
+	memory = pDeviceMemory->getOffsetPointer(pMemoryOffset);
 }
 
 void Buffer::copyFrom(const void* srcMemory, VkDeviceSize pSize, VkDeviceSize pOffset)
diff --git a/src/Vulkan/VkBuffer.hpp b/src/Vulkan/VkBuffer.hpp
index 26520c7..13e8732 100644
--- a/src/Vulkan/VkBuffer.hpp
+++ b/src/Vulkan/VkBuffer.hpp
@@ -20,6 +20,8 @@
 namespace vk
 {
 
+class DeviceMemory;
+
 class Buffer : public Object<Buffer, VkBuffer>
 {
 public:
@@ -29,7 +31,7 @@
 	static size_t ComputeRequiredAllocationSize(const VkBufferCreateInfo* pCreateInfo);
 
 	const VkMemoryRequirements getMemoryRequirements() const;
-	void bind(VkDeviceMemory pDeviceMemory, VkDeviceSize pMemoryOffset);
+	void bind(DeviceMemory* pDeviceMemory, VkDeviceSize pMemoryOffset);
 	void copyFrom(const void* srcMemory, VkDeviceSize size, VkDeviceSize offset);
 	void copyTo(void* dstMemory, VkDeviceSize size, VkDeviceSize offset) const;
 	void copyTo(Buffer* dstBuffer, const VkBufferCopy& pRegion) const;
diff --git a/src/Vulkan/VkBufferView.cpp b/src/Vulkan/VkBufferView.cpp
index e268ffb..5973bc8 100644
--- a/src/Vulkan/VkBufferView.cpp
+++ b/src/Vulkan/VkBufferView.cpp
@@ -20,11 +20,11 @@
 {
 
 BufferView::BufferView(const VkBufferViewCreateInfo* pCreateInfo, void* mem) :
-    buffer(pCreateInfo->buffer), format(pCreateInfo->format), offset(pCreateInfo->offset)
+    buffer(Cast(pCreateInfo->buffer)), format(pCreateInfo->format), offset(pCreateInfo->offset)
 {
     if (pCreateInfo->range == VK_WHOLE_SIZE)
     {
-        range = Cast(pCreateInfo->buffer)->getSize() - offset;
+        range = buffer->getSize() - offset;
     }
     else
     {
@@ -34,7 +34,7 @@
 
 void * BufferView::getPointer() const
 {
-    return Cast(buffer)->getOffsetPointer(offset);
+    return buffer->getOffsetPointer(offset);
 }
 
 }
\ No newline at end of file
diff --git a/src/Vulkan/VkBufferView.hpp b/src/Vulkan/VkBufferView.hpp
index 8564274..732f600 100644
--- a/src/Vulkan/VkBufferView.hpp
+++ b/src/Vulkan/VkBufferView.hpp
@@ -22,6 +22,8 @@
 namespace vk
 {
 
+class Buffer;
+
 class BufferView : public Object<BufferView, VkBufferView>
 {
 public:
@@ -39,7 +41,7 @@
 
 	const uint32_t id = ImageView::nextID++;	// ID space for sampling function cache, shared with imageviews
 private:
-	VkBuffer     buffer;
+	Buffer      *buffer;
 	VkFormat     format;
 	VkDeviceSize offset;
 	VkDeviceSize range;
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index 398d20f..de72b92 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -41,9 +41,9 @@
 class BeginRenderPass : public CommandBuffer::Command
 {
 public:
-	BeginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
+	BeginRenderPass(RenderPass* renderPass, Framebuffer* framebuffer, VkRect2D renderArea,
 	                uint32_t clearValueCount, const VkClearValue* pClearValues) :
-		renderPass(Cast(renderPass)), framebuffer(Cast(framebuffer)), renderArea(renderArea),
+		renderPass(renderPass), framebuffer(framebuffer), renderArea(renderArea),
 		clearValueCount(clearValueCount)
 	{
 		// FIXME (b/119409619): use an allocator here so we can control all memory allocations
@@ -125,7 +125,7 @@
 class ExecuteCommands : public CommandBuffer::Command
 {
 public:
-	ExecuteCommands(const VkCommandBuffer& commandBuffer) : commandBuffer(Cast(commandBuffer))
+	ExecuteCommands(const CommandBuffer* commandBuffer) : commandBuffer(commandBuffer)
 	{
 	}
 
@@ -142,8 +142,8 @@
 class PipelineBind : public CommandBuffer::Command
 {
 public:
-	PipelineBind(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) :
-		pipelineBindPoint(pipelineBindPoint), pipeline(Cast(pipeline))
+	PipelineBind(VkPipelineBindPoint pipelineBindPoint, Pipeline* pipeline) :
+		pipelineBindPoint(pipelineBindPoint), pipeline(pipeline)
 	{
 	}
 
@@ -192,8 +192,8 @@
 class DispatchIndirect : public CommandBuffer::Command
 {
 public:
-	DispatchIndirect(VkBuffer buffer, VkDeviceSize offset) :
-			buffer(Cast(buffer)), offset(offset)
+	DispatchIndirect(Buffer* buffer, VkDeviceSize offset) :
+			buffer(buffer), offset(offset)
 	{
 	}
 
@@ -218,8 +218,8 @@
 
 struct VertexBufferBind : public CommandBuffer::Command
 {
-	VertexBufferBind(uint32_t binding, const VkBuffer buffer, const VkDeviceSize offset) :
-		binding(binding), buffer(Cast(buffer)), offset(offset)
+	VertexBufferBind(uint32_t binding, Buffer* buffer, const VkDeviceSize offset) :
+		binding(binding), buffer(buffer), offset(offset)
 	{
 	}
 
@@ -236,8 +236,8 @@
 
 struct IndexBufferBind : public CommandBuffer::Command
 {
-	IndexBufferBind(const VkBuffer buffer, const VkDeviceSize offset, const VkIndexType indexType) :
-		buffer(Cast(buffer)), offset(offset), indexType(indexType)
+	IndexBufferBind(Buffer* buffer, const VkDeviceSize offset, const VkIndexType indexType) :
+		buffer(buffer), offset(offset), indexType(indexType)
 	{
 
 	}
@@ -655,8 +655,8 @@
 
 struct DrawIndirect : public DrawBase
 {
-	DrawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
-			: buffer(Cast(buffer)), offset(offset), drawCount(drawCount), stride(stride)
+	DrawIndirect(Buffer* buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
+			: buffer(buffer), offset(offset), drawCount(drawCount), stride(stride)
 	{
 	}
 
@@ -678,8 +678,8 @@
 
 struct DrawIndexedIndirect : public DrawBase
 {
-	DrawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
-			: buffer(Cast(buffer)), offset(offset), drawCount(drawCount), stride(stride)
+	DrawIndexedIndirect(Buffer* buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
+			: buffer(buffer), offset(offset), drawCount(drawCount), stride(stride)
 	{
 	}
 
@@ -701,8 +701,8 @@
 
 struct ImageToImageCopy : public CommandBuffer::Command
 {
-	ImageToImageCopy(VkImage srcImage, VkImage dstImage, const VkImageCopy& region) :
-		srcImage(Cast(srcImage)), dstImage(Cast(dstImage)), region(region)
+	ImageToImageCopy(const Image* srcImage, Image* dstImage, const VkImageCopy& region) :
+		srcImage(srcImage), dstImage(dstImage), region(region)
 	{
 	}
 
@@ -712,15 +712,15 @@
 	}
 
 private:
-	Image* srcImage;
+	const Image* srcImage;
 	Image* dstImage;
 	const VkImageCopy region;
 };
 
 struct BufferToBufferCopy : public CommandBuffer::Command
 {
-	BufferToBufferCopy(VkBuffer srcBuffer, VkBuffer dstBuffer, const VkBufferCopy& region) :
-		srcBuffer(Cast(srcBuffer)), dstBuffer(Cast(dstBuffer)), region(region)
+	BufferToBufferCopy(const Buffer* srcBuffer, Buffer* dstBuffer, const VkBufferCopy& region) :
+		srcBuffer(srcBuffer), dstBuffer(dstBuffer), region(region)
 	{
 	}
 
@@ -730,15 +730,15 @@
 	}
 
 private:
-	Buffer* srcBuffer;
+	const Buffer* srcBuffer;
 	Buffer* dstBuffer;
 	const VkBufferCopy region;
 };
 
 struct ImageToBufferCopy : public CommandBuffer::Command
 {
-	ImageToBufferCopy(VkImage srcImage, VkBuffer dstBuffer, const VkBufferImageCopy& region) :
-		srcImage(Cast(srcImage)), dstBuffer(Cast(dstBuffer)), region(region)
+	ImageToBufferCopy(Image* srcImage, Buffer* dstBuffer, const VkBufferImageCopy& region) :
+		srcImage(srcImage), dstBuffer(dstBuffer), region(region)
 	{
 	}
 
@@ -755,8 +755,8 @@
 
 struct BufferToImageCopy : public CommandBuffer::Command
 {
-	BufferToImageCopy(VkBuffer srcBuffer, VkImage dstImage, const VkBufferImageCopy& region) :
-		srcBuffer(Cast(srcBuffer)), dstImage(Cast(dstImage)), region(region)
+	BufferToImageCopy(Buffer* srcBuffer, Image* dstImage, const VkBufferImageCopy& region) :
+		srcBuffer(srcBuffer), dstImage(dstImage), region(region)
 	{
 	}
 
@@ -773,8 +773,8 @@
 
 struct FillBuffer : public CommandBuffer::Command
 {
-	FillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) :
-		dstBuffer(Cast(dstBuffer)), dstOffset(dstOffset), size(size), data(data)
+	FillBuffer(Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) :
+		dstBuffer(dstBuffer), dstOffset(dstOffset), size(size), data(data)
 	{
 	}
 
@@ -792,8 +792,8 @@
 
 struct UpdateBuffer : public CommandBuffer::Command
 {
-	UpdateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint8_t* pData) :
-		dstBuffer(Cast(dstBuffer)), dstOffset(dstOffset), data(pData, &pData[dataSize])
+	UpdateBuffer(Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint8_t* pData) :
+		dstBuffer(dstBuffer), dstOffset(dstOffset), data(pData, &pData[dataSize])
 	{
 	}
 
@@ -810,8 +810,8 @@
 
 struct ClearColorImage : public CommandBuffer::Command
 {
-	ClearColorImage(VkImage image, const VkClearColorValue& color, const VkImageSubresourceRange& range) :
-		image(Cast(image)), color(color), range(range)
+	ClearColorImage(Image* image, const VkClearColorValue& color, const VkImageSubresourceRange& range) :
+		image(image), color(color), range(range)
 	{
 	}
 
@@ -828,8 +828,8 @@
 
 struct ClearDepthStencilImage : public CommandBuffer::Command
 {
-	ClearDepthStencilImage(VkImage image, const VkClearDepthStencilValue& depthStencil, const VkImageSubresourceRange& range) :
-		image(Cast(image)), depthStencil(depthStencil), range(range)
+	ClearDepthStencilImage(Image* image, const VkClearDepthStencilValue& depthStencil, const VkImageSubresourceRange& range) :
+		image(image), depthStencil(depthStencil), range(range)
 	{
 	}
 
@@ -867,8 +867,8 @@
 
 struct BlitImage : public CommandBuffer::Command
 {
-	BlitImage(VkImage srcImage, VkImage dstImage, const VkImageBlit& region, VkFilter filter) :
-		srcImage(Cast(srcImage)), dstImage(Cast(dstImage)), region(region), filter(filter)
+	BlitImage(const Image* srcImage, Image* dstImage, const VkImageBlit& region, VkFilter filter) :
+		srcImage(srcImage), dstImage(dstImage), region(region), filter(filter)
 	{
 	}
 
@@ -886,8 +886,8 @@
 
 struct ResolveImage : public CommandBuffer::Command
 {
-	ResolveImage(VkImage srcImage, VkImage dstImage, const VkImageResolve& region) :
-		srcImage(Cast(srcImage)), dstImage(Cast(dstImage)), region(region)
+	ResolveImage(const Image* srcImage, Image* dstImage, const VkImageResolve& region) :
+		srcImage(srcImage), dstImage(dstImage), region(region)
 	{
 	}
 
@@ -925,7 +925,7 @@
 
 struct SignalEvent : public CommandBuffer::Command
 {
-	SignalEvent(VkEvent ev, VkPipelineStageFlags stageMask) : ev(Cast(ev)), stageMask(stageMask)
+	SignalEvent(Event* ev, VkPipelineStageFlags stageMask) : ev(ev), stageMask(stageMask)
 	{
 	}
 
@@ -942,7 +942,7 @@
 
 struct ResetEvent : public CommandBuffer::Command
 {
-	ResetEvent(VkEvent ev, VkPipelineStageFlags stageMask) : ev(Cast(ev)), stageMask(stageMask)
+	ResetEvent(Event* ev, VkPipelineStageFlags stageMask) : ev(ev), stageMask(stageMask)
 	{
 	}
 
@@ -958,7 +958,7 @@
 
 struct WaitEvent : public CommandBuffer::Command
 {
-	WaitEvent(VkEvent ev) : ev(Cast(ev))
+	WaitEvent(Event* ev) : ev(ev)
 	{
 	}
 
@@ -974,7 +974,7 @@
 
 struct BindDescriptorSet : public CommandBuffer::Command
 {
-	BindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, vk::PipelineLayout *pipelineLayout, uint32_t set, const VkDescriptorSet& descriptorSet,
+	BindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, const PipelineLayout *pipelineLayout, uint32_t set, DescriptorSet* descriptorSet,
 		uint32_t dynamicOffsetCount, uint32_t const *dynamicOffsets)
 		: pipelineBindPoint(pipelineBindPoint), pipelineLayout(pipelineLayout), set(set), descriptorSet(descriptorSet),
 		  dynamicOffsetCount(dynamicOffsetCount)
@@ -992,7 +992,7 @@
 		auto dynamicOffsetBase = pipelineLayout->getDynamicOffsetBase(set);
 		ASSERT_OR_RETURN(dynamicOffsetBase + dynamicOffsetCount <= MAX_DESCRIPTOR_SET_COMBINED_BUFFERS_DYNAMIC);
 
-		pipelineState.descriptorSets[set] = vk::Cast(descriptorSet);
+		pipelineState.descriptorSets[set] = descriptorSet;
 		for (uint32_t i = 0; i < dynamicOffsetCount; i++)
 		{
 			pipelineState.descriptorDynamicOffsets[dynamicOffsetBase + i] = dynamicOffsets[i];
@@ -1001,9 +1001,9 @@
 
 private:
 	VkPipelineBindPoint pipelineBindPoint;
-	PipelineLayout *pipelineLayout;
+	const PipelineLayout *pipelineLayout;
 	uint32_t set;
-	const VkDescriptorSet descriptorSet;
+	vk::DescriptorSet* descriptorSet;
 	uint32_t dynamicOffsetCount;
 	DescriptorSet::DynamicOffsets dynamicOffsets;
 };
@@ -1032,8 +1032,8 @@
 
 struct BeginQuery : public CommandBuffer::Command
 {
-	BeginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
-		: queryPool(Cast(queryPool)), query(query), flags(flags)
+	BeginQuery(QueryPool* queryPool, uint32_t query, VkQueryControlFlags flags)
+		: queryPool(queryPool), query(query), flags(flags)
 	{
 	}
 
@@ -1051,8 +1051,8 @@
 
 struct EndQuery : public CommandBuffer::Command
 {
-	EndQuery(VkQueryPool queryPool, uint32_t query)
-		: queryPool(Cast(queryPool)), query(query)
+	EndQuery(QueryPool* queryPool, uint32_t query)
+		: queryPool(queryPool), query(query)
 	{
 	}
 
@@ -1069,8 +1069,8 @@
 
 struct ResetQueryPool : public CommandBuffer::Command
 {
-	ResetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
-		: queryPool(Cast(queryPool)), firstQuery(firstQuery), queryCount(queryCount)
+	ResetQueryPool(QueryPool* queryPool, uint32_t firstQuery, uint32_t queryCount)
+		: queryPool(queryPool), firstQuery(firstQuery), queryCount(queryCount)
 	{
 	}
 
@@ -1087,8 +1087,8 @@
 
 struct WriteTimeStamp : public CommandBuffer::Command
 {
-	WriteTimeStamp(VkQueryPool queryPool, uint32_t query)
-		: queryPool(Cast(queryPool)), query(query)
+	WriteTimeStamp(QueryPool* queryPool, uint32_t query)
+		: queryPool(queryPool), query(query)
 	{
 	}
 
@@ -1104,25 +1104,24 @@
 
 struct CopyQueryPoolResults : public CommandBuffer::Command
 {
-	CopyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
-		VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
-		: queryPool(Cast(queryPool)), firstQuery(firstQuery), queryCount(queryCount),
+	CopyQueryPoolResults(const QueryPool* queryPool, uint32_t firstQuery, uint32_t queryCount,
+		Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
+		: queryPool(queryPool), firstQuery(firstQuery), queryCount(queryCount),
 		  dstBuffer(dstBuffer), dstOffset(dstOffset), stride(stride), flags(flags)
 	{
 	}
 
 	void play(CommandBuffer::ExecutionState& executionState)
 	{
-		vk::Buffer* buffer = Cast(dstBuffer);
-		queryPool->getResults(firstQuery, queryCount, buffer->getSize() - dstOffset,
-		                      buffer->getOffsetPointer(dstOffset), stride, flags);
+		queryPool->getResults(firstQuery, queryCount, dstBuffer->getSize() - dstOffset,
+		                      dstBuffer->getOffsetPointer(dstOffset), stride, flags);
 	}
 
 private:
-	QueryPool* queryPool;
+	const QueryPool* queryPool;
 	uint32_t firstQuery;
 	uint32_t queryCount;
-	VkBuffer dstBuffer;
+	Buffer* dstBuffer;
 	VkDeviceSize dstOffset;
 	VkDeviceSize stride;
 	VkQueryResultFlags flags;
@@ -1194,7 +1193,7 @@
 	commands->push_back(std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
 }
 
-void CommandBuffer::beginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
+void CommandBuffer::beginRenderPass(RenderPass* renderPass, Framebuffer* framebuffer, VkRect2D renderArea,
                                     uint32_t clearValueCount, const VkClearValue* clearValues, VkSubpassContents contents)
 {
 	ASSERT(state == RECORDING);
@@ -1220,7 +1219,7 @@
 
 	for(uint32_t i = 0; i < commandBufferCount; ++i)
 	{
-		addCommand<ExecuteCommands>(pCommandBuffers[i]);
+		addCommand<ExecuteCommands>(vk::Cast(pCommandBuffers[i]));
 	}
 }
 
@@ -1244,7 +1243,7 @@
 	addCommand<PipelineBarrier>();
 }
 
-void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
+void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, Pipeline* pipeline)
 {
 	switch(pipelineBindPoint)
 	{
@@ -1262,37 +1261,37 @@
 {
 	for(uint32_t i = 0; i < bindingCount; ++i)
 	{
-		addCommand<VertexBufferBind>(i + firstBinding, pBuffers[i], pOffsets[i]);
+		addCommand<VertexBufferBind>(i + firstBinding, vk::Cast(pBuffers[i]), pOffsets[i]);
 	}
 }
 
-void CommandBuffer::beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
+void CommandBuffer::beginQuery(QueryPool* queryPool, uint32_t query, VkQueryControlFlags flags)
 {
 	addCommand<BeginQuery>(queryPool, query, flags);
 }
 
-void CommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
+void CommandBuffer::endQuery(QueryPool* queryPool, uint32_t query)
 {
 	addCommand<EndQuery>(queryPool, query);
 }
 
-void CommandBuffer::resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
+void CommandBuffer::resetQueryPool(QueryPool* queryPool, uint32_t firstQuery, uint32_t queryCount)
 {
 	addCommand<ResetQueryPool>(queryPool, firstQuery, queryCount);
 }
 
-void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
+void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, QueryPool* queryPool, uint32_t query)
 {
 	addCommand<WriteTimeStamp>(queryPool, query);
 }
 
-void CommandBuffer::copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
-	VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
+void CommandBuffer::copyQueryPoolResults(const QueryPool* queryPool, uint32_t firstQuery, uint32_t queryCount,
+	Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
 {
 	addCommand<CopyQueryPoolResults>(queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
 }
 
-void CommandBuffer::pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags,
+void CommandBuffer::pushConstants(PipelineLayout* layout, VkShaderStageFlags stageFlags,
 	uint32_t offset, uint32_t size, const void* pValues)
 {
 	addCommand<SetPushConstants>(offset, size, pValues);
@@ -1369,7 +1368,7 @@
 	addCommand<SetStencilReference>(faceMask, reference);
 }
 
-void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout vkLayout,
+void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, const PipelineLayout* layout,
 	uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
 	uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
 {
@@ -1378,7 +1377,6 @@
 	for(uint32_t i = 0; i < descriptorSetCount; i++)
 	{
 		auto descriptorSetIndex = firstSet + i;
-		auto layout = vk::Cast(vkLayout);
 		auto setLayout = layout->getDescriptorSetLayout(descriptorSetIndex);
 
 		auto numDynamicDescriptors = setLayout->getDynamicDescriptorCount();
@@ -1386,7 +1384,7 @@
 		ASSERT(dynamicOffsetCount >= numDynamicDescriptors);
 
 		addCommand<BindDescriptorSet>(
-				pipelineBindPoint, layout, descriptorSetIndex, pDescriptorSets[i],
+				pipelineBindPoint, layout, descriptorSetIndex, Cast(pDescriptorSets[i]),
 				dynamicOffsetCount, pDynamicOffsets);
 
 		pDynamicOffsets += numDynamicDescriptors;
@@ -1394,7 +1392,7 @@
 	}
 }
 
-void CommandBuffer::bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
+void CommandBuffer::bindIndexBuffer(Buffer* buffer, VkDeviceSize offset, VkIndexType indexType)
 {
 	addCommand<IndexBufferBind>(buffer, offset, indexType);
 }
@@ -1404,12 +1402,12 @@
 	addCommand<Dispatch>(0, 0, 0, groupCountX, groupCountY, groupCountZ);
 }
 
-void CommandBuffer::dispatchIndirect(VkBuffer buffer, VkDeviceSize offset)
+void CommandBuffer::dispatchIndirect(Buffer* buffer, VkDeviceSize offset)
 {
 	addCommand<DispatchIndirect>(buffer, offset);
 }
 
-void CommandBuffer::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
+void CommandBuffer::copyBuffer(const Buffer* srcBuffer, Buffer* dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
 {
 	ASSERT(state == RECORDING);
 
@@ -1419,7 +1417,7 @@
 	}
 }
 
-void CommandBuffer::copyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
+void CommandBuffer::copyImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
 	uint32_t regionCount, const VkImageCopy* pRegions)
 {
 	ASSERT(state == RECORDING);
@@ -1434,7 +1432,7 @@
 	}
 }
 
-void CommandBuffer::blitImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
+void CommandBuffer::blitImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
 	uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
 {
 	ASSERT(state == RECORDING);
@@ -1449,7 +1447,7 @@
 	}
 }
 
-void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout,
+void CommandBuffer::copyBufferToImage(Buffer* srcBuffer, Image* dstImage, VkImageLayout dstImageLayout,
 	uint32_t regionCount, const VkBufferImageCopy* pRegions)
 {
 	ASSERT(state == RECORDING);
@@ -1460,7 +1458,7 @@
 	}
 }
 
-void CommandBuffer::copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer,
+void CommandBuffer::copyImageToBuffer(Image* srcImage, VkImageLayout srcImageLayout, Buffer* dstBuffer,
 	uint32_t regionCount, const VkBufferImageCopy* pRegions)
 {
 	ASSERT(state == RECORDING);
@@ -1472,21 +1470,21 @@
 	}
 }
 
-void CommandBuffer::updateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
+void CommandBuffer::updateBuffer(Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
 {
 	ASSERT(state == RECORDING);
 
 	addCommand<UpdateBuffer>(dstBuffer, dstOffset, dataSize, reinterpret_cast<const uint8_t*>(pData));
 }
 
-void CommandBuffer::fillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
+void CommandBuffer::fillBuffer(Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
 {
 	ASSERT(state == RECORDING);
 
 	addCommand<FillBuffer>(dstBuffer, dstOffset, size, data);
 }
 
-void CommandBuffer::clearColorImage(VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
+void CommandBuffer::clearColorImage(Image* image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
 	uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
 {
 	ASSERT(state == RECORDING);
@@ -1497,7 +1495,7 @@
 	}
 }
 
-void CommandBuffer::clearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
+void CommandBuffer::clearDepthStencilImage(Image* image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
 	uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
 {
 	ASSERT(state == RECORDING);
@@ -1522,7 +1520,7 @@
 	}
 }
 
-void CommandBuffer::resolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
+void CommandBuffer::resolveImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
 	uint32_t regionCount, const VkImageResolve* pRegions)
 {
 	ASSERT(state == RECORDING);
@@ -1537,14 +1535,14 @@
 	}
 }
 
-void CommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
+void CommandBuffer::setEvent(Event* event, VkPipelineStageFlags stageMask)
 {
 	ASSERT(state == RECORDING);
 
 	addCommand<SignalEvent>(event, stageMask);
 }
 
-void CommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
+void CommandBuffer::resetEvent(Event* event, VkPipelineStageFlags stageMask)
 {
 	ASSERT(state == RECORDING);
 
@@ -1563,7 +1561,7 @@
 	// Note: srcStageMask and dstStageMask are currently ignored
 	for(uint32_t i = 0; i < eventCount; i++)
 	{
-		addCommand<WaitEvent>(pEvents[i]);
+		addCommand<WaitEvent>(vk::Cast(pEvents[i]));
 	}
 }
 
@@ -1577,12 +1575,12 @@
 	addCommand<DrawIndexed>(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
 }
 
-void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
+void CommandBuffer::drawIndirect(Buffer* buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
 {
 	addCommand<DrawIndirect>(buffer, offset, drawCount, stride);
 }
 
-void CommandBuffer::drawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
+void CommandBuffer::drawIndexedIndirect(Buffer* buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
 {
 	addCommand<DrawIndexedIndirect>(buffer, offset, drawCount, stride);
 }
diff --git a/src/Vulkan/VkCommandBuffer.hpp b/src/Vulkan/VkCommandBuffer.hpp
index 1fc81cd..adef7e7 100644
--- a/src/Vulkan/VkCommandBuffer.hpp
+++ b/src/Vulkan/VkCommandBuffer.hpp
@@ -34,8 +34,12 @@
 {
 
 class Buffer;
+class Event;
 class Framebuffer;
+class Image;
 class Pipeline;
+class PipelineLayout;
+class QueryPool;
 class RenderPass;
 
 class CommandBuffer
@@ -51,7 +55,7 @@
 	VkResult end();
 	VkResult reset(VkCommandPoolResetFlags flags);
 
-	void beginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
+	void beginRenderPass(RenderPass* renderPass, Framebuffer* framebuffer, VkRect2D renderArea,
 	                     uint32_t clearValueCount, const VkClearValue* pClearValues, VkSubpassContents contents);
 	void nextSubpass(VkSubpassContents contents);
 	void endRenderPass();
@@ -65,17 +69,17 @@
 	                     uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
 	                     uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
 	                     uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
-	void bindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline);
+	void bindPipeline(VkPipelineBindPoint pipelineBindPoint, Pipeline* pipeline);
 	void bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
 	                       const VkBuffer* pBuffers, const VkDeviceSize* pOffsets);
 
-	void beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags);
-	void endQuery(VkQueryPool queryPool, uint32_t query);
-	void resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
-	void writeTimestamp(VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query);
-	void copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
-	                          VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags);
-	void pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags,
+	void beginQuery(QueryPool* queryPool, uint32_t query, VkQueryControlFlags flags);
+	void endQuery(QueryPool* queryPool, uint32_t query);
+	void resetQueryPool(QueryPool* queryPool, uint32_t firstQuery, uint32_t queryCount);
+	void writeTimestamp(VkPipelineStageFlagBits pipelineStage, QueryPool* queryPool, uint32_t query);
+	void copyQueryPoolResults(const QueryPool* queryPool, uint32_t firstQuery, uint32_t queryCount,
+	                          Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags);
+	void pushConstants(PipelineLayout* layout, VkShaderStageFlags stageFlags,
 	                   uint32_t offset, uint32_t size, const void* pValues);
 
 	void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports);
@@ -87,33 +91,33 @@
 	void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask);
 	void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask);
 	void setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference);
-	void bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
+	void bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, const PipelineLayout* layout,
 		uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
 		uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets);
-	void bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType);
+	void bindIndexBuffer(Buffer* buffer, VkDeviceSize offset, VkIndexType indexType);
 	void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
-	void dispatchIndirect(VkBuffer buffer, VkDeviceSize offset);
-	void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions);
-	void copyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
+	void dispatchIndirect(Buffer* buffer, VkDeviceSize offset);
+	void copyBuffer(const Buffer* srcBuffer, Buffer* dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions);
+	void copyImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
 		uint32_t regionCount, const VkImageCopy* pRegions);
-	void blitImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
+	void blitImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
 		uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter);
-	void copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout,
+	void copyBufferToImage(Buffer* srcBuffer, Image* dstImage, VkImageLayout dstImageLayout,
 		uint32_t regionCount, const VkBufferImageCopy* pRegions);
-	void copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer,
+	void copyImageToBuffer(Image* srcImage, VkImageLayout srcImageLayout, Buffer* dstBuffer,
 		uint32_t regionCount, const VkBufferImageCopy* pRegions);
-	void updateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData);
-	void fillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data);
-	void clearColorImage(VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
+	void updateBuffer(Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData);
+	void fillBuffer(Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data);
+	void clearColorImage(Image* image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
 		uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
-	void clearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
+	void clearDepthStencilImage(Image* image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
 		uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
 	void clearAttachments(uint32_t attachmentCount, const VkClearAttachment* pAttachments,
 		uint32_t rectCount, const VkClearRect* pRects);
-	void resolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
+	void resolveImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
 		uint32_t regionCount, const VkImageResolve* pRegions);
-	void setEvent(VkEvent event, VkPipelineStageFlags stageMask);
-	void resetEvent(VkEvent event, VkPipelineStageFlags stageMask);
+	void setEvent(Event* event, VkPipelineStageFlags stageMask);
+	void resetEvent(Event* event, VkPipelineStageFlags stageMask);
 	void waitEvents(uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask,
 		VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
 		uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
@@ -121,8 +125,8 @@
 
 	void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
 	void drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
-	void drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
-	void drawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+	void drawIndirect(Buffer* buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+	void drawIndexedIndirect(Buffer* buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
 
 	// TODO(sugoi): Move ExecutionState out of CommandBuffer (possibly into Device)
 	struct ExecutionState
diff --git a/src/Vulkan/VkDescriptorPool.cpp b/src/Vulkan/VkDescriptorPool.cpp
index bd1719a..fa4df1f 100644
--- a/src/Vulkan/VkDescriptorPool.cpp
+++ b/src/Vulkan/VkDescriptorPool.cpp
@@ -62,7 +62,7 @@
 	{
 		for(uint32_t i = 0; i < descriptorSetCount; i++)
 		{
-			Cast(pSetLayouts[i])->initialize(pDescriptorSets[i]);
+			Cast(pSetLayouts[i])->initialize(vk::Cast(pDescriptorSets[i]));
 		}
 	}
 	return result;
diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp
index 624fef9..d6668cd 100644
--- a/src/Vulkan/VkDescriptorSetLayout.cpp
+++ b/src/Vulkan/VkDescriptorSetLayout.cpp
@@ -144,10 +144,9 @@
 	return 0;
 }
 
-void DescriptorSetLayout::initialize(VkDescriptorSet vkDescriptorSet)
+void DescriptorSetLayout::initialize(DescriptorSet* descriptorSet)
 {
 	// Use a pointer to this descriptor set layout as the descriptor set's header
-	DescriptorSet* descriptorSet = vk::Cast(vkDescriptorSet);
 	descriptorSet->header.layout = this;
 	uint8_t* mem = descriptorSet->data;
 
diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp
index 08408f2..8ebdfda 100644
--- a/src/Vulkan/VkDescriptorSetLayout.hpp
+++ b/src/Vulkan/VkDescriptorSetLayout.hpp
@@ -84,7 +84,7 @@
 	static void WriteDescriptorSet(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);
 
-	void initialize(VkDescriptorSet descriptorSet);
+	void initialize(DescriptorSet* descriptorSet);
 
 	// Returns the total size of the descriptor set in bytes.
 	size_t getDescriptorSetAllocationSize() const;
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index d7878ec..ad253cf 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -323,7 +323,7 @@
 
 #undef MAKE_VULKAN_DEVICE_ENTRY
 
-PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName)
+PFN_vkVoidFunction GetInstanceProcAddr(Instance* instance, const char* pName)
 {
 	auto globalFunction = globalFunctionPointers.find(std::string(pName));
 	if(globalFunction != globalFunctionPointers.end())
@@ -331,7 +331,7 @@
 		return globalFunction->second;
 	}
 
-	if(instance != VK_NULL_HANDLE)
+	if(instance != nullptr)
 	{
 		auto instanceFunction = instanceFunctionPointers.find(std::string(pName));
 		if(instanceFunction != instanceFunctionPointers.end())
@@ -358,7 +358,7 @@
 	return nullptr;
 }
 
-PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName)
+PFN_vkVoidFunction GetDeviceProcAddr(Device* device, const char* pName)
 {
 	auto deviceFunction = deviceFunctionPointers.find(std::string(pName));
 	if(deviceFunction != deviceFunctionPointers.end())
@@ -366,10 +366,9 @@
 		return deviceFunction->second;
 	}
 
-	vk::Device* myDevice = Cast(device);
 	for(const auto& deviceExtensionFunctions : deviceExtensionFunctionPointers)
 	{
-		if(myDevice->hasExtension(deviceExtensionFunctions.first))
+		if(device->hasExtension(deviceExtensionFunctions.first))
 		{
 			deviceFunction = deviceExtensionFunctions.second.find(std::string(pName));
 			if(deviceFunction != deviceExtensionFunctions.second.end())
diff --git a/src/Vulkan/VkGetProcAddress.h b/src/Vulkan/VkGetProcAddress.h
index 0531b77..27562ff 100644
--- a/src/Vulkan/VkGetProcAddress.h
+++ b/src/Vulkan/VkGetProcAddress.h
@@ -19,8 +19,13 @@
 
 namespace vk
 {
-PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName);
-PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName);
+
+class Device;
+class Instance;
+
+PFN_vkVoidFunction GetInstanceProcAddr(Instance* instance, const char* pName);
+PFN_vkVoidFunction GetDeviceProcAddr(Device* device, const char* pName);
+
 }
 
 #endif // VK_UTILS_HPP_
\ No newline at end of file
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp
index 7374a84..7d4209d 100644
--- a/src/Vulkan/VkImage.cpp
+++ b/src/Vulkan/VkImage.cpp
@@ -96,9 +96,9 @@
 	return memoryRequirements;
 }
 
-void Image::bind(VkDeviceMemory pDeviceMemory, VkDeviceSize pMemoryOffset)
+void Image::bind(DeviceMemory* pDeviceMemory, VkDeviceSize pMemoryOffset)
 {
-	deviceMemory = Cast(pDeviceMemory);
+	deviceMemory = pDeviceMemory;
 	memoryOffset = pMemoryOffset;
 	if(decompressedImage)
 	{
diff --git a/src/Vulkan/VkImage.hpp b/src/Vulkan/VkImage.hpp
index f31209d..ff9511a 100644
--- a/src/Vulkan/VkImage.hpp
+++ b/src/Vulkan/VkImage.hpp
@@ -35,7 +35,7 @@
 
 	const VkMemoryRequirements getMemoryRequirements() const;
 	void getSubresourceLayout(const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout) const;
-	void bind(VkDeviceMemory pDeviceMemory, VkDeviceSize pMemoryOffset);
+	void bind(DeviceMemory* pDeviceMemory, VkDeviceSize pMemoryOffset);
 	void copyTo(Image* dstImage, const VkImageCopy& pRegion) const;
 	void copyTo(Buffer* dstBuffer, const VkBufferImageCopy& region);
 	void copyFrom(Buffer* srcBuffer, const VkBufferImageCopy& region);
diff --git a/src/Vulkan/VkQueue.cpp b/src/Vulkan/VkQueue.cpp
index 3657c1f..4c03198 100644
--- a/src/Vulkan/VkQueue.cpp
+++ b/src/Vulkan/VkQueue.cpp
@@ -91,14 +91,14 @@
 	garbageCollect();
 }
 
-VkResult Queue::submit(uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence)
+VkResult Queue::submit(uint32_t submitCount, const VkSubmitInfo* pSubmits, Fence* fence)
 {
 	garbageCollect();
 
 	Task task;
 	task.submitCount = submitCount;
 	task.pSubmits = DeepCopySubmitInfo(submitCount, pSubmits);
-	task.events = (fence != VK_NULL_HANDLE) ? vk::Cast(fence) : nullptr;
+	task.events = fence;
 
 	if(task.events)
 	{
diff --git a/src/Vulkan/VkQueue.hpp b/src/Vulkan/VkQueue.hpp
index e32541c..cfa462b 100644
--- a/src/Vulkan/VkQueue.hpp
+++ b/src/Vulkan/VkQueue.hpp
@@ -31,6 +31,8 @@
 namespace vk
 {
 
+class Fence;
+
 class Queue
 {
 	VK_LOADER_DATA loaderData = { ICD_LOADER_MAGIC };
@@ -44,7 +46,7 @@
 		return reinterpret_cast<VkQueue>(this);
 	}
 
-	VkResult submit(uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence);
+	VkResult submit(uint32_t submitCount, const VkSubmitInfo* pSubmits, Fence* fence);
 	VkResult waitIdle();
 #ifndef __ANDROID__
 	void present(const VkPresentInfoKHR* presentInfo);
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index bc39d38..9bacfb6 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -83,7 +83,7 @@
 {
 	TRACE("(VkInstance instance = %p, const char* pName = %p)", instance, pName);
 
-	return vk::GetInstanceProcAddr(instance, pName);
+	return vk::GetInstanceProcAddr(vk::Cast(instance), pName);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion)
@@ -361,14 +361,14 @@
 {
 	TRACE("(VkInstance instance = %p, const char* pName = %p)", instance, pName);
 
-	return vk::GetInstanceProcAddr(instance, pName);
+	return vk::GetInstanceProcAddr(vk::Cast(instance), pName);
 }
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName)
 {
 	TRACE("(VkDevice device = %p, const char* pName = %p)", device, pName);
 
-	return vk::GetDeviceProcAddr(device, pName);
+	return vk::GetDeviceProcAddr(vk::Cast(device), pName);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
@@ -589,7 +589,7 @@
 	TRACE("(VkQueue queue = %p, uint32_t submitCount = %d, const VkSubmitInfo* pSubmits = %p, VkFence fence = %p)",
 	      queue, submitCount, pSubmits, fence.get());
 
-	return vk::Cast(queue)->submit(submitCount, pSubmits, fence);
+	return vk::Cast(queue)->submit(submitCount, pSubmits, vk::Cast(fence));
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue)
@@ -715,7 +715,7 @@
 	TRACE("(VkDevice device = %p, VkBuffer buffer = %p, VkDeviceMemory memory = %p, VkDeviceSize memoryOffset = %d)",
 		    device, buffer.get(), memory.get(), int(memoryOffset));
 
-	vk::Cast(buffer)->bind(memory, memoryOffset);
+	vk::Cast(buffer)->bind(vk::Cast(memory), memoryOffset);
 
 	return VK_SUCCESS;
 }
@@ -725,7 +725,7 @@
 	TRACE("(VkDevice device = %p, VkImage image = %p, VkDeviceMemory memory = %p, VkDeviceSize memoryOffset = %d)",
 		    device, image.get(), memory.get(), int(memoryOffset));
 
-	vk::Cast(image)->bind(memory, memoryOffset);
+	vk::Cast(image)->bind(vk::Cast(memory), memoryOffset);
 
 	return VK_SUCCESS;
 }
@@ -1636,7 +1636,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineBindPoint pipelineBindPoint = %d, VkPipeline pipeline = %p)",
 		    commandBuffer, int(pipelineBindPoint), pipeline.get());
 
-	vk::Cast(commandBuffer)->bindPipeline(pipelineBindPoint, pipeline);
+	vk::Cast(commandBuffer)->bindPipeline(pipelineBindPoint, vk::Cast(pipeline));
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
@@ -1715,7 +1715,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineBindPoint pipelineBindPoint = %d, VkPipelineLayout layout = %p, uint32_t firstSet = %d, uint32_t descriptorSetCount = %d, const VkDescriptorSet* pDescriptorSets = %p, uint32_t dynamicOffsetCount = %d, const uint32_t* pDynamicOffsets = %p)",
 	      commandBuffer, int(pipelineBindPoint), layout.get(), int(firstSet), int(descriptorSetCount), pDescriptorSets, int(dynamicOffsetCount), pDynamicOffsets);
 
-	vk::Cast(commandBuffer)->bindDescriptorSets(pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
+	vk::Cast(commandBuffer)->bindDescriptorSets(pipelineBindPoint, vk::Cast(layout), firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
@@ -1723,7 +1723,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer buffer = %p, VkDeviceSize offset = %d, VkIndexType indexType = %d)",
 	      commandBuffer, buffer.get(), int(offset), int(indexType));
 
-	vk::Cast(commandBuffer)->bindIndexBuffer(buffer, offset, indexType);
+	vk::Cast(commandBuffer)->bindIndexBuffer(vk::Cast(buffer), offset, indexType);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
@@ -1755,7 +1755,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer buffer = %p, VkDeviceSize offset = %d, uint32_t drawCount = %d, uint32_t stride = %d)",
 		    commandBuffer, buffer.get(), int(offset), int(drawCount), int(stride));
 
-	vk::Cast(commandBuffer)->drawIndirect(buffer, offset, drawCount, stride);
+	vk::Cast(commandBuffer)->drawIndirect(vk::Cast(buffer), offset, drawCount, stride);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
@@ -1763,7 +1763,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer buffer = %p, VkDeviceSize offset = %d, uint32_t drawCount = %d, uint32_t stride = %d)",
 		    commandBuffer, buffer.get(), int(offset), int(drawCount), int(stride));
 
-	vk::Cast(commandBuffer)->drawIndexedIndirect(buffer, offset, drawCount, stride);
+	vk::Cast(commandBuffer)->drawIndexedIndirect(vk::Cast(buffer), offset, drawCount, stride);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
@@ -1779,7 +1779,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer buffer = %p, VkDeviceSize offset = %d)",
 	      commandBuffer, buffer.get(), int(offset));
 
-	vk::Cast(commandBuffer)->dispatchIndirect(buffer, offset);
+	vk::Cast(commandBuffer)->dispatchIndirect(vk::Cast(buffer), offset);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
@@ -1787,7 +1787,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer srcBuffer = %p, VkBuffer dstBuffer = %p, uint32_t regionCount = %d, const VkBufferCopy* pRegions = %p)",
 	      commandBuffer, srcBuffer.get(), dstBuffer.get(), int(regionCount), pRegions);
 
-	vk::Cast(commandBuffer)->copyBuffer(srcBuffer, dstBuffer, regionCount, pRegions);
+	vk::Cast(commandBuffer)->copyBuffer(vk::Cast(srcBuffer), vk::Cast(dstBuffer), regionCount, pRegions);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions)
@@ -1795,7 +1795,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkImage srcImage = %p, VkImageLayout srcImageLayout = %d, VkImage dstImage = %p, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageCopy* pRegions = %p)",
 	      commandBuffer, srcImage.get(), srcImageLayout, dstImage.get(), dstImageLayout, int(regionCount), pRegions);
 
-	vk::Cast(commandBuffer)->copyImage(srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+	vk::Cast(commandBuffer)->copyImage(vk::Cast(srcImage), srcImageLayout, vk::Cast(dstImage), dstImageLayout, regionCount, pRegions);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
@@ -1803,7 +1803,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkImage srcImage = %p, VkImageLayout srcImageLayout = %d, VkImage dstImage = %p, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageBlit* pRegions = %p, VkFilter filter = %d)",
 	      commandBuffer, srcImage.get(), srcImageLayout, dstImage.get(), dstImageLayout, int(regionCount), pRegions, filter);
 
-	vk::Cast(commandBuffer)->blitImage(srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
+	vk::Cast(commandBuffer)->blitImage(vk::Cast(srcImage), srcImageLayout, vk::Cast(dstImage), dstImageLayout, regionCount, pRegions, filter);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions)
@@ -1811,7 +1811,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer srcBuffer = %p, VkImage dstImage = %p, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkBufferImageCopy* pRegions = %p)",
 	      commandBuffer, srcBuffer.get(), dstImage.get(), dstImageLayout, int(regionCount), pRegions);
 
-	vk::Cast(commandBuffer)->copyBufferToImage(srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
+	vk::Cast(commandBuffer)->copyBufferToImage(vk::Cast(srcBuffer), vk::Cast(dstImage), dstImageLayout, regionCount, pRegions);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions)
@@ -1819,7 +1819,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkImage srcImage = %p, VkImageLayout srcImageLayout = %d, VkBuffer dstBuffer = %p, uint32_t regionCount = %d, const VkBufferImageCopy* pRegions = %p)",
 		    commandBuffer, srcImage.get(), int(srcImageLayout), dstBuffer.get(), int(regionCount), pRegions);
 
-	vk::Cast(commandBuffer)->copyImageToBuffer(srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
+	vk::Cast(commandBuffer)->copyImageToBuffer(vk::Cast(srcImage), srcImageLayout, vk::Cast(dstBuffer), regionCount, pRegions);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
@@ -1827,7 +1827,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer dstBuffer = %p, VkDeviceSize dstOffset = %d, VkDeviceSize dataSize = %d, const void* pData = %p)",
 	      commandBuffer, dstBuffer.get(), int(dstOffset), int(dataSize), pData);
 
-	vk::Cast(commandBuffer)->updateBuffer(dstBuffer, dstOffset, dataSize, pData);
+	vk::Cast(commandBuffer)->updateBuffer(vk::Cast(dstBuffer), dstOffset, dataSize, pData);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
@@ -1835,7 +1835,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer dstBuffer = %p, VkDeviceSize dstOffset = %d, VkDeviceSize size = %d, uint32_t data = %d)",
 	      commandBuffer, dstBuffer.get(), int(dstOffset), int(size), data);
 
-	vk::Cast(commandBuffer)->fillBuffer(dstBuffer, dstOffset, size, data);
+	vk::Cast(commandBuffer)->fillBuffer(vk::Cast(dstBuffer), dstOffset, size, data);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
@@ -1843,7 +1843,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkImage image = %p, VkImageLayout imageLayout = %d, const VkClearColorValue* pColor = %p, uint32_t rangeCount = %d, const VkImageSubresourceRange* pRanges = %p)",
 	      commandBuffer, image.get(), int(imageLayout), pColor, int(rangeCount), pRanges);
 
-	vk::Cast(commandBuffer)->clearColorImage(image, imageLayout, pColor, rangeCount, pRanges);
+	vk::Cast(commandBuffer)->clearColorImage(vk::Cast(image), imageLayout, pColor, rangeCount, pRanges);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
@@ -1851,7 +1851,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkImage image = %p, VkImageLayout imageLayout = %d, const VkClearDepthStencilValue* pDepthStencil = %p, uint32_t rangeCount = %d, const VkImageSubresourceRange* pRanges = %p)",
 	      commandBuffer, image.get(), int(imageLayout), pDepthStencil, int(rangeCount), pRanges);
 
-	vk::Cast(commandBuffer)->clearDepthStencilImage(image, imageLayout, pDepthStencil, rangeCount, pRanges);
+	vk::Cast(commandBuffer)->clearDepthStencilImage(vk::Cast(image), imageLayout, pDepthStencil, rangeCount, pRanges);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects)
@@ -1867,7 +1867,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkImage srcImage = %p, VkImageLayout srcImageLayout = %d, VkImage dstImage = %p, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageResolve* pRegions = %p)",
 	      commandBuffer, srcImage.get(), int(srcImageLayout), dstImage.get(), int(dstImageLayout), regionCount, pRegions);
 
-	vk::Cast(commandBuffer)->resolveImage(srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+	vk::Cast(commandBuffer)->resolveImage(vk::Cast(srcImage), srcImageLayout, vk::Cast(dstImage), dstImageLayout, regionCount, pRegions);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
@@ -1875,7 +1875,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkEvent event = %p, VkPipelineStageFlags stageMask = %d)",
 	      commandBuffer, event.get(), int(stageMask));
 
-	vk::Cast(commandBuffer)->setEvent(event, stageMask);
+	vk::Cast(commandBuffer)->setEvent(vk::Cast(event), stageMask);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
@@ -1883,7 +1883,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkEvent event = %p, VkPipelineStageFlags stageMask = %d)",
 	      commandBuffer, event.get(), int(stageMask));
 
-	vk::Cast(commandBuffer)->resetEvent(event, stageMask);
+	vk::Cast(commandBuffer)->resetEvent(vk::Cast(event), stageMask);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
@@ -1911,7 +1911,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkQueryPool queryPool = %p, uint32_t query = %d, VkQueryControlFlags flags = %d)",
 	      commandBuffer, queryPool.get(), query, int(flags));
 
-	vk::Cast(commandBuffer)->beginQuery(queryPool, query, flags);
+	vk::Cast(commandBuffer)->beginQuery(vk::Cast(queryPool), query, flags);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query)
@@ -1919,7 +1919,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkQueryPool queryPool = %p, uint32_t query = %d)",
 	      commandBuffer, queryPool.get(), int(query));
 
-	vk::Cast(commandBuffer)->endQuery(queryPool, query);
+	vk::Cast(commandBuffer)->endQuery(vk::Cast(queryPool), query);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
@@ -1927,7 +1927,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkQueryPool queryPool = %p, uint32_t firstQuery = %d, uint32_t queryCount = %d)",
 	      commandBuffer, queryPool.get(), int(firstQuery), int(queryCount));
 
-	vk::Cast(commandBuffer)->resetQueryPool(queryPool, firstQuery, queryCount);
+	vk::Cast(commandBuffer)->resetQueryPool(vk::Cast(queryPool), firstQuery, queryCount);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
@@ -1935,7 +1935,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineStageFlagBits pipelineStage = %d, VkQueryPool queryPool = %p, uint32_t query = %d)",
 	      commandBuffer, int(pipelineStage), queryPool.get(), int(query));
 
-	vk::Cast(commandBuffer)->writeTimestamp(pipelineStage, queryPool, query);
+	vk::Cast(commandBuffer)->writeTimestamp(pipelineStage, vk::Cast(queryPool), query);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
@@ -1943,7 +1943,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkQueryPool queryPool = %p, uint32_t firstQuery = %d, uint32_t queryCount = %d, VkBuffer dstBuffer = %p, VkDeviceSize dstOffset = %d, VkDeviceSize stride = %d, VkQueryResultFlags flags = %d)",
 	      commandBuffer, queryPool.get(), int(firstQuery), int(queryCount), dstBuffer.get(), int(dstOffset), int(stride), int(flags));
 
-	vk::Cast(commandBuffer)->copyQueryPoolResults(queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
+	vk::Cast(commandBuffer)->copyQueryPoolResults(vk::Cast(queryPool), firstQuery, queryCount, vk::Cast(dstBuffer), dstOffset, stride, flags);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues)
@@ -1951,7 +1951,7 @@
 	TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineLayout layout = %p, VkShaderStageFlags stageFlags = %d, uint32_t offset = %d, uint32_t size = %d, const void* pValues = %p)",
 	      commandBuffer, layout.get(), stageFlags, offset, size, pValues);
 
-	vk::Cast(commandBuffer)->pushConstants(layout, stageFlags, offset, size, pValues);
+	vk::Cast(commandBuffer)->pushConstants(vk::Cast(layout), stageFlags, offset, size, pValues);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents)
@@ -1977,7 +1977,7 @@
 		renderPassBeginInfo = renderPassBeginInfo->pNext;
 	}
 
-	vk::Cast(commandBuffer)->beginRenderPass(pRenderPassBegin->renderPass, pRenderPassBegin->framebuffer,
+	vk::Cast(commandBuffer)->beginRenderPass(vk::Cast(pRenderPassBegin->renderPass), vk::Cast(pRenderPassBegin->framebuffer),
 	                                         pRenderPassBegin->renderArea, pRenderPassBegin->clearValueCount,
 	                                         pRenderPassBegin->pClearValues, contents);
 }
@@ -2024,7 +2024,7 @@
 			UNIMPLEMENTED("pBindInfos[%d].pNext", i);
 		}
 
-		vk::Cast(pBindInfos[i].buffer)->bind(pBindInfos[i].memory, pBindInfos[i].memoryOffset);
+		vk::Cast(pBindInfos[i].buffer)->bind(vk::Cast(pBindInfos[i].memory), pBindInfos[i].memoryOffset);
 	}
 
 	return VK_SUCCESS;
@@ -2042,7 +2042,7 @@
 			UNIMPLEMENTED("pBindInfos[%d].pNext", i);
 		}
 
-		vk::Cast(pBindInfos[i].image)->bind(pBindInfos[i].memory, pBindInfos[i].memoryOffset);
+		vk::Cast(pBindInfos[i].image)->bind(vk::Cast(pBindInfos[i].memory), pBindInfos[i].memoryOffset);
 	}
 
 	return VK_SUCCESS;
@@ -2659,7 +2659,8 @@
 		return status;
 	}
 
-	status = vk::Cast(*pSwapchain)->createImages(device, pCreateInfo);
+	auto swapchain = vk::Cast(*pSwapchain);
+	status = swapchain->createImages(device, pCreateInfo);
 
 	if(status != VK_SUCCESS)
 	{
@@ -2667,7 +2668,7 @@
 		return status;
 	}
 
-	vk::Cast(pCreateInfo->surface)->associateSwapchain(*pSwapchain);
+	vk::Cast(pCreateInfo->surface)->associateSwapchain(swapchain);
 
 	return VK_SUCCESS;
 }
@@ -2699,7 +2700,7 @@
 	TRACE("(VkDevice device = %p, VkSwapchainKHR swapchain = %p, uint64_t timeout = %d, VkSemaphore semaphore = %p, VkFence fence = %p, uint32_t* pImageIndex = %p)",
 			device, swapchain.get(), int(timeout), semaphore.get(), fence.get(), pImageIndex);
 
-	return vk::Cast(swapchain)->getNextImage(timeout, semaphore, fence, pImageIndex);
+	return vk::Cast(swapchain)->getNextImage(timeout, vk::Cast(semaphore), vk::Cast(fence), pImageIndex);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo)
diff --git a/src/WSI/VkSurfaceKHR.cpp b/src/WSI/VkSurfaceKHR.cpp
index 74c0e40..f6019db 100644
--- a/src/WSI/VkSurfaceKHR.cpp
+++ b/src/WSI/VkSurfaceKHR.cpp
@@ -169,9 +169,9 @@
 	return VK_SUCCESS;
 }
 
-void SurfaceKHR::associateSwapchain(VkSwapchainKHR swapchain)
+void SurfaceKHR::associateSwapchain(SwapchainKHR* swapchain)
 {
-	associatedSwapchain = Cast(swapchain);
+	associatedSwapchain = swapchain;
 }
 
 void SurfaceKHR::disassociateSwapchain()
diff --git a/src/WSI/VkSurfaceKHR.hpp b/src/WSI/VkSurfaceKHR.hpp
index 7fb1591..9a2f3ff 100644
--- a/src/WSI/VkSurfaceKHR.hpp
+++ b/src/WSI/VkSurfaceKHR.hpp
@@ -83,7 +83,7 @@
 	virtual void detachImage(PresentImage* image) = 0;
 	virtual void present(PresentImage* image) = 0;
 
-	void associateSwapchain(VkSwapchainKHR swapchain);
+	void associateSwapchain(SwapchainKHR* swapchain);
 	void disassociateSwapchain();
 	bool hasAssociatedSwapchain();
 
diff --git a/src/WSI/VkSwapchainKHR.cpp b/src/WSI/VkSwapchainKHR.cpp
index d265141..0ca781d 100644
--- a/src/WSI/VkSwapchainKHR.cpp
+++ b/src/WSI/VkSwapchainKHR.cpp
@@ -171,7 +171,7 @@
 	return VK_SUCCESS;
 }
 
-VkResult SwapchainKHR::getNextImage(uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex)
+VkResult SwapchainKHR::getNextImage(uint64_t timeout, Semaphore* semaphore, Fence* fence, uint32_t *pImageIndex)
 {
 	for(uint32_t i = 0; i < imageCount; i++)
 	{
@@ -183,12 +183,12 @@
 
 			if(semaphore)
 			{
-				vk::Cast(semaphore)->signal();
+				semaphore->signal();
 			}
 
 			if(fence)
 			{
-				vk::Cast(fence)->complete();
+				fence->complete();
 			}
 
 			return VK_SUCCESS;
diff --git a/src/WSI/VkSwapchainKHR.hpp b/src/WSI/VkSwapchainKHR.hpp
index d9fc725..4ae8446 100644
--- a/src/WSI/VkSwapchainKHR.hpp
+++ b/src/WSI/VkSwapchainKHR.hpp
@@ -25,6 +25,9 @@
 namespace vk
 {
 
+class Fence;
+class Semaphore;
+
 class SwapchainKHR : public Object<SwapchainKHR, VkSwapchainKHR>
 {
 public:
@@ -41,7 +44,7 @@
 	uint32_t getImageCount() const;
 	VkResult getImages(uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) const;
 
-	VkResult getNextImage(uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex);
+	VkResult getNextImage(uint64_t timeout, Semaphore* semaphore, Fence* fence, uint32_t* pImageIndex);
 
 	void present(uint32_t index);