Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-03-18 03:26:08 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-03-18 03:56:34 +0300
commitc4644b484d30d7dee62425a18d6896acf6fcbb0c (patch)
tree7a8b15f6a1a4739d750c00f24c81fb1261c89042
parentb7355425cdff8f3f23e386f2817d5702b46f7bd6 (diff)
GPUTexture: Add support for depth_stencil textures.
-rw-r--r--source/blender/gpu/GPU_texture.h6
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c16
-rw-r--r--source/blender/gpu/intern/gpu_texture.c60
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c2
4 files changed, 56 insertions, 28 deletions
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index a8df80cd626..6295c5aac12 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -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
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index bd08f9d9195..87d734dd40b 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -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;
}
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 3513250993e..2e5b32e416d 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -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;
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index fc5c3ce3613..8f0a38c8675 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -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;