Example #1
0
void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties, uint32_t featureFlags) {
    GrShaderCaps* shaderCaps = fShaderCaps.get();
    shaderCaps->fVersionDeclString = "#version 330\n";


    // fConfigOutputSwizzle will default to RGBA so we only need to set it for alpha only config.
    for (int i = 0; i < kGrPixelConfigCnt; ++i) {
        GrPixelConfig config = static_cast<GrPixelConfig>(i);
        if (GrPixelConfigIsAlphaOnly(config)) {
            shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRR();
            shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
        } else {
            if (kGray_8_GrPixelConfig == config) {
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRA();
            } else if (kRGBA_4444_GrPixelConfig == config) {
                // The vulkan spec does not require R4G4B4A4 to be supported for texturing so we
                // store the data in a B4G4R4A4 texture and then swizzle it when doing texture reads
                // or writing to outputs. Since we're not actually changing the data at all, the
                // only extra work is the swizzle in the shader for all operations.
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::BGRA();
                shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::BGRA();
            } else {
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGBA();
            }
        }
    }

    if (kImagination_VkVendor == properties.vendorID) {
        shaderCaps->fAtan2ImplementedAsAtanYOverX = true;
    }

    // Vulkan is based off ES 3.0 so the following should all be supported
    shaderCaps->fUsesPrecisionModifiers = true;
    shaderCaps->fFlatInterpolationSupport = true;

    // GrShaderCaps

    shaderCaps->fShaderDerivativeSupport = true;
    shaderCaps->fGeometryShaderSupport = SkToBool(featureFlags & kGeometryShader_GrVkFeatureFlag);

    shaderCaps->fDualSourceBlendingSupport = SkToBool(featureFlags & kDualSrcBlend_GrVkFeatureFlag);
    if (kAMD_VkVendor == properties.vendorID) {
        // Currently DualSourceBlending is not working on AMD. vkCreateGraphicsPipeline fails when
        // using a draw with dual source. Looking into whether it is driver bug or issue with our
        // SPIR-V. Bug skia:6405
        shaderCaps->fDualSourceBlendingSupport = false;
    }

    shaderCaps->fIntegerSupport = true;
    shaderCaps->fTexelBufferSupport = true;
    shaderCaps->fTexelFetchSupport = true;
    shaderCaps->fVertexIDSupport = true;

    // Assume the minimum precisions mandated by the SPIR-V spec.
    shaderCaps->fShaderPrecisionVaries = true;
    for (int s = 0; s < kGrShaderTypeCount; ++s) {
        auto& highp = shaderCaps->fFloatPrecisions[s][kHigh_GrSLPrecision];
        highp.fLogRangeLow = highp.fLogRangeHigh = 127;
        highp.fBits = 23;

        auto& mediump = shaderCaps->fFloatPrecisions[s][kMedium_GrSLPrecision];
        mediump.fLogRangeLow = mediump.fLogRangeHigh = 14;
        mediump.fBits = 10;

        shaderCaps->fFloatPrecisions[s][kLow_GrSLPrecision] = mediump;
    }
    shaderCaps->initSamplerPrecisionTable();

    shaderCaps->fMaxVertexSamplers =
    shaderCaps->fMaxGeometrySamplers =
    shaderCaps->fMaxFragmentSamplers = SkTMin(
                                       SkTMin(properties.limits.maxPerStageDescriptorSampledImages,
                                              properties.limits.maxPerStageDescriptorSamplers),
                                              (uint32_t)INT_MAX);
    shaderCaps->fMaxCombinedSamplers = SkTMin(
                                       SkTMin(properties.limits.maxDescriptorSetSampledImages,
                                              properties.limits.maxDescriptorSetSamplers),
                                              (uint32_t)INT_MAX);
}