Browse Source

Vulkan: Added the missing support for 3D textures. Now all vulkan tests pass

Panagiotis Christopoulos Charitos 8 years ago
parent
commit
faf4e53f67

+ 1 - 1
src/anki/gr/Texture.h

@@ -42,7 +42,7 @@ public:
 	TextureUsageBit m_usage = TextureUsageBit::NONE; ///< How the texture will be used.
 	TextureUsageBit m_initialUsage = TextureUsageBit::NONE; ///< It's initial usage.
 
-	/// It's usual usage. That way you won't need to call CommandBuffer::informTextureCurrentUsage() all the time.
+	/// It's usual usage. That way you won't need to call CommandBuffer::informTextureXXXCurrentUsage() all the time.
 	TextureUsageBit m_usageWhenEncountered = TextureUsageBit::NONE;
 
 	U32 m_width = 0;

+ 1 - 1
src/anki/gr/vulkan/CommandBuffer.cpp

@@ -281,7 +281,7 @@ void CommandBuffer::copyBufferToTextureSurface(
 void CommandBuffer::copyBufferToTextureVolume(
 	BufferPtr buff, PtrSize offset, PtrSize range, TexturePtr tex, const TextureVolumeInfo& vol)
 {
-	ANKI_ASSERT(!"TODO");
+	m_impl->copyBufferToTextureVolume(buff, offset, range, tex, vol);
 }
 
 void CommandBuffer::fillBuffer(BufferPtr buff, PtrSize offset, PtrSize size, U32 value)

+ 108 - 0
src/anki/gr/vulkan/CommandBufferImpl.cpp

@@ -689,4 +689,112 @@ void CommandBufferImpl::copyBufferToTextureSurface(
 	m_bufferList.pushBack(m_alloc, buff);
 }
 
+void CommandBufferImpl::copyBufferToTextureVolume(
+	BufferPtr buff, PtrSize offset, PtrSize range, TexturePtr tex, const TextureVolumeInfo& vol)
+{
+	commandCommon();
+
+	TextureImpl& impl = *tex->m_impl;
+	impl.checkVolume(vol);
+	ANKI_ASSERT(impl.usageValid(TextureUsageBit::TRANSFER_DESTINATION));
+	const VkImageLayout layout = m_texUsageTracker.findLayout(*tex, vol);
+
+	if(!impl.m_workarounds)
+	{
+		U width = impl.m_width >> vol.m_level;
+		U height = impl.m_height >> vol.m_level;
+		U depth = impl.m_depth >> vol.m_level;
+		(void)depth;
+		ANKI_ASSERT(range == computeVolumeSize(width, height, depth, impl.m_format));
+
+		// Copy
+		VkBufferImageCopy region;
+		region.imageSubresource.aspectMask = impl.m_aspect;
+		region.imageSubresource.baseArrayLayer = impl.computeVkArrayLayer(vol);
+		region.imageSubresource.layerCount = 1;
+		region.imageSubresource.mipLevel = vol.m_level;
+		region.imageOffset = {0, 0, 0};
+		region.imageExtent.width = width;
+		region.imageExtent.height = height;
+		region.imageExtent.depth = impl.m_depth;
+		region.bufferOffset = offset;
+		region.bufferImageHeight = 0;
+		region.bufferRowLength = 0;
+
+		ANKI_CMD(vkCmdCopyBufferToImage(m_handle, buff->m_impl->getHandle(), impl.m_imageHandle, layout, 1, &region),
+			ANY_OTHER_COMMAND);
+	}
+	else if(!!(impl.m_workarounds & TextureImplWorkaround::R8G8B8_TO_R8G8B8A8))
+	{
+		// Find the offset to the RGBA staging buff
+		U width = impl.m_width >> vol.m_level;
+		U height = impl.m_height >> vol.m_level;
+		U depth = impl.m_depth >> vol.m_level;
+
+		// Create a new shadow buffer
+		const PtrSize shadowSize =
+			computeVolumeSize(width, height, depth, PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM));
+		BufferPtr shadow =
+			getGrManager().newInstance<Buffer>(shadowSize, BufferUsageBit::TRANSFER_ALL, BufferMapAccessBit::NONE);
+		const VkBuffer shadowHandle = shadow->m_impl->getHandle();
+		m_bufferList.pushBack(m_alloc, shadow);
+
+		// Create the copy regions
+		DynamicArrayAuto<VkBufferCopy> copies(m_alloc);
+		copies.create(width * height * depth);
+		U count = 0;
+		for(U x = 0; x < width; ++x)
+		{
+			for(U y = 0; y < height; ++y)
+			{
+				for(U d = 0; d < depth; ++d)
+				{
+					VkBufferCopy& c = copies[count++];
+					c.srcOffset = (d * height * width + y * width + x) * 3 + offset;
+					c.dstOffset = (d * height * width + y * width + x) * 4 + 0;
+					c.size = 3;
+				}
+			}
+		}
+
+		// Copy buffer to buffer
+		ANKI_CMD(vkCmdCopyBuffer(m_handle, buff->m_impl->getHandle(), shadowHandle, copies.getSize(), &copies[0]),
+			ANY_OTHER_COMMAND);
+
+		// Set barrier
+		setBufferBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
+			VK_ACCESS_TRANSFER_WRITE_BIT,
+			VK_PIPELINE_STAGE_TRANSFER_BIT,
+			VK_ACCESS_TRANSFER_READ_BIT,
+			0,
+			shadowSize,
+			shadowHandle);
+
+		// Do the copy to the image
+		VkBufferImageCopy region;
+		region.imageSubresource.aspectMask = impl.m_aspect;
+		region.imageSubresource.baseArrayLayer = impl.computeVkArrayLayer(vol);
+		region.imageSubresource.layerCount = 1;
+		region.imageSubresource.mipLevel = vol.m_level;
+		region.imageOffset = {0, 0, 0};
+		region.imageExtent.width = width;
+		region.imageExtent.height = height;
+		region.imageExtent.depth = depth;
+		region.bufferOffset = 0;
+		region.bufferImageHeight = 0;
+		region.bufferRowLength = 0;
+
+		ANKI_CMD(vkCmdCopyBufferToImage(
+					 m_handle, shadowHandle, impl.m_imageHandle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region),
+			ANY_OTHER_COMMAND);
+	}
+	else
+	{
+		ANKI_ASSERT(0);
+	}
+
+	m_texList.pushBack(m_alloc, tex);
+	m_bufferList.pushBack(m_alloc, buff);
+}
+
 } // end namespace anki

+ 3 - 0
src/anki/gr/vulkan/CommandBufferImpl.h

@@ -295,6 +295,9 @@ public:
 	void copyBufferToTextureSurface(
 		BufferPtr buff, PtrSize offset, PtrSize range, TexturePtr tex, const TextureSurfaceInfo& surf);
 
+	void copyBufferToTextureVolume(
+		BufferPtr buff, PtrSize offset, PtrSize range, TexturePtr tex, const TextureVolumeInfo& vol);
+
 	void informTextureSurfaceCurrentUsage(TexturePtr& tex, const TextureSurfaceInfo& surf, TextureUsageBit crntUsage)
 	{
 		m_texUsageTracker.setUsage(*tex, surf, crntUsage, m_alloc);

+ 12 - 1
src/anki/gr/vulkan/GrManagerImpl.cpp

@@ -240,6 +240,12 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 #endif
 	}};
 
+	ANKI_VK_LOGI("Will enable the following instanse extensions:");
+	for(const char* c : EXTENSIONS)
+	{
+		ANKI_VK_LOGI("\t%s", c);
+	}
+
 	VkApplicationInfo app = {};
 	app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
 	app.pApplicationName = "unamed";
@@ -254,7 +260,12 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 
 	if(init.m_config->getNumber("debugContext"))
 	{
-		ANKI_VK_LOGI("Will enable debug layers");
+		ANKI_VK_LOGI("Will enable the following debug layers:");
+		for(const char* c : LAYERS)
+		{
+			ANKI_VK_LOGI("\t%s", c);
+		}
+
 		ci.enabledLayerCount = LAYERS.getSize();
 		ci.ppEnabledLayerNames = &LAYERS[0];
 	}

+ 1 - 0
tests/gr/Gr.cpp

@@ -1201,6 +1201,7 @@ ANKI_TEST(Gr, 3DTextures)
 	init.m_format = PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM);
 	init.m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::TRANSFER_DESTINATION;
 	init.m_initialUsage = TextureUsageBit::TRANSFER_DESTINATION;
+	init.m_usageWhenEncountered = TextureUsageBit::SAMPLED_FRAGMENT;
 	init.m_height = 2;
 	init.m_width = 2;
 	init.m_mipmapsCount = 2;