Specialize descriptor contents for storage images
Bug: b/130768731
Test: dEQP-VK.image.*
Change-Id: Iebea846a5fe611aa4ad769e2fb7c636ddb5dbc4d
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29408
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Vulkan/VkBufferView.cpp b/src/Vulkan/VkBufferView.cpp
new file mode 100644
index 0000000..168f2ac
--- /dev/null
+++ b/src/Vulkan/VkBufferView.cpp
@@ -0,0 +1,40 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "VkBufferView.hpp"
+#include "VkBuffer.hpp"
+#include "VkFormat.h"
+
+namespace vk
+{
+
+BufferView::BufferView(const VkBufferViewCreateInfo* pCreateInfo, void* mem) :
+ buffer(pCreateInfo->buffer), format(pCreateInfo->format), offset(pCreateInfo->offset)
+{
+ if (pCreateInfo->range == VK_WHOLE_SIZE)
+ {
+ range = Cast(pCreateInfo->buffer)->getSize() - offset;
+ }
+ else
+ {
+ range = pCreateInfo->range - offset;
+ }
+}
+
+void * BufferView::getPointer() const
+{
+ return Cast(buffer)->getOffsetPointer(offset);
+}
+
+}
\ No newline at end of file
diff --git a/src/Vulkan/VkBufferView.hpp b/src/Vulkan/VkBufferView.hpp
index e7fc734..db68bb6 100644
--- a/src/Vulkan/VkBufferView.hpp
+++ b/src/Vulkan/VkBufferView.hpp
@@ -16,6 +16,7 @@
#define VK_BUFFER_VIEW_HPP_
#include "VkObject.hpp"
+#include "VkFormat.h"
namespace vk
{
@@ -23,11 +24,7 @@
class BufferView : public Object<BufferView, VkBufferView>
{
public:
- BufferView(const VkBufferViewCreateInfo* pCreateInfo, void* mem) :
- buffer(pCreateInfo->buffer), format(pCreateInfo->format), offset(pCreateInfo->offset), range(pCreateInfo->range)
- {
- }
-
+ BufferView(const VkBufferViewCreateInfo* pCreateInfo, void* mem);
~BufferView() = delete;
static size_t ComputeRequiredAllocationSize(const VkBufferViewCreateInfo* pCreateInfo)
@@ -35,6 +32,9 @@
return 0;
}
+ void *getPointer() const;
+ uint32_t getElementCount() const { return range / Format(format).bytes(); }
+
private:
VkBuffer buffer;
VkFormat format;
diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp
index 106e3f2..ded7cd0 100644
--- a/src/Vulkan/VkDescriptorSetLayout.cpp
+++ b/src/Vulkan/VkDescriptorSetLayout.cpp
@@ -17,6 +17,7 @@
#include "VkDescriptorSet.hpp"
#include "VkSampler.hpp"
#include "VkImageView.hpp"
+#include "VkBufferView.hpp"
#include "System/Types.hpp"
#include <algorithm>
@@ -95,10 +96,11 @@
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
return sizeof(SampledImageDescriptor);
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ return sizeof(StorageImageDescriptor);
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
return sizeof(VkDescriptorImageInfo);
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
- case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
return sizeof(VkBufferView);
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
@@ -244,19 +246,18 @@
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
- case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
return reinterpret_cast<const uint8_t*>(writeDescriptorSet.pImageInfo);
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
- case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
return reinterpret_cast<const uint8_t*>(writeDescriptorSet.pTexelBufferView);
- break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
return reinterpret_cast<const uint8_t*>(writeDescriptorSet.pBufferInfo);
- break;
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ ASSERT("descriptorType has custom handling");
default:
UNIMPLEMENTED("descriptorType");
return nullptr;
@@ -432,6 +433,32 @@
}
}
}
+ else if (writeDescriptorSet.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+ {
+ auto descriptor = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
+ for(uint32_t i = 0; i < writeDescriptorSet.descriptorCount; i++)
+ {
+ auto imageView = vk::Cast(writeDescriptorSet.pImageInfo[i].imageView);
+ descriptor[i].ptr = imageView->getOffsetPointer({0, 0, 0}, VK_IMAGE_ASPECT_COLOR_BIT);
+ descriptor[i].extent = imageView->getMipLevelExtent(0);
+ descriptor[i].rowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
+ descriptor[i].slicePitchBytes = imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
+ descriptor[i].arrayLayers = imageView->getSubresourceRange().layerCount;
+ }
+ }
+ else if (writeDescriptorSet.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
+ {
+ auto descriptor = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
+ for (uint32_t i = 0; i < writeDescriptorSet.descriptorCount; i++)
+ {
+ auto bufferView = vk::Cast(writeDescriptorSet.pTexelBufferView[i]);
+ descriptor[i].ptr = bufferView->getPointer();
+ descriptor[i].extent = {bufferView->getElementCount(), 1, 1};
+ descriptor[i].rowPitchBytes = 0;
+ descriptor[i].slicePitchBytes = 0;
+ descriptor[i].arrayLayers = 1;
+ }
+ }
else
{
// If the dstBinding has fewer than descriptorCount array elements remaining
diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp
index 6ccd12e..621e13f 100644
--- a/src/Vulkan/VkDescriptorSetLayout.hpp
+++ b/src/Vulkan/VkDescriptorSetLayout.hpp
@@ -36,6 +36,15 @@
sw::Texture texture;
};
+struct StorageImageDescriptor
+{
+ void *ptr;
+ VkExtent3D extent;
+ int rowPitchBytes;
+ int slicePitchBytes;
+ int arrayLayers;
+};
+
class DescriptorSetLayout : public Object<DescriptorSetLayout, VkDescriptorSetLayout>
{
public:
diff --git a/src/Vulkan/VkImageView.cpp b/src/Vulkan/VkImageView.cpp
index b5e3c0a..b403fb2 100644
--- a/src/Vulkan/VkImageView.cpp
+++ b/src/Vulkan/VkImageView.cpp
@@ -103,7 +103,7 @@
if(!format.isCompatible(image->getFormat()))
{
UNIMPLEMENTED("incompatible formats");
- }
+ }
VkImageSubresourceRange sr;
sr.aspectMask = aspectMask;
diff --git a/src/Vulkan/vulkan.vcxproj b/src/Vulkan/vulkan.vcxproj
index b11ece5..59e8098 100644
--- a/src/Vulkan/vulkan.vcxproj
+++ b/src/Vulkan/vulkan.vcxproj
@@ -110,6 +110,7 @@
<ClCompile Include="libVulkan.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="VkBuffer.cpp" />
+ <ClCompile Include="VkBufferView.cpp" />
<ClCompile Include="VkCommandBuffer.cpp" />
<ClCompile Include="VkCommandPool.cpp" />
<ClCompile Include="VkDebug.cpp" />
diff --git a/src/Vulkan/vulkan.vcxproj.filters b/src/Vulkan/vulkan.vcxproj.filters
index 3b95e02..9c99109 100644
--- a/src/Vulkan/vulkan.vcxproj.filters
+++ b/src/Vulkan/vulkan.vcxproj.filters
@@ -174,6 +174,9 @@
<ClCompile Include="VkBuffer.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
+ <ClCompile Include="VkBufferView.cpp">
+ <Filter>Source Files\Vulkan</Filter>
+ </ClCompile>
<ClCompile Include="VkCommandBuffer.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>