Commit f29e2bf7 by Jason Macnak

Handle image properties from external device memory

Some external device memories really represent existing images with requirements and not just memory blobs. For AHB, we want to use the stride from the gralloc buffer. Bug: b/141698760 Bug: b/147316305 Test: launch_cvd && cts -m CtsDeqpTestCases dEQP-VK.api.external.memory.android_hardware_buffer.* Change-Id: If657c91e458545b58d1d3b0f15f807ca9828b09c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/50068 Presubmit-Ready: Jason Macnak <natsu@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarJason Macnak <natsu@google.com>
parent 1a8935a4
...@@ -306,6 +306,23 @@ bool DeviceMemory::checkExternalMemoryHandleType( ...@@ -306,6 +306,23 @@ bool DeviceMemory::checkExternalMemoryHandleType(
return (supportedHandleTypes & handle_type_bit) != 0; return (supportedHandleTypes & handle_type_bit) != 0;
} }
bool DeviceMemory::hasExternalImageProperties() const
{
return external && external->hasExternalImageProperties();
}
int DeviceMemory::externalImageRowPitchBytes() const
{
if(external)
{
return external->externalImageRowPitchBytes();
}
// This function should never be called on non-external memory.
ASSERT(false);
return -1;
}
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
VkResult DeviceMemory::exportFd(int *pFd) const VkResult DeviceMemory::exportFd(int *pFd) const
{ {
......
...@@ -57,6 +57,9 @@ public: ...@@ -57,6 +57,9 @@ public:
// Internal implementation class for external memory. Platform-specific. // Internal implementation class for external memory. Platform-specific.
class ExternalBase; class ExternalBase;
bool hasExternalImageProperties() const;
int externalImageRowPitchBytes() const;
private: private:
void *buffer = nullptr; void *buffer = nullptr;
VkDeviceSize size = 0; VkDeviceSize size = 0;
......
...@@ -28,6 +28,39 @@ ...@@ -28,6 +28,39 @@
namespace { namespace {
int GetBytesFromAHBFormat(uint32_t ahbFormat)
{
switch(ahbFormat)
{
case AHARDWAREBUFFER_FORMAT_D16_UNORM:
return 2;
case AHARDWAREBUFFER_FORMAT_D24_UNORM:
return 3;
case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
return 4;
case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
return 4;
case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
return 8;
case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
return 2;
case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
return 4;
case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
return 4;
case AHARDWAREBUFFER_FORMAT_S8_UINT:
return 1;
default:
// TODO(b/165302991)
// - AHARDWAREBUFFER_FORMAT_BLOB
// - AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT
// - AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT
// - AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM
UNSUPPORTED("Requested bytes() for unsupported format %d", int(ahbFormat));
return -1;
}
}
uint32_t GetAHBFormatFromVkFormat(VkFormat format) uint32_t GetAHBFormatFromVkFormat(VkFormat format)
{ {
switch(format) switch(format)
...@@ -295,14 +328,13 @@ VkResult AHardwareBufferExternalMemory::importAndroidHardwareBuffer(struct AHard ...@@ -295,14 +328,13 @@ VkResult AHardwareBufferExternalMemory::importAndroidHardwareBuffer(struct AHard
ahb = buffer; ahb = buffer;
AHardwareBuffer_acquire(ahb); AHardwareBuffer_acquire(ahb);
AHardwareBuffer_describe(ahb, &ahbDesc);
return lockAndroidHardwareBuffer(pBuffer); return lockAndroidHardwareBuffer(pBuffer);
} }
VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(void **pBuffer) VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(void **pBuffer)
{ {
AHardwareBuffer_Desc desc = {};
if(allocateInfo.imageHandle) if(allocateInfo.imageHandle)
{ {
vk::Image *image = allocateInfo.imageHandle; vk::Image *image = allocateInfo.imageHandle;
...@@ -311,31 +343,32 @@ VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(void **pBu ...@@ -311,31 +343,32 @@ VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(void **pBu
VkExtent3D extent = image->getExtent(); VkExtent3D extent = image->getExtent();
desc.width = extent.width; ahbDesc.width = extent.width;
desc.height = extent.height; ahbDesc.height = extent.height;
desc.layers = image->getArrayLayers(); ahbDesc.layers = image->getArrayLayers();
desc.format = GetAHBFormatFromVkFormat(image->getFormat()); ahbDesc.format = GetAHBFormatFromVkFormat(image->getFormat());
desc.usage = GetAHBUsageFromVkImageFlags(image->getFlags(), image->getUsage()); ahbDesc.usage = GetAHBUsageFromVkImageFlags(image->getFlags(), image->getUsage());
} }
else else
{ {
vk::Buffer *buffer = allocateInfo.bufferHandle; vk::Buffer *buffer = allocateInfo.bufferHandle;
ASSERT(buffer != nullptr); ASSERT(buffer != nullptr);
desc.width = static_cast<uint32_t>(buffer->getSize()); ahbDesc.width = static_cast<uint32_t>(buffer->getSize());
desc.height = 1; ahbDesc.height = 1;
desc.layers = 1; ahbDesc.layers = 1;
desc.format = AHARDWAREBUFFER_FORMAT_BLOB; ahbDesc.format = AHARDWAREBUFFER_FORMAT_BLOB;
desc.usage = GetAHBUsageFromVkBufferFlags(buffer->getFlags(), buffer->getUsage()); ahbDesc.usage = GetAHBUsageFromVkBufferFlags(buffer->getFlags(), buffer->getUsage());
} }
// create a new ahb from desc int ret = AHardwareBuffer_allocate(&ahbDesc, &ahb);
int ret = AHardwareBuffer_allocate(&desc, &ahb);
if(ret != 0) if(ret != 0)
{ {
return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;
} }
AHardwareBuffer_describe(ahb, &ahbDesc);
return lockAndroidHardwareBuffer(pBuffer); return lockAndroidHardwareBuffer(pBuffer);
} }
...@@ -458,4 +491,9 @@ VkResult AHardwareBufferExternalMemory::GetAndroidHardwareBufferProperties(VkDev ...@@ -458,4 +491,9 @@ VkResult AHardwareBufferExternalMemory::GetAndroidHardwareBufferProperties(VkDev
return result; return result;
} }
int AHardwareBufferExternalMemory::externalImageRowPitchBytes() const
{
return GetBytesFromAHBFormat(ahbDesc.format) * ahbDesc.stride;
}
#endif // SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER #endif // SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
...@@ -69,6 +69,9 @@ public: ...@@ -69,6 +69,9 @@ public:
static VkResult GetAndroidHardwareBufferFormatProperties(const AHardwareBuffer_Desc &ahbDesc, VkAndroidHardwareBufferFormatPropertiesANDROID *pFormat); static VkResult GetAndroidHardwareBufferFormatProperties(const AHardwareBuffer_Desc &ahbDesc, VkAndroidHardwareBufferFormatPropertiesANDROID *pFormat);
static VkResult GetAndroidHardwareBufferProperties(VkDevice &device, const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties); static VkResult GetAndroidHardwareBufferProperties(VkDevice &device, const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties);
bool hasExternalImageProperties() const override final { return true; }
int externalImageRowPitchBytes() const override final;
private: private:
VkResult importAndroidHardwareBuffer(struct AHardwareBuffer *buffer, void **pBuffer); VkResult importAndroidHardwareBuffer(struct AHardwareBuffer *buffer, void **pBuffer);
VkResult allocateAndroidHardwareBuffer(void **pBuffer); VkResult allocateAndroidHardwareBuffer(void **pBuffer);
...@@ -76,6 +79,7 @@ private: ...@@ -76,6 +79,7 @@ private:
VkResult unlockAndroidHardwareBuffer(); VkResult unlockAndroidHardwareBuffer();
struct AHardwareBuffer *ahb = nullptr; struct AHardwareBuffer *ahb = nullptr;
AHardwareBuffer_Desc ahbDesc = {};
vk::Device *device = nullptr; vk::Device *device = nullptr;
AllocateInfo allocateInfo; AllocateInfo allocateInfo;
}; };
......
...@@ -57,6 +57,11 @@ public: ...@@ -57,6 +57,11 @@ public:
} }
#endif #endif
// Some external device memories, such as Android hardware buffers, represent
// specific images with requirements.
virtual bool hasExternalImageProperties() const { return false; }
virtual int externalImageRowPitchBytes() const { return 0; }
protected: protected:
ExternalBase() = default; ExternalBase() = default;
}; };
......
...@@ -749,6 +749,11 @@ VkExtent3D Image::getMipLevelExtent(VkImageAspectFlagBits aspect, uint32_t mipLe ...@@ -749,6 +749,11 @@ VkExtent3D Image::getMipLevelExtent(VkImageAspectFlagBits aspect, uint32_t mipLe
int Image::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const int Image::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{ {
if(deviceMemory && deviceMemory->hasExternalImageProperties())
{
return deviceMemory->externalImageRowPitchBytes();
}
// Depth and Stencil pitch should be computed separately // Depth and Stencil pitch should be computed separately
ASSERT((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != ASSERT((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)); (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment