WIP: Vulkan: Workbench #107886
|
@ -624,6 +624,12 @@ static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI()
|
|||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI);
|
||||
#endif
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH_COMPONENT24, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24);
|
||||
|
||||
#if RUN_COMPONENT_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F()
|
||||
{
|
||||
|
@ -631,12 +637,6 @@ static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F()
|
|||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH_COMPONENT24, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH_COMPONENT16, GPU_DATA_UINT, uint32_t>();
|
||||
|
|
|
@ -46,6 +46,8 @@ bool VKBuffer::create(int64_t size_in_bytes,
|
|||
VkBufferUsageFlagBits buffer_usage)
|
||||
{
|
||||
BLI_assert(!is_allocated());
|
||||
BLI_assert(vk_buffer_ == VK_NULL_HANDLE);
|
||||
BLI_assert(mapped_memory_ == nullptr);
|
||||
|
||||
size_in_bytes_ = size_in_bytes;
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
|
|
|
@ -97,6 +97,7 @@ template<typename T> VkObjectType to_vk_object_type(T /*vk_obj*/)
|
|||
return VK_OBJECT_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
#define NOT_YET_IMPLEMENTED printf("%s not implemented yet\n", __func__);
|
||||
#define NOT_YET_IMPLEMENTED \
|
||||
printf("%s:%d `%s` not implemented yet\n", __FILE__, __LINE__, __func__);
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -238,6 +238,7 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format)
|
|||
case GPU_RGBA32UI:
|
||||
case GPU_RG32UI:
|
||||
case GPU_R32UI:
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
return ConversionType::PASS_THROUGH;
|
||||
|
||||
case GPU_RGBA16UI:
|
||||
|
@ -304,7 +305,6 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format)
|
|||
case GPU_SRGB8:
|
||||
case GPU_RGB9_E5:
|
||||
case GPU_DEPTH_COMPONENT32F:
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
case GPU_DEPTH_COMPONENT16:
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
@ -935,7 +935,8 @@ void convert_device_to_host(void *dst_buffer,
|
|||
eGPUTextureFormat device_format)
|
||||
{
|
||||
ConversionType conversion_type = reversed(host_to_device(host_format, device_format));
|
||||
BLI_assert(conversion_type != ConversionType::UNSUPPORTED);
|
||||
BLI_assert_msg(conversion_type != ConversionType::UNSUPPORTED,
|
||||
"Data conversion between host_format and device_format isn't supported (yet).");
|
||||
convert_buffer(dst_buffer, src_buffer, buffer_size, device_format, conversion_type);
|
||||
}
|
||||
|
||||
|
|
|
@ -232,8 +232,8 @@ void VKFrameBuffer::attachment_set_loadstore_op(GPUAttachmentType /*type*/,
|
|||
|
||||
void VKFrameBuffer::read(eGPUFrameBufferBits plane,
|
||||
eGPUDataFormat format,
|
||||
const int /*area*/[4],
|
||||
int channel_len,
|
||||
const int area[4],
|
||||
int /*channel_len*/,
|
||||
int slot,
|
||||
void *r_data)
|
||||
{
|
||||
|
@ -243,30 +243,19 @@ void VKFrameBuffer::read(eGPUFrameBufferBits plane,
|
|||
texture = unwrap(unwrap(attachments_[GPU_FB_COLOR_ATTACHMENT0 + slot].tex));
|
||||
break;
|
||||
|
||||
case GPU_DEPTH_BIT:
|
||||
texture = unwrap(unwrap(attachments_[GPU_FB_DEPTH_ATTACHMENT].tex));
|
||||
break;
|
||||
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_assert_msg(texture,
|
||||
"Trying to read back color texture from framebuffer, but no color texture is "
|
||||
"available in requested slot.");
|
||||
void *data = texture->read(0, format);
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - Add support for area.
|
||||
* - Add support for channel_len.
|
||||
* Best option would be to add this to VKTexture so we don't over-allocate and reduce number of
|
||||
* times copies are made.
|
||||
*/
|
||||
BLI_assert(format == GPU_DATA_FLOAT);
|
||||
BLI_assert(channel_len == 4);
|
||||
int mip_size[3] = {1, 1, 1};
|
||||
texture->mip_size_get(0, mip_size);
|
||||
const size_t mem_size = mip_size[0] * mip_size[1] * mip_size[2] * sizeof(float) * channel_len;
|
||||
memcpy(r_data, data, mem_size);
|
||||
MEM_freeN(data);
|
||||
"Trying to read back texture from framebuffer, but no texture is available in "
|
||||
"requested slot.");
|
||||
texture->read_sub(0, format, area, r_data);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -37,9 +37,15 @@ void VKTexture::init(VkImage vk_image, VkImageLayout layout)
|
|||
current_layout_ = layout;
|
||||
}
|
||||
|
||||
void VKTexture::generate_mipmap() {}
|
||||
void VKTexture::generate_mipmap()
|
||||
{
|
||||
NOT_YET_IMPLEMENTED
|
||||
}
|
||||
|
||||
void VKTexture::copy_to(Texture * /*tex*/) {}
|
||||
void VKTexture::copy_to(Texture * /*tex*/)
|
||||
{
|
||||
NOT_YET_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void VKTexture::clear(eGPUDataFormat format, const void *data)
|
||||
{
|
||||
|
@ -60,13 +66,22 @@ void VKTexture::clear(eGPUDataFormat format, const void *data)
|
|||
vk_image_, current_layout_get(), clear_color, Span<VkImageSubresourceRange>(&range, 1));
|
||||
}
|
||||
|
||||
void VKTexture::swizzle_set(const char /*swizzle_mask*/[4]) {}
|
||||
void VKTexture::swizzle_set(const char /*swizzle_mask*/[4])
|
||||
{
|
||||
NOT_YET_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void VKTexture::stencil_texture_mode_set(bool /*use_stencil*/) {}
|
||||
void VKTexture::stencil_texture_mode_set(bool /*use_stencil*/)
|
||||
{
|
||||
NOT_YET_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void VKTexture::mip_range_set(int /*min*/, int /*max*/) {}
|
||||
void VKTexture::mip_range_set(int /*min*/, int /*max*/)
|
||||
{
|
||||
NOT_YET_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void *VKTexture::read(int mip, eGPUDataFormat format)
|
||||
void VKTexture::read_sub(int mip, eGPUDataFormat format, const int area[4], void *r_data)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
|
@ -74,20 +89,18 @@ void *VKTexture::read(int mip, eGPUDataFormat format)
|
|||
/* Vulkan images cannot be directly mapped to host memory and requires a staging buffer. */
|
||||
VKBuffer staging_buffer;
|
||||
|
||||
/* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
|
||||
int extent[3] = {1, 1, 1};
|
||||
mip_size_get(mip, extent);
|
||||
size_t sample_len = extent[0] * extent[1] * extent[2];
|
||||
size_t sample_len = area[2] * area[3];
|
||||
size_t device_memory_size = sample_len * to_bytesize(format_);
|
||||
size_t host_memory_size = sample_len * to_bytesize(format_, format);
|
||||
|
||||
staging_buffer.create(
|
||||
device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageExtent.width = extent[0];
|
||||
region.imageExtent.height = extent[1];
|
||||
region.imageExtent.depth = extent[2];
|
||||
region.imageOffset.x = area[0];
|
||||
region.imageOffset.y = area[1];
|
||||
region.imageExtent.width = area[2];
|
||||
region.imageExtent.height = area[3];
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_);
|
||||
region.imageSubresource.mipLevel = mip;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
|
@ -96,8 +109,19 @@ void *VKTexture::read(int mip, eGPUDataFormat format)
|
|||
command_buffer.copy(staging_buffer, *this, Span<VkBufferImageCopy>(®ion, 1));
|
||||
command_buffer.submit();
|
||||
|
||||
convert_device_to_host(r_data, staging_buffer.mapped_memory_get(), sample_len, format, format_);
|
||||
}
|
||||
|
||||
void *VKTexture::read(int mip, eGPUDataFormat format)
|
||||
{
|
||||
int mip_size[3] = {1, 1, 1};
|
||||
mip_size_get(mip, mip_size);
|
||||
size_t sample_len = mip_size[0] * mip_size[1];
|
||||
size_t host_memory_size = sample_len * to_bytesize(format_, format);
|
||||
|
||||
void *data = MEM_mallocN(host_memory_size, __func__);
|
||||
convert_device_to_host(data, staging_buffer.mapped_memory_get(), sample_len, format, format_);
|
||||
int area[4] = {0, 0, mip_size[0], mip_size[1]};
|
||||
read_sub(mip, format, area, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -158,6 +182,7 @@ void VKTexture::update_sub(int /*offset*/[3],
|
|||
eGPUDataFormat /*format*/,
|
||||
GPUPixelBuffer * /*pixbuf*/)
|
||||
{
|
||||
NOT_YET_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* TODO(fclem): Legacy. Should be removed at some point. */
|
||||
|
|
|
@ -39,6 +39,7 @@ class VKTexture : public Texture {
|
|||
void stencil_texture_mode_set(bool use_stencil) override;
|
||||
void mip_range_set(int min, int max) override;
|
||||
void *read(int mip, eGPUDataFormat format) override;
|
||||
void read_sub(int mip, eGPUDataFormat format, const int area[4], void *r_data);
|
||||
void update_sub(
|
||||
int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data) override;
|
||||
void update_sub(int offset[3],
|
||||
|
|
Loading…
Reference in New Issue