GPUTexture: Add support for depth_stencil textures.

This commit is contained in:
Clément Foucault 2017-03-18 01:26:08 +01:00
parent b7355425cd
commit c4644b484d
4 changed files with 56 additions and 28 deletions

View File

@ -101,8 +101,8 @@ typedef enum GPUTextureFormat {
GPU_RGB10_A2,
GPU_RGB10_A2UI,
GPU_DEPTH32F_STENCIL8,
GPU_DEPTH24_STENCIL8,
#endif
GPU_DEPTH24_STENCIL8,
/* Texture only format */
#if 0
@ -155,6 +155,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int d, const float *pixels, char
GPUTexture *GPU_texture_create_3D_custom(
int w, int h, int d, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
GPUTexture *GPU_texture_create_depth_with_stencil(int w, int h, char err_out[256]);
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256]);
GPUTexture *GPU_texture_from_blender(
@ -183,7 +184,8 @@ void GPU_texture_framebuffer_set(GPUTexture *tex, struct GPUFrameBuffer *fb, int
int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);
int GPU_texture_depth(const GPUTexture *tex);
bool GPU_texture_depth(const GPUTexture *tex);
bool GPU_texture_stencil(const GPUTexture *tex);
int GPU_texture_opengl_bindcode(const GPUTexture *tex);
#ifdef __cplusplus

View File

@ -133,14 +133,16 @@ bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slo
}
}
if (GPU_texture_depth(tex))
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
if (GPU_texture_stencil(tex) && GPU_texture_depth(tex))
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
else if (GPU_texture_depth(tex))
attachment = GL_DEPTH_ATTACHMENT;
else
attachment = GL_COLOR_ATTACHMENT0 + slot;
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), 0);
@ -168,7 +170,11 @@ void GPU_framebuffer_texture_detach(GPUTexture *tex)
GG.currentfb = fb->object;
}
if (GPU_texture_depth(tex)) {
if (GPU_texture_stencil(tex) && GPU_texture_depth(tex)) {
fb->depthtex = NULL;
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
}
else if (GPU_texture_depth(tex)) {
fb->depthtex = NULL;
attachment = GL_DEPTH_ATTACHMENT;
}

View File

@ -62,19 +62,30 @@ struct GPUTexture {
GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
int fb_attachment; /* slot the texture is attached to */
bool depth; /* is a depth texture? */
bool stencil; /* is a stencil texture? */
};
static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type, GLenum *format, bool *is_depth)
static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type, GLenum *format, GLenum *data_format, bool *is_depth, bool *is_stencil)
{
if (data_type == GPU_DEPTH_COMPONENT24 ||
data_type == GPU_DEPTH_COMPONENT16 ||
data_type == GPU_DEPTH_COMPONENT32F)
{
*is_depth = true;
*is_stencil = false;
*data_format = GL_FLOAT;
*format = GL_DEPTH_COMPONENT;
}
else if (data_type == GPU_DEPTH24_STENCIL8) {
*is_depth = true;
*is_stencil = true;
*data_format = GL_UNSIGNED_INT_24_8;
*format = GL_DEPTH_STENCIL;
}
else {
*is_depth = false;
*is_stencil = false;
*data_format = GL_FLOAT;
switch (components) {
case 1: *format = GL_RED; break;
@ -95,7 +106,7 @@ static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type,
case GPU_RGBA8: return GL_RGBA8;
case GPU_R8: return GL_R8;
/* Special formats texture & renderbuffer */
/* ** Add Format here **/
case GPU_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;
/* Texture only format */
/* ** Add Format here **/
/* Special formats texture only */
@ -148,20 +159,20 @@ static float *GPU_texture_3D_rescale(GPUTexture *tex, int w, int h, int d, int c
/* This tries to allocate video memory for a given texture
* If alloc fails, lower the resolution until it fits. */
static bool GPU_texture_try_alloc(
GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, int channels,
bool try_rescale, const float *fpixels, float **rescaled_fpixels)
GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, GLenum data_format,
int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels)
{
int r_width;
switch (proxy) {
case GL_PROXY_TEXTURE_1D:
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, GL_FLOAT, NULL);
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
break;
case GL_PROXY_TEXTURE_2D:
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, NULL);
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
break;
case GL_PROXY_TEXTURE_3D:
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, NULL);
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
break;
}
@ -182,11 +193,11 @@ static bool GPU_texture_try_alloc(
if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break;
if (proxy == GL_PROXY_TEXTURE_1D)
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, GL_FLOAT, NULL);
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
else if (proxy == GL_PROXY_TEXTURE_2D)
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, NULL);
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
else if (proxy == GL_PROXY_TEXTURE_3D)
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, NULL);
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
}
@ -213,7 +224,7 @@ static GPUTexture *GPU_texture_create_nD(
GPUTextureFormat data_type, int components, int samples,
const bool can_rescale, char err_out[256])
{
GLenum format, internalformat, proxy;
GLenum format, internalformat, proxy, data_format;
float *rescaled_fpixels = NULL;
const float *pix;
bool valid;
@ -228,6 +239,7 @@ static GPUTexture *GPU_texture_create_nD(
tex->d = d;
tex->number = -1;
tex->refcount = 1;
tex->fb_attachment = -1;
if (n == 1) {
if (h == 0)
@ -245,12 +257,10 @@ static GPUTexture *GPU_texture_create_nD(
tex->target_base = tex->target = GL_TEXTURE_3D;
}
tex->fb_attachment = -1;
if (samples && n == 2 && d == 0)
tex->target = GL_TEXTURE_2D_MULTISAMPLE;
internalformat = GPU_texture_get_format(components, data_type, &format, &tex->depth);
internalformat = GPU_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil);
/* Generate Texture object */
glGenTextures(1, &tex->bindcode);
@ -278,7 +288,7 @@ static GPUTexture *GPU_texture_create_nD(
proxy = GL_PROXY_TEXTURE_1D;
}
valid = GPU_texture_try_alloc(tex, proxy, internalformat, format, components, can_rescale, fpixels,
valid = GPU_texture_try_alloc(tex, proxy, internalformat, format, data_format, components, can_rescale, fpixels,
&rescaled_fpixels);
if (!valid) {
@ -294,7 +304,7 @@ static GPUTexture *GPU_texture_create_nD(
pix = (rescaled_fpixels) ? rescaled_fpixels : fpixels;
if (tex->target == GL_TEXTURE_1D) {
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, GL_FLOAT, pix);
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, data_format, pix);
}
else if (tex->target == GL_TEXTURE_1D_ARRAY ||
tex->target == GL_TEXTURE_2D ||
@ -303,14 +313,14 @@ static GPUTexture *GPU_texture_create_nD(
if (samples) {
glTexImage2DMultisample(tex->target, samples, internalformat, tex->w, tex->h, true);
if (pix)
glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, GL_FLOAT, pix);
glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, data_format, pix);
}
else {
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, pix);
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, data_format, pix);
}
}
else {
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, pix);
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, pix);
}
if (rescaled_fpixels)
@ -494,6 +504,11 @@ GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH_COMPONENT24, 1, 0, false, err_out);
}
GPUTexture *GPU_texture_create_depth_with_stencil(int w, int h, char err_out[256])
{
return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH24_STENCIL8, 1, 0, false, err_out);
}
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256])
{
return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH_COMPONENT24, 1, samples, false, err_out);
@ -708,11 +723,16 @@ int GPU_texture_height(const GPUTexture *tex)
return tex->h;
}
int GPU_texture_depth(const GPUTexture *tex)
bool GPU_texture_depth(const GPUTexture *tex)
{
return tex->depth;
}
bool GPU_texture_stencil(const GPUTexture *tex)
{
return tex->stencil;
}
int GPU_texture_opengl_bindcode(const GPUTexture *tex)
{
return tex->bindcode;

View File

@ -214,7 +214,7 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
}
/* Depth */
dtxl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
dtxl->depth = GPU_texture_create_depth_with_stencil(rect_w, rect_h, NULL);
if (!dtxl->depth) {
ok = false;
goto cleanup;