1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Merge pull request #108422 from stuartcarnie/108115_metal_cpu_read_bit

Metal: Fix `texture_get_data` other linear formats
This commit is contained in:
Thaddeus Crews
2025-10-15 16:31:02 -05:00
9 changed files with 253 additions and 191 deletions

View File

@@ -1903,71 +1903,6 @@ uint32_t RenderingDevice::_texture_vrs_method_to_usage_bits() const {
}
}
Vector<uint8_t> RenderingDevice::_texture_get_data(Texture *tex, uint32_t p_layer, bool p_2d) {
uint32_t width, height, depth;
uint32_t tight_mip_size = get_image_format_required_size(tex->format, tex->width, tex->height, p_2d ? 1 : tex->depth, tex->mipmaps, &width, &height, &depth);
Vector<uint8_t> image_data;
image_data.resize(tight_mip_size);
uint32_t blockw, blockh;
get_compressed_image_format_block_dimensions(tex->format, blockw, blockh);
uint32_t block_size = get_compressed_image_format_block_byte_size(tex->format);
uint32_t pixel_size = get_image_format_pixel_size(tex->format);
{
uint8_t *w = image_data.ptrw();
uint32_t mipmap_offset = 0;
for (uint32_t mm_i = 0; mm_i < tex->mipmaps; mm_i++) {
uint32_t image_total = get_image_format_required_size(tex->format, tex->width, tex->height, p_2d ? 1 : tex->depth, mm_i + 1, &width, &height, &depth);
uint8_t *write_ptr_mipmap = w + mipmap_offset;
tight_mip_size = image_total - mipmap_offset;
RDD::TextureSubresource subres;
subres.aspect = RDD::TEXTURE_ASPECT_COLOR;
subres.layer = p_layer;
subres.mipmap = mm_i;
RDD::TextureCopyableLayout layout;
driver->texture_get_copyable_layout(tex->driver_id, subres, &layout);
uint8_t *img_mem = driver->texture_map(tex->driver_id, subres);
ERR_FAIL_NULL_V(img_mem, Vector<uint8_t>());
for (uint32_t z = 0; z < depth; z++) {
uint8_t *write_ptr = write_ptr_mipmap + z * tight_mip_size / depth;
const uint8_t *slice_read_ptr = img_mem + z * layout.depth_pitch;
if (block_size > 1) {
// Compressed.
uint32_t line_width = (block_size * (width / blockw));
for (uint32_t y = 0; y < height / blockh; y++) {
const uint8_t *rptr = slice_read_ptr + y * layout.row_pitch;
uint8_t *wptr = write_ptr + y * line_width;
memcpy(wptr, rptr, line_width);
}
} else {
// Uncompressed.
for (uint32_t y = 0; y < height; y++) {
const uint8_t *rptr = slice_read_ptr + y * layout.row_pitch;
uint8_t *wptr = write_ptr + y * pixel_size * width;
memcpy(wptr, rptr, (uint64_t)pixel_size * width);
}
}
}
driver->texture_unmap(tex->driver_id);
mipmap_offset = image_total;
}
}
return image_data;
}
Vector<uint8_t> RenderingDevice::texture_get_data(RID p_texture, uint32_t p_layer) {
ERR_RENDER_THREAD_GUARD_V(Vector<uint8_t>());
@@ -1984,8 +1919,7 @@ Vector<uint8_t> RenderingDevice::texture_get_data(RID p_texture, uint32_t p_laye
_check_transfer_worker_texture(tex);
if (tex->usage_flags & TEXTURE_USAGE_CPU_READ_BIT) {
// Does not need anything fancy, map and read.
return _texture_get_data(tex, p_layer);
return driver->texture_get_data(tex->driver_id, p_layer);
} else {
LocalVector<RDD::TextureCopyableLayout> mip_layouts;
uint32_t work_mip_alignment = driver->api_trait_get(RDD::API_TRAIT_TEXTURE_TRANSFER_ALIGNMENT);

View File

@@ -347,7 +347,6 @@ public:
uint32_t texture_upload_region_size_px = 0;
uint32_t texture_download_region_size_px = 0;
Vector<uint8_t> _texture_get_data(Texture *tex, uint32_t p_layer, bool p_2d = false);
uint32_t _texture_layer_count(Texture *p_texture) const;
uint32_t _texture_alignment(Texture *p_texture) const;
Error _texture_initialize(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, RDD::TextureLayout p_dst_layout, bool p_immediate_flush);

View File

@@ -271,6 +271,8 @@ public:
virtual void texture_free(TextureID p_texture) = 0;
virtual uint64_t texture_get_allocation_size(TextureID p_texture) = 0;
virtual void texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) = 0;
// Returns the data of a texture layer for a CPU texture that was created with TEXTURE_USAGE_CPU_READ_BIT.
virtual Vector<uint8_t> texture_get_data(TextureID p_texture, uint32_t p_layer) = 0;
virtual uint8_t *texture_map(TextureID p_texture, const TextureSubresource &p_subresource) = 0;
virtual void texture_unmap(TextureID p_texture) = 0;
virtual BitField<TextureUsageBits> texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) = 0;