Refactor rendering driver copy APIs to fix D3D12 issues.
Co-authored-by: Stuart Carnie <stuart.carnie@gmail.com>
This commit is contained in:
@ -519,7 +519,7 @@ void MDCommandBuffer::_copy_texture_buffer(CopySource p_source,
|
||||
for (uint32_t i = 0; i < p_regions.size(); i++) {
|
||||
RDD::BufferTextureCopyRegion region = p_regions[i];
|
||||
|
||||
uint32_t mip_level = region.texture_subresources.mipmap;
|
||||
uint32_t mip_level = region.texture_subresource.mipmap;
|
||||
MTLOrigin txt_origin = MTLOriginMake(region.texture_offset.x, region.texture_offset.y, region.texture_offset.z);
|
||||
MTLSize src_extent = mipmapLevelSizeFromTexture(texture, mip_level);
|
||||
MTLSize txt_size = clampMTLSize(MTLSizeMake(region.texture_region_size.x, region.texture_region_size.y, region.texture_region_size.z),
|
||||
@ -535,18 +535,15 @@ void MDCommandBuffer::_copy_texture_buffer(CopySource p_source,
|
||||
MTLBlitOption blit_options = options;
|
||||
|
||||
if (pf.isDepthFormat(mtlPixFmt) && pf.isStencilFormat(mtlPixFmt)) {
|
||||
bool want_depth = flags::all(region.texture_subresources.aspect, RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
||||
bool want_stencil = flags::all(region.texture_subresources.aspect, RDD::TEXTURE_ASPECT_STENCIL_BIT);
|
||||
|
||||
// The stencil component is always 1 byte per pixel.
|
||||
// Don't reduce depths of 32-bit depth/stencil formats.
|
||||
if (want_depth && !want_stencil) {
|
||||
if (region.texture_subresource.aspect == RDD::TEXTURE_ASPECT_DEPTH) {
|
||||
if (pf.getBytesPerTexel(mtlPixFmt) != 4) {
|
||||
bytesPerRow -= buffImgWd;
|
||||
bytesPerImg -= buffImgWd * buffImgHt;
|
||||
}
|
||||
blit_options |= MTLBlitOptionDepthFromDepthStencil;
|
||||
} else if (want_stencil && !want_depth) {
|
||||
} else if (region.texture_subresource.aspect == RDD::TEXTURE_ASPECT_STENCIL) {
|
||||
// The stencil component is always 1 byte per pixel.
|
||||
bytesPerRow = buffImgWd;
|
||||
bytesPerImg = buffImgWd * buffImgHt;
|
||||
blit_options |= MTLBlitOptionStencilFromDepthStencil;
|
||||
@ -558,31 +555,27 @@ void MDCommandBuffer::_copy_texture_buffer(CopySource p_source,
|
||||
}
|
||||
|
||||
if (p_source == CopySource::Buffer) {
|
||||
for (uint32_t lyrIdx = 0; lyrIdx < region.texture_subresources.layer_count; lyrIdx++) {
|
||||
[enc copyFromBuffer:buffer->metal_buffer
|
||||
sourceOffset:region.buffer_offset + (bytesPerImg * lyrIdx)
|
||||
sourceBytesPerRow:bytesPerRow
|
||||
sourceBytesPerImage:bytesPerImg
|
||||
sourceSize:txt_size
|
||||
toTexture:texture
|
||||
destinationSlice:region.texture_subresources.base_layer + lyrIdx
|
||||
destinationLevel:mip_level
|
||||
destinationOrigin:txt_origin
|
||||
options:blit_options];
|
||||
}
|
||||
[enc copyFromBuffer:buffer->metal_buffer
|
||||
sourceOffset:region.buffer_offset
|
||||
sourceBytesPerRow:bytesPerRow
|
||||
sourceBytesPerImage:bytesPerImg
|
||||
sourceSize:txt_size
|
||||
toTexture:texture
|
||||
destinationSlice:region.texture_subresource.layer
|
||||
destinationLevel:mip_level
|
||||
destinationOrigin:txt_origin
|
||||
options:blit_options];
|
||||
} else {
|
||||
for (uint32_t lyrIdx = 0; lyrIdx < region.texture_subresources.layer_count; lyrIdx++) {
|
||||
[enc copyFromTexture:texture
|
||||
sourceSlice:region.texture_subresources.base_layer + lyrIdx
|
||||
sourceLevel:mip_level
|
||||
sourceOrigin:txt_origin
|
||||
sourceSize:txt_size
|
||||
toBuffer:buffer->metal_buffer
|
||||
destinationOffset:region.buffer_offset + (bytesPerImg * lyrIdx)
|
||||
destinationBytesPerRow:bytesPerRow
|
||||
destinationBytesPerImage:bytesPerImg
|
||||
options:blit_options];
|
||||
}
|
||||
[enc copyFromTexture:texture
|
||||
sourceSlice:region.texture_subresource.layer
|
||||
sourceLevel:mip_level
|
||||
sourceOrigin:txt_origin
|
||||
sourceSize:txt_size
|
||||
toBuffer:buffer->metal_buffer
|
||||
destinationOffset:region.buffer_offset
|
||||
destinationBytesPerRow:bytesPerRow
|
||||
destinationBytesPerImage:bytesPerImg
|
||||
options:blit_options];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,8 +149,6 @@ public:
|
||||
virtual uint64_t texture_get_allocation_size(TextureID p_texture) override final;
|
||||
virtual void texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) override final;
|
||||
virtual Vector<uint8_t> texture_get_data(TextureID p_texture, uint32_t p_layer) override final;
|
||||
virtual uint8_t *texture_map(TextureID p_texture, const TextureSubresource &p_subresource) override final;
|
||||
virtual void texture_unmap(TextureID p_texture) override final;
|
||||
virtual BitField<TextureUsageBits> texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) override final;
|
||||
virtual bool texture_can_make_shared_with_format(TextureID p_texture, DataFormat p_format, bool &r_raw_reinterpretation) override final;
|
||||
|
||||
|
||||
@ -563,33 +563,21 @@ uint64_t RenderingDeviceDriverMetal::texture_get_allocation_size(TextureID p_tex
|
||||
|
||||
void RenderingDeviceDriverMetal::texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) {
|
||||
id<MTLTexture> __unsafe_unretained obj = rid::get(p_texture);
|
||||
*r_layout = {};
|
||||
|
||||
PixelFormats &pf = *pixel_formats;
|
||||
DataFormat format = pf.getDataFormat(obj.pixelFormat);
|
||||
|
||||
MTLSize sz = MTLSizeMake(obj.width, obj.height, obj.depth);
|
||||
|
||||
if (p_subresource.mipmap > 0) {
|
||||
r_layout->offset = get_image_format_required_size(format, sz.width, sz.height, sz.depth, p_subresource.mipmap);
|
||||
}
|
||||
|
||||
sz = mipmapLevelSizeFromSize(sz, p_subresource.mipmap);
|
||||
uint32_t w = MAX(1u, obj.width >> p_subresource.mipmap);
|
||||
uint32_t h = MAX(1u, obj.height >> p_subresource.mipmap);
|
||||
uint32_t d = MAX(1u, obj.depth >> p_subresource.mipmap);
|
||||
|
||||
uint32_t bw = 0, bh = 0;
|
||||
get_compressed_image_format_block_dimensions(format, bw, bh);
|
||||
uint32_t sbw = 0, sbh = 0;
|
||||
r_layout->size = get_image_format_required_size(format, sz.width, sz.height, sz.depth, 1, &sbw, &sbh);
|
||||
r_layout->row_pitch = r_layout->size / ((sbh / bh) * sz.depth);
|
||||
r_layout->depth_pitch = r_layout->size / sz.depth;
|
||||
|
||||
uint32_t array_length = obj.arrayLength;
|
||||
if (obj.textureType == MTLTextureTypeCube) {
|
||||
array_length = 6;
|
||||
} else if (obj.textureType == MTLTextureTypeCubeArray) {
|
||||
array_length *= 6;
|
||||
}
|
||||
r_layout->layer_pitch = r_layout->size / array_length;
|
||||
uint32_t sbw = 0, sbh = 0;
|
||||
*r_layout = {};
|
||||
r_layout->size = get_image_format_required_size(format, w, h, d, 1, &sbw, &sbh);
|
||||
r_layout->row_pitch = r_layout->size / ((sbh / bh) * d);
|
||||
}
|
||||
|
||||
Vector<uint8_t> RenderingDeviceDriverMetal::texture_get_data(TextureID p_texture, uint32_t p_layer) {
|
||||
@ -654,20 +642,6 @@ Vector<uint8_t> RenderingDeviceDriverMetal::texture_get_data(TextureID p_texture
|
||||
return image_data;
|
||||
}
|
||||
|
||||
uint8_t *RenderingDeviceDriverMetal::texture_map(TextureID p_texture, const TextureSubresource &p_subresource) {
|
||||
id<MTLTexture> obj = rid::get(p_texture);
|
||||
ERR_FAIL_COND_V_MSG(obj.storageMode != MTLStorageModeShared, nullptr, "Texture must be created with TEXTURE_USAGE_CPU_READ_BIT set.");
|
||||
ERR_FAIL_COND_V_MSG(obj.buffer, nullptr, "Texture mapping is not supported for non-linear textures in Metal.");
|
||||
ERR_FAIL_COND_V_MSG(p_subresource.layer > 0, nullptr, "A linear texture should have a single layer.");
|
||||
ERR_FAIL_COND_V_MSG(p_subresource.mipmap > 0, nullptr, "A linear texture should have a single mipmap.");
|
||||
|
||||
return (uint8_t *)obj.buffer.contents;
|
||||
}
|
||||
|
||||
void RenderingDeviceDriverMetal::texture_unmap(TextureID p_texture) {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
BitField<RDD::TextureUsageBits> RenderingDeviceDriverMetal::texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) {
|
||||
PixelFormats &pf = *pixel_formats;
|
||||
if (pf.getMTLPixelFormat(p_format) == MTLPixelFormatInvalid) {
|
||||
|
||||
Reference in New Issue
Block a user