GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl) : GrGpuGL(gl, get_binding_in_use(gl)) { GrGLProgram::GLSLVersion glslVersion = get_glsl_version(this->glBinding(), gl); // Enable supported shader-releated caps fCaps.fShaderSupport = true; fCaps.fSupportPerVertexCoverage = true; if (kDesktop_GrGLBinding == this->glBinding()) { fCaps.fDualSourceBlendingSupport = this->glVersion() >= GR_GL_VER(3,3) || this->hasExtension("GL_ARB_blend_func_extended"); fCaps.fShaderDerivativeSupport = true; // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS fCaps.fGeometryShaderSupport = this->glVersion() >= GR_GL_VER(3,2) && glslVersion >= GrGLProgram::k150_GLSLVersion; } else { fCaps.fShaderDerivativeSupport = this->hasExtension("GL_OES_standard_derivatives"); } GR_GL_GetIntegerv(gl, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttribs); fProgramData = NULL; fProgramCache = new ProgramCache(gl, glslVersion); #if 0 this->programUnitTest(); #endif }
/** * Initializes potential list of extensions if ctx == NULL, or actually enables * extensions for a context. */ void intelInitExtensions(struct gl_context *ctx) { struct intel_context *intel = intel_context(ctx); driInitExtensions(ctx, card_extensions, GL_FALSE); _mesa_map_function_array(GL_VERSION_2_1_functions); ctx->Const.GLSLVersion = get_glsl_version(); if (intel->gen >= 5) driInitExtensions(ctx, ironlake_extensions, GL_FALSE); if (intel->gen >= 4) driInitExtensions(ctx, brw_extensions, GL_FALSE); if (intel->gen == 3) { driInitExtensions(ctx, i915_extensions, GL_FALSE); if (driQueryOptionb(&intel->optionCache, "fragment_shader")) driInitExtensions(ctx, fragment_shader_extensions, GL_FALSE); if (driQueryOptionb(&intel->optionCache, "stub_occlusion_query")) driInitExtensions(ctx, arb_oq_extensions, GL_FALSE); } }
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; }