📄 shaderobjects_3dlabs.c
字号:
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 + -