Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/opengl/gl_texture.cc
| Show First 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | switch (this->dimensions_count()) { | ||||
| case 2: | case 2: | ||||
| glTextureSubImage2D(tex_id_, mip, UNPACK2(offset), UNPACK2(extent), format, type, data); | glTextureSubImage2D(tex_id_, mip, UNPACK2(offset), UNPACK2(extent), format, type, data); | ||||
| break; | break; | ||||
| case 3: | case 3: | ||||
| glTextureSubImage3D(tex_id_, mip, UNPACK3(offset), UNPACK3(extent), format, type, data); | glTextureSubImage3D(tex_id_, mip, UNPACK3(offset), UNPACK3(extent), format, type, data); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| has_pixels_ = true; | |||||
| } | } | ||||
| void GLTexture::update_sub( | void GLTexture::update_sub( | ||||
| int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) | int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) | ||||
| { | { | ||||
| BLI_assert(validate_data_format(format_, type)); | BLI_assert(validate_data_format(format_, type)); | ||||
| BLI_assert(data != nullptr); | BLI_assert(data != nullptr); | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | switch (dimensions) { | ||||
| case 2: | case 2: | ||||
| glTexSubImage2D(target_, mip, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, data); | glTexSubImage2D(target_, mip, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, data); | ||||
| break; | break; | ||||
| case 3: | case 3: | ||||
| glTexSubImage3D(target_, mip, UNPACK3(offset), UNPACK3(extent), gl_format, gl_type, data); | glTexSubImage3D(target_, mip, UNPACK3(offset), UNPACK3(extent), gl_format, gl_type, data); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| has_pixels_ = true; | |||||
| } | } | ||||
| /** | /** | ||||
| * This will create the mipmap images and populate them with filtered data from base level. | * This will create the mipmap images and populate them with filtered data from base level. | ||||
| * | * | ||||
| * WARNING: Depth textures are not populated but they have their mips correctly defined. | * WARNING: Depth textures are not populated but they have their mips correctly defined. | ||||
| * WARNING: This resets the mipmap range. | * WARNING: This resets the mipmap range. | ||||
| */ | */ | ||||
| void GLTexture::generate_mipmap() | void GLTexture::generate_mipmap() | ||||
| { | { | ||||
| this->ensure_mipmaps(9999); | this->ensure_mipmaps(9999); | ||||
| /* Some drivers have bugs when using #glGenerateMipmap with depth textures (see T56789). | /* Some drivers have bugs when using #glGenerateMipmap with depth textures (see T56789). | ||||
| * In this case we just create a complete texture with mipmaps manually without | * In this case we just create a complete texture with mipmaps manually without | ||||
| * down-sampling. You must initialize the texture levels using other methods like | * down-sampling. You must initialize the texture levels using other methods like | ||||
| * #GPU_framebuffer_recursive_downsample(). */ | * #GPU_framebuffer_recursive_downsample(). */ | ||||
| if (format_flag_ & GPU_FORMAT_DEPTH) { | if (format_flag_ & GPU_FORMAT_DEPTH) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (GLContext::generate_mipmap_workaround) { | |||||
| /* Broken glGenerateMipmap, don't call it and render without mipmaps. | |||||
| * If no top level pixels have been filled in, the levels will get filled by | |||||
| * other means and there is no need to disable mipmapping. */ | |||||
| if (has_pixels_) { | |||||
| this->mip_range_set(0, 0); | |||||
| } | |||||
| return; | |||||
| } | |||||
| /* Down-sample from mip 0 using implementation. */ | /* Down-sample from mip 0 using implementation. */ | ||||
| if (GLContext::direct_state_access_support) { | if (GLContext::direct_state_access_support) { | ||||
| glGenerateTextureMipmap(tex_id_); | glGenerateTextureMipmap(tex_id_); | ||||
| } | } | ||||
| else { | else { | ||||
| GLContext::state_manager_active_get()->texture_bind_temp(this); | GLContext::state_manager_active_get()->texture_bind_temp(this); | ||||
| glGenerateMipmap(target_); | glGenerateMipmap(target_); | ||||
| } | } | ||||
| Show All 14 Lines | else { | ||||
| GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); | GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); | ||||
| FrameBuffer *fb = reinterpret_cast<FrameBuffer *>(this->framebuffer_get()); | FrameBuffer *fb = reinterpret_cast<FrameBuffer *>(this->framebuffer_get()); | ||||
| fb->bind(true); | fb->bind(true); | ||||
| fb->clear_attachment(this->attachment_type(0), data_format, data); | fb->clear_attachment(this->attachment_type(0), data_format, data); | ||||
| GPU_framebuffer_bind(prev_fb); | GPU_framebuffer_bind(prev_fb); | ||||
| } | } | ||||
| has_pixels_ = true; | |||||
| } | } | ||||
| void GLTexture::copy_to(Texture *dst_) | void GLTexture::copy_to(Texture *dst_) | ||||
| { | { | ||||
| GLTexture *dst = static_cast<GLTexture *>(dst_); | GLTexture *dst = static_cast<GLTexture *>(dst_); | ||||
| GLTexture *src = this; | GLTexture *src = this; | ||||
| BLI_assert((dst->w_ == src->w_) && (dst->h_ == src->h_) && (dst->d_ == src->d_)); | BLI_assert((dst->w_ == src->w_) && (dst->h_ == src->h_) && (dst->d_ == src->d_)); | ||||
| Show All 10 Lines | if (GLContext::copy_image_support) { | ||||
| glCopyImageSubData( | glCopyImageSubData( | ||||
| src->tex_id_, target_, mip, 0, 0, 0, dst->tex_id_, target_, mip, 0, 0, 0, UNPACK3(extent)); | src->tex_id_, target_, mip, 0, 0, 0, dst->tex_id_, target_, mip, 0, 0, 0, UNPACK3(extent)); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Fallback for older GL. */ | /* Fallback for older GL. */ | ||||
| GPU_framebuffer_blit( | GPU_framebuffer_blit( | ||||
| src->framebuffer_get(), 0, dst->framebuffer_get(), 0, to_framebuffer_bits(format_)); | src->framebuffer_get(), 0, dst->framebuffer_get(), 0, to_framebuffer_bits(format_)); | ||||
| } | } | ||||
| has_pixels_ = true; | |||||
| } | } | ||||
| void *GLTexture::read(int mip, eGPUDataFormat type) | void *GLTexture::read(int mip, eGPUDataFormat type) | ||||
| { | { | ||||
| BLI_assert(!(format_flag_ & GPU_FORMAT_COMPRESSED)); | BLI_assert(!(format_flag_ & GPU_FORMAT_COMPRESSED)); | ||||
| BLI_assert(mip <= mipmaps_ || mip == 0); | BLI_assert(mip <= mipmaps_ || mip == 0); | ||||
| BLI_assert(validate_data_format(format_, type)); | BLI_assert(validate_data_format(format_, type)); | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | struct GPUFrameBuffer *GLTexture::framebuffer_get() | ||||
| if (framebuffer_) { | if (framebuffer_) { | ||||
| return framebuffer_; | return framebuffer_; | ||||
| } | } | ||||
| BLI_assert(!(type_ & (GPU_TEXTURE_ARRAY | GPU_TEXTURE_CUBE | GPU_TEXTURE_1D | GPU_TEXTURE_3D))); | BLI_assert(!(type_ & (GPU_TEXTURE_ARRAY | GPU_TEXTURE_CUBE | GPU_TEXTURE_1D | GPU_TEXTURE_3D))); | ||||
| /* TODO(fclem): cleanup this. Don't use GPU object but blender::gpu ones. */ | /* TODO(fclem): cleanup this. Don't use GPU object but blender::gpu ones. */ | ||||
| GPUTexture *gputex = reinterpret_cast<GPUTexture *>(static_cast<Texture *>(this)); | GPUTexture *gputex = reinterpret_cast<GPUTexture *>(static_cast<Texture *>(this)); | ||||
| framebuffer_ = GPU_framebuffer_create(name_); | framebuffer_ = GPU_framebuffer_create(name_); | ||||
| GPU_framebuffer_texture_attach(framebuffer_, gputex, 0, 0); | GPU_framebuffer_texture_attach(framebuffer_, gputex, 0, 0); | ||||
| has_pixels_ = true; | |||||
| return framebuffer_; | return framebuffer_; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Sampler objects | /** \name Sampler objects | ||||
| * \{ */ | * \{ */ | ||||
| ▲ Show 20 Lines • Show All 229 Lines • Show Last 20 Lines | |||||