GPU: Add workarounds for buggy glBlitFramebuffer function on macOS + Radeon
When calling glBlitFramebuffer on most (if not all) mac that have a GPU from the Radeon Pro series, the data is not properly copied and only a subset of the pixels are correctly copied. This only happens when blitting the depth buffer if the depth buffer is GL_DEPTH24_STENCIL8. Changing the depth buffer format to GPU_DEPTH32F_STENCIL8 fixes the issue but only works if blitting the depth componnent. The stencil componnent still provoke issues when being copied.
This commit is contained in:
		@@ -52,6 +52,7 @@ 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_depth_blitting_workaround(void);
 | 
			
		||||
 | 
			
		||||
bool GPU_mem_stats_supported(void);
 | 
			
		||||
void GPU_mem_stats_get(int *totalmem, int *freemem);
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,11 @@ static struct GPUGlobal {
 | 
			
		||||
	 * GL_TEXTURE_MAX_LEVEL is higher than the target mip.
 | 
			
		||||
	 * We need a workaround in this cases. */
 | 
			
		||||
	bool mip_render_workaround;
 | 
			
		||||
	/* There is an issue with the glBlitFramebuffer on MacOS with radeon pro graphics.
 | 
			
		||||
	 * Blitting depth with GL_DEPTH24_STENCIL8 is buggy so the workaround is to use
 | 
			
		||||
	 * GPU_DEPTH32F_STENCIL8. Then Blitting depth will work but blitting stencil will
 | 
			
		||||
	 * still be broken. */
 | 
			
		||||
	bool depth_blitting_workaround;
 | 
			
		||||
} GG = {1, 0};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -195,6 +200,11 @@ bool GPU_mip_render_workaround(void)
 | 
			
		||||
	return GG.mip_render_workaround;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GPU_depth_blitting_workaround(void)
 | 
			
		||||
{
 | 
			
		||||
	return GG.depth_blitting_workaround;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpu_extensions_init(void)
 | 
			
		||||
{
 | 
			
		||||
	/* during 2.8 development each platform has its own OpenGL minimum requirements
 | 
			
		||||
@@ -243,6 +253,12 @@ void gpu_extensions_init(void)
 | 
			
		||||
	if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) {
 | 
			
		||||
		GG.device = GPU_DEVICE_ATI;
 | 
			
		||||
		GG.driver = GPU_DRIVER_OFFICIAL;
 | 
			
		||||
 | 
			
		||||
#if defined(__APPLE__)
 | 
			
		||||
		if (strstr(vendor, "AMD Radeon Pro")) {
 | 
			
		||||
			GG.depth_blitting_workaround = true;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	else if (strstr(vendor, "NVIDIA")) {
 | 
			
		||||
		GG.device = GPU_DEVICE_NVIDIA;
 | 
			
		||||
 
 | 
			
		||||
@@ -512,6 +512,12 @@ GPUTexture *GPU_texture_create_nD(
 | 
			
		||||
		CLAMP_MAX(samples, GPU_max_color_texture_samples());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((tex_format == GPU_DEPTH24_STENCIL8) && GPU_depth_blitting_workaround()) {
 | 
			
		||||
		/* MacOS + Radeon Pro fails to blit depth on GPU_DEPTH24_STENCIL8
 | 
			
		||||
		 * but works on GPU_DEPTH32F_STENCIL8. */
 | 
			
		||||
		tex_format = GPU_DEPTH32F_STENCIL8;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
 | 
			
		||||
	tex->w = w;
 | 
			
		||||
	tex->h = h;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user