void copy_val(int a[], int n, int m) { int i; for(i = 0; i < n; i++) a[i] = random_val(m); }
/* * gen_vals - Generate the integer values we'll use to test a function */ static int gen_vals(int test_vals[], int min, int max, int test_range, int arg) { int i; int test_count = 0; /* Special case: If the user has specified a specific function argument using the -1, -2, or -3 flags, then simply use this argument and return */ if (has_arg[arg]) { test_vals[0] = argval[arg]; return 1; } /* * Special case: Generate test vals for floating point functions * where the input argument is an unsigned bit-level * representation of a float. For this case we want to test the * regions around zero, the smallest normalized and largest * denormalized numbers, one, and the largest normalized number, * as well as inf and nan. */ if ((min == 1 && max == 1)) { unsigned smallest_norm = 0x00800000; unsigned one = 0x3f800000; unsigned largest_norm = 0x7f000000; unsigned inf = 0x7f800000; unsigned nan = 0x7fc00000; unsigned sign = 0x80000000; /* Test range should be at most 1/2 the range of one exponent value */ if (test_range > (1 << 23)) { test_range = 1 << 23; } /* Functions where the input argument is an unsigned bit-level representation of a float. The number of tests generated inside this loop body is the value k referenced in the comment for the global variable MAX_TEST_VALS. */ for (i = 0; i < test_range; i++) { /* Denorms around zero */ test_vals[test_count++] = i; test_vals[test_count++] = sign | i; /* Region around norm to denorm transition */ test_vals[test_count++] = smallest_norm + i; test_vals[test_count++] = smallest_norm - i; test_vals[test_count++] = sign | (smallest_norm + i); test_vals[test_count++] = sign | (smallest_norm - i); /* Region around one */ test_vals[test_count++] = one + i; test_vals[test_count++] = one - i; test_vals[test_count++] = sign | (one + i); test_vals[test_count++] = sign | (one - i); /* Region below largest norm */ test_vals[test_count++] = largest_norm - i; test_vals[test_count++] = sign | (largest_norm - i); } /* special vals */ test_vals[test_count++] = inf; /* inf */ test_vals[test_count++] = sign | inf; /* -inf */ test_vals[test_count++] = nan; /* nan */ test_vals[test_count++] = sign | nan; /* -nan */ return test_count; } /* * Normal case: Generate test vals for integer functions */ /* If the range is small enough, then do exhaustively */ if (max - MAX_TEST_VALS <= min) { for (i = min; i <= max; i++) test_vals[test_count++] = i; return test_count; } /* Otherwise, need to sample. Do so near the boundaries, around zero, and for some random cases. */ for (i = 0; i < test_range; i++) { /* Test around the boundaries */ test_vals[test_count++] = min + i; test_vals[test_count++] = max - i; /* If zero falls between min and max, then also test around zero */ if (i >= min && i <= max) test_vals[test_count++] = i; if (-i >= min && -i <= max) test_vals[test_count++] = -i; /* Random case between min and max */ test_vals[test_count++] = random_val(min, max); } return test_count; }
bool GrGpuGLShaders::programUnitTest() { GrGLProgram::GLSLVersion glslVersion = get_glsl_version(this->glBinding(), this->glInterface()); static const int STAGE_OPTS[] = { 0, StageDesc::kNoPerspective_OptFlagBit, StageDesc::kIdentity_CoordMapping }; GrGLProgram program; ProgramDesc& pdesc = program.fProgramDesc; static const int NUM_TESTS = 512; // GrRandoms nextU() values have patterns in the low bits // So using nextU() % array_count might never take some values. GrRandom random; for (int t = 0; t < NUM_TESTS; ++t) { #if 0 GrPrintf("\nTest Program %d\n-------------\n", t); static const int stop = -1; if (t == stop) { int breakpointhere = 9; } #endif pdesc.fVertexLayout = 0; pdesc.fEmitsPointSize = random.nextF() > .5f; pdesc.fColorType = static_cast<int>(random.nextF() * ProgramDesc::kColorTypeCnt); int idx = (int)(random.nextF() * (SkXfermode::kCoeffModesCnt)); pdesc.fColorFilterXfermode = (SkXfermode::Mode)idx; idx = (int)(random.nextF() * (GrDrawState::kNumStages + 1)); pdesc.fFirstCoverageStage = idx; pdesc.fVertexLayout |= (random.nextF() > .5f) ? GrDrawTarget::kCoverage_VertexLayoutBit : 0; #if GR_GL_EXPERIMENTAL_GS pdesc.fExperimentalGS = this->getCaps().fGeometryShaderSupport && random.nextF() > .5f; #endif bool edgeAA = random.nextF() > .5f; if (edgeAA) { bool vertexEdgeAA = random.nextF() > .5f; if (vertexEdgeAA) { pdesc.fVertexLayout |= GrDrawTarget::kEdge_VertexLayoutBit; if (this->getCaps().fShaderDerivativeSupport) { pdesc.fVertexEdgeType = random.nextF() > 0.5f ? GrDrawState::kHairQuad_EdgeType : GrDrawState::kHairLine_EdgeType; } else { pdesc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType; } pdesc.fEdgeAANumEdges = 0; } else { pdesc.fEdgeAANumEdges = static_cast<int>(1 + random.nextF() * this->getMaxEdges()); pdesc.fEdgeAAConcave = random.nextF() > .5f; } } else { pdesc.fEdgeAANumEdges = 0; } if (this->getCaps().fDualSourceBlendingSupport) { pdesc.fDualSrcOutput = (ProgramDesc::DualSrcOutput) (int)(random.nextF() * ProgramDesc::kDualSrcOutputCnt); } else { pdesc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput; } for (int s = 0; s < GrDrawState::kNumStages; ++s) { // enable the stage? if (random.nextF() > .5f) { // use separate tex coords? if (random.nextF() > .5f) { int t = (int)(random.nextF() * GrDrawState::kMaxTexCoords); pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t); } else { pdesc.fVertexLayout |= StagePosAsTexCoordVertexLayoutBit(s); } } // use text-formatted verts? if (random.nextF() > .5f) { pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit; } idx = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS)); StageDesc& stage = pdesc.fStages[s]; stage.fOptFlags = STAGE_OPTS[idx]; stage.fModulation = random_val(&random, StageDesc::kModulationCnt); stage.fCoordMapping = random_val(&random, StageDesc::kCoordMappingCnt); stage.fFetchMode = random_val(&random, StageDesc::kFetchModeCnt); // convolution shaders don't work with persp tex matrix if (stage.fFetchMode == StageDesc::kConvolution_FetchMode) { stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit; } stage.setEnabled(VertexUsesStage(s, pdesc.fVertexLayout)); stage.fKernelWidth = static_cast<int8_t>(4 * random.nextF() + 2); } CachedData cachedData; if (!program.genProgram(this->glInterface(), glslVersion, &cachedData)) { return false; } DeleteProgram(this->glInterface(), &cachedData); } return true; }