37 glGenTextures(1, &tex_id_);
46 if (ctx !=
nullptr && is_bound_) {
67 if (!this->proxy_check(0)) {
78 glTexStorage1D(target_,
mipmaps_, internal_format,
w_);
81 glTexStorage2D(target_,
mipmaps_, internal_format,
w_,
h_);
91 glTextureParameteri(tex_id_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
94 glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
112 glTextureBuffer(tex_id_, internal_format, gl_vbo->vbo_id_);
115 glTexBuffer(target_, internal_format, gl_vbo->vbo_id_);
129 glTextureView(tex_id_,
136 this->layer_count());
142 stencil_texture_mode_set(use_stencil);
154void GLTexture::update_sub_direct_state_access(
155 int mip,
int offset[3],
int extent[3], GLenum
format, GLenum type,
const void *data)
162 glCompressedTextureSubImage1D(tex_id_, mip, offset[0], extent[0],
format, size, data);
165 glCompressedTextureSubImage2D(
169 glCompressedTextureSubImage3D(
178 glTextureSubImage1D(tex_id_, mip, offset[0], extent[0],
format, type, data);
193 int mip,
int offset[3],
int extent[3],
eGPUDataFormat type,
const void *data)
205 GLenum gl_type =
to_gl(type);
209 this->update_sub_direct_state_access(mip, offset, extent, gl_format, gl_type, data);
215 for (
int i = 0; i < extent[2]; i++) {
216 GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + offset[2] + i;
217 glTexSubImage2D(target, mip,
UNPACK2(offset),
UNPACK2(extent), gl_format, gl_type, data);
222 switch (dimensions) {
225 glCompressedTexSubImage1D(target_, mip, offset[0], extent[0], gl_format, size, data);
228 glCompressedTexSubImage2D(
229 target_, mip,
UNPACK2(offset),
UNPACK2(extent), gl_format, size, data);
232 glCompressedTexSubImage3D(
233 target_, mip,
UNPACK3(offset),
UNPACK3(extent), gl_format, size, data);
238 switch (dimensions) {
241 glTexSubImage1D(target_, mip, offset[0], extent[0], gl_format, gl_type, data);
244 glTexSubImage2D(target_, mip,
UNPACK2(offset),
UNPACK2(extent), gl_format, gl_type, data);
247 glTexSubImage3D(target_, mip,
UNPACK3(offset),
UNPACK3(extent), gl_format, gl_type, data);
258 GPUPixelBuffer *pixbuf)
273 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pix_buf_handle);
275 switch (dimensions) {
278 glTexSubImage1D(target_, 0, offset[0], extent[0], gl_format, gl_type,
nullptr);
281 glTexSubImage2D(target_, 0,
UNPACK2(offset),
UNPACK2(extent), gl_format, gl_type,
nullptr);
284 glTexSubImage3D(target_, 0,
UNPACK3(offset),
UNPACK3(extent), gl_format, gl_type,
nullptr);
288 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
319 glGenerateTextureMipmap(tex_id_);
323 glGenerateMipmap(target_);
334 GLenum gl_type =
to_gl(data_format);
335 glClearTexImage(tex_id_, mip, gl_format, gl_type, data);
362 int extent[3] = {1, 1, 1};
365 src->tex_id_, target_, mip, 0, 0, 0, dst->tex_id_, target_, mip, 0, 0, 0,
UNPACK3(extent));
377 int extent[3] = {1, 1, 1};
380 size_t sample_len = extent[0] * extent[1] * extent[2];
382 size_t texture_size = sample_len * sample_size;
386 void *data =
MEM_mallocN(texture_size + 8,
"GPU_texture_read");
389 GLenum gl_type =
to_gl(type);
392 glGetTextureImage(tex_id_, mip, gl_format, gl_type, texture_size, data);
397 size_t cube_face_size = texture_size / 6;
398 char *pdata = (
char *)data;
399 for (
int i = 0; i < 6; i++, pdata += cube_face_size) {
400 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, mip, gl_format, gl_type, pdata);
404 glGetTexImage(target_, mip, gl_format, gl_type, data);
423 glTextureParameteriv(tex_id_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
427 glTexParameteriv(target_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
431void GLTexture::stencil_texture_mode_set(
bool use_stencil)
434 GLint value = use_stencil ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT;
436 glTextureParameteri(tex_id_, GL_DEPTH_STENCIL_TEXTURE_MODE, value);
440 glTexParameteri(target_, GL_DEPTH_STENCIL_TEXTURE_MODE, value);
450 glTextureParameteri(tex_id_, GL_TEXTURE_BASE_LEVEL,
min);
451 glTextureParameteri(tex_id_, GL_TEXTURE_MAX_LEVEL, max);
455 glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL,
min);
456 glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, max);
481 switch (extend_mode) {
483 return GL_CLAMP_TO_EDGE;
487 return GL_MIRRORED_REPEAT;
489 return GL_CLAMP_TO_BORDER;
492 return GL_CLAMP_TO_EDGE;
503 glGenSamplers(samplers_state_cache_count_, &samplers_state_cache_[0][0][0]);
507 const GLenum extend_t =
to_gl(extend_yz);
511 const GLenum extend_s =
to_gl(extend_x);
519 GL_LINEAR_MIPMAP_LINEAR :
522 GL_NEAREST_MIPMAP_LINEAR :
527 GLuint
sampler = samplers_state_cache_[extend_yz_i][extend_x_i][filtering_i];
528 glSamplerParameteri(
sampler, GL_TEXTURE_WRAP_S, extend_s);
529 glSamplerParameteri(
sampler, GL_TEXTURE_WRAP_T, extend_t);
530 glSamplerParameteri(
sampler, GL_TEXTURE_WRAP_R, extend_t);
531 glSamplerParameteri(
sampler, GL_TEXTURE_MIN_FILTER, min_filter);
532 glSamplerParameteri(
sampler, GL_TEXTURE_MAG_FILTER, mag_filter);
553 glSamplerParameteri(compare_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
554 glSamplerParameteri(compare_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
555 glSamplerParameteri(compare_sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
556 glSamplerParameteri(compare_sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
557 glSamplerParameteri(compare_sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
558 glSamplerParameteri(compare_sampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
559 glSamplerParameteri(compare_sampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
566 glSamplerParameteri(icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
567 glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
578 float max_anisotropy = 1.0f;
579 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
581 const float anisotropic_filter =
min_ff(max_anisotropy,
U.anisotropic_filter);
591 glSamplerParameterf(samplers_state_cache_[extend_yz_i][extend_x_i][filtering_i],
592 GL_TEXTURE_MAX_ANISOTROPY_EXT,
602 glDeleteSamplers(samplers_state_cache_count_, &samplers_state_cache_[0][0][0]);
629bool GLTexture::proxy_check(
int mip)
635 int size[3] = {1, 1, 1};
645 if (size[0] > max_3d_size || size[1] > max_3d_size || size[2] > max_3d_size) {
650 if (size[0] > max_size || size[1] > max_size) {
655 if (size[0] > max_size) {
660 if (size[0] > max_cube_size) {
686 switch (dimensions) {
689 glCompressedTexImage1D(gl_proxy, mip, size[0], 0, gl_format, img_size,
nullptr);
692 glCompressedTexImage2D(gl_proxy, mip,
UNPACK2(size), 0, gl_format, img_size,
nullptr);
695 glCompressedTexImage3D(gl_proxy, mip,
UNPACK3(size), 0, gl_format, img_size,
nullptr);
700 switch (dimensions) {
703 glTexImage1D(gl_proxy, mip, internal_format, size[0], 0, gl_format, gl_type,
nullptr);
707 gl_proxy, mip, internal_format,
UNPACK2(size), 0, gl_format, gl_type,
nullptr);
711 gl_proxy, mip, internal_format,
UNPACK3(size), 0, gl_format, gl_type,
nullptr);
717 glGetTexLevelParameteriv(gl_proxy, 0, GL_TEXTURE_WIDTH, &width);
743 attachment_read.
tex ==
nullptr)
747 "Feedback loop: Trying to bind a texture (%s) with mip range %d-%d but mip %d is "
748 "attached to the active framebuffer (%s)",
774 glGenBuffers(1, &gl_id_);
784 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_id_);
785 glBufferData(GL_PIXEL_UNPACK_BUFFER, size,
nullptr, GL_DYNAMIC_DRAW);
786 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
794 glDeleteBuffers(1, &gl_id_);
804 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_id_);
805 void *
ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
812 glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
813 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
#define BLI_assert_unreachable()
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()
bool GPU_depth_blitting_workaround()
bool GPU_mip_render_workaround()
int GPU_max_texture_size()
GPUFrameBuffer * GPU_framebuffer_create(const char *name)
#define GPU_ATTACHMENT_TEXTURE(_texture)
GPUFrameBuffer * GPU_framebuffer_active_get()
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
void GPU_framebuffer_free(GPUFrameBuffer *framebuffer)
@ GPU_SAMPLER_CUSTOM_ICON
@ GPU_SAMPLER_CUSTOM_COMPARE
@ GPU_SAMPLER_STATE_TYPE_CUSTOM
@ GPU_SAMPLER_STATE_TYPE_INTERNAL
int64_t GPU_pixel_buffer_get_native_handle(GPUPixelBuffer *pixel_buf)
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
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 void tex_free(GLuint tex_id)
static bool texture_filter_anisotropic_support
static bool clear_texture_support
static GLint max_cubemap_size
static bool generate_mipmap_workaround
GLPixelBuffer(size_t size)
size_t get_size() override
int64_t get_native_handle() override
void texture_bind_temp(GLTexture *tex)
GLTexture(const char *name)
void copy_to(Texture *dst) override
void mip_range_set(int min, int max) override
static void samplers_init()
static GLuint get_sampler(const GPUSamplerState &sampler_state)
static void samplers_update()
uint gl_bindcode_get() const override
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
eGPUTextureFormat format_
eGPUTextureFormatFlag format_flag_
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
local_group_size(16, 16) .push_constant(Type local_group_size(16, 16) .push_constant(Type input_tx sampler(1, ImageType::FLOAT_2D, "matte_tx") .image(0
BLI_INLINE float fb(float length, float L)
void *(* MEM_mallocN)(size_t len, const char *str)
void raise_gl_error(const char *info)
void object_label(GLenum type, GLuint object, const char *name)
static Context * unwrap(GPUContext *ctx)
GLenum to_gl_target(eGPUTextureType type)
size_t to_block_size(eGPUTextureFormat data_type)
static GPUContext * wrap(Context *ctx)
GLenum to_gl_internal_format(eGPUTextureFormat format)
constexpr bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
size_t to_bytesize(GPUIndexBufType type)
GLenum to_gl_proxy(eGPUTextureType type)
GLenum to_gl_data_format(eGPUTextureFormat format)
eGPUDataFormat to_data_format(eGPUTextureFormat tex_format)
GLenum swizzle_to_gl(const char swizzle)
static GLenum to_gl(const GPUAttachmentType type)
GPUSamplerCustomType custom_type
GPUSamplerExtendMode extend_yz
GPUSamplerFiltering filtering
std::string to_string() const
GPUSamplerExtendMode extend_x