Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/metal/mtl_texture.mm
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| /** \file | /** \file | ||||
| * \ingroup gpu | * \ingroup gpu | ||||
| */ | */ | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "DNA_userdef_types.h" | #include "DNA_userdef_types.h" | ||||
| #include "GPU_batch.h" | #include "GPU_batch.h" | ||||
| #include "GPU_batch_presets.h" | #include "GPU_batch_presets.h" | ||||
| #include "GPU_capabilities.h" | #include "GPU_capabilities.h" | ||||
| #include "GPU_framebuffer.h" | #include "GPU_framebuffer.h" | ||||
| #include "GPU_immediate.h" | |||||
| #include "GPU_platform.h" | #include "GPU_platform.h" | ||||
| #include "GPU_state.h" | #include "GPU_state.h" | ||||
| #include "mtl_backend.hh" | #include "mtl_backend.hh" | ||||
| #include "mtl_common.hh" | #include "mtl_common.hh" | ||||
| #include "mtl_context.hh" | #include "mtl_context.hh" | ||||
| #include "mtl_debug.hh" | #include "mtl_debug.hh" | ||||
| #include "mtl_texture.hh" | #include "mtl_texture.hh" | ||||
| ▲ Show 20 Lines • Show All 275 Lines • ▼ Show 20 Lines | void gpu::MTLTexture::blit(gpu::MTLTexture *dst, | ||||
| /* Fetch restore framebuffer and blit target framebuffer from destination texture. */ | /* Fetch restore framebuffer and blit target framebuffer from destination texture. */ | ||||
| GPUFrameBuffer *restore_fb = GPU_framebuffer_active_get(); | GPUFrameBuffer *restore_fb = GPU_framebuffer_active_get(); | ||||
| GPUFrameBuffer *blit_target_fb = dst->get_blit_framebuffer(dst_slice, dst_mip); | GPUFrameBuffer *blit_target_fb = dst->get_blit_framebuffer(dst_slice, dst_mip); | ||||
| BLI_assert(blit_target_fb); | BLI_assert(blit_target_fb); | ||||
| GPU_framebuffer_bind(blit_target_fb); | GPU_framebuffer_bind(blit_target_fb); | ||||
| /* Execute graphics draw call to perform the blit. */ | /* Execute graphics draw call to perform the blit. */ | ||||
| GPUBatch *quad = GPU_batch_preset_quad(); | GPUBatch *quad = GPU_batch_preset_quad(); | ||||
| GPU_batch_set_shader(quad, shader); | GPU_batch_set_shader(quad, shader); | ||||
| float w = dst->width_get(); | float w = dst->width_get(); | ||||
| float h = dst->height_get(); | float h = dst->height_get(); | ||||
| GPU_shader_uniform_2f(shader, "fullscreen", w, h); | GPU_shader_uniform_2f(shader, "fullscreen", w, h); | ||||
| GPU_shader_uniform_2f(shader, "src_offset", src_x_offset, src_y_offset); | GPU_shader_uniform_2f(shader, "src_offset", src_x_offset, src_y_offset); | ||||
| GPU_shader_uniform_2f(shader, "dst_offset", dst_x_offset, dst_y_offset); | GPU_shader_uniform_2f(shader, "dst_offset", dst_x_offset, dst_y_offset); | ||||
| Show All 17 Lines | void gpu::MTLTexture::blit(gpu::MTLTexture *dst, | ||||
| GPU_face_culling(GPU_CULL_NONE); | GPU_face_culling(GPU_CULL_NONE); | ||||
| GPU_stencil_test(GPU_STENCIL_ALWAYS); | GPU_stencil_test(GPU_STENCIL_ALWAYS); | ||||
| GPU_depth_mask(false); | GPU_depth_mask(false); | ||||
| GPU_blend(GPU_BLEND_NONE); | GPU_blend(GPU_BLEND_NONE); | ||||
| GPU_depth_test(GPU_DEPTH_ALWAYS); | GPU_depth_test(GPU_DEPTH_ALWAYS); | ||||
| GPU_batch_draw(quad); | GPU_batch_draw(quad); | ||||
| /* TMP draw with IMM TODO(Metal): Remove this once GPUBatch is supported. */ | |||||
| GPUVertFormat *imm_format = immVertexFormat(); | |||||
| uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | |||||
| immBindShader(shader); | |||||
| immBegin(GPU_PRIM_TRI_STRIP, 4); | |||||
| immVertex2f(pos, 1, 0); | |||||
| immVertex2f(pos, 0, 0); | |||||
| immVertex2f(pos, 1, 1); | |||||
| immVertex2f(pos, 0, 1); | |||||
| immEnd(); | |||||
| immUnbindProgram(); | |||||
| /**********************/ | |||||
| /* restoring old pipeline state. */ | /* restoring old pipeline state. */ | ||||
| GPU_depth_mask(depth_write_prev); | GPU_depth_mask(depth_write_prev); | ||||
| GPU_stencil_write_mask_set(stencil_mask_prev); | GPU_stencil_write_mask_set(stencil_mask_prev); | ||||
| GPU_stencil_test(stencil_test_prev); | GPU_stencil_test(stencil_test_prev); | ||||
| GPU_face_culling(culling_test_prev); | GPU_face_culling(culling_test_prev); | ||||
| GPU_depth_mask(depth_write_prev); | GPU_depth_mask(depth_write_prev); | ||||
| GPU_blend(blend_prev); | GPU_blend(blend_prev); | ||||
| GPU_depth_test(depth_test_prev); | GPU_depth_test(depth_test_prev); | ||||
| ▲ Show 20 Lines • Show All 1,110 Lines • ▼ Show 20 Lines | |||||
| bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo) | bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo) | ||||
| { | { | ||||
| /* Not a valid vertex buffer format, though verifying texture is not set as such | /* Not a valid vertex buffer format, though verifying texture is not set as such | ||||
| * as this is not supported on Apple Silicon. */ | * as this is not supported on Apple Silicon. */ | ||||
| BLI_assert_msg(this->format_ != GPU_DEPTH24_STENCIL8, | BLI_assert_msg(this->format_ != GPU_DEPTH24_STENCIL8, | ||||
| "Apple silicon does not support GPU_DEPTH24_S8"); | "Apple silicon does not support GPU_DEPTH24_S8"); | ||||
| 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; | return true; | ||||
| } | } | ||||
| bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset) | bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset) | ||||
| { | { | ||||
| BLI_assert(src); | BLI_assert(src); | ||||
| /* Zero initialize. */ | /* Zero initialize. */ | ||||
| ▲ Show 20 Lines • Show All 256 Lines • Show Last 20 Lines | |||||