本文整理汇总了C++中MAX2函数的典型用法代码示例。如果您正苦于以下问题:C++ MAX2函数的具体用法?C++ MAX2怎么用?C++ MAX2使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了MAX2函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: validate_resources
static void
validate_resources(const struct subtest_t st, GLuint prog, bool *pass)
{
GLsizei max_size = 0, size, i;
char * name;
/* Do not run the test for GL_ATOMIC_COUNTER_BUFFER.
* From the GL_ARB_program_interface_query extension:
*
* "The error INVALID_OPERATION is generated if <programInterface>
* is ATOMIC_COUNTER_BUFFER, since active atomic counter buffer
* resources are not assigned name strings."
*/
if (st.programInterface == GL_ATOMIC_COUNTER_BUFFER)
return;
name = (char *) malloc(st.max_length_name);
for (i = 0; i < st.active_resources; i++) {
GLuint index;
glGetProgramResourceName(prog, st.programInterface,
i, st.max_length_name,
&size, name);
piglit_check_gl_error(GL_NO_ERROR);
/* keep track of the maximum size */
if (size > max_size) {
max_size = size;
}
/* Check the names. Transform feedback requires the order to be
* the same as the one given in glTransformFeedbackVaryings.
* From the GL_ARB_program_interface_query extension:
*
* "The order of the active resource list is
* implementation-dependent for all interfaces except for
* TRANSFORM_FEEDBACK_VARYING. For TRANSFORM_FEEDBACK_VARYING,
* the active resource list will use the variable order
* specified in the the most recent call to
* TransformFeedbackVaryings before the last call to
* LinkProgram.
*/
if (st.resources && !is_resource_in_list(st.resources, name, i,
st.programInterface == GL_TRANSFORM_FEEDBACK_VARYING)) {
fprintf(stderr, "Resource '%s' not found in '%s' "
"resource list or found at the wrong "
"index\n", name,
st.programInterface_str);
*pass = false;
}
/* Check the position of the arguments and see if it matches
* with the current position we are in.
*/
index = glGetProgramResourceIndex(prog, st.programInterface,
name);
if (index != i) {
fprintf(stderr, "%s: Resource '%s' is not at the "
"position reported by "
"glGetProgramResourceIndex (%i instead "
"of %i)\n",
st.programInterface_str, name, index, i);
*pass = false;
}
/* check the equivalence with the old API */
if (!consistency_check(prog, st.programInterface, name,
index)) {
*pass = false;
}
}
free(name);
/* glGetProgramResourceName does not count the NULL terminator as part
* of the size contrarily to glGetProgramInterfaceiv.
* From the GL_ARB_program_interface_query extension:
*
* "void GetProgramInterfaceiv(uint program, enum programInterface,
* enum pname, int *params);
* [...]
* If <pname> is MAX_NAME_LENGTH, the value returned is the length of
* the longest active name string for an active resource in
* <programInterface>. This length includes an extra character for the
* null terminator."
*
* "void GetProgramResourceName(uint program, enum programInterface,
* uint index, sizei bufSize,
* sizei *length, char *name);
* [...]
* The actual number of characters written into <name>, excluding the
* null terminator, is returned in <length>."
*/
if (max_size != MAX2(0, st.max_length_name - 1)) {
fprintf(stderr, "'%s actual max length' expected %i but got "
"%i\n", st.programInterface_str,
st.max_length_name - 1, max_size);
*pass = false;
}
}
示例2: update_maxwell_data_k
/* Set the current k point for the Maxwell solver. k is given in the
basis of the reciprocal lattice vectors, G1, G2, and G3. */
void update_maxwell_data_k(maxwell_data *d, real k[3],
real G1[3], real G2[3], real G3[3])
{
int nx = d->nx, ny = d->ny, nz = d->nz;
int cx = MAX2(1,d->nx/2), cy = MAX2(1,d->ny/2), cz = MAX2(1,d->nz/2);
k_data *kpG = d->k_plus_G;
real *kpGn2 = d->k_plus_G_normsqr;
int x, y, z;
real kx, ky, kz;
kx = G1[0]*k[0] + G2[0]*k[1] + G3[0]*k[2];
ky = G1[1]*k[0] + G2[1]*k[1] + G3[1]*k[2];
kz = G1[2]*k[0] + G2[2]*k[1] + G3[2]*k[2];
d->zero_k = kx == 0.0 && ky == 0.0 && kz == 0.0;
d->current_k[0] = kx;
d->current_k[1] = ky;
d->current_k[2] = kz;
/* make sure current parity is still valid: */
set_maxwell_data_parity(d, d->parity);
for (x = d->local_x_start; x < d->local_x_start + d->local_nx; ++x) {
int kxi = (x >= cx) ? (x - nx) : x;
for (y = 0; y < ny; ++y) {
int kyi = (y >= cy) ? (y - ny) : y;
for (z = 0; z < nz; ++z, kpG++, kpGn2++) {
int kzi = (z >= cz) ? (z - nz) : z;
real kpGx, kpGy, kpGz, a, b, c, leninv;
/* Compute k+G (noting that G is negative because
of the choice of sign in the FFTW Fourier transform): */
kpGx = kx - (G1[0]*kxi + G2[0]*kyi + G3[0]*kzi);
kpGy = ky - (G1[1]*kxi + G2[1]*kyi + G3[1]*kzi);
kpGz = kz - (G1[2]*kxi + G2[2]*kyi + G3[2]*kzi);
a = kpGx*kpGx + kpGy*kpGy + kpGz*kpGz;
kpG->kmag = sqrt(a);
*kpGn2 = a;
/* Now, compute the two normal vectors: */
/* (Note that we choose them so that m has odd/even
parity in z/y, and n is even/odd in z/y.) */
if (a == 0) {
kpG->nx = 0.0; kpG->ny = 1.0; kpG->nz = 0.0;
kpG->mx = 0.0; kpG->my = 0.0; kpG->mz = 1.0;
}
else {
if (kpGx == 0.0 && kpGy == 0.0) {
/* put n in the y direction if k+G is in z: */
kpG->nx = 0.0;
kpG->ny = 1.0;
kpG->nz = 0.0;
}
else {
/* otherwise, let n = z x (k+G), normalized: */
compute_cross(&a, &b, &c,
0.0, 0.0, 1.0,
kpGx, kpGy, kpGz);
leninv = 1.0 / sqrt(a*a + b*b + c*c);
kpG->nx = a * leninv;
kpG->ny = b * leninv;
kpG->nz = c * leninv;
}
/* m = n x (k+G), normalized */
compute_cross(&a, &b, &c,
kpG->nx, kpG->ny, kpG->nz,
kpGx, kpGy, kpGz);
leninv = 1.0 / sqrt(a*a + b*b + c*c);
kpG->mx = a * leninv;
kpG->my = b * leninv;
kpG->mz = c * leninv;
}
#ifdef DEBUG
#define DOT(u0,u1,u2,v0,v1,v2) ((u0)*(v0) + (u1)*(v1) + (u2)*(v2))
/* check orthogonality */
CHECK(fabs(DOT(kpGx, kpGy, kpGz,
kpG->nx, kpG->ny, kpG->nz)) < 1e-6,
"vectors not orthogonal!");
CHECK(fabs(DOT(kpGx, kpGy, kpGz,
kpG->mx, kpG->my, kpG->mz)) < 1e-6,
"vectors not orthogonal!");
CHECK(fabs(DOT(kpG->mx, kpG->my, kpG->mz,
kpG->nx, kpG->ny, kpG->nz)) < 1e-6,
"vectors not orthogonal!");
/* check normalization */
CHECK(fabs(DOT(kpG->nx, kpG->ny, kpG->nz,
kpG->nx, kpG->ny, kpG->nz) - 1.0) < 1e-6,
"vectors not unit vectors!");
CHECK(fabs(DOT(kpG->mx, kpG->my, kpG->mz,
kpG->mx, kpG->my, kpG->mz) - 1.0) < 1e-6,
"vectors not unit vectors!");
//.........这里部分代码省略.........
示例3: nv50_fragprog_assign_slots
static int
nv50_fragprog_assign_slots(struct nv50_ir_prog_info *info)
{
struct nv50_program *prog = (struct nv50_program *)info->driverPriv;
unsigned i, n, m, c;
unsigned nvary;
unsigned nflat;
unsigned nintp = 0;
/* count recorded non-flat inputs */
for (m = 0, i = 0; i < info->numInputs; ++i) {
switch (info->in[i].sn) {
case TGSI_SEMANTIC_POSITION:
case TGSI_SEMANTIC_FACE:
continue;
default:
m += info->in[i].flat ? 0 : 1;
break;
}
}
/* careful: id may be != i in info->in[prog->in[i].id] */
/* Fill prog->in[] so that non-flat inputs are first and
* kick out special inputs that don't use the RESULT_MAP.
*/
for (n = 0, i = 0; i < info->numInputs; ++i) {
if (info->in[i].sn == TGSI_SEMANTIC_POSITION) {
prog->fp.interp |= info->in[i].mask << 24;
for (c = 0; c < 4; ++c)
if (info->in[i].mask & (1 << c))
info->in[i].slot[c] = nintp++;
} else
if (info->in[i].sn == TGSI_SEMANTIC_FACE) {
info->in[i].slot[0] = 255;
} else {
unsigned j = info->in[i].flat ? m++ : n++;
if (info->in[i].sn == TGSI_SEMANTIC_COLOR)
prog->vp.bfc[info->in[i].si] = j;
else if (info->in[i].sn == TGSI_SEMANTIC_PRIMID)
prog->vp.attrs[2] |= NV50_3D_VP_GP_BUILTIN_ATTR_EN_PRIMITIVE_ID;
prog->in[j].id = i;
prog->in[j].mask = info->in[i].mask;
prog->in[j].sn = info->in[i].sn;
prog->in[j].si = info->in[i].si;
prog->in[j].linear = info->in[i].linear;
prog->in_nr++;
}
}
if (!(prog->fp.interp & (8 << 24))) {
++nintp;
prog->fp.interp |= 8 << 24;
}
for (i = 0; i < prog->in_nr; ++i) {
int j = prog->in[i].id;
prog->in[i].hw = nintp;
for (c = 0; c < 4; ++c)
if (prog->in[i].mask & (1 << c))
info->in[j].slot[c] = nintp++;
}
/* (n == m) if m never increased, i.e. no flat inputs */
nflat = (n < m) ? (nintp - prog->in[n].hw) : 0;
nintp -= bitcount4(prog->fp.interp >> 24); /* subtract position inputs */
nvary = nintp - nflat;
prog->fp.interp |= nvary << NV50_3D_FP_INTERPOLANT_CTRL_COUNT_NONFLAT__SHIFT;
prog->fp.interp |= nintp << NV50_3D_FP_INTERPOLANT_CTRL_COUNT__SHIFT;
/* put front/back colors right after HPOS */
prog->fp.colors = 4 << NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT;
for (i = 0; i < 2; ++i)
if (prog->vp.bfc[i] < 0xff)
prog->fp.colors += bitcount4(prog->in[prog->vp.bfc[i]].mask) << 16;
/* FP outputs */
if (info->prop.fp.numColourResults > 1)
prog->fp.flags[0] |= NV50_3D_FP_CONTROL_MULTIPLE_RESULTS;
for (i = 0; i < info->numOutputs; ++i) {
prog->out[i].id = i;
prog->out[i].sn = info->out[i].sn;
prog->out[i].si = info->out[i].si;
prog->out[i].mask = info->out[i].mask;
if (i == info->io.fragDepth || i == info->io.sampleMask)
continue;
prog->out[i].hw = info->out[i].si * 4;
for (c = 0; c < 4; ++c)
info->out[i].slot[c] = prog->out[i].hw + c;
prog->max_out = MAX2(prog->max_out, prog->out[i].hw + 4);
}
if (info->io.sampleMask < PIPE_MAX_SHADER_OUTPUTS) {
//.........这里部分代码省略.........
示例4: svga_link_shaders
/**
* Examine input and output shaders info to link outputs from the
* output shader to inputs from the input shader.
* Basically, we'll remap input shader's input slots to new numbers
* based on semantic name/index of the outputs from the output shader.
*/
void
svga_link_shaders(const struct tgsi_shader_info *outshader_info,
const struct tgsi_shader_info *inshader_info,
struct shader_linkage *linkage)
{
unsigned i, free_slot;
for (i = 0; i < ARRAY_SIZE(linkage->input_map); i++) {
linkage->input_map[i] = INVALID_INDEX;
}
/* Assign input slots for input shader inputs.
* Basically, we want to use the same index for the output shader's outputs
* and the input shader's inputs that should be linked together.
* We'll modify the input shader's inputs to match the output shader.
*/
assert(inshader_info->num_inputs <=
ARRAY_SIZE(inshader_info->input_semantic_name));
/* free register index that can be used for built-in varyings */
free_slot = outshader_info->num_outputs + 1;
for (i = 0; i < inshader_info->num_inputs; i++) {
unsigned sem_name = inshader_info->input_semantic_name[i];
unsigned sem_index = inshader_info->input_semantic_index[i];
unsigned j;
/**
* Get the clip distance inputs from the output shader's
* clip distance shadow copy.
*/
if (sem_name == TGSI_SEMANTIC_CLIPDIST) {
linkage->input_map[i] = outshader_info->num_outputs + 1 + sem_index;
/* make sure free_slot includes this extra output */
free_slot = MAX2(free_slot, linkage->input_map[i] + 1);
}
else {
/* search output shader outputs for same item */
for (j = 0; j < outshader_info->num_outputs; j++) {
assert(j < ARRAY_SIZE(outshader_info->output_semantic_name));
if (outshader_info->output_semantic_name[j] == sem_name &&
outshader_info->output_semantic_index[j] == sem_index) {
linkage->input_map[i] = j;
break;
}
}
}
}
linkage->num_inputs = inshader_info->num_inputs;
/* Things like the front-face register are handled here */
for (i = 0; i < inshader_info->num_inputs; i++) {
if (linkage->input_map[i] == INVALID_INDEX) {
unsigned j = free_slot++;
linkage->input_map[i] = j;
}
}
/* Debug */
if (SVGA_DEBUG & DEBUG_TGSI) {
unsigned reg = 0;
debug_printf("### linkage info:\n");
for (i = 0; i < linkage->num_inputs; i++) {
assert(linkage->input_map[i] != INVALID_INDEX);
debug_printf(" input[%d] slot %u %s %u %s\n",
i,
linkage->input_map[i],
tgsi_semantic_names[inshader_info->input_semantic_name[i]],
inshader_info->input_semantic_index[i],
tgsi_interpolate_names[inshader_info->input_interpolate[i]]);
/* make sure no repeating register index */
if (reg & 1 << linkage->input_map[i]) {
assert(0);
}
reg |= 1 << linkage->input_map[i];
}
}
}
示例5: MAX3
template<class T> inline T MAX3(T a, T b, T c) { return MAX2(MAX2(a, b), c); }
示例6: copy_image_with_memcpy
static void
copy_image_with_memcpy(struct brw_context *brw,
struct intel_mipmap_tree *src_mt, int src_level,
int src_x, int src_y, int src_z,
struct intel_mipmap_tree *dst_mt, int dst_level,
int dst_x, int dst_y, int dst_z,
int src_width, int src_height)
{
bool same_slice;
void *mapped, *src_mapped, *dst_mapped;
ptrdiff_t src_stride, dst_stride, cpp;
int map_x1, map_y1, map_x2, map_y2;
GLuint src_bw, src_bh;
cpp = _mesa_get_format_bytes(src_mt->format);
_mesa_get_format_block_size(src_mt->format, &src_bw, &src_bh);
assert(src_width % src_bw == 0);
assert(src_height % src_bw == 0);
assert(src_x % src_bw == 0);
assert(src_y % src_bw == 0);
/* If we are on the same miptree, same level, and same slice, then
* intel_miptree_map won't let us map it twice. We have to do things a
* bit differently. In particular, we do a single map large enough for
* both portions and in read-write mode.
*/
same_slice = src_mt == dst_mt && src_level == dst_level && src_z == dst_z;
if (same_slice) {
assert(dst_x % src_bw == 0);
assert(dst_y % src_bw == 0);
map_x1 = MIN2(src_x, dst_x);
map_y1 = MIN2(src_y, dst_y);
map_x2 = MAX2(src_x, dst_x) + src_width;
map_y2 = MAX2(src_y, dst_y) + src_height;
intel_miptree_map(brw, src_mt, src_level, src_z,
map_x1, map_y1, map_x2 - map_x1, map_y2 - map_y1,
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
&mapped, &src_stride);
dst_stride = src_stride;
/* Set the offsets here so we don't have to think about while looping */
src_mapped = mapped + ((src_y - map_y1) / src_bh) * src_stride +
((src_x - map_x1) / src_bw) * cpp;
dst_mapped = mapped + ((dst_y - map_y1) / src_bh) * dst_stride +
((dst_x - map_x1) / src_bw) * cpp;
} else {
intel_miptree_map(brw, src_mt, src_level, src_z,
src_x, src_y, src_width, src_height,
GL_MAP_READ_BIT, &src_mapped, &src_stride);
intel_miptree_map(brw, dst_mt, dst_level, dst_z,
dst_x, dst_y, src_width, src_height,
GL_MAP_WRITE_BIT, &dst_mapped, &dst_stride);
}
src_width /= (int)src_bw;
src_height /= (int)src_bh;
for (int i = 0; i < src_height; ++i) {
memcpy(dst_mapped, src_mapped, src_width * cpp);
src_mapped += src_stride;
dst_mapped += dst_stride;
}
if (same_slice) {
intel_miptree_unmap(brw, src_mt, src_level, src_z);
} else {
intel_miptree_unmap(brw, dst_mt, dst_level, dst_z);
intel_miptree_unmap(brw, src_mt, src_level, src_z);
}
}
示例7: mirrorX
//.........这里部分代码省略.........
//
before = SysUtils::getCurrentMillis();
PROGRESS_BEGIN_MESSAGE("Sorting nodes' edges");
NBNodesEdgesSorter::sortNodesEdges(myNodeCont);
PROGRESS_TIME_MESSAGE(before);
myEdgeCont.computeLaneShapes();
//
before = SysUtils::getCurrentMillis();
PROGRESS_BEGIN_MESSAGE("Computing node shapes");
if (oc.exists("geometry.junction-mismatch-threshold")) {
myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
} else {
myNodeCont.computeNodeShapes();
}
PROGRESS_TIME_MESSAGE(before);
//
before = SysUtils::getCurrentMillis();
PROGRESS_BEGIN_MESSAGE("Computing edge shapes");
myEdgeCont.computeEdgeShapes();
PROGRESS_TIME_MESSAGE(before);
// resort edges based on the node and edge shapes
NBNodesEdgesSorter::sortNodesEdges(myNodeCont, true);
NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false);
// APPLY SPEED MODIFICATIONS
if (oc.exists("speed.offset")) {
const SUMOReal speedOffset = oc.getFloat("speed.offset");
const SUMOReal speedFactor = oc.getFloat("speed.factor");
if (speedOffset != 0 || speedFactor != 1 || oc.isSet("speed.minimum")) {
const SUMOReal speedMin = oc.isSet("speed.minimum") ? oc.getFloat("speed.minimum") : -std::numeric_limits<SUMOReal>::infinity();
before = SysUtils::getCurrentMillis();
PROGRESS_BEGIN_MESSAGE("Applying speed modifications");
for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
(*i).second->setSpeed(-1, MAX2((*i).second->getSpeed() * speedFactor + speedOffset, speedMin));
}
PROGRESS_TIME_MESSAGE(before);
}
}
// CONNECTIONS COMPUTATION
//
before = SysUtils::getCurrentMillis();
PROGRESS_BEGIN_MESSAGE("Computing node types");
NBNodeTypeComputer::computeNodeTypes(myNodeCont);
PROGRESS_TIME_MESSAGE(before);
//
bool haveCrossings = false;
if (oc.getBool("crossings.guess")) {
haveCrossings = true;
int crossings = 0;
for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
crossings += (*i).second->guessCrossings();
}
WRITE_MESSAGE("Guessed " + toString(crossings) + " pedestrian crossings.");
}
if (!haveCrossings) {
// recheck whether we had crossings in the input
for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
if (i->second->getCrossings().size() > 0) {
haveCrossings = true;
break;
}
}
}
if (oc.isDefault("no-internal-links") && !haveCrossings && myHaveLoadedNetworkWithoutInternalEdges) {
示例8: _mesa_program_resource_prop
unsigned
_mesa_program_resource_prop(struct gl_shader_program *shProg,
struct gl_program_resource *res, GLuint index,
const GLenum prop, GLint *val, const char *caller)
{
GET_CURRENT_CONTEXT(ctx);
#define VALIDATE_TYPE(type)\
if (res->Type != type)\
goto invalid_operation;
switch(prop) {
case GL_NAME_LENGTH:
if (res->Type == GL_ATOMIC_COUNTER_BUFFER)
goto invalid_operation;
/* Base name +3 if array '[0]' + terminator. */
*val = strlen(_mesa_program_resource_name(res)) +
(_mesa_program_resource_array_size(res) > 0 ? 3 : 0) + 1;
return 1;
case GL_TYPE:
switch (res->Type) {
case GL_UNIFORM:
*val = RESOURCE_UNI(res)->type->gl_type;
return 1;
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
*val = RESOURCE_VAR(res)->type->gl_type;
return 1;
case GL_TRANSFORM_FEEDBACK_VARYING:
*val = RESOURCE_XFB(res)->Type;
return 1;
default:
goto invalid_operation;
}
case GL_ARRAY_SIZE:
switch (res->Type) {
case GL_UNIFORM:
*val = MAX2(RESOURCE_UNI(res)->array_elements, 1);
return 1;
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
*val = MAX2(RESOURCE_VAR(res)->type->length, 1);
return 1;
case GL_TRANSFORM_FEEDBACK_VARYING:
*val = MAX2(RESOURCE_XFB(res)->Size, 1);
return 1;
default:
goto invalid_operation;
}
case GL_OFFSET:
VALIDATE_TYPE(GL_UNIFORM);
*val = RESOURCE_UNI(res)->offset;
return 1;
case GL_BLOCK_INDEX:
VALIDATE_TYPE(GL_UNIFORM);
*val = RESOURCE_UNI(res)->block_index;
return 1;
case GL_ARRAY_STRIDE:
VALIDATE_TYPE(GL_UNIFORM);
*val = RESOURCE_UNI(res)->array_stride;
return 1;
case GL_MATRIX_STRIDE:
VALIDATE_TYPE(GL_UNIFORM);
*val = RESOURCE_UNI(res)->matrix_stride;
return 1;
case GL_IS_ROW_MAJOR:
VALIDATE_TYPE(GL_UNIFORM);
*val = RESOURCE_UNI(res)->row_major;
return 1;
case GL_ATOMIC_COUNTER_BUFFER_INDEX:
VALIDATE_TYPE(GL_UNIFORM);
*val = RESOURCE_UNI(res)->atomic_buffer_index;
return 1;
case GL_BUFFER_BINDING:
case GL_BUFFER_DATA_SIZE:
case GL_NUM_ACTIVE_VARIABLES:
case GL_ACTIVE_VARIABLES:
return get_buffer_property(shProg, res, prop, val, caller);
case GL_REFERENCED_BY_COMPUTE_SHADER:
if (!_mesa_has_compute_shaders(ctx))
goto invalid_enum;
/* fallthrough */
case GL_REFERENCED_BY_VERTEX_SHADER:
case GL_REFERENCED_BY_GEOMETRY_SHADER:
case GL_REFERENCED_BY_FRAGMENT_SHADER:
switch (res->Type) {
case GL_UNIFORM:
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
case GL_UNIFORM_BLOCK:
case GL_ATOMIC_COUNTER_BUFFER:
*val = is_resource_referenced(shProg, res, index,
stage_from_enum(prop));
return 1;
default:
goto invalid_operation;
}
case GL_LOCATION:
switch (res->Type) {
case GL_UNIFORM:
//.........这里部分代码省略.........
示例9: vbo_split_prims
void vbo_split_prims( struct gl_context *ctx,
const struct gl_client_array *arrays[],
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
GLuint min_index,
GLuint max_index,
vbo_draw_func draw,
const struct split_limits *limits )
{
GLint max_basevertex = prim->basevertex;
GLuint i;
for (i = 1; i < nr_prims; i++)
max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
/* XXX max_basevertex is computed but not used, why? */
if (ib) {
if (limits->max_indices == 0) {
/* Could traverse the indices, re-emitting vertices in turn.
* But it's hard to see why this case would be needed - for
* software tnl, it is better to convert to non-indexed
* rendering after transformation is complete. Are there any devices
* with hardware tnl that cannot do indexed rendering?
*
* For now, this path is disabled.
*/
assert(0);
}
else if (max_index - min_index >= limits->max_verts) {
/* The vertex buffers are too large for hardware (or the
* swtnl module). Traverse the indices, re-emitting vertices
* in turn. Use a vertex cache to preserve some of the
* sharing from the original index list.
*/
vbo_split_copy(ctx, arrays, prim, nr_prims, ib,
draw, limits );
}
else if (ib->count > limits->max_indices) {
/* The index buffer is too large for hardware. Try to split
* on whole-primitive boundaries, otherwise try to split the
* individual primitives.
*/
vbo_split_inplace(ctx, arrays, prim, nr_prims, ib,
min_index, max_index, draw, limits );
}
else {
/* Why were we called? */
assert(0);
}
}
else {
if (max_index - min_index >= limits->max_verts) {
/* The vertex buffer is too large for hardware (or the swtnl
* module). Try to split on whole-primitive boundaries,
* otherwise try to split the individual primitives.
*/
vbo_split_inplace(ctx, arrays, prim, nr_prims, ib,
min_index, max_index, draw, limits );
}
else {
/* Why were we called? */
assert(0);
}
}
}
示例10: compute_blend_ref
static void
compute_blend_ref(const struct pipe_blend_state *blend,
const double *src,
const double *dst,
const double *con,
double *res)
{
double src_term[4];
double dst_term[4];
compute_blend_ref_term(blend->rt[0].rgb_src_factor, blend->rt[0].alpha_src_factor,
src, src, dst, con, src_term);
compute_blend_ref_term(blend->rt[0].rgb_dst_factor, blend->rt[0].alpha_dst_factor,
dst, src, dst, con, dst_term);
/*
* Combine RGB terms
*/
switch (blend->rt[0].rgb_func) {
case PIPE_BLEND_ADD:
res[0] = src_term[0] + dst_term[0]; /* R */
res[1] = src_term[1] + dst_term[1]; /* G */
res[2] = src_term[2] + dst_term[2]; /* B */
break;
case PIPE_BLEND_SUBTRACT:
res[0] = src_term[0] - dst_term[0]; /* R */
res[1] = src_term[1] - dst_term[1]; /* G */
res[2] = src_term[2] - dst_term[2]; /* B */
break;
case PIPE_BLEND_REVERSE_SUBTRACT:
res[0] = dst_term[0] - src_term[0]; /* R */
res[1] = dst_term[1] - src_term[1]; /* G */
res[2] = dst_term[2] - src_term[2]; /* B */
break;
case PIPE_BLEND_MIN:
res[0] = MIN2(src_term[0], dst_term[0]); /* R */
res[1] = MIN2(src_term[1], dst_term[1]); /* G */
res[2] = MIN2(src_term[2], dst_term[2]); /* B */
break;
case PIPE_BLEND_MAX:
res[0] = MAX2(src_term[0], dst_term[0]); /* R */
res[1] = MAX2(src_term[1], dst_term[1]); /* G */
res[2] = MAX2(src_term[2], dst_term[2]); /* B */
break;
default:
assert(0);
}
/*
* Combine A terms
*/
switch (blend->rt[0].alpha_func) {
case PIPE_BLEND_ADD:
res[3] = src_term[3] + dst_term[3]; /* A */
break;
case PIPE_BLEND_SUBTRACT:
res[3] = src_term[3] - dst_term[3]; /* A */
break;
case PIPE_BLEND_REVERSE_SUBTRACT:
res[3] = dst_term[3] - src_term[3]; /* A */
break;
case PIPE_BLEND_MIN:
res[3] = MIN2(src_term[3], dst_term[3]); /* A */
break;
case PIPE_BLEND_MAX:
res[3] = MAX2(src_term[3], dst_term[3]); /* A */
break;
default:
assert(0);
}
}
示例11: scale_by_NewRatio_aligned
// Minimum sizes of the generations may be different than
// the initial sizes. An inconsistency is permitted here
// in the total size that can be specified explicitly by
// command line specification of OldSize and NewSize and
// also a command line specification of -Xms. Issue a warning
// but allow the values to pass.
void GenCollectorPolicy::initialize_size_info() {
CollectorPolicy::initialize_size_info();
_initial_young_size = NewSize;
_max_young_size = MaxNewSize;
_initial_old_size = OldSize;
// Determine maximum size of the young generation.
if (FLAG_IS_DEFAULT(MaxNewSize)) {
_max_young_size = scale_by_NewRatio_aligned(_max_heap_byte_size);
// Bound the maximum size by NewSize below (since it historically
// would have been NewSize and because the NewRatio calculation could
// yield a size that is too small) and bound it by MaxNewSize above.
// Ergonomics plays here by previously calculating the desired
// NewSize and MaxNewSize.
_max_young_size = MIN2(MAX2(_max_young_size, _initial_young_size), MaxNewSize);
}
// Given the maximum young size, determine the initial and
// minimum young sizes.
if (_max_heap_byte_size == _initial_heap_byte_size) {
// The maximum and initial heap sizes are the same so the generation's
// initial size must be the same as it maximum size. Use NewSize as the
// size if set on command line.
_max_young_size = FLAG_IS_CMDLINE(NewSize) ? NewSize : _max_young_size;
_initial_young_size = _max_young_size;
// Also update the minimum size if min == initial == max.
if (_max_heap_byte_size == _min_heap_byte_size) {
_min_young_size = _max_young_size;
}
} else {
if (FLAG_IS_CMDLINE(NewSize)) {
// If NewSize is set on the command line, we should use it as
// the initial size, but make sure it is within the heap bounds.
_initial_young_size =
MIN2(_max_young_size, bound_minus_alignment(NewSize, _initial_heap_byte_size));
_min_young_size = bound_minus_alignment(_initial_young_size, _min_heap_byte_size);
} else {
// For the case where NewSize is not set on the command line, use
// NewRatio to size the initial generation size. Use the current
// NewSize as the floor, because if NewRatio is overly large, the resulting
// size can be too small.
_initial_young_size =
MIN2(_max_young_size, MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize));
}
}
log_trace(gc, heap)("1: Minimum young " SIZE_FORMAT " Initial young " SIZE_FORMAT " Maximum young " SIZE_FORMAT,
_min_young_size, _initial_young_size, _max_young_size);
// At this point the minimum, initial and maximum sizes
// of the overall heap and of the young generation have been determined.
// The maximum old size can be determined from the maximum young
// and maximum heap size since no explicit flags exist
// for setting the old generation maximum.
_max_old_size = MAX2(_max_heap_byte_size - _max_young_size, _gen_alignment);
// If no explicit command line flag has been set for the
// old generation size, use what is left.
if (!FLAG_IS_CMDLINE(OldSize)) {
// The user has not specified any value but the ergonomics
// may have chosen a value (which may or may not be consistent
// with the overall heap size). In either case make
// the minimum, maximum and initial sizes consistent
// with the young sizes and the overall heap sizes.
_min_old_size = _gen_alignment;
_initial_old_size = MIN2(_max_old_size, MAX2(_initial_heap_byte_size - _initial_young_size, _min_old_size));
// _max_old_size has already been made consistent above.
} else {
// OldSize has been explicitly set on the command line. Use it
// for the initial size but make sure the minimum allow a young
// generation to fit as well.
// If the user has explicitly set an OldSize that is inconsistent
// with other command line flags, issue a warning.
// The generation minimums and the overall heap minimum should
// be within one generation alignment.
if (_initial_old_size > _max_old_size) {
log_warning(gc, ergo)("Inconsistency between maximum heap size and maximum "
"generation sizes: using maximum heap = " SIZE_FORMAT
", -XX:OldSize flag is being ignored",
_max_heap_byte_size);
_initial_old_size = _max_old_size;
}
_min_old_size = MIN2(_initial_old_size, _min_heap_byte_size - _min_young_size);
}
// The initial generation sizes should match the initial heap size,
// if not issue a warning and resize the generations. This behavior
// differs from JDK8 where the generation sizes have higher priority
// than the initial heap size.
//.........这里部分代码省略.........
示例12: assert
void GenCollectorPolicy::initialize_flags() {
CollectorPolicy::initialize_flags();
assert(_gen_alignment != 0, "Generation alignment not set up properly");
assert(_heap_alignment >= _gen_alignment,
"heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT,
_heap_alignment, _gen_alignment);
assert(_gen_alignment % _space_alignment == 0,
"gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
_gen_alignment, _space_alignment);
assert(_heap_alignment % _gen_alignment == 0,
"heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT,
_heap_alignment, _gen_alignment);
// All generational heaps have a young gen; handle those flags here
// Make sure the heap is large enough for two generations
size_t smallest_new_size = young_gen_size_lower_bound();
size_t smallest_heap_size = align_size_up(smallest_new_size + old_gen_size_lower_bound(),
_heap_alignment);
if (MaxHeapSize < smallest_heap_size) {
FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size);
_max_heap_byte_size = MaxHeapSize;
}
// If needed, synchronize _min_heap_byte size and _initial_heap_byte_size
if (_min_heap_byte_size < smallest_heap_size) {
_min_heap_byte_size = smallest_heap_size;
if (InitialHeapSize < _min_heap_byte_size) {
FLAG_SET_ERGO(size_t, InitialHeapSize, smallest_heap_size);
_initial_heap_byte_size = smallest_heap_size;
}
}
// Make sure NewSize allows an old generation to fit even if set on the command line
if (FLAG_IS_CMDLINE(NewSize) && NewSize >= _initial_heap_byte_size) {
log_warning(gc, ergo)("NewSize was set larger than initial heap size, will use initial heap size.");
FLAG_SET_ERGO(size_t, NewSize, bound_minus_alignment(NewSize, _initial_heap_byte_size));
}
// Now take the actual NewSize into account. We will silently increase NewSize
// if the user specified a smaller or unaligned value.
size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize);
bounded_new_size = MAX2(smallest_new_size, (size_t)align_size_down(bounded_new_size, _gen_alignment));
if (bounded_new_size != NewSize) {
FLAG_SET_ERGO(size_t, NewSize, bounded_new_size);
}
_min_young_size = smallest_new_size;
_initial_young_size = NewSize;
if (!FLAG_IS_DEFAULT(MaxNewSize)) {
if (MaxNewSize >= MaxHeapSize) {
// Make sure there is room for an old generation
size_t smaller_max_new_size = MaxHeapSize - _gen_alignment;
if (FLAG_IS_CMDLINE(MaxNewSize)) {
log_warning(gc, ergo)("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "
"heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.",
MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
}
FLAG_SET_ERGO(size_t, MaxNewSize, smaller_max_new_size);
if (NewSize > MaxNewSize) {
FLAG_SET_ERGO(size_t, NewSize, MaxNewSize);
_initial_young_size = NewSize;
}
} else if (MaxNewSize < _initial_young_size) {
FLAG_SET_ERGO(size_t, MaxNewSize, _initial_young_size);
} else if (!is_size_aligned(MaxNewSize, _gen_alignment)) {
FLAG_SET_ERGO(size_t, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));
}
_max_young_size = MaxNewSize;
}
if (NewSize > MaxNewSize) {
// At this point this should only happen if the user specifies a large NewSize and/or
// a small (but not too small) MaxNewSize.
if (FLAG_IS_CMDLINE(MaxNewSize)) {
log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
"A new max generation size of " SIZE_FORMAT "k will be used.",
NewSize/K, MaxNewSize/K, NewSize/K);
}
FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
_max_young_size = MaxNewSize;
}
if (SurvivorRatio < 1 || NewRatio < 1) {
vm_exit_during_initialization("Invalid young gen ratio specified");
}
if (OldSize < old_gen_size_lower_bound()) {
FLAG_SET_ERGO(size_t, OldSize, old_gen_size_lower_bound());
}
if (!is_size_aligned(OldSize, _gen_alignment)) {
FLAG_SET_ERGO(size_t, OldSize, align_size_down(OldSize, _gen_alignment));
}
if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {
// NewRatio will be used later to set the young generation size so we use
// it to calculate how big the heap should be based on the requested OldSize
// and NewRatio.
assert(NewRatio > 0, "NewRatio should have been set up earlier");
size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
//.........这里部分代码省略.........
示例13: vc4_emit_gl_shader_state
static void
vc4_emit_gl_shader_state(struct vc4_context *vc4,
const struct pipe_draw_info *info,
uint32_t extra_index_bias)
{
struct vc4_job *job = vc4->job;
/* VC4_DIRTY_VTXSTATE */
struct vc4_vertex_stateobj *vtx = vc4->vtx;
/* VC4_DIRTY_VTXBUF */
struct vc4_vertexbuf_stateobj *vertexbuf = &vc4->vertexbuf;
/* The simulator throws a fit if VS or CS don't read an attribute, so
* we emit a dummy read.
*/
uint32_t num_elements_emit = MAX2(vtx->num_elements, 1);
/* Emit the shader record. */
struct vc4_cl_out *shader_rec =
cl_start_shader_reloc(&job->shader_rec, 3 + num_elements_emit);
/* VC4_DIRTY_PRIM_MODE | VC4_DIRTY_RASTERIZER */
cl_u16(&shader_rec,
VC4_SHADER_FLAG_ENABLE_CLIPPING |
(vc4->prog.fs->fs_threaded ?
0 : VC4_SHADER_FLAG_FS_SINGLE_THREAD) |
((info->mode == PIPE_PRIM_POINTS &&
vc4->rasterizer->base.point_size_per_vertex) ?
VC4_SHADER_FLAG_VS_POINT_SIZE : 0));
/* VC4_DIRTY_COMPILED_FS */
cl_u8(&shader_rec, 0); /* fs num uniforms (unused) */
cl_u8(&shader_rec, vc4->prog.fs->num_inputs);
cl_reloc(job, &job->shader_rec, &shader_rec, vc4->prog.fs->bo, 0);
cl_u32(&shader_rec, 0); /* UBO offset written by kernel */
/* VC4_DIRTY_COMPILED_VS */
cl_u16(&shader_rec, 0); /* vs num uniforms */
cl_u8(&shader_rec, vc4->prog.vs->vattrs_live);
cl_u8(&shader_rec, vc4->prog.vs->vattr_offsets[8]);
cl_reloc(job, &job->shader_rec, &shader_rec, vc4->prog.vs->bo, 0);
cl_u32(&shader_rec, 0); /* UBO offset written by kernel */
/* VC4_DIRTY_COMPILED_CS */
cl_u16(&shader_rec, 0); /* cs num uniforms */
cl_u8(&shader_rec, vc4->prog.cs->vattrs_live);
cl_u8(&shader_rec, vc4->prog.cs->vattr_offsets[8]);
cl_reloc(job, &job->shader_rec, &shader_rec, vc4->prog.cs->bo, 0);
cl_u32(&shader_rec, 0); /* UBO offset written by kernel */
uint32_t max_index = 0xffff;
for (int i = 0; i < vtx->num_elements; i++) {
struct pipe_vertex_element *elem = &vtx->pipe[i];
struct pipe_vertex_buffer *vb =
&vertexbuf->vb[elem->vertex_buffer_index];
struct vc4_resource *rsc = vc4_resource(vb->buffer);
/* not vc4->dirty tracked: vc4->last_index_bias */
uint32_t offset = (vb->buffer_offset +
elem->src_offset +
vb->stride * (info->index_bias +
extra_index_bias));
uint32_t vb_size = rsc->bo->size - offset;
uint32_t elem_size =
util_format_get_blocksize(elem->src_format);
cl_reloc(job, &job->shader_rec, &shader_rec, rsc->bo, offset);
cl_u8(&shader_rec, elem_size - 1);
cl_u8(&shader_rec, vb->stride);
cl_u8(&shader_rec, vc4->prog.vs->vattr_offsets[i]);
cl_u8(&shader_rec, vc4->prog.cs->vattr_offsets[i]);
if (vb->stride > 0) {
max_index = MIN2(max_index,
(vb_size - elem_size) / vb->stride);
}
}
if (vtx->num_elements == 0) {
assert(num_elements_emit == 1);
struct vc4_bo *bo = vc4_bo_alloc(vc4->screen, 4096, "scratch VBO");
cl_reloc(job, &job->shader_rec, &shader_rec, bo, 0);
cl_u8(&shader_rec, 16 - 1); /* element size */
cl_u8(&shader_rec, 0); /* stride */
cl_u8(&shader_rec, 0); /* VS VPM offset */
cl_u8(&shader_rec, 0); /* CS VPM offset */
vc4_bo_unreference(&bo);
}
cl_end(&job->shader_rec, shader_rec);
struct vc4_cl_out *bcl = cl_start(&job->bcl);
/* the actual draw call. */
cl_u8(&bcl, VC4_PACKET_GL_SHADER_STATE);
assert(vtx->num_elements <= 8);
/* Note that number of attributes == 0 in the packet means 8
* attributes. This field also contains the offset into shader_rec.
*/
cl_u32(&bcl, num_elements_emit & 0x7);
cl_end(&job->bcl, bcl);
vc4_write_uniforms(vc4, vc4->prog.fs,
&vc4->constbuf[PIPE_SHADER_FRAGMENT],
&vc4->fragtex);
vc4_write_uniforms(vc4, vc4->prog.vs,
//.........这里部分代码省略.........
示例14: _mesa_reallocate_registers
/**
* This function implements "Linear Scan Register Allocation" to reduce
* the number of temporary registers used by the program.
*
* We compute the "live interval" for all temporary registers then
* examine the overlap of the intervals to allocate new registers.
* Basically, if two intervals do not overlap, they can use the same register.
*/
static void
_mesa_reallocate_registers(struct gl_program *prog)
{
struct interval_list liveIntervals;
GLint registerMap[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
GLboolean usedRegs[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
GLuint i;
GLint maxTemp = -1;
if (dbg) {
printf("Optimize: Begin live-interval register reallocation\n");
_mesa_print_program(prog);
}
for (i = 0; i < REG_ALLOCATE_MAX_PROGRAM_TEMPS; i++){
registerMap[i] = -1;
usedRegs[i] = GL_FALSE;
}
if (!find_live_intervals(prog, &liveIntervals)) {
if (dbg)
printf("Aborting register reallocation\n");
return;
}
{
struct interval_list activeIntervals;
activeIntervals.Num = 0;
/* loop over live intervals, allocating a new register for each */
for (i = 0; i < liveIntervals.Num; i++) {
const struct interval *live = liveIntervals.Intervals + i;
if (dbg)
printf("Consider register %u\n", live->Reg);
/* Expire old intervals. Intervals which have ended with respect
* to the live interval can have their remapped registers freed.
*/
{
GLint j;
for (j = 0; j < (GLint) activeIntervals.Num; j++) {
const struct interval *inv = activeIntervals.Intervals + j;
if (inv->End >= live->Start) {
/* Stop now. Since the activeInterval list is sorted
* we know we don't have to go further.
*/
break;
}
else {
/* Interval 'inv' has expired */
const GLint regNew = registerMap[inv->Reg];
ASSERT(regNew >= 0);
if (dbg)
printf(" expire interval for reg %u\n", inv->Reg);
/* remove interval j from active list */
remove_interval(&activeIntervals, inv);
j--; /* counter-act j++ in for-loop above */
/* return register regNew to the free pool */
if (dbg)
printf(" free reg %d\n", regNew);
ASSERT(usedRegs[regNew] == GL_TRUE);
usedRegs[regNew] = GL_FALSE;
}
}
}
/* find a free register for this live interval */
{
const GLint k = alloc_register(usedRegs);
if (k < 0) {
/* out of registers, give up */
return;
}
registerMap[live->Reg] = k;
maxTemp = MAX2(maxTemp, k);
if (dbg)
printf(" remap register %u -> %d\n", live->Reg, k);
}
/* Insert this live interval into the active list which is sorted
* by increasing end points.
*/
insert_interval_by_end(&activeIntervals, live);
}
}
if (maxTemp + 1 < (GLint) liveIntervals.Num) {
/* OK, we've reduced the number of registers needed.
//.........这里部分代码省略.........
示例15: ocean_texture
/* ***** actual texture sampling ***** */
int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres)
{
OceanTex *ot = tex->ot;
ModifierData *md;
OceanModifierData *omd;
texres->tin = 0.0f;
if ( !(ot) ||
!(ot->object) ||
!(md = (ModifierData *)modifiers_findByType(ot->object, eModifierType_Ocean)) ||
!(omd = (OceanModifierData *)md)->ocean)
{
return 0;
}
else {
const int do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
int cfra = R.r.cfra;
int retval = TEX_INT;
OceanResult ocr;
const float u = 0.5f + 0.5f * texvec[0];
const float v = 0.5f + 0.5f * texvec[1];
if (omd->oceancache && omd->cached == true) {
CLAMP(cfra, omd->bakestart, omd->bakeend);
cfra -= omd->bakestart; /* shift to 0 based */
BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
}
else { /* non-cached */
if (G.is_rendering)
BKE_ocean_eval_uv_catrom(omd->ocean, &ocr, u, v);
else
BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
ocr.foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage);
}
switch (ot->output) {
case TEX_OCN_DISPLACEMENT:
/* XYZ displacement */
texres->tr = 0.5f + 0.5f * ocr.disp[0];
texres->tg = 0.5f + 0.5f * ocr.disp[2];
texres->tb = 0.5f + 0.5f * ocr.disp[1];
texres->tr = MAX2(0.0f, texres->tr);
texres->tg = MAX2(0.0f, texres->tg);
texres->tb = MAX2(0.0f, texres->tb);
BRICONTRGB;
retval = TEX_RGB;
break;
case TEX_OCN_EMINUS:
/* -ve eigenvectors ? */
texres->tr = ocr.Eminus[0];
texres->tg = ocr.Eminus[2];
texres->tb = ocr.Eminus[1];
retval = TEX_RGB;
break;
case TEX_OCN_EPLUS:
/* -ve eigenvectors ? */
texres->tr = ocr.Eplus[0];
texres->tg = ocr.Eplus[2];
texres->tb = ocr.Eplus[1];
retval = TEX_RGB;
break;
case TEX_OCN_JPLUS:
texres->tin = ocr.Jplus;
retval = TEX_INT;
break;
case TEX_OCN_FOAM:
texres->tin = ocr.foam;
BRICONT;
retval = TEX_INT;
break;
}
/* if normals needed */
if (texres->nor && do_normals) {
normalize_v3_v3(texres->nor, ocr.normal);
retval |= TEX_NOR;
}
texres->ta = 1.0f;
return retval;
//.........这里部分代码省略.........