diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-03-18 03:26:08 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-03-18 03:56:34 +0300 |
commit | c4644b484d30d7dee62425a18d6896acf6fcbb0c (patch) | |
tree | 7a8b15f6a1a4739d750c00f24c81fb1261c89042 /source/blender/gpu | |
parent | b7355425cdff8f3f23e386f2817d5702b46f7bd6 (diff) |
GPUTexture: Add support for depth_stencil textures.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_texture.h | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_framebuffer.c | 16 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 60 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 2 |
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; |