GPUTexture: Add skeleton of the new GLTexture class

This commit is contained in:
2020-09-02 01:25:32 +02:00
parent f72c1c4547
commit a92d77acf7
8 changed files with 328 additions and 8 deletions

View File

@@ -96,6 +96,7 @@ set(SRC
opengl/gl_shader.cc
opengl/gl_shader_interface.cc
opengl/gl_state.cc
opengl/gl_texture.cc
opengl/gl_uniform_buffer.cc
opengl/gl_vertex_array.cc
@@ -143,6 +144,7 @@ set(SRC
intern/gpu_shader_private.hh
intern/gpu_shader_interface.hh
intern/gpu_state_private.hh
intern/gpu_texture_private.hh
intern/gpu_uniform_buffer_private.hh
intern/gpu_vertex_format_private.h

View File

@@ -34,6 +34,7 @@ class Batch;
class DrawList;
class FrameBuffer;
class Shader;
class Texture;
class UniformBuf;
class GPUBackend {
@@ -48,7 +49,7 @@ class GPUBackend {
virtual DrawList *drawlist_alloc(int list_length) = 0;
virtual FrameBuffer *framebuffer_alloc(const char *name) = 0;
virtual Shader *shader_alloc(const char *name) = 0;
// virtual Texture *texture_alloc(void) = 0;
virtual Texture *texture_alloc(const char *name) = 0;
virtual UniformBuf *uniformbuf_alloc(int size, const char *name) = 0;
};

View File

@@ -292,7 +292,8 @@ bool GPU_framebuffer_check_valid(GPUFrameBuffer *gpu_fb, char err_out[256])
void GPU_framebuffer_texture_attach_ex(GPUFrameBuffer *gpu_fb, GPUAttachment attachment, int slot)
{
GPUAttachmentType type = blender::gpu::Texture::attachment_type(attachment.tex, slot);
Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
GPUAttachmentType type = tex->attachment_type(slot);
reinterpret_cast<FrameBuffer *>(gpu_fb)->attachment_set(type, attachment);
}

View File

@@ -46,6 +46,48 @@
#include "gpu_context_private.hh"
#include "gpu_framebuffer_private.hh"
#include "gpu_texture_private.hh"
namespace blender::gpu {
/* -------------------------------------------------------------------- */
/** \name Creation & Deletion
* \{ */
Texture::Texture(const char *name)
{
if (name) {
BLI_strncpy(name_, name, sizeof(name_));
}
else {
name_[0] = '\0';
}
}
Texture::~Texture()
{
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Operation
* \{ */
void Texture::attach_to(FrameBuffer *)
{
}
/** \} */
} // namespace blender::gpu
/* -------------------------------------------------------------------- */
/** \name C-API
* \{ */
using namespace blender::gpu;
static struct GPUTextureGlobal {
/** Texture used in place of invalid textures (not loaded correctly, missing). */
GPUTexture *invalid_tex_1D;
@@ -2238,6 +2280,8 @@ void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name GPU Sampler Objects
*

View File

@@ -25,15 +25,88 @@
#include "BLI_assert.h"
#include "gpu_framebuffer_private.hh"
namespace blender {
namespace gpu {
typedef enum eGPUTextureFlag {
GPU_TEXFORMAT_DEPTH = (1 << 0),
GPU_TEXFORMAT_STENCIL = (1 << 1),
GPU_TEXFORMAT_INTEGER = (1 << 2),
GPU_TEXFORMAT_FLOAT = (1 << 3),
GPU_TEXTURE_1D = (1 << 10),
GPU_TEXTURE_2D = (1 << 11),
GPU_TEXTURE_3D = (1 << 12),
GPU_TEXTURE_CUBE = (1 << 13),
GPU_TEXTURE_ARRAY = (1 << 14),
GPU_TEXTURE_BUFFER = (1 << 15),
GPU_TEXTURE_1D_ARRAY = (GPU_TEXTURE_1D | GPU_TEXTURE_ARRAY),
GPU_TEXTURE_2D_ARRAY = (GPU_TEXTURE_2D | GPU_TEXTURE_ARRAY),
GPU_TEXTURE_CUBE_ARRAY = (GPU_TEXTURE_CUBE | GPU_TEXTURE_ARRAY),
GPU_TEXTURE_TARGET = (GPU_TEXTURE_1D | GPU_TEXTURE_2D | GPU_TEXTURE_3D | GPU_TEXTURE_CUBE |
GPU_TEXTURE_ARRAY),
} eGPUTextureFlag;
ENUM_OPERATORS(eGPUTextureFlag)
#ifdef DEBUG
# define DEBUG_NAME_LEN 64
#else
# define DEBUG_NAME_LEN 8
#endif
/* Maximum number of FBOs a texture can be attached to. */
#define GPU_TEX_MAX_FBO_ATTACHED 12
class Texture {
public:
/** TODO(fclem): make it a non-static function. */
static GPUAttachmentType attachment_type(GPUTexture *tex, int slot)
/** Width & Height & Depth. */
int w = 0, h = 0, d = 0;
/** Number of color/alpha channels. */
int components = 0;
/** Internal data format and it's characteristics. */
eGPUTextureFormat format;
eGPUTextureFlag flag;
/** Internal Sampler state. */
eGPUSamplerState sampler_state;
/** Number of mipmaps this texture has. */
int mipmaps = 0;
/** Reference counter. */
int refcount = 0;
/** Width & Height (of source data), optional. */
int src_w = 0, src_h = 0;
/** Framebuffer references to update on deletion. */
GPUAttachmentType fb_attachment[GPU_TEX_MAX_FBO_ATTACHED];
FrameBuffer *fb[GPU_TEX_MAX_FBO_ATTACHED];
protected:
/** For debugging */
char name_[DEBUG_NAME_LEN];
public:
Texture(const char *name);
virtual ~Texture();
virtual void bind(int slot) = 0;
virtual void update(void *data) = 0;
virtual void update_sub(void *data, int offset[3], int size[3]) = 0;
virtual void generate_mipmap(void) = 0;
virtual void copy_to(Texture *tex) = 0;
virtual void swizzle_set(char swizzle_mask[4]) = 0;
/* TODO(fclem) Legacy. Should be removed at some point. */
virtual uint gl_bindcode_get(void) = 0;
void attach_to(FrameBuffer *fb);
GPUAttachmentType attachment_type(int slot) const
{
switch (GPU_texture_format(tex)) {
switch (format) {
case GPU_DEPTH_COMPONENT32F:
case GPU_DEPTH_COMPONENT24:
case GPU_DEPTH_COMPONENT16:
@@ -44,10 +117,12 @@ class Texture {
BLI_assert(slot == 0);
return GPU_FB_DEPTH_STENCIL_ATTACHMENT;
default:
return static_cast<GPUAttachmentType>(GPU_FB_COLOR_ATTACHMENT0 + slot);
return GPU_FB_COLOR_ATTACHMENT0 + slot;
}
}
};
#undef DEBUG_NAME_LEN
} // namespace gpu
} // namespace blender

View File

@@ -32,6 +32,7 @@
#include "gl_drawlist.hh"
#include "gl_framebuffer.hh"
#include "gl_shader.hh"
#include "gl_texture.hh"
#include "gl_uniform_buffer.hh"
namespace blender {
@@ -72,6 +73,11 @@ class GLBackend : public GPUBackend {
return new GLShader(name);
};
Texture *texture_alloc(const char *name)
{
return new GLTexture(name);
};
UniformBuf *uniformbuf_alloc(int size, const char *name)
{
return new GLUniformBuf(size, name);

View File

@@ -0,0 +1,98 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2020 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup gpu
*/
#include "BKE_global.h"
#include "gl_backend.hh"
#include "gl_texture.hh"
namespace blender::gpu {
/* -------------------------------------------------------------------- */
/** \name Creation & Deletion
* \{ */
GLTexture::GLTexture(const char *name) : Texture(name)
{
BLI_assert(GPU_context_active_get() != NULL);
glGenTextures(1, &tex_id_);
#ifndef __APPLE__
if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) {
char sh_name[64];
SNPRINTF(sh_name, "Texture-%s", name);
glObjectLabel(GL_TEXTURE, tex_id_, -1, sh_name);
}
#endif
}
GLTexture::~GLTexture()
{
GLBackend::get()->tex_free(tex_id_);
}
void GLTexture::init(void)
{
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Operations
* \{ */
void GLTexture::bind(int /*slot*/)
{
}
void GLTexture::update(void * /*data*/)
{
}
void GLTexture::update_sub(void * /*data*/, int /*offset*/[3], int /*size*/[3])
{
}
void GLTexture::generate_mipmap(void)
{
}
void GLTexture::copy_to(Texture * /*tex*/)
{
}
void GLTexture::swizzle_set(char /*swizzle_mask*/[4])
{
}
/** \} */
/* TODO(fclem) Legacy. Should be removed at some point. */
uint GLTexture::gl_bindcode_get(void)
{
return tex_id_;
}
} // namespace blender::gpu

View File

@@ -31,14 +31,107 @@
#pragma once
#include "MEM_guardedalloc.h"
#include "BLI_assert.h"
#include "gpu_texture_private.hh"
#include "glew-mx.h"
namespace blender {
namespace gpu {
static GLenum to_gl(eGPUDataFormat format)
#if 0
class GLContext {
/** Currently bound textures. Updated before drawing. */
GLuint bound_textures[64];
GLuint bound_samplers[64];
/** All sampler objects. Last one is for icon sampling. */
GLuint samplers[GPU_SAMPLER_MAX + 1];
};
#endif
class GLTexture : public Texture {
private:
/** Texture unit to which this texture is bound. */
int slot = -1;
/** Target to bind the texture to (GL_TEXTURE_1D, GL_TEXTURE_2D, etc...)*/
GLenum target_ = -1;
/** opengl identifier for texture. */
GLuint tex_id_ = 0;
/** Legacy workaround for texture copy. */
GLuint copy_fb = 0;
GPUContext *copy_fb_ctx = NULL;
public:
GLTexture(const char *name);
~GLTexture();
void bind(int slot) override;
void update(void *data) override;
void update_sub(void *data, int offset[3], int size[3]) override;
void generate_mipmap(void) override;
void copy_to(Texture *tex) override;
void swizzle_set(char swizzle_mask[4]) override;
/* TODO(fclem) Legacy. Should be removed at some point. */
uint gl_bindcode_get(void) override;
private:
void init(void);
};
static inline GLenum target_to_gl(eGPUTextureFlag target)
{
switch (target & GPU_TEXTURE_TARGET) {
case GPU_TEXTURE_1D:
return GL_TEXTURE_1D;
case GPU_TEXTURE_1D | GPU_TEXTURE_ARRAY:
return GL_TEXTURE_1D_ARRAY;
case GPU_TEXTURE_2D:
return GL_TEXTURE_2D;
case GPU_TEXTURE_2D | GPU_TEXTURE_ARRAY:
return GL_TEXTURE_2D_ARRAY;
case GPU_TEXTURE_3D:
return GL_TEXTURE_3D;
case GPU_TEXTURE_CUBE:
return GL_TEXTURE_CUBE_MAP;
case GPU_TEXTURE_CUBE | GPU_TEXTURE_ARRAY:
return GL_TEXTURE_CUBE_MAP_ARRAY_ARB;
case GPU_TEXTURE_BUFFER:
return GL_TEXTURE_BUFFER;
default:
BLI_assert(0);
return GPU_TEXTURE_1D;
}
}
static inline GLenum swizzle_to_gl(const char swizzle)
{
switch (swizzle) {
default:
case 'x':
case 'r':
return GL_RED;
case 'y':
case 'g':
return GL_GREEN;
case 'z':
case 'b':
return GL_BLUE;
case 'w':
case 'a':
return GL_ALPHA;
case '0':
return GL_ZERO;
case '1':
return GL_ONE;
}
}
static inline GLenum to_gl(eGPUDataFormat format)
{
switch (format) {
case GPU_DATA_FLOAT:
@@ -60,7 +153,7 @@ static GLenum to_gl(eGPUDataFormat format)
}
/* Assume Unorm / Float target. Used with glReadPixels. */
static GLenum channel_len_to_gl(int channel_len)
static inline GLenum channel_len_to_gl(int channel_len)
{
switch (channel_len) {
case 1: