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:
-rw-r--r--source/blender/gpu/GPU_extensions.h1
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c42
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c6
-rw-r--r--source/blender/gpu/intern/gpu_texture.c25
4 files changed, 66 insertions, 8 deletions
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 1059ba06953..994f545eb38 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -51,6 +51,7 @@ int GPU_max_ubo_binds(void);
int GPU_max_ubo_size(void);
int GPU_color_depth(void);
void GPU_get_dfdy_factors(float fac[2]);
+bool GPU_mip_render_workaround(void);
bool GPU_mem_stats_supported(void);
void GPU_mem_stats_get(int *totalmem, int *freemem);
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 198f986d06e..c95f5e5e252 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -37,8 +37,10 @@
#include "BLI_math_vector.h"
#include "BKE_global.h"
+#include "MEM_guardedalloc.h"
#include "GPU_extensions.h"
+#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_texture.h"
@@ -83,8 +85,42 @@ static struct GPUGlobal {
* number is factor on screen and second is off-screen */
float dfdyfactors[2];
float max_anisotropy;
+ /* Some Intel drivers have issues with using mips as framebuffer targets if
+ * GL_TEXTURE_MAX_LEVEL is higher than the target mip.
+ * We need a workaround in this cases. */
+ bool mip_render_workaround;
} GG = {1, 0};
+
+static void gpu_detect_mip_render_workaround(void)
+{
+ int cube_size = 2;
+ float *source_pix = MEM_callocN(sizeof(float) * 4 * 6 * cube_size * cube_size, __func__);
+ float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f};
+
+ GPUTexture *tex = GPU_texture_create_cube(cube_size, GPU_RGBA16F, source_pix, NULL);
+ MEM_freeN(source_pix);
+
+ GPU_texture_bind(tex, 0);
+ GPU_texture_generate_mipmap(tex);
+ glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, 0);
+ GPU_texture_unbind(tex);
+
+ GPUFrameBuffer *fb = GPU_framebuffer_create();
+ GPU_framebuffer_texture_attach(fb, tex, 0, 1);
+ GPU_framebuffer_bind(fb);
+ GPU_framebuffer_clear_color(fb, clear_color);
+ GPU_framebuffer_restore();
+ GPU_framebuffer_free(fb);
+
+ float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 1);
+ GG.mip_render_workaround = !equals_v4v4(clear_color, data);
+
+ MEM_freeN(data);
+ GPU_texture_free(tex);
+}
+
/* GPU Types */
bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
@@ -154,6 +190,11 @@ void GPU_get_dfdy_factors(float fac[2])
copy_v2_v2(fac, GG.dfdyfactors);
}
+bool GPU_mip_render_workaround(void)
+{
+ return GG.mip_render_workaround;
+}
+
void gpu_extensions_init(void)
{
/* during 2.8 development each platform has its own OpenGL minimum requirements
@@ -253,6 +294,7 @@ void gpu_extensions_init(void)
GG.os = GPU_OS_UNIX;
#endif
+ gpu_detect_mip_render_workaround();
/* df/dy calculation factors, those are dependent on driver */
if ((strstr(vendor, "ATI") && strstr(version, "3.3.10750"))) {
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 346d1320b75..7329eee44b0 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -640,11 +640,15 @@ void GPU_framebuffer_recursive_downsample(
for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; ++type) {
if (fb->attachments[type].tex != NULL) {
+ /* Some Intel HDXXX have issue with rendering to a mipmap that is below
+ * the texture GL_TEXTURE_MAX_LEVEL. So even if it not correct, in this case
+ * we allow GL_TEXTURE_MAX_LEVEL to be one level lower. In practice it does work! */
+ int next_lvl = (GPU_mip_render_workaround()) ? i : i - 1;
/* bind next level for rendering but first restrict fetches only to previous level */
GPUTexture *tex = fb->attachments[type].tex;
GPU_texture_bind(tex, 0);
glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_BASE_LEVEL, i - 1);
- glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, i - 1);
+ glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, next_lvl);
GPU_texture_unbind(tex);
/* copy attachment and replace miplevel. */
GPUAttachment attachment = fb->attachments[type];
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 6a8e686afb3..c3a1148a360 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -916,12 +916,13 @@ GPUTexture *GPU_texture_create_cube(
const int channels = gpu_get_component_count(tex_format);
if (fpixels) {
- fpixels_px = fpixels + 0 * w * w * channels;
- fpixels_nx = fpixels + 1 * w * w * channels;
- fpixels_py = fpixels + 2 * w * w * channels;
- fpixels_ny = fpixels + 3 * w * w * channels;
- fpixels_pz = fpixels + 4 * w * w * channels;
- fpixels_nz = fpixels + 5 * w * w * channels;
+ int face_ofs = w * w * channels;
+ fpixels_px = fpixels + 0 * face_ofs;
+ fpixels_nx = fpixels + 1 * face_ofs;
+ fpixels_py = fpixels + 2 * face_ofs;
+ fpixels_ny = fpixels + 3 * face_ofs;
+ fpixels_pz = fpixels + 4 * face_ofs;
+ fpixels_nz = fpixels + 5 * face_ofs;
}
else {
fpixels_px = fpixels_py = fpixels_pz = fpixels_nx = fpixels_ny = fpixels_nz = NULL;
@@ -1099,6 +1100,7 @@ void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplv
samples_count *= size[0];
samples_count *= max_ii(1, size[1]);
samples_count *= max_ii(1, size[2]);
+ samples_count *= (GPU_texture_cube(tex)) ? 6 : 1;
switch (gpu_data_format) {
case GPU_DATA_FLOAT:
@@ -1123,7 +1125,16 @@ void *GPU_texture_read(GPUTexture *tex, GPUDataFormat gpu_data_format, int miplv
glBindTexture(tex->target, tex->bindcode);
- glGetTexImage(tex->target, miplvl, data_format, data_type, buf);
+ if (GPU_texture_cube(tex)) {
+ int cube_face_size = buf_size / 6;
+ for (int i = 0; i < 6; ++i) {
+ glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, miplvl, data_format, data_type,
+ ((char *)buf) + cube_face_size * i);
+ }
+ }
+ else {
+ glGetTexImage(tex->target, miplvl, data_format, data_type, buf);
+ }
glBindTexture(tex->target, 0);