38 glGenTextures(1, &tex_id_);
47 if (ctx !=
nullptr && is_bound_) {
62 if (!this->proxy_check(0)) {
73 glTexStorage1D(target_,
mipmaps_, internal_format,
w_);
76 glTexStorage2D(target_,
mipmaps_, internal_format,
w_,
h_);
86 glTextureParameteri(tex_id_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
89 glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
107 glTextureBuffer(tex_id_, internal_format, gl_vbo->vbo_id_);
110 glTexBuffer(target_, internal_format, gl_vbo->vbo_id_);
127 glTextureView(tex_id_,
134 this->layer_count());
139 if (
ELEM(
format_, TextureFormat::SFLOAT_32_DEPTH_UINT_8)) {
140 stencil_texture_mode_set(use_stencil);
152void GLTexture::update_sub_direct_state_access(
153 int mip,
int offset[3],
int extent[3], GLenum
format, GLenum type,
const void *
data)
160 glCompressedTextureSubImage1D(tex_id_, mip, offset[0], extent[0],
format,
size,
data);
163 glCompressedTextureSubImage2D(
167 glCompressedTextureSubImage3D(
176 glTextureSubImage1D(tex_id_, mip, offset[0], extent[0],
format, type,
data);
203 const uint texture_unpack_row_length =
205 const bool do_texture_unpack = !
ELEM(texture_unpack_row_length, 0, extent[0]);
208 std::unique_ptr<uint8_t, MEM_freeN_smart_ptr_deleter> unpack_buffer =
nullptr;
209 if (do_texture_unpack) {
211 "Compressed data with texture_unpack_row_length != 0 is not supported.");
213 "3D texture data with texture_unpack_row_length != 0 is not supported.");
217 size_t dst_total_count = dst_row_stride *
max_ii(extent[1], 1) *
max_ii(extent[2], 1);
223 const uint8_t *src_ptr =
static_cast<const uint8_t *
>(
data);
224 uint8_t *dst_ptr = unpack_buffer.get();
225 for (
int y = 0;
y <
max_ii(extent[1], 1); ++
y) {
226 std::memcpy(dst_ptr, src_ptr, dst_row_stride);
227 src_ptr += src_row_stride;
228 dst_ptr += dst_row_stride;
233 data = unpack_buffer.get();
237 std::unique_ptr<uint16_t, MEM_freeN_smart_ptr_deleter> clamped_half_buffer =
nullptr;
239 size_t dst_pixel_count =
max_ii(extent[0], 1) *
max_ii(extent[1], 1) *
max_ii(extent[2], 1);
243 clamped_half_buffer.reset(
249 constexpr int64_t chunk_size = 4 * 1024 * 1024;
261 data = clamped_half_buffer.get();
266 if (do_texture_unpack) {
267 unpack_buffer.reset(
nullptr);
273 GLenum gl_type =
to_gl(type);
277 this->update_sub_direct_state_access(mip, offset, extent, gl_format, gl_type,
data);
283 for (
int i = 0;
i < extent[2];
i++) {
284 GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + offset[2] +
i;
285 glTexSubImage2D(target, mip,
UNPACK2(offset),
UNPACK2(extent), gl_format, gl_type,
data);
290 switch (dimensions) {
293 glCompressedTexSubImage1D(target_, mip, offset[0], extent[0], gl_format,
size,
data);
296 glCompressedTexSubImage2D(
300 glCompressedTexSubImage3D(
306 switch (dimensions) {
309 glTexSubImage1D(target_, mip, offset[0], extent[0], gl_format, gl_type,
data);
312 glTexSubImage2D(target_, mip,
UNPACK2(offset),
UNPACK2(extent), gl_format, gl_type,
data);
315 glTexSubImage3D(target_, mip,
UNPACK3(offset),
UNPACK3(extent), gl_format, gl_type,
data);
326 GPUPixelBuffer *pixbuf)
341 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pix_buf_handle);
343 switch (dimensions) {
346 glTexSubImage1D(target_, 0, offset[0], extent[0], gl_format, gl_type,
nullptr);
349 glTexSubImage2D(target_, 0,
UNPACK2(offset),
UNPACK2(extent), gl_format, gl_type,
nullptr);
352 glTexSubImage3D(target_, 0,
UNPACK3(offset),
UNPACK3(extent), gl_format, gl_type,
nullptr);
356 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
386 glGenerateTextureMipmap(tex_id_);
390 glGenerateMipmap(target_);
425 int extent[3] = {1, 1, 1};
428 src->tex_id_, target_, mip, 0, 0, 0, dst->tex_id_, target_, mip, 0, 0, 0,
UNPACK3(extent));
440 int extent[3] = {1, 1, 1};
443 size_t sample_len = extent[0] * extent[1] * extent[2];
445 size_t texture_size = sample_len * sample_size;
452 format_ == TextureFormat::SFLOAT_32_DEPTH_UINT_8 ? TextureFormat::SFLOAT_32_DEPTH :
format_);
453 GLenum gl_type =
to_gl(type);
456 glGetTextureImage(tex_id_, mip, gl_format, gl_type, texture_size,
data);
461 size_t cube_face_size = texture_size / 6;
462 char *pdata = (
char *)
data;
463 for (
int i = 0;
i < 6;
i++, pdata += cube_face_size) {
464 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X +
i, mip, gl_format, gl_type, pdata);
468 glGetTexImage(target_, mip, gl_format, gl_type,
data);
487 glTextureParameteriv(tex_id_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
491 glTexParameteriv(target_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
495void GLTexture::stencil_texture_mode_set(
bool use_stencil)
498 GLint value = use_stencil ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT;
500 glTextureParameteri(tex_id_, GL_DEPTH_STENCIL_TEXTURE_MODE, value);
504 glTexParameteri(target_, GL_DEPTH_STENCIL_TEXTURE_MODE, value);
514 glTextureParameteri(tex_id_, GL_TEXTURE_BASE_LEVEL,
min);
515 glTextureParameteri(tex_id_, GL_TEXTURE_MAX_LEVEL,
max);
519 glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL,
min);
520 glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL,
max);
545 switch (extend_mode) {
547 return GL_CLAMP_TO_EDGE;
551 return GL_MIRRORED_REPEAT;
553 return GL_CLAMP_TO_BORDER;
556 return GL_CLAMP_TO_EDGE;
567 glGenSamplers(samplers_state_cache_count_, &samplers_state_cache_[0][0][0]);
571 const GLenum extend_t =
to_gl(extend_yz);
575 const GLenum extend_s =
to_gl(extend_x);
583 GL_LINEAR_MIPMAP_LINEAR :
586 GL_NEAREST_MIPMAP_LINEAR :
591 GLuint sampler = samplers_state_cache_[extend_yz_i][extend_x_i][filtering_i];
592 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, extend_s);
593 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, extend_t);
594 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, extend_t);
595 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, min_filter);
596 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, mag_filter);
617 glSamplerParameteri(compare_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
618 glSamplerParameteri(compare_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
619 glSamplerParameteri(compare_sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
620 glSamplerParameteri(compare_sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
621 glSamplerParameteri(compare_sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
622 glSamplerParameteri(compare_sampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
623 glSamplerParameteri(compare_sampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
630 glSamplerParameteri(icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
631 glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
642 float max_anisotropy = 1.0f;
643 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
645 const float anisotropic_filter =
min_ff(max_anisotropy,
U.anisotropic_filter);
655 glSamplerParameterf(samplers_state_cache_[extend_yz_i][extend_x_i][filtering_i],
656 GL_TEXTURE_MAX_ANISOTROPY_EXT,
666 glDeleteSamplers(samplers_state_cache_count_, &samplers_state_cache_[0][0][0]);
676 return custom_samplers_state_cache_[
sampler_state.custom_type];
691bool GLTexture::proxy_check(
int mip)
700 int size[3] = {1, 1, 1};
710 if (
size[0] > max_3d_size ||
size[1] > max_3d_size ||
size[2] > max_3d_size) {
715 if (
size[0] > max_size ||
size[1] > max_size) {
720 if (
size[0] > max_size) {
725 if (
size[0] > max_cube_size) {
751 switch (dimensions) {
754 glCompressedTexImage1D(gl_proxy, mip,
size[0], 0, gl_format, img_size,
nullptr);
757 glCompressedTexImage2D(gl_proxy, mip,
UNPACK2(
size), 0, gl_format, img_size,
nullptr);
760 glCompressedTexImage3D(gl_proxy, mip,
UNPACK3(
size), 0, gl_format, img_size,
nullptr);
765 switch (dimensions) {
768 glTexImage1D(gl_proxy, mip, internal_format,
size[0], 0, gl_format, gl_type,
nullptr);
772 gl_proxy, mip, internal_format,
UNPACK2(
size), 0, gl_format, gl_type,
nullptr);
776 gl_proxy, mip, internal_format,
UNPACK3(
size), 0, gl_format, gl_type,
nullptr);
782 glGetTexLevelParameteriv(gl_proxy, 0, GL_TEXTURE_WIDTH, &width);
803 attachment_read.
tex ==
nullptr)
807 "Feedback loop: Trying to bind a texture (%s) with mip range %d-%d but mip %d is "
808 "attached to the active framebuffer (%s)",
827 glGenBuffers(1, &gl_id_);
837 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_id_);
838 glBufferData(GL_PIXEL_UNPACK_BUFFER,
size,
nullptr, GL_DYNAMIC_DRAW);
839 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
847 glDeleteBuffers(1, &gl_id_);
857 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_id_);
858 void *
ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
865 glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
866 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
874 return native_handle;
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
#define SNPRINTF(dst, format,...)
int GPU_max_texture_3d_size()
int GPU_max_texture_layers()
int GPU_max_texture_size()
blender::gpu::FrameBuffer * GPU_framebuffer_create(const char *name)
#define GPU_ATTACHMENT_TEXTURE(_texture)
void GPU_framebuffer_free(blender::gpu::FrameBuffer *fb)
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
blender::gpu::FrameBuffer * GPU_framebuffer_active_get()
@ GPU_SAMPLER_CUSTOM_ICON
@ GPU_SAMPLER_CUSTOM_COMPARE
GPUPixelBufferNativeHandle GPU_pixel_buffer_get_native_handle(GPUPixelBuffer *pixel_buf)
@ GPU_SAMPLER_STATE_TYPE_CUSTOM
@ GPU_SAMPLER_STATE_TYPE_INTERNAL
static const int GPU_SAMPLER_FILTERING_TYPES_COUNT
@ GPU_SAMPLER_EXTEND_MODE_MIRRORED_REPEAT
@ GPU_SAMPLER_EXTEND_MODE_REPEAT
@ GPU_SAMPLER_EXTEND_MODE_EXTEND
@ GPU_SAMPLER_EXTEND_MODE_CLAMP_TO_BORDER
#define GPU_SAMPLER_CUSTOM_TYPES_COUNT
@ GPU_SAMPLER_FILTERING_MIPMAP
@ GPU_SAMPLER_FILTERING_ANISOTROPIC
@ GPU_SAMPLER_FILTERING_LINEAR
#define GPU_SAMPLER_EXTEND_MODES_COUNT
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr T * data() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr const T * data() const
StateManager * state_manager
void attachment_set(GPUAttachmentType type, const GPUAttachment &new_attachment)
static bool stencil_texturing_support
static GLStateManager * state_manager_active_get()
static bool direct_state_access_support
static bool texture_filter_anisotropic_support
static void texture_free(GLuint tex_id)
static GLint max_cubemap_size
static bool generate_mipmap_workaround
GPUPixelBufferNativeHandle get_native_handle() override
GLPixelBuffer(size_t size)
size_t get_size() override
void texture_bind_temp(GLTexture *tex)
uint texture_unpack_row_length_get() const
GLTexture(const char *name)
void copy_to(Texture *dst) override
void mip_range_set(int min, int max) override
friend class GLFrameBuffer
static void samplers_init()
static GLuint get_sampler(const GPUSamplerState &sampler_state)
static void samplers_update()
void * read(int mip, eGPUDataFormat type) override
static void samplers_free()
bool init_internal() override
void check_feedback_loop()
void generate_mipmap() override
void update_sub(int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) override
void clear(eGPUDataFormat format, const void *data) override
void swizzle_set(const char swizzle_mask[4]) override
virtual void texture_unbind(Texture *tex)=0
virtual void image_unbind(Texture *tex)=0
GPUSamplerState sampler_state
char name_[DEBUG_NAME_LEN]
FrameBuffer * fb_[GPU_TEX_MAX_FBO_ATTACHED]
int dimensions_count() const
GPUAttachmentType fb_attachment_[GPU_TEX_MAX_FBO_ATTACHED]
GPUAttachmentType attachment_type(int slot) const
void mip_size_get(int mip, int r_size[3]) const
Texture(const char *name)
GPUTextureFormatFlag format_flag_
BLI_INLINE float fb(float length, float L)
void * MEM_mallocN(size_t len, const char *str)
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
void raise_gl_error(const char *info)
void object_label(GLenum type, GLuint object, const char *name)
GLenum to_gl_internal_format(TextureFormat format)
GLenum to_gl_target(GPUTextureType type)
bool is_half_float(TextureFormat format)
eGPUDataFormat to_texture_data_format(TextureFormat tex_format)
GLenum to_gl_data_format(TextureFormat format)
GLenum to_gl_proxy(GPUTextureType type)
size_t to_block_size(TextureFormat data_type)
int to_bytesize(const DataFormat format)
GLenum swizzle_to_gl(const char swizzle)
int to_component_len(TextureFormat format)
constexpr bool validate_data_format(TextureFormat tex_format, eGPUDataFormat data_format)
static GLenum to_gl(const GPUAttachmentType type)
void float_to_half_make_finite_array(const float *src, uint16_t *dst, size_t length)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
blender::gpu::Texture * tex