Exemplo n.º 1
0
void agp_empty_vstore(struct storage_info_t* vs, size_t w, size_t h)
{
	size_t sz = w * h * sizeof(av_pixel);
	vs->vinf.text.s_raw = sz;

/* this is to allow an override of s_fmt and still handle reset */
	if (vs->vinf.text.s_fmt == 0)
		vs->vinf.text.s_fmt = GL_PIXEL_FORMAT;
	if (vs->vinf.text.d_fmt == 0)
		vs->vinf.text.d_fmt = GL_STORE_PIXEL_FORMAT;

	vs->vinf.text.raw = arcan_alloc_mem(
		vs->vinf.text.s_raw,
		ARCAN_MEM_VBUFFER, ARCAN_MEM_BZERO, ARCAN_MEMALIGN_PAGE
	);
	vs->w = w;
	vs->h = h;
	vs->bpp = sizeof(av_pixel);
	vs->txmapped = TXSTATE_TEX2D;

	agp_update_vstore(vs, true);

	arcan_mem_free(vs->vinf.text.raw);
	vs->vinf.text.raw = 0;
	vs->vinf.text.s_raw = 0;
}
Exemplo n.º 2
0
Arquivo: gl21.c Projeto: mewbak/arcan
void agp_resize_vstore(struct storage_info_t* s, size_t w, size_t h)
{
	struct agp_fenv* env = agp_env();
	s->w = w;
	s->h = h;
	s->bpp = sizeof(av_pixel);

	alloc_buffer(s);
	rebuild_pbo(s);

	agp_update_vstore(s, true);
}
Exemplo n.º 3
0
void agp_empty_vstore(struct storage_info_t* vs, size_t w, size_t h)
{
	size_t sz = w * h * sizeof(av_pixel);
	vs->vinf.text.s_raw = sz;
	vs->vinf.text.raw = arcan_alloc_mem(
		vs->vinf.text.s_raw,
		ARCAN_MEM_VBUFFER, ARCAN_MEM_BZERO, ARCAN_MEMALIGN_PAGE
	);
	vs->w = w;
	vs->h = h;
	vs->txmapped = TXSTATE_TEX2D;

	agp_update_vstore(vs, true);

	arcan_mem_free(vs->vinf.text.raw);
	vs->vinf.text.raw = 0;
	vs->vinf.text.s_raw = 0;
}
Exemplo n.º 4
0
static bool alloc_fbo(struct agp_rendertarget* dst, bool retry)
{
	struct agp_fenv* env = agp_env();
	env->gen_framebuffers(1, &dst->fbo);
	int mode = dst->mode & (~RENDERTARGET_DOUBLEBUFFER);

/* need both stencil and depth buffer, but we don't need the data from them */
	env->bind_framebuffer(GL_FRAMEBUFFER, dst->fbo);

	if (mode > RENDERTARGET_DEPTH)
	{
		env->framebuffer_texture_2d(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
			GL_TEXTURE_2D, dst->store->vinf.text.glid, 0);

/* need a Z buffer in the offscreen rendering but don't want
 * bo store it, so setup a renderbuffer */
		if (mode > RENDERTARGET_COLOR){
			env->gen_renderbuffers(1, &dst->depth);

/* could use GL_DEPTH_COMPONENT only if we'd know that there
 * wouldn't be any clipping in the active rendertarget */
			if (!retry){
				env->bind_renderbuffer(GL_RENDERBUFFER, dst->depth);
				env->renderbuffer_storage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
					dst->store->w, dst->store->h);
				env->bind_renderbuffer(GL_RENDERBUFFER, 0);
				env->framebuffer_renderbuffer(GL_FRAMEBUFFER,
					GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, dst->depth);
			}
		}
	}
	else {
/* DEPTH buffer only (shadowmapping, ...) convert the storage to
 * contain a depth texture */
		size_t w = dst->store->w;
		size_t h = dst->store->h;

		agp_drop_vstore(dst->store);

		struct storage_info_t* store = dst->store;

		memset(store, '\0', sizeof(struct storage_info_t));

		store->txmapped   = TXSTATE_DEPTH;
		store->txu        = ARCAN_VTEX_CLAMP;
		store->txv        = ARCAN_VTEX_CLAMP;
		store->scale      = ARCAN_VIMAGE_NOPOW2;
		store->imageproc  = IMAGEPROC_NORMAL;
		store->filtermode = ARCAN_VFILTER_NONE;
		store->refcount   = 1;
		store->w = w;
		store->h = h;

/* generate ID etc. special path for TXSTATE_DEPTH */
		agp_update_vstore(store, true);

		env->draw_buffer(GL_NONE);
		env->read_buffer(GL_NONE);

		env->framebuffer_texture_2d(GL_FRAMEBUFFER,
			GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, store->vinf.text.glid, 0);
	}

/* basic error handling / status checking
 * may be possible that we should cache this in the
 * rendertarget and only call when / if something changes as
 * it's not certain that drivers won't stall the pipeline on this */
	GLenum status = env->check_framebuffer(GL_FRAMEBUFFER);
	if (status != GL_FRAMEBUFFER_COMPLETE){
		arcan_warning("FBO support broken, couldn't create basic FBO:\n");
		switch(status){
		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
			if (!retry){
				arcan_warning("\t Incomplete Attachment, attempting "
					"simple framebuffer, this will likely break 3D and complex"
					"clipping operations.\n");
				return alloc_fbo(dst, true);
			}
			else
				arcan_warning("\t Simple attachement broke as well "
					"likely driver issue.\n");
		break;

#ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
		case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
			arcan_warning("\t Not all attached buffers have "
				"the same dimensions.\n");
		break;
#endif

		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
			arcan_warning("\t One or several FBO attachment points are missing.\n");
		break;

		case GL_FRAMEBUFFER_UNSUPPORTED:
			arcan_warning("\t Request formats combination unsupported.\n");
		break;
		}

		if (dst->fbo != GL_NONE)
			env->delete_framebuffers(1,&dst->fbo);
		if (dst->depth != GL_NONE)
			env->delete_renderbuffers(1,&dst->depth);

		dst->fbo = dst->depth = GL_NONE;
		return false;
	}

	env->bind_framebuffer(GL_FRAMEBUFFER, 0);
	return true;
}
Exemplo n.º 5
0
Arquivo: gl21.c Projeto: mewbak/arcan
struct stream_meta agp_stream_prepare(struct storage_info_t* s,
		struct stream_meta meta, enum stream_type type)
{
	struct agp_fenv* env = agp_env();
	struct stream_meta res = meta;
	res.state = true;
	res.type = type;

	switch (type){
	case STREAM_RAW:
		if (!s->vinf.text.wid)
			setup_unpack_pbo(s, NULL);

		alloc_buffer(s);

		res.buf = s->vinf.text.raw;
		res.state = res.buf != NULL;
	break;

	case STREAM_RAW_DIRECT_COPY:
		alloc_buffer(s);
	case STREAM_RAW_DIRECT:
		if (!s->vinf.text.wid)
			setup_unpack_pbo(s, meta.buf);

		if (meta.dirty)
			pbo_stream_sub(s, meta.buf, &meta, type == STREAM_RAW_DIRECT_COPY);
		else
			pbo_stream(s, meta.buf, &meta, type == STREAM_RAW_DIRECT_COPY);
	break;

/* resynch: drop PBOs and GLid, alloc / upload and rebuild possible PBOs */
	case STREAM_EXT_RESYNCH:
		agp_null_vstore(s);
		agp_update_vstore(s, true);
		rebuild_pbo(s);
	break;

	case STREAM_RAW_DIRECT_SYNCHRONOUS:
		agp_activate_vstore(s);

		if (meta.dirty){
			set_pixel_store(s->w, meta);
			env->tex_subimage_2d(GL_TEXTURE_2D, 0, meta.x1, meta.y1, meta.w, meta.h,
				s->vinf.text.s_fmt ? s->vinf.text.s_fmt : GL_PIXEL_FORMAT,
				GL_UNSIGNED_BYTE, meta.buf
			);
			reset_pixel_store();
		}
		else
			env->tex_subimage_2d(GL_TEXTURE_2D, 0, 0, 0, s->w, s->h,
				s->vinf.text.s_fmt ? s->vinf.text.s_fmt : GL_PIXEL_FORMAT,
				GL_UNSIGNED_BYTE, meta.buf
			);
		agp_deactivate_vstore();
	break;

	case STREAM_HANDLE:
/* if platform_video_map_handle fails here, prepare an empty vstore and attempt
 * again, if that succeeds it means that we had to go through a RTT
 * indirection, if that fails we should convey back to the client that
	we can't accept this kind of transfer */
	res.state = platform_video_map_handle(s, meta.handle);
	break;
	}

	return res;
}