Metal: Resolve runtime issues with texture views
When creating a texture view, Metal may require that the original GPUTexture state is modified in some way. This may be a result of deferred creation, or, to cache the texture view against the source. As a result, GPUTexture passed into GPU_texture_create_view cannot be const. Small fixes have also been made in the Metal texture implementation to ensure correct function of texture views. Authored by Apple: Michael Parkin-White Pull Request: https://projects.blender.org/blender/blender/pulls/107167
This commit is contained in:
committed by
Jeroen Bakker
parent
46316b29dc
commit
36e1ebc78d
@@ -703,7 +703,7 @@ void GPU_texture_free(GPUTexture *texture);
|
||||
* TODO(fclem): Target conversion (ex: Texture 2D as Texture 2D Array) is not implemented yet.
|
||||
*/
|
||||
GPUTexture *GPU_texture_create_view(const char *name,
|
||||
const GPUTexture *source_texture,
|
||||
GPUTexture *source_texture,
|
||||
eGPUTextureFormat view_format,
|
||||
int mip_start,
|
||||
int mip_len,
|
||||
|
||||
@@ -132,7 +132,7 @@ bool Texture::init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format)
|
||||
return this->init_internal(vbo);
|
||||
}
|
||||
|
||||
bool Texture::init_view(const GPUTexture *src_,
|
||||
bool Texture::init_view(GPUTexture *src_,
|
||||
eGPUTextureFormat format,
|
||||
eGPUTextureType type,
|
||||
int mip_start,
|
||||
@@ -448,7 +448,7 @@ GPUTexture *GPU_texture_create_error(int dimension, bool is_array)
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_create_view(const char *name,
|
||||
const GPUTexture *src,
|
||||
GPUTexture *src,
|
||||
eGPUTextureFormat format,
|
||||
int mip_start,
|
||||
int mip_len,
|
||||
|
||||
@@ -132,7 +132,7 @@ class Texture {
|
||||
bool init_3D(int w, int h, int d, int mip_len, eGPUTextureFormat format);
|
||||
bool init_cubemap(int w, int layers, int mip_len, eGPUTextureFormat format);
|
||||
bool init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format);
|
||||
bool init_view(const GPUTexture *src,
|
||||
bool init_view(GPUTexture *src,
|
||||
eGPUTextureFormat format,
|
||||
eGPUTextureType type,
|
||||
int mip_start,
|
||||
@@ -313,7 +313,7 @@ class Texture {
|
||||
protected:
|
||||
virtual bool init_internal() = 0;
|
||||
virtual bool init_internal(GPUVertBuf *vbo) = 0;
|
||||
virtual bool init_internal(const GPUTexture *src, int mip_offset, int layer_offset) = 0;
|
||||
virtual bool init_internal(GPUTexture *src, int mip_offset, int layer_offset) = 0;
|
||||
};
|
||||
|
||||
/* Syntactic sugar. */
|
||||
|
||||
@@ -181,7 +181,6 @@ class MTLTexture : public Texture {
|
||||
bool is_baked_ = false;
|
||||
MTLTextureDescriptor *texture_descriptor_ = nullptr;
|
||||
id<MTLTexture> texture_ = nil;
|
||||
MTLTextureUsage usage_;
|
||||
|
||||
/* Texture Storage. */
|
||||
id<MTLBuffer> texture_buffer_ = nil;
|
||||
@@ -284,7 +283,7 @@ class MTLTexture : public Texture {
|
||||
protected:
|
||||
bool init_internal() override;
|
||||
bool init_internal(GPUVertBuf *vbo) override;
|
||||
bool init_internal(const GPUTexture *src,
|
||||
bool init_internal(GPUTexture *src,
|
||||
int mip_offset,
|
||||
int layer_offset) override; /* Texture View */
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ void gpu::MTLTexture::bake_mip_swizzle_view()
|
||||
}
|
||||
|
||||
int range_len = min_ii((mip_texture_max_level_ - mip_texture_base_level_) + 1,
|
||||
texture_.mipmapLevelCount);
|
||||
texture_.mipmapLevelCount - mip_texture_base_level_);
|
||||
BLI_assert(range_len > 0);
|
||||
BLI_assert(mip_texture_base_level_ < texture_.mipmapLevelCount);
|
||||
BLI_assert(mip_texture_base_layer_ < num_slices);
|
||||
@@ -1152,7 +1152,7 @@ void gpu::MTLTexture::ensure_mipmaps(int miplvl)
|
||||
void gpu::MTLTexture::generate_mipmap()
|
||||
{
|
||||
/* Fetch Active Context. */
|
||||
MTLContext *ctx = reinterpret_cast<MTLContext *>(GPU_context_active_get());
|
||||
MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
|
||||
BLI_assert(ctx);
|
||||
|
||||
if (!ctx->device) {
|
||||
@@ -1265,7 +1265,7 @@ void gpu::MTLTexture::clear(eGPUDataFormat data_format, const void *data)
|
||||
|
||||
/* Create clear framebuffer. */
|
||||
GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get();
|
||||
FrameBuffer *fb = reinterpret_cast<FrameBuffer *>(this->get_blit_framebuffer(0, 0));
|
||||
FrameBuffer *fb = unwrap(this->get_blit_framebuffer(0, 0));
|
||||
fb->bind(true);
|
||||
fb->clear_attachment(this->attachment_type(0), data_format, data);
|
||||
GPU_framebuffer_bind(prev_fb);
|
||||
@@ -1805,7 +1805,7 @@ bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset)
|
||||
bool gpu::MTLTexture::init_internal(GPUTexture *src, int mip_offset, int layer_offset)
|
||||
{
|
||||
BLI_assert(src);
|
||||
|
||||
@@ -1817,12 +1817,17 @@ bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int l
|
||||
source_texture_ = src;
|
||||
mip_texture_base_level_ = mip_offset;
|
||||
mip_texture_base_layer_ = layer_offset;
|
||||
texture_view_dirty_flags_ |= TEXTURE_VIEW_MIP_DIRTY;
|
||||
|
||||
/* Assign usage. */
|
||||
gpu_image_usage_flags_ = GPU_texture_usage(src);
|
||||
BLI_assert_msg(
|
||||
gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW,
|
||||
"Source texture of TextureView must have GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW usage flag.");
|
||||
|
||||
/* Assign texture as view. */
|
||||
const gpu::MTLTexture *mtltex = static_cast<const gpu::MTLTexture *>(unwrap(src));
|
||||
gpu::MTLTexture *mtltex = static_cast<gpu::MTLTexture *>(unwrap(src));
|
||||
mtltex->ensure_baked();
|
||||
texture_ = mtltex->texture_;
|
||||
BLI_assert(texture_);
|
||||
[texture_ retain];
|
||||
|
||||
@@ -178,7 +178,7 @@ bool GLTexture::init_internal(GPUVertBuf *vbo)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GLTexture::init_internal(const GPUTexture *src, int mip_offset, int layer_offset)
|
||||
bool GLTexture::init_internal(GPUTexture *src, int mip_offset, int layer_offset)
|
||||
{
|
||||
BLI_assert(GLContext::texture_storage_support);
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ class GLTexture : public Texture {
|
||||
/** Return true on success. */
|
||||
bool init_internal(GPUVertBuf *vbo) override;
|
||||
/** Return true on success. */
|
||||
bool init_internal(const GPUTexture *src, int mip_offset, int layer_offset) override;
|
||||
bool init_internal(GPUTexture *src, int mip_offset, int layer_offset) override;
|
||||
|
||||
private:
|
||||
bool proxy_check(int mip);
|
||||
|
||||
@@ -174,7 +174,7 @@ bool VKTexture::init_internal(GPUVertBuf * /*vbo*/)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VKTexture::init_internal(const GPUTexture * /*src*/, int /*mip_offset*/, int /*layer_offset*/)
|
||||
bool VKTexture::init_internal(GPUTexture * /*src*/, int /*mip_offset*/, int /*layer_offset*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class VKTexture : public Texture {
|
||||
protected:
|
||||
bool init_internal() override;
|
||||
bool init_internal(GPUVertBuf *vbo) override;
|
||||
bool init_internal(const GPUTexture *src, int mip_offset, int layer_offset) override;
|
||||
bool init_internal(GPUTexture *src, int mip_offset, int layer_offset) override;
|
||||
|
||||
private:
|
||||
/** Is this texture already allocated on device. */
|
||||
|
||||
Reference in New Issue
Block a user