⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shaderobjects_3dlabs.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	there's only one string to deal with, we pass its address directly */

	if (impl->_obj.offset_count <= 1)
		strings = &impl->_obj.source;
	else
	{
		GLsizei i, offset = 0;

		strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
		if (strings == NULL)
			return;

		for (i = 0; i < impl->_obj.offset_count; i++)
		{
			GLsizei size = impl->_obj.offsets[i] - offset;

			strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
			if (strings[i] == NULL)
			{
				GLsizei j;

				for (j = 0; j < i; j++)
					_mesa_free (strings[j]);
				_mesa_free (strings);
				return;
			}

			_mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
			strings[i][size] = '\0';
			offset = impl->_obj.offsets[i];
		}
	}

	/* TODO set these fields to some REAL numbers */
	res.maxLights = 8;
	res.maxClipPlanes = 6;
	res.maxTextureUnits = 2;
	res.maxTextureCoords = 2;
	res.maxVertexAttribs = 8;
	res.maxVertexUniformComponents = 64;
	res.maxVaryingFloats = 8;
	res.maxVertexTextureImageUnits = 2;
	res.maxCombinedTextureImageUnits = 2;
	res.maxTextureImageUnits = 2;
	res.maxFragmentUniformComponents = 64;
	res.maxDrawBuffers = 1;

	if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
			EShOptFull, &res, 0))
		impl->_obj.compile_status = GL_TRUE;
	if (impl->_obj.offset_count > 1)
	{
		GLsizei i;

		for (i = 0; i < impl->_obj.offset_count; i++)
			_mesa_free (strings[i]);
		_mesa_free (strings);
	}

	impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
		impl->_obj._3dlabs_shhandle._obj.handle));
#else
	if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER)
		type = slang_unit_fragment_shader;
	else
		type = slang_unit_vertex_shader;
	slang_info_log_construct (&info_log);
	if (_slang_compile (impl->_obj.source, &impl->_obj.unit, type, &info_log))
	{
		impl->_obj.compile_status = GL_TRUE;
	}
	if (info_log.text != NULL)
		impl->_obj._generic.info_log = _mesa_strdup (info_log.text);
	else
		impl->_obj._generic.info_log = _mesa_strdup ("");
	slang_info_log_destruct (&info_log);
#endif
}

static struct gl2_shader_intf _shader_vftbl = {
	{
		{
			_unknown_AddRef,
			_unknown_Release,
			_shader_QueryInterface
		},
		_generic_Delete,
		_shader_GetType,
		_generic_GetName,
		_generic_GetDeleteStatus,
		_generic_GetInfoLog
	},
	NULL,		/* abstract GetSubType */
	_shader_GetCompileStatus,
	_shader_SetSource,
	_shader_GetSource,
	_shader_Compile
};

static void
_shader_constructor (struct gl2_shader_impl *impl)
{
	_generic_constructor ((struct gl2_generic_impl *) impl);
	_3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
		&impl->_vftbl);
	impl->_vftbl = &_shader_vftbl;
	impl->_obj._generic._unknown._destructor = _shader_destructor;
	impl->_obj.compile_status = GL_FALSE;
	impl->_obj.source = NULL;
	impl->_obj.offsets = NULL;
	impl->_obj.offset_count = 0;
}

struct gl2_program_obj
{
	struct gl2_container_obj _container;
	GLboolean link_status;
	GLboolean validate_status;
#if USE_3DLABS_FRONTEND
	ShHandle linker;
	ShHandle uniforms;
#endif
	slang_program prog;
};

struct gl2_program_impl
{
	struct gl2_program_intf *_vftbl;
	struct gl2_program_obj _obj;
};

static void
_program_destructor (struct gl2_unknown_intf **intf)
{
	struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
#if USE_3DLABS_FRONTEND
	ShDestruct (impl->_obj.linker);
	ShDestruct (impl->_obj.uniforms);
#endif
	_container_destructor (intf);
	slang_program_dtr (&impl->_obj.prog);
}

static struct gl2_unknown_intf **
_program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
{
	if (uiid == UIID_PROGRAM)
	{
		(**intf).AddRef (intf);
		return intf;
	}
	return _container_QueryInterface (intf, uiid);
}

static GLenum
_program_GetType (struct gl2_generic_intf **intf)
{
	return GL_PROGRAM_OBJECT_ARB;
}

static GLboolean
_program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
{
	GET_CURRENT_CONTEXT(ctx);
	struct gl2_unknown_intf **sha;

	sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
	if (sha == NULL)
	{
		_mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
		return GL_FALSE;
	}

	(**sha).Release (sha);
	return _container_Attach (intf, att);
}

static GLboolean
_program_GetLinkStatus (struct gl2_program_intf **intf)
{
	struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;

	return impl->_obj.link_status;
}

static GLboolean
_program_GetValidateStatus (struct gl2_program_intf **intf)
{
	struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;

	return impl->_obj.validate_status;
}

static GLvoid
_program_Link (struct gl2_program_intf **intf)
{
	struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
#if USE_3DLABS_FRONTEND
	ShHandle *handles;
#endif
	GLuint i, count;
	slang_translation_unit *units[2];

	impl->_obj.link_status = GL_FALSE;
	_mesa_free ((void *) impl->_obj._container._generic.info_log);
	impl->_obj._container._generic.info_log = NULL;
	slang_program_dtr (&impl->_obj.prog);
	slang_program_ctr (&impl->_obj.prog);

#if USE_3DLABS_FRONTEND
	handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
	if (handles == NULL)
		return;

	for (i = 0; i < impl->_obj._container.attached_count; i++)
	{
		struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
		struct gl2_3dlabs_shhandle_intf **sh;

		sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
			(struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
		if (sh != NULL)
		{
			handles[i] = (**sh).GetShHandle (sh);
			(**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
		}
		else
		{
			_mesa_free (handles);
			return;
		}
	}

	if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
			impl->_obj.uniforms, NULL, NULL))
		impl->_obj.link_status = GL_TRUE;

	impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
#else
	count = impl->_obj._container.attached_count;
	if (count == 0 || count > 2)
		return;
	for (i = 0; i < count; i++)
	{
		struct gl2_generic_intf **obj;
		struct gl2_unknown_intf **unk;
		struct gl2_shader_impl *sha;

		obj = impl->_obj._container.attached[i];
		unk = (**obj)._unknown.QueryInterface ((struct gl2_unknown_intf **) obj, UIID_SHADER);
		(**obj)._unknown.Release ((struct gl2_unknown_intf **) obj);
		if (unk == NULL)
			return;
		sha = (struct gl2_shader_impl *) unk;
		units[i] = &sha->_obj.unit;
		(**unk).Release (unk);
	}

	impl->_obj.link_status = _slang_link (&impl->_obj.prog, units, count);
	if (impl->_obj.link_status)
		impl->_obj._container._generic.info_log = _mesa_strdup ("Link OK.\n");
	else
		impl->_obj._container._generic.info_log = _mesa_strdup ("Link failed.\n");
#endif
}

static GLvoid
_program_Validate (struct gl2_program_intf **intf)
{
	struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;

	impl->_obj.validate_status = GL_FALSE;
	_mesa_free ((void *) impl->_obj._container._generic.info_log);
	impl->_obj._container._generic.info_log = NULL;

	/* TODO validate */
}

static GLvoid
write_common_fixed (slang_program *pro, GLuint index, const GLvoid *src, GLuint off, GLuint size)
{
	GLuint i;

	for (i = 0; i < SLANG_SHADER_MAX; i++)
	{
		GLuint addr;

		addr = pro->common_fixed_entries[i][index];
		if (addr != ~0)
		{
			GLubyte *dst;

			dst = (GLubyte *) pro->machines[i]->mem + addr + off * size;
			_mesa_memcpy (dst, src, size);
		}
	}
}

static GLvoid
write_common_fixed_mat4 (slang_program *pro, GLmatrix *matrix, GLuint off, GLuint i, GLuint ii,
                         GLuint it, GLuint iit)
{
	GLfloat mat[16];

	/* we want inverse matrix */
	if (!matrix->inv)
	{
		/* allocate inverse matrix and make it dirty */
		_math_matrix_alloc_inv (matrix);
		_math_matrix_loadf (matrix, matrix->m);
	}
	_math_matrix_analyse (matrix);

	write_common_fixed (pro, i, matrix->m, off, 16 * sizeof (GLfloat));

	/* inverse */
	write_common_fixed (pro, ii, matrix->inv, off, 16 * sizeof (GLfloat));

	/* transpose */
	_math_transposef (mat, matrix->m);
	write_common_fixed (pro, it, mat, off, 16 * sizeof (GLfloat));

	/* inverse transpose */
	_math_transposef (mat, matrix->inv);
	write_common_fixed (pro, iit, mat, off, 16 * sizeof (GLfloat));
}

static GLvoid
write_common_fixed_material (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e, GLuint a,
                             GLuint d, GLuint sp, GLuint sh)
{
	GLfloat v[17];

	COPY_4FV(v, ctx->Light.Material.Attrib[e]);
	COPY_4FV((v + 4), ctx->Light.Material.Attrib[a]);
	COPY_4FV((v + 8), ctx->Light.Material.Attrib[d]);
	COPY_4FV((v + 12), ctx->Light.Material.Attrib[sp]);
	v[16] = ctx->Light.Material.Attrib[sh][0];
	write_common_fixed (pro, i, v, 0, 17 * sizeof (GLfloat));
}

static GLvoid
write_common_fixed_light_model_product (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e,
                                        GLuint a)
{
	GLfloat v[4];

	SCALE_4V(v,	ctx->Light.Material.Attrib[a], ctx->Light.Model.Ambient);
	ACC_4V(v, ctx->Light.Material.Attrib[e]);
	write_common_fixed (pro, i, v, 0, 4 * sizeof (GLfloat));
}

static GLvoid
write_common_fixed_light_product (GLcontext *ctx, slang_program *pro, GLuint off, GLuint i, GLuint a,
                                  GLuint d, GLuint s)
{
	GLfloat v[12];

	SCALE_4V(v, ctx->Light.Light[off].Ambient, ctx->Light.Material.Attrib[a]);
	SCALE_4V((v + 4), ctx->Light.Light[off].Diffuse, ctx->Light.Material.Attrib[d]);
	SCALE_4V((v + 8), ctx->Light.Light[off].Specular, ctx->Light.Material.Attrib[s]);
	write_common_fixed (pro, i, v, off, 12 * sizeof (GLfloat));
}

static GLvoid
_program_UpdateFixedUniforms (struct gl2_program_intf **intf)
{
	GET_CURRENT_CONTEXT(ctx);
	struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
	slang_program *pro = &impl->_obj.prog;
	GLuint i;
	GLfloat v[29];
	GLfloat *p;

	/* MODELVIEW matrix */
	write_common_fixed_mat4 (pro, ctx->ModelviewMatrixStack.Top, 0,
		SLANG_COMMON_FIXED_MODELVIEWMATRIX,
		SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE,
		SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE,
		SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE);

	/* PROJECTION matrix */
	write_common_fixed_mat4 (pro, ctx->ProjectionMatrixStack.Top, 0,
		SLANG_COMMON_FIXED_PROJECTIONMATRIX,
		SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE,
		SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE,
		SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE);

	/* MVP matrix */
	write_common_fixed_mat4 (pro, &ctx->_ModelProjectMatrix, 0,
		SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX,
		SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE,
		SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE,
		SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE);

	for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
	{
		/* TEXTURE matrix */
		write_common_fixed_mat4 (pro, ctx->TextureMatrixStack[i].Top, i,
			SLANG_COMMON_FIXED_TEXTUREMATRIX,
			SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE,
			SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE,
			SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE);

		/* EYE_PLANE texture-coordinate generation */
		write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANES, ctx->Texture.Unit[i].EyePlaneS,
			i, 4 * sizeof (GLfloat));
		write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANET, ctx->Texture.Unit[i].EyePlaneT,
			i, 4 * sizeof (GLfloat));
		write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANER, ctx->Texture.Unit[i].EyePlaneR,
			i, 4 * sizeof (GLfloat));
		write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANEQ, ctx->Texture.Unit[i].EyePlaneQ,
			i, 4 * sizeof (GLfloat));

		/* OBJECT_PLANE texture-coordinate generation */
		write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANES, ctx->Texture.Unit[i].ObjectPlaneS,
			i, 4 * sizeof (GLfloat));
		write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANET, ctx->Texture.Unit[i].ObjectPlaneT,
			i, 4 * sizeof (GLfloat));
		write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANER, ctx->Texture.Unit[i].ObjectPlaneR,
			i, 4 * sizeof (GLfloat));
		write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANEQ, ctx->Texture.Unit[i].ObjectPlaneQ,
			i, 4 * sizeof (GLfloat));
	}

	/* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */
	p = ctx->ModelviewMatrixStack.Top->inv;
	v[0] = p[0];
	v[1] = p[4];
	v[2] = p[8];
	v[3] = p[1];
	v[4] = p[5];
	v[5] = p[9];
	v[6] = p[2];
	v[7] = p[6];
	v[8] = p[10];
	write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0, 9 * sizeof (GLfloat));

	/* normal scale */
	write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALSCALE, &ctx->_ModelViewInvScale, 0, sizeof (GLfloat));

	/* depth range parameters */
	v[0] = ctx->Viewport.Near;
	v[1] = ctx->Viewport.Far;
	v[2] = ctx->Viewport.Far - ctx->Viewport.Near;
	write_common_fixed (pro, SLANG_COMMON_FIXED_DEPTHRANGE, v, 0, 3 * sizeof (GLfloat));

	/* CLIP_PLANEi */
	for (i = 0; i < ctx->Const.MaxClipPlanes; i++)
	{
		write_common_fixed (pro, SLANG_COMMON_FIXED_CLIPPLANE, ctx->Transform.EyeUserPlane[i], i,
			4 * sizeof (GLfloat));
	}

	/* point parameters */
	v[0] = ctx->Point.Size;
	v[1] = ctx->Point.MinSize;
	v[2] = ctx->Point.MaxSize;
	v[3] = ctx->Point.Threshold;
	COPY_3FV((v + 4), ctx->Point.Params);
	write_common_fixed (pro, SLANG_COMMON_FIXED_POINT, v, 0, 7 * sizeof (GLfloat));

	/* material parameters */
	write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_FRONTMATERIAL,
		MAT_ATTRIB_FRONT_EMISSION,
		MAT_ATTRIB_FRONT_AMBIENT,
		MAT_ATTRIB_FRONT_DIFFUSE,
		MAT_ATTRIB_FRONT_SPECULAR,
		MAT_ATTRIB_FRONT_SHININESS);
	write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_BACKMATERIAL,
		MAT_ATTRIB_BACK_EMISSION,
		MAT_ATTRIB_BACK_AMBIENT,
		MAT_ATTRIB_BACK_DIFFUSE,
		MAT_ATTRIB_BACK_SPECULAR,
		MAT_ATTRIB_BACK_SHININESS);

	for (i = 0; i < ctx->Const.MaxLights; i++)
	{
		/* light source parameters */
		COPY_4FV(v, ctx->Light.Light[i].Ambient);
		COPY_4FV((v + 4), ctx->Light.Light[i].Diffuse);
		COPY_4FV((v + 8), ctx->Light.Light[i].Specular);
		COPY_4FV((v + 12), ctx->Light.Light[i].EyePosition);
		COPY_2FV((v + 16), ctx->Light.Light[i].EyePosition);
		v[18] = ctx->Light.Light[i].EyePosition[2] + 1.0f;
		NORMALIZE_3FV((v + 16));
		v[19] = 0.0f;
		COPY_3V((v + 20), ctx->Light.Light[i].EyeDirection);
		v[23] = ctx->Light.Light[i].SpotExponent;
		v[24] = ctx->Light.Light[i].SpotCutoff;
		v[25] = ctx->Light.Light[i]._CosCutoffNeg;
		v[26] = ctx->Light.Light[i].ConstantAttenuation;
		v[27] = ctx->Light.Light[i].LinearAttenuation;
		v[28] = ctx->Light.Light[i].QuadraticAttenuation;
		write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTSOURCE, v, i, 29 * sizeof (GLfloat));

		/* light product */
		write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT,
			MAT_ATTRIB_FRONT_AMBIENT,
			MAT_ATTRIB_FRONT_DIFFUSE,
			MAT_ATTRIB_FRONT_SPECULAR);
		write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_BACKLIGHTPRODUCT,
			MAT_ATTRIB_BACK_AMBIENT,
			MAT_ATTRIB_BACK_DIFFUSE,
			MAT_ATTRIB_BACK_SPECULAR);
	}

	/* light model parameters */
	write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTMODEL, ctx->Light.Model.Ambient, 0, 4 * sizeof (GLfloat));

	/* light model product */
	write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT,
		MAT_ATTRIB_FRONT_EMISSION,
		MAT_ATTRIB_FRONT_AMBIENT);
	write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT,
		MAT_ATTRIB_BACK_EMISSION,
		MAT_ATTRIB_BACK_AMBIENT);

	/* TEXTURE_ENV_COLOR */
	for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
	{
		write_common_fixed (pro, SLANG_COMMON_FIXED_TEXTUREENVCOLOR, ctx->Texture.Unit[i].EnvColor,
			i, 4 * sizeof (GLfloat));
	}

	/* fog parameters */
	COPY_4FV(v, ctx->Fog.Color);
	v[4] = ctx->Fog.Density;
	v[5] = ctx->Fog.Start;
	v[6] = ctx->Fog.End;
	v[7] = ctx->Fog._Scale;
	write_common_fixed (pro, SLANG_COMMON_FIXED_FOG, v, 0, 8 * sizeof (GLfloat));
}

static GLvoid
_program_UpdateFixedAttribute (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
							  GLuint offset, GLuint size, GLboolean write)
{
	struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
	slang_program *pro = &impl->_obj.prog;
	GLuint addr;

	addr = pro->vertex_fixed_entries[index];
	if (addr != ~0)
	{
		GLubyte *mem;

		mem = (GLubyte *) pro->machines[SLANG_SHADER_VERTEX]->mem + addr + offset * size;
		if (write)
			_mesa_memcpy (mem, data, size);
		else
			_mesa_memcpy (data, mem, size);
	}
}

static GLvoid
_program_UpdateFixedVarying (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
							GLuint offset, GLuint size, GLboolean write)
{
	struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
	slang_program *pro = &impl->_obj.prog;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -