Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/metal/mtl_texture.mm')
-rw-r--r--source/blender/gpu/metal/mtl_texture.mm125
1 files changed, 106 insertions, 19 deletions
diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm
index 2b7c2333bff..4af46c13751 100644
--- a/source/blender/gpu/metal/mtl_texture.mm
+++ b/source/blender/gpu/metal/mtl_texture.mm
@@ -20,6 +20,7 @@
#include "mtl_context.hh"
#include "mtl_debug.hh"
#include "mtl_texture.hh"
+#include "mtl_vertex_buffer.hh"
#include "GHOST_C-api.h"
@@ -50,7 +51,6 @@ void gpu::MTLTexture::mtl_texture_init()
/* VBO. */
vert_buffer_ = nullptr;
vert_buffer_mtl_ = nil;
- vert_buffer_offset_ = -1;
/* Default Swizzle. */
tex_swizzle_mask_[0] = 'r';
@@ -169,26 +169,39 @@ void gpu::MTLTexture::bake_mip_swizzle_view()
id<MTLTexture> gpu::MTLTexture::get_metal_handle()
{
- /* ensure up to date and baked. */
- this->ensure_baked();
-
/* Verify VBO texture shares same buffer. */
if (resource_mode_ == MTL_TEXTURE_MODE_VBO) {
- int r_offset = -1;
+ id<MTLBuffer> buf = vert_buffer_->get_metal_buffer();
+
+ /* Source vertex buffer has been re-generated, require re-initialisation. */
+ if (buf != vert_buffer_mtl_) {
+ MTL_LOG_INFO(
+ "MTLTexture '%p' using MTL_TEXTURE_MODE_VBO requires re-generation due to updated "
+ "Vertex-Buffer.\n",
+ this);
+ /* Clear state. */
+ this->reset();
+
+ /* Re-initialise. */
+ this->init_internal(wrap(vert_buffer_));
+
+ /* Update for assertion check below. */
+ buf = vert_buffer_->get_metal_buffer();
+ }
- /* TODO(Metal): Fetch buffer from MTLVertBuf when implemented. */
- id<MTLBuffer> buf = nil; /*vert_buffer_->get_metal_buffer(&r_offset);*/
+ /* Ensure buffer is valid.
+ * Fetchvert buffer handle directly in-case it changed above. */
BLI_assert(vert_buffer_mtl_ != nil);
- BLI_assert(buf == vert_buffer_mtl_ && r_offset == vert_buffer_offset_);
-
- UNUSED_VARS(buf);
- UNUSED_VARS_NDEBUG(r_offset);
+ BLI_assert(vert_buffer_->get_metal_buffer() == vert_buffer_mtl_);
}
+ /* ensure up to date and baked. */
+ this->ensure_baked();
+
if (is_baked_) {
/* For explicit texture views, ensure we always return the texture view. */
if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
- BLI_assert(mip_swizzle_view_ && "Texture view should always have a valid handle.");
+ BLI_assert_msg(mip_swizzle_view_, "Texture view should always have a valid handle.");
}
if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
@@ -208,7 +221,7 @@ id<MTLTexture> gpu::MTLTexture::get_metal_handle_base()
/* For explicit texture views, always return the texture view. */
if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
- BLI_assert(mip_swizzle_view_ && "Texture view should always have a valid handle.");
+ BLI_assert_msg(mip_swizzle_view_, "Texture view should always have a valid handle.");
if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
bake_mip_swizzle_view();
}
@@ -915,7 +928,7 @@ void gpu::MTLTexture::generate_mipmap()
/* Ensure texture is baked. */
this->ensure_baked();
- BLI_assert(is_baked_ && texture_ && "MTLTexture is not valid");
+ BLI_assert_msg(is_baked_ && texture_, "MTLTexture is not valid");
if (mipmaps_ == 1 || mtl_max_mips_ == 1) {
MTL_LOG_WARNING("Call to generate mipmaps on texture with 'mipmaps_=1\n'");
@@ -1231,7 +1244,7 @@ void gpu::MTLTexture::read_internal(int mip,
depth_format_mode = 4;
break;
default:
- BLI_assert(false && "Unhandled depth read format case");
+ BLI_assert_msg(false, "Unhandled depth read format case");
break;
}
}
@@ -1445,11 +1458,85 @@ bool gpu::MTLTexture::init_internal()
bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo)
{
- /* Zero initialize. */
- this->prepare_internal();
+ /* Not a valid vertex buffer format, though verifying texture is not set as such
+ * as this is not supported on Apple Silicon. */
+ BLI_assert_msg(this->format_ != GPU_DEPTH24_STENCIL8,
+ "Apple silicon does not support GPU_DEPTH24_S8");
- /* TODO(Metal): Add implementation for GPU Vert buf. */
- return false;
+ MTLPixelFormat mtl_format = gpu_texture_format_to_metal(this->format_);
+ mtl_max_mips_ = 1;
+ mipmaps_ = 0;
+ this->mip_range_set(0, 0);
+
+ /* Create texture from GPUVertBuf's buffer. */
+ MTLVertBuf *mtl_vbo = static_cast<MTLVertBuf *>(unwrap(vbo));
+ mtl_vbo->bind();
+ mtl_vbo->flag_used();
+
+ /* Get Metal Buffer. */
+ id<MTLBuffer> source_buffer = mtl_vbo->get_metal_buffer();
+ BLI_assert(source_buffer);
+
+ /* Verify size. */
+ if (w_ <= 0) {
+ MTL_LOG_WARNING("Allocating texture buffer of width 0!\n");
+ w_ = 1;
+ }
+
+ /* Verify Texture and vertex buffer alignment. */
+ int bytes_per_pixel = get_mtl_format_bytesize(mtl_format);
+ int bytes_per_row = bytes_per_pixel * w_;
+
+ MTLContext *mtl_ctx = MTLContext::get();
+ uint align_requirement = static_cast<uint>(
+ [mtl_ctx->device minimumLinearTextureAlignmentForPixelFormat:mtl_format]);
+
+ /* Verify per-vertex size aligns with texture size. */
+ const GPUVertFormat *format = GPU_vertbuf_get_format(vbo);
+ BLI_assert(bytes_per_pixel == format->stride &&
+ "Pixel format stride MUST match the texture format stride -- These being different "
+ "is likely caused by Metal's VBO padding to a minimum of 4-bytes per-vertex");
+ UNUSED_VARS_NDEBUG(format);
+
+ /* Create texture descriptor. */
+ BLI_assert(type_ == GPU_TEXTURE_BUFFER);
+ texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
+ texture_descriptor_.pixelFormat = mtl_format;
+ texture_descriptor_.textureType = MTLTextureTypeTextureBuffer;
+ texture_descriptor_.width = w_;
+ texture_descriptor_.height = 1;
+ texture_descriptor_.depth = 1;
+ texture_descriptor_.arrayLength = 1;
+ texture_descriptor_.mipmapLevelCount = mtl_max_mips_;
+ texture_descriptor_.usage =
+ MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
+ MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
+ texture_descriptor_.storageMode = [source_buffer storageMode];
+ texture_descriptor_.sampleCount = 1;
+ texture_descriptor_.cpuCacheMode = [source_buffer cpuCacheMode];
+ texture_descriptor_.hazardTrackingMode = [source_buffer hazardTrackingMode];
+
+ texture_ = [source_buffer
+ newTextureWithDescriptor:texture_descriptor_
+ offset:0
+ bytesPerRow:ceil_to_multiple_u(bytes_per_row, align_requirement)];
+ aligned_w_ = bytes_per_row / bytes_per_pixel;
+
+ BLI_assert(texture_);
+ texture_.label = [NSString stringWithUTF8String:this->get_name()];
+ is_baked_ = true;
+ is_dirty_ = false;
+ resource_mode_ = MTL_TEXTURE_MODE_VBO;
+
+ /* Track Status. */
+ vert_buffer_ = mtl_vbo;
+ vert_buffer_mtl_ = source_buffer;
+
+ /* Cleanup. */
+ [texture_descriptor_ release];
+ texture_descriptor_ = nullptr;
+
+ return true;
}
bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset)