From 30e20b6278b0a80e04fdee60637a9acd7bb0139d Mon Sep 17 00:00:00 2001 From: elasota Date: Sun, 26 Aug 2018 20:22:56 -0400 Subject: [PATCH] Partial fixes for 3D texture issues --- drivers/gles2/rasterizer_storage_gles2.cpp | 19 ++++++++++++++---- drivers/gles2/rasterizer_storage_gles2.h | 4 +++- drivers/gles3/rasterizer_storage_gles3.cpp | 23 +++++++++++++++++----- drivers/gles3/rasterizer_storage_gles3.h | 8 +++++++- scene/resources/texture.cpp | 2 +- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 3cee42983d4f..22e56fbb094f 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -365,6 +365,7 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_ ERR_FAIL_COND(!texture); texture->width = p_width; texture->height = p_height; + texture->depth = 0; texture->format = p_format; texture->flags = p_flags; texture->stored_cube_sides = 0; @@ -384,6 +385,7 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_ } break; case VS::TEXTURE_TYPE_3D: { texture->images.resize(p_depth_3d); + texture->depth = p_depth_3d; } break; default: { ERR_PRINT("Unknown texture type!"); @@ -396,6 +398,7 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_ texture->alloc_width = texture->width; texture->alloc_height = texture->height; + texture->alloc_depth = texture->depth; texture->gl_format_cache = format; texture->gl_type_cache = type; @@ -591,7 +594,9 @@ Ref RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) PoolVector data; - int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0); + int alloc_depth = MAX(texture->alloc_depth, 1); + + int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0) * alloc_depth; data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers PoolVector::Write wb = data.write(); @@ -620,7 +625,7 @@ Ref RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) wb = PoolVector::Write(); - data.resize(data_size); + data.resize(data_size / alloc_depth); Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, real_format, data)); @@ -780,7 +785,7 @@ void RasterizerStorageGLES2::texture_debug_usage(List *r_info) tinfo.format = t->format; tinfo.width = t->alloc_width; tinfo.height = t->alloc_height; - tinfo.depth = 0; + tinfo.depth = t->alloc_depth; tinfo.bytes = t->total_data_size; r_info->push_back(tinfo); } @@ -3662,6 +3667,8 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { texture->alloc_width = rt->width; texture->height = rt->height; texture->alloc_height = rt->height; + texture->depth = 0; + texture->alloc_depth = 0; texture->active = true; texture_set_flags(rt->texture, texture->flags); @@ -3709,6 +3716,8 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) { Texture *tex = texture_owner.get(rt->texture); tex->alloc_height = 0; tex->alloc_width = 0; + tex->alloc_depth = 0; + tex->depth = 0; tex->width = 0; tex->height = 0; tex->active = false; @@ -3732,8 +3741,10 @@ RID RasterizerStorageGLES2::render_target_create() { t->flags = 0; t->width = 0; t->height = 0; - t->alloc_height = 0; + t->depth = 0; t->alloc_width = 0; + t->alloc_height = 0; + t->alloc_depth = 0; t->format = Image::FORMAT_R8; t->target = GL_TEXTURE_2D; t->gl_format_cache = 0; diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 88783d7160a3..c3066b754dbf 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -232,7 +232,7 @@ public: String path; uint32_t flags; int width, height, depth; - int alloc_width, alloc_height; + int alloc_width, alloc_height, alloc_depth; Image::Format format; VS::TextureType type; @@ -275,8 +275,10 @@ public: flags = 0; width = 0; height = 0; + depth = 0; alloc_width = 0; alloc_height = 0; + alloc_depth = 0; format = Image::FORMAT_L8; target = 0; diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 3697cccef442..8ae6040aed52 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -667,7 +667,7 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_ int mipmaps = 0; while (width != 1 && height != 1) { - glTexImage3D(texture->target, 0, internal_format, width, height, depth, 0, format, type, NULL); + glTexImage3D(texture->target, mipmaps, internal_format, width, height, depth, 0, format, type, NULL); width = MAX(1, width / 2); height = MAX(1, height / 2); @@ -1029,7 +1029,11 @@ Ref RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) PoolVector data; - int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0); + int alloc_depth = MAX(texture->alloc_depth, 1); + + ERR_FAIL_COND_V(p_layer < 0 || p_layer >= alloc_depth, Ref()); + + int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0) * alloc_depth; data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers PoolVector::Write wb = data.write(); @@ -1085,9 +1089,13 @@ Ref RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) img_format = real_format; } - wb = PoolVector::Write(); + int slice_size = data_size / alloc_depth; - data.resize(data_size); + if (p_layer) { + memcpy(&wb[0], &wb[slice_size * p_layer], slice_size); + } + + data.resize(slice_size); Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, img_format, data)); @@ -1275,7 +1283,7 @@ void RasterizerStorageGLES3::texture_debug_usage(List *r_info) tinfo.format = t->format; tinfo.width = t->alloc_width; tinfo.height = t->alloc_height; - tinfo.depth = 0; + tinfo.depth = t->alloc_depth; tinfo.bytes = t->total_data_size; r_info->push_back(tinfo); } @@ -1442,6 +1450,7 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_ ctex->height = p_resolution; ctex->alloc_width = p_resolution; ctex->alloc_height = p_resolution; + ctex->alloc_depth = 0; ctex->format = use_float ? Image::FORMAT_RGBAH : Image::FORMAT_RGBA8; ctex->target = GL_TEXTURE_CUBE_MAP; ctex->gl_format_cache = format; @@ -6464,6 +6473,7 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) { Texture *tex = texture_owner.get(rt->texture); tex->alloc_height = 0; tex->alloc_width = 0; + tex->alloc_depth = 0; tex->width = 0; tex->height = 0; tex->active = false; @@ -6577,6 +6587,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { tex->height = rt->height; tex->alloc_height = rt->height; tex->active = true; + tex->alloc_depth = 0; texture_set_flags(rt->texture, tex->flags); } @@ -6865,8 +6876,10 @@ RID RasterizerStorageGLES3::render_target_create() { t->flags = 0; t->width = 0; t->height = 0; + t->depth = 0; t->alloc_height = 0; t->alloc_width = 0; + t->alloc_depth = 0; t->format = Image::FORMAT_R8; t->target = GL_TEXTURE_2D; t->gl_format_cache = 0; diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index b74dd77e2633..43b7d5fc997f 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -294,7 +294,13 @@ public: stored_cube_sides = 0; ignore_mipmaps = false; render_target = NULL; - flags = width = height = 0; + flags = 0; + width = 0; + height = 0; + depth = 0; + alloc_width = 0; + alloc_height = 0; + alloc_depth = 0; tex_id = 0; data_size = 0; format = Image::FORMAT_L8; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 811e5c3d2cab..1c082d914357 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2051,8 +2051,8 @@ void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_dept width = p_width; height = p_height; depth = p_depth; - flags = p_flags; + format = p_format; } void TextureLayered::set_layer_data(const Ref &p_image, int p_layer) {