Exemple #1
0
/**
 * Try to do a blit using resource_copy_region. The function calls
 * resource_copy_region if the blit description is compatible with it.
 *
 * It returns TRUE if the blit was done using resource_copy_region.
 *
 * It returns FALSE otherwise and the caller must fall back to a more generic
 * codepath for the blit operation. (e.g. by using u_blitter)
 */
boolean
util_try_blit_via_copy_region(struct pipe_context *ctx,
                              const struct pipe_blit_info *blit)
{
   unsigned mask = util_format_get_mask(blit->dst.format);

   /* No format conversions. */
   if (blit->src.resource->format != blit->src.format ||
       blit->dst.resource->format != blit->dst.format ||
       !util_is_format_compatible(
          util_format_description(blit->src.resource->format),
          util_format_description(blit->dst.resource->format))) {
      return FALSE;
   }

   /* No masks, no filtering, no scissor. */
   if ((blit->mask & mask) != mask ||
       blit->filter != PIPE_TEX_FILTER_NEAREST ||
       blit->scissor_enable) {
      return FALSE;
   }

   /* No flipping. */
   if (blit->src.box.width < 0 ||
       blit->src.box.height < 0 ||
       blit->src.box.depth < 0) {
      return FALSE;
   }

   /* No scaling. */
   if (blit->src.box.width != blit->dst.box.width ||
       blit->src.box.height != blit->dst.box.height ||
       blit->src.box.depth != blit->dst.box.depth) {
      return FALSE;
   }

   /* No out-of-bounds access. */
   if (!is_box_inside_resource(blit->src.resource, &blit->src.box,
                               blit->src.level) ||
       !is_box_inside_resource(blit->dst.resource, &blit->dst.box,
                               blit->dst.level)) {
      return FALSE;
   }

   /* Sample counts must match. */
   if (get_sample_count(blit->src.resource) !=
       get_sample_count(blit->dst.resource)) {
      return FALSE;
   }

   if (blit->alpha_blend)
      return FALSE;

   ctx->resource_copy_region(ctx, blit->dst.resource, blit->dst.level,
                             blit->dst.box.x, blit->dst.box.y, blit->dst.box.z,
                             blit->src.resource, blit->src.level,
                             &blit->src.box);
   return TRUE;
}
asmlinkage int px_sys_clone(unsigned long clone_flgs, unsigned long newsp, struct pt_regs *regs)
{
	int ret = 0;
	unsigned long lsc;

	INIT_STACK_FRAME; 

	mutex_lock(&fork_mutex);

	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	ret = px_original_sys_clone(clone_flgs, newsp, regs);
	
	mutex_unlock(&fork_mutex);
	CUTTAIL_STACK_FRAME;

	if ((ret >= 0) && (gb_enable_os_hooks))
	{
		if (!(clone_flgs & CLONE_THREAD))
		{
			enum_modules_for_process(ret, lsc);
		}
	}

	//mutex_unlock(&fork_mutex);

	return ret;
}
asmlinkage int px_sys_execve(char *filenameei, char **argv, char **envp, struct pt_regs *regs)
{
	int ret;
	unsigned long lsc;

	INIT_STACK_FRAME; 

	/** 
	 * here we just use the mutex to make sure the fork call is finished, 
	 *   no need to keep the mutex till the call finished 
	 **/
	mutex_lock(&fork_mutex);
	mutex_unlock(&fork_mutex);

	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	ret = px_original_sys_execve(filenameei, argv, envp, regs);

	CUTTAIL_STACK_FRAME;

	if ((ret >= 0) && (gb_enable_os_hooks))
	{
		enum_modules_for_process(current->tgid, lsc);
	}

	return ret;
}
asmlinkage int px_sys_vfork(struct pt_regs *regs)
{
	int ret = 0;
	unsigned long lsc;

	INIT_STACK_FRAME; 

	mutex_lock(&fork_mutex);
	mutex_unlock(&fork_mutex);
	
	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	ret = px_original_sys_vfork(regs);

	CUTTAIL_STACK_FRAME;

	if ((ret >= 0) && (gb_enable_os_hooks))
	{
		enum_modules_for_process(ret, lsc);
	}

	return ret;
}
int module_init_notifier(struct notifier_block *self,
                         unsigned long event,
                         void *arg)
{
	struct module *mod = (struct module *)arg;
	unsigned int name_offset;
	unsigned int lsc;
	
	lsc = get_sample_count();
	
	name_offset = 0;


	if (event == MODULE_STATE_COMING)
	{
		if (mod->init_size > 0)
		{
			module_load_notif((char *)mod->name, name_offset, 0,
				              (__u32)mod->module_init, mod->init_size,
				              MODULE_FLAG_GLOBAL, lsc);
		}
		
		if (mod->core_size > 0)
		{	
			module_load_notif((char*)mod->name, name_offset, 0,
				              (__u32)mod->module_core, mod->core_size,
				              MODULE_FLAG_GLOBAL, lsc);
		}
	}
	
	return 0;
}
asmlinkage int px_sys_mmap2(
		unsigned long addr, unsigned long len,
		unsigned long prot, unsigned long flgs,
		unsigned long fd, unsigned long pgoff
/*		unsigned long lRegSP*/
		)
{
	int ret = 0;
	int saved_r5;
	unsigned long lsc;
	struct file *file;

	INIT_STACK_FRAME; 

	// here we must save r5 since it will be used by the OS sys_mmap2 code
	__asm__("str r5, %0\n\t":"=m"(saved_r5):);

	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	// restore r5 
	__asm__("ldr r5, %0\n\t"::"m"(saved_r5):"r5");

	ret = px_original_sys_mmap2( addr, len, prot, flgs, fd, pgoff);

	CUTTAIL_STACK_FRAME;

	if (gb_enable_os_hooks && !IS_ERR((void *)ret) && (prot & PROT_EXEC) && !(flgs & MAP_ANONYMOUS))
	{
		//rcu_read_lock();

		if ((file = fcheck(fd))!= NULL)
		{
			char *pname;
			
			memset(name, 0, PATH_MAX * sizeof(char));
			pname = px_d_path(file, name, PATH_MAX);
			
			if (pname)
			{
				unsigned long name_offset;

				name_offset = get_filename_offset(pname);

				module_load_notif(pname, name_offset, current->tgid,
						          ret, len, 0, lsc);
			}
			
		}
		//rcu_read_unlock();
	}
	
	return ret;
}
asmlinkage int px_sys_mmap(struct mmap_arg_struct *arg)
{
	int ret = 0;
	struct mmap_arg_struct tmp;
	struct file *file;
	unsigned long long lsc;
	char * name = NULL;

	lsc = get_sample_count();

	if (copy_from_user(&tmp, arg, sizeof(tmp)) != 0)
	{
		return -EFAULT;
	}

 	ret = px_original_sys_mmap(arg);

	if (gb_enable_os_hooks && (!IS_ERR((void*)ret)) && (tmp.prot & PROT_EXEC) && !(tmp.flags & MAP_ANONYMOUS))
	{
		//rcu_read_lock();
		if ((file = fcheck(tmp.fd)) != NULL)
		{
			char *filename;
			//memset(name, 0, PATH_MAX * sizeof(char));
			name = kzalloc(PATH_MAX, GFP_ATOMIC);

			if (name == NULL)
			{
				return ret;
			}

			filename = px_d_path(file, name, PATH_MAX);
			if (filename)
			{
				unsigned long name_offset;

				name_offset = get_filename_offset(filename);

				module_load_notif(filename, name_offset, current->tgid,
					              ret, tmp.len,
					              0, lsc);
			}

			kfree(name);
		}

		//rcu_read_unlock();
	}

	return ret;
}
/* 
 * we hook this system call in order to get the new process name 
 * if it is modified by changing argv[0]
 * assume that it is followed by a prctl(PR_SET_NAME, ...)
 */
asmlinkage long px_sys_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
{
	long ret = 0;
	char * new_name = NULL;
	char * old_name = NULL;
	unsigned long long lsc;

	INIT_STACK_FRAME;

	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	ret = px_original_sys_prctl(option, arg2, arg3, arg4, arg5);
	
	CUTTAIL_STACK_FRAME;

	if ((ret == 0) && (option == PR_SET_NAME))
	{
		new_name = kzalloc(PATH_MAX, GFP_ATOMIC);
		old_name = kzalloc(PATH_MAX, GFP_ATOMIC);
		
		if ((new_name != NULL) && (old_name != NULL))
		{
			if (is_proc_name_modified(current, new_name, old_name))
			{
				enum_modules_for_process(current->tgid, lsc, new_name);
			}
		}
		
		if (new_name != NULL)
			kfree(new_name);

		if (old_name != NULL)
			kfree(old_name);
	}

	return ret;
}
Exemple #9
0
rtt::fbo* rtt::add_buffer(const unsigned int width_, const unsigned int height_,
                          const GLenum* target, const TEXTURE_FILTERING* filtering,
                          const TEXTURE_ANTI_ALIASING* taa,
                          const GLint* wrap_s, const GLint* wrap_t,
                          const GLint* internal_format,
                          const GLenum* format,
                          const GLenum* type,
                          const unsigned int attachment_count,
                          const rtt::DEPTH_TYPE depth_type,
                          const rtt::STENCIL_TYPE stencil_type) {
    unsigned int width = width_;
    unsigned int height = height_;

    rtt::fbo* buffer = new rtt::fbo(attachment_count);
    buffers.push_back(buffer);
    buffer->width = width;
    buffer->height = height;
    buffer->draw_width = width;
    buffer->draw_height = height;
    buffer->depth_type = depth_type;
    buffer->stencil_type = stencil_type;
    buffer->samples = 0;

    //
    const size_t max_tex_size = exts->get_max_texture_size();
    const float fmax_tex_size = max_tex_size;
    size2 orig_resolution = size2(width, height);
    float ssaa = 0.0f;
    for(unsigned int i = 0; i < buffer->attachment_count; i++) {
        buffer->anti_aliasing[i] = taa[i];

        float ssaa_factor = get_anti_aliasing_scale(buffer->anti_aliasing[i]);
        if(ssaa_factor <= 1.0f) continue;

        //
        // try lower ssaa setting
        float cur_ssaa_factor = ssaa_factor;
        while(cur_ssaa_factor >= 2.0f) {
            if(float(orig_resolution.x) * ssaa_factor > fmax_tex_size ||
                    float(orig_resolution.y) * ssaa_factor > fmax_tex_size) {
                cur_ssaa_factor -= 2.0f;
                continue;
            }
            else break;
        }

        if(cur_ssaa_factor <= 0.0f) {
            log_error("couldn't create a SSAA%u buffer (nor using a smaller SSAA setting)!", ssaa_factor);
            break; // break, since this won't work with any setting
        }

        if(cur_ssaa_factor < ssaa_factor) {
            log_error("couldn't create a SSAA%u buffer - using SSAA%u instead!", ssaa_factor, cur_ssaa_factor);
        }

        ssaa = std::max(ssaa, cur_ssaa_factor);
    }

    // apply ssaa
    if(ssaa > 0.0f) {
        const float2 ssaa_res = get_resolution_for_scale(ssaa, size2(width, height));
        width = (unsigned int)ssaa_res.x;
        height = (unsigned int)ssaa_res.y;
        buffer->width = width;
        buffer->height = height;
        buffer->draw_width = width;
        buffer->draw_height = height;
    }

    //
    glGenFramebuffers(1, &buffer->fbo_id);
    glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id);

    glGenTextures((GLsizei)attachment_count, &buffer->tex[0]);
    for(unsigned int i = 0; i < buffer->attachment_count; i++) {
#if defined(FLOOR_IOS) && !defined(PLATFORM_X64)
        if(i > 0) {
            log_error("too many FBO attachments - only one is allowed on iOS!");
            break;
        }
#endif

        buffer->target[i] = target[i];
        glBindTexture(buffer->target[i], buffer->tex[i]);

        glTexParameteri(buffer->target[i], GL_TEXTURE_MAG_FILTER,
                        (filtering[i] == TEXTURE_FILTERING::POINT ? GL_NEAREST : GL_LINEAR));
        glTexParameteri(buffer->target[i], GL_TEXTURE_MIN_FILTER, texman::select_filter(filtering[i]));
        glTexParameteri(buffer->target[i], GL_TEXTURE_WRAP_S, wrap_s[i]);
        glTexParameteri(buffer->target[i], GL_TEXTURE_WRAP_T, wrap_t[i]);
        if(exts->is_anisotropic_filtering_support() && filtering[i] >= TEXTURE_FILTERING::BILINEAR) {
            glTexParameteri(buffer->target[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, (GLint)exts->get_max_anisotropic_filtering());
        }

        switch(buffer->target[i]) {
#if !defined(FLOOR_IOS)
        case GL_TEXTURE_1D:
            glTexImage1D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, 0, format[i], type[i], nullptr);
            break;
#endif
        case GL_TEXTURE_2D:
            glTexImage2D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, 0, format[i], type[i], nullptr);
            break;
#if !defined(FLOOR_IOS)
        case GL_TEXTURE_2D_MULTISAMPLE:
            glTexImage2DMultisample(buffer->target[i], (GLsizei)get_sample_count(buffer->anti_aliasing[0]), texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, false);
            break;
#endif
        default:
            glTexImage2D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, 0, format[i], type[i], nullptr);
            break;
        }

        if(filtering[i] > TEXTURE_FILTERING::LINEAR) {
            buffer->auto_mipmap[i] = true;
            //glGenerateMipmap(buffer->target[i]);
        }
        else buffer->auto_mipmap[i] = false;

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, buffer->target[i], buffer->tex[i], 0);

#if !defined(FLOOR_IOS)
#if defined(A2E_DEBUG)
        // TODO: fbo/texture checking
        GLint check_internal_format = 0, check_type = 0, check_size = 0;
        glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_INTERNAL_FORMAT, &check_internal_format);
        glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_RED_TYPE, &check_type);
        glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_RED_SIZE, &check_size);
        //log_debug("FBO: iformat: %X, type: %X, size: %d", check_internal_format, check_type, check_size);
#endif
#endif
    }

    current_buffer = buffer;
    check_fbo(current_buffer);

    // check if a depth attachment should be created
    if(depth_type != DEPTH_TYPE::NONE) {
        // apparently opencl/opengl depth texture sharing only works with a float format
#if !defined(A2E_INFERRED_RENDERING_CL)
        GLenum depth_internel_format = GL_DEPTH_COMPONENT24;
        GLenum depth_storage_type = GL_UNSIGNED_INT;
#else
        GLenum depth_internel_format = GL_DEPTH_COMPONENT32F;
        GLenum depth_storage_type = GL_FLOAT;
#endif
        GLenum depth_format = GL_DEPTH_COMPONENT;
        GLenum depth_attachment_type = GL_DEPTH_ATTACHMENT;
        if(stencil_type == STENCIL_TYPE::STENCIL_8) {
#if !defined(A2E_INFERRED_RENDERING_CL)
            depth_internel_format = GL_DEPTH24_STENCIL8;
            depth_storage_type = GL_UNSIGNED_INT_24_8;
#else
            depth_internel_format = GL_DEPTH32F_STENCIL8;
            depth_storage_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
#endif
            depth_format = GL_DEPTH_STENCIL;
            depth_attachment_type = GL_DEPTH_STENCIL_ATTACHMENT;
        }
        buffer->depth_attachment_type = depth_attachment_type;

        switch(buffer->anti_aliasing[0]) {
        case TEXTURE_ANTI_ALIASING::NONE:
        case TEXTURE_ANTI_ALIASING::SSAA_2:
        case TEXTURE_ANTI_ALIASING::SSAA_4:
        case TEXTURE_ANTI_ALIASING::FXAA:
        case TEXTURE_ANTI_ALIASING::SSAA_4_3_FXAA:
        case TEXTURE_ANTI_ALIASING::SSAA_2_FXAA:
            if(depth_type == DEPTH_TYPE::RENDERBUFFER) {
                glGenRenderbuffers(1, &buffer->depth_buffer);
                glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer);
                glRenderbufferStorage(GL_RENDERBUFFER, depth_internel_format, (GLsizei)width, (GLsizei)height);
            }
            else if(depth_type == DEPTH_TYPE::TEXTURE_2D) {
                glGenTextures(1, &buffer->depth_buffer);
                glBindTexture(GL_TEXTURE_2D, buffer->depth_buffer);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);

                glTexImage2D(GL_TEXTURE_2D, 0, texman::convert_internal_format((GLint)depth_internel_format), (GLsizei)width, (GLsizei)height, 0, depth_format, depth_storage_type, nullptr);
                glFramebufferTexture2D(GL_FRAMEBUFFER, depth_attachment_type, GL_TEXTURE_2D, buffer->depth_buffer, 0);
            }

            check_fbo(current_buffer);
            break;
        case TEXTURE_ANTI_ALIASING::MSAA_2:
        case TEXTURE_ANTI_ALIASING::MSAA_4:
        case TEXTURE_ANTI_ALIASING::MSAA_8:
        case TEXTURE_ANTI_ALIASING::MSAA_16:
        case TEXTURE_ANTI_ALIASING::MSAA_32:
        case TEXTURE_ANTI_ALIASING::MSAA_64: {
            buffer->samples = get_sample_count(buffer->anti_aliasing[0]);

            glGenFramebuffers((GLsizei)attachment_count, &buffer->resolve_buffer[0]);
            for(size_t i = 0; i < attachment_count; i++) {
                glBindFramebuffer(GL_FRAMEBUFFER, buffer->resolve_buffer[i]);
                glFramebufferTexture2D(GL_FRAMEBUFFER, (GLenum)(GL_COLOR_ATTACHMENT0+i), target[i], buffer->tex[i], 0);
            }
            check_fbo(current_buffer);

            glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id);

            glGenRenderbuffers(1, &buffer->color_buffer);
            glBindRenderbuffer(GL_RENDERBUFFER, buffer->color_buffer);
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, (GLsizei)buffer->samples, (GLenum)internal_format[0], (GLsizei)buffer->width, (GLsizei)buffer->height);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, buffer->color_buffer);
            check_fbo(current_buffer);

            if(depth_type == DEPTH_TYPE::RENDERBUFFER) {
                glGenRenderbuffers(1, &buffer->depth_buffer);
                glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer);
                glRenderbufferStorageMultisample(GL_RENDERBUFFER, (GLsizei)buffer->samples, depth_internel_format, (GLsizei)buffer->width, (GLsizei)buffer->height);
                glFramebufferRenderbuffer(GL_FRAMEBUFFER, depth_attachment_type, GL_RENDERBUFFER, buffer->depth_buffer);
            }
#if !defined(FLOOR_IOS)
            else if(depth_type == DEPTH_TYPE::TEXTURE_2D) {
                glGenTextures(1, &buffer->depth_buffer);
                glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, buffer->depth_buffer);
                glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

                glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, (GLsizei)buffer->samples, texman::convert_internal_format((GLint)depth_internel_format), (GLsizei)width, (GLsizei)height, false);
                glFramebufferTexture2D(GL_FRAMEBUFFER, depth_attachment_type, GL_TEXTURE_2D_MULTISAMPLE, buffer->depth_buffer, 0);
            }
#endif

            check_fbo(current_buffer);
        }
        break;
#if !defined(FLOOR_IOS) && 0 // TODO: fix or remove this
        case TEXTURE_ANTI_ALIASING::CSAA_8:
        case TEXTURE_ANTI_ALIASING::CSAA_8Q:
        case TEXTURE_ANTI_ALIASING::CSAA_16:
        case TEXTURE_ANTI_ALIASING::CSAA_16Q:
        case TEXTURE_ANTI_ALIASING::CSAA_32:
        case TEXTURE_ANTI_ALIASING::CSAA_32Q: {
            int color_samples, coverage_samples;
            switch(buffer->anti_aliasing[0]) {
            case TEXTURE_ANTI_ALIASING::CSAA_8:
                color_samples = 4;
                coverage_samples = 8;
                break;
            case TEXTURE_ANTI_ALIASING::CSAA_8Q:
                color_samples = 8;
                coverage_samples = 8;
                break;
            case TEXTURE_ANTI_ALIASING::CSAA_16:
                color_samples = 4;
                coverage_samples = 16;
                break;
            case TEXTURE_ANTI_ALIASING::CSAA_16Q:
                color_samples = 8;
                coverage_samples = 16;
                break;
            case TEXTURE_ANTI_ALIASING::CSAA_32: // TODO: ratio?
            case TEXTURE_ANTI_ALIASING::CSAA_32Q: // TODO: ratio?
            default:
                color_samples = 4;
                coverage_samples = 8;
                break;
            }

            glGenRenderbuffers(1, &buffer->depth_buffer);
            glGenRenderbuffers(1, &buffer->color_buffer);

            glGenFramebuffers(1, &buffer->resolve_buffer[0]);

            glBindFramebuffer(GL_FRAMEBUFFER, buffer->resolve_buffer[0]);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer->tex[0], 0);
            check_fbo(current_buffer);

            glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id);
            glBindRenderbuffer(GL_RENDERBUFFER, buffer->color_buffer);

            glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, coverage_samples, color_samples, (GLenum)internal_format[0], (GLsizei)buffer->width, (GLsizei)buffer->height);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, buffer->color_buffer);
            check_fbo(current_buffer);

            glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer);
            glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, coverage_samples, color_samples, depth_internel_format, (GLsizei)buffer->width, (GLsizei)buffer->height);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, depth_attachment_type, GL_RENDERBUFFER, buffer->depth_buffer);
            check_fbo(current_buffer);
        }
        break;
#else
        case TEXTURE_ANTI_ALIASING::CSAA_8:
        case TEXTURE_ANTI_ALIASING::CSAA_8Q:
        case TEXTURE_ANTI_ALIASING::CSAA_16:
        case TEXTURE_ANTI_ALIASING::CSAA_16Q:
        case TEXTURE_ANTI_ALIASING::CSAA_32:
        case TEXTURE_ANTI_ALIASING::CSAA_32Q:
            log_error("CSAA not supported right now");
            break;
#endif
        }
    }

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);

    return buffer;
}