示例#1
0
/**
 * A function which emits a meta key into the key builder.  This is required because shader code may
 * be dependent on properties of the effect that the effect itself doesn't use
 * in its key (e.g. the pixel format of textures used). So we create a meta-key for
 * every effect using this function. It is also responsible for inserting the effect's class ID
 * which must be different for every GrProcessor subclass. It can fail if an effect uses too many
 * textures, transforms, etc, for the space allotted in the meta-key.  NOTE, both FPs and GPs share
 * this function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
 */
static bool get_meta_key(const GrProcessor& proc,
                         const GrGLCaps& caps,
                         uint32_t transformKey,
                         uint32_t attribKey,
                         GrProcessorKeyBuilder* b,
                         uint16_t* processorKeySize) {
    const GrBackendProcessorFactory& factory = proc.getFactory();
    factory.getGLProcessorKey(proc, caps, b);
    size_t size = b->size();
    if (size > SK_MaxU16) {
        *processorKeySize = 0; // suppresses a warning.
        return false;
    }
    *processorKeySize = SkToU16(size);
    uint32_t textureKey = gen_texture_key(proc, caps);
    uint32_t classID = proc.getFactory().classID();

    // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
    // don't fit.
    static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
    if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) {
        return false;
    }

    uint32_t* key = b->add32n(2);
    key[0] = (textureKey << 16 | transformKey);
    key[1] = (classID << 16);
    return true;
}
示例#2
0
static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrProcessor& proc,
                             const GrGLSLCaps& caps) {
    int numTextures = proc.numTextures();
    int numSamplers = numTextures + proc.numBuffers();
    // Need two bytes per key (swizzle, sampler type, and precision).
    int word32Count = (numSamplers + 1) / 2;
    if (0 == word32Count) {
        return;
    }
    uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count));
    int i = 0;
    for (; i < numTextures; ++i) {
        const GrTextureAccess& access = proc.textureAccess(i);
        const GrTexture* tex = access.getTexture();
        k16[i] = sampler_key(tex->samplerType(), tex->config(), access.getVisibility(), caps);
    }
    for (; i < numSamplers; ++i) {
        const GrBufferAccess& access = proc.bufferAccess(i - numTextures);
        k16[i] = sampler_key(kSamplerBuffer_GrSLType, access.texelConfig(), access.visibility(),
                             caps);
    }
    // zero the last 16 bits if the number of samplers is odd.
    if (numSamplers & 0x1) {
        k16[numSamplers] = 0;
    }
}
static void prepare_sampled_images(const GrProcessor& processor, GrVkGpu* gpu) {
    for (int i = 0; i < processor.numTextures(); ++i) {
        const GrTextureAccess& texAccess = processor.textureAccess(i);
        GrVkTexture* vkTexture = static_cast<GrVkTexture*>(processor.texture(i));
        SkASSERT(vkTexture);

        // We may need to resolve the texture first if it is also a render target
        GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
        if (texRT) {
            gpu->onResolveRenderTarget(texRT);
        }

        const GrTextureParams& params = texAccess.getParams();
        // Check if we need to regenerate any mip maps
        if (GrTextureParams::kMipMap_FilterMode == params.filterMode()) {
            if (vkTexture->texturePriv().mipMapsAreDirty()) {
                gpu->generateMipmap(vkTexture);
                vkTexture->texturePriv().dirtyMipMaps(false);
            }
        }

        // TODO: If we ever decide to create the secondary command buffers ahead of time before we
        // are actually going to submit them, we will need to track the sampled images and delay
        // adding the layout change/barrier until we are ready to submit.
        vkTexture->setImageLayout(gpu,
                                  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                                  VK_ACCESS_SHADER_READ_BIT,
                                  VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
                                  false);
    }
}
示例#4
0
void GrGLProgram::generateMipmaps(const GrProcessor& processor,
                                  bool allowSRGBInputs) {
    for (int i = 0; i < processor.numTextures(); ++i) {
        const GrTextureAccess& access = processor.textureAccess(i);
        fGpu->generateMipmaps(access.getParams(), allowSRGBInputs,
                              static_cast<GrGLTexture*>(access.getTexture()));
    }
}
示例#5
0
static void append_texture_bindings(const GrProcessor& processor,
                                    SkTArray<const GrTextureAccess*>* textureBindings) {
    if (int numTextures = processor.numTextures()) {
        const GrTextureAccess** bindings = textureBindings->push_back_n(numTextures);
        int i = 0;
        do {
            bindings[i] = &processor.textureAccess(i);
        } while (++i < numTextures);
    }
}
示例#6
0
bool GrProcessor::hasSameTextureAccesses(const GrProcessor& that) const {
    if (this->numTextures() != that.numTextures()) {
        return false;
    }
    for (int i = 0; i < this->numTextures(); ++i) {
        if (this->textureAccess(i) != that.textureAccess(i)) {
            return false;
        }
    }
    return true;
}
示例#7
0
static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) {
    uint32_t key = 0;
    int numTextures = proc.numTextures();
    for (int t = 0; t < numTextures; ++t) {
        const GrTextureAccess& access = proc.textureAccess(t);
        uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
        if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
            key |= 1 << t;
        }
    }
    return key;
}
示例#8
0
void GrGLProgram::bindTextures(const GrGLInstalledProc* ip, const GrProcessor& processor) {
    const SkTArray<GrGLInstalledProc::Sampler, true>& samplers = ip->fSamplers;
    int numSamplers = samplers.count();
    SkASSERT(numSamplers == processor.numTextures());
    for (int s = 0; s < numSamplers; ++s) {
        SkASSERT(samplers[s].fTextureUnit >= 0);
        const GrTextureAccess& textureAccess = processor.textureAccess(s);
        fGpu->bindTexture(samplers[s].fTextureUnit,
                          textureAccess.getParams(),
                          static_cast<GrGLTexture*>(textureAccess.getTexture()));
    }
}
示例#9
0
void GrGLProgram::bindTextures(const GrProcessor& processor,
                               bool allowSRGBInputs,
                               int* nextSamplerIdx) {
    for (int i = 0; i < processor.numTextures(); ++i) {
        const GrTextureAccess& access = processor.textureAccess(i);
        fGpu->bindTexture((*nextSamplerIdx)++, access.getParams(),
                          allowSRGBInputs, static_cast<GrGLTexture*>(access.getTexture()));
    }
    for (int i = 0; i < processor.numBuffers(); ++i) {
        const GrBufferAccess& access = processor.bufferAccess(i);
        fGpu->bindTexelBuffer((*nextSamplerIdx)++, access.offsetInBytes(), access.texelConfig(),
                              static_cast<GrGLBuffer*>(access.buffer()));
    }
}
示例#10
0
void GrVkProgramBuilder::emitSamplers(const GrProcessor& processor,
                                      GrGLSLTextureSampler::TextureSamplerArray* outSamplers) {
    int numTextures = processor.numTextures();
    UniformHandle* localSamplerUniforms = fSamplerUniforms.push_back_n(numTextures);
    SkString name;
    for (int t = 0; t < numTextures; ++t) {
        name.printf("%d", t);
        localSamplerUniforms[t]  =
            fUniformHandler.addUniform(kFragment_GrShaderFlag,
                                       kSampler2D_GrSLType, kDefault_GrSLPrecision,
                                       name.c_str());
        outSamplers->emplace_back(localSamplerUniforms[t], processor.textureAccess(t));
    }
}
void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
                                      GrGLProcessor::TextureSamplerArray* outSamplers,
                                      GrGLInstalledProc<Proc>* ip) {
    int numTextures = processor.numTextures();
    ip->fSamplers.push_back_n(numTextures);
    SkString name;
    for (int t = 0; t < numTextures; ++t) {
        name.printf("Sampler%d", t);
        ip->fSamplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                     kSampler2D_GrSLType, kDefault_GrSLPrecision,
                                                     name.c_str());
        SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
                               (ip->fSamplers[t].fUniform, processor.textureAccess(t)));
    }
}
示例#12
0
static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) {
    uint32_t key = 0;
    int numTextures = proc.numTextures();
    int shift = 0;
    for (int t = 0; t < numTextures; ++t) {
        const GrTextureAccess& access = proc.textureAccess(t);
        if (swizzle_requires_alpha_remapping(*caps.glslCaps(), access.getTexture()->config())) {
            key |= 1 << shift;
        }
        if (GR_GL_TEXTURE_EXTERNAL == static_cast<GrGLTexture*>(access.getTexture())->target()) {
            key |= 2 << shift;
        }
        shift += 2;
    }
    return key;
}
示例#13
0
void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman,
                                  const GrProcessor& processor) {
    const GrBicubicEffect& bicubicEffect = processor.cast<GrBicubicEffect>();
    const GrTexture& texture = *processor.texture(0);
    float imageIncrement[2];
    imageIncrement[0] = 1.0f / texture.width();
    imageIncrement[1] = 1.0f / texture.height();
    pdman.set2fv(fImageIncrementUni, 1, imageIncrement);
    pdman.setMatrix4f(fCoefficientsUni, bicubicEffect.coefficients());
    fDomain.setData(pdman, bicubicEffect.domain(), texture.origin());
}
示例#14
0
static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc,
                            const GrGLSLCaps& caps) {
    int numTextures = proc.numTextures();
    SkASSERT(0 == proc.numBuffers());
    // Need two bytes per key (swizzle, sampler type, and precision).
    int word32Count = (proc.numTextures() + 1) / 2;
    if (0 == word32Count) {
        return;
    }
    uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count));
    for (int i = 0; i < numTextures; ++i) {
        const GrTextureAccess& access = proc.textureAccess(i);
        GrTexture* texture = access.getTexture();
        k16[i] = SkToU16(caps.configTextureSwizzle(texture->config()).asKey() |
                         (caps.samplerPrecision(texture->config(), access.getVisibility()) << 8));
    }
    // zero the last 16 bits if the number of textures is odd.
    if (numTextures & 0x1) {
        k16[numTextures] = 0;
    }
}
示例#15
0
void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
                                      GrGLSLTextureSampler::TextureSamplerArray* outSamplers) {
    int numTextures = processor.numTextures();
    UniformHandle* localSamplerUniforms = fSamplerUniforms.push_back_n(numTextures);
    SkString name;
    for (int t = 0; t < numTextures; ++t) {
        name.printf("Sampler%d", t);
        GrSLType samplerType = get_sampler_type(processor.textureAccess(t));
        localSamplerUniforms[t] =
            fUniformHandler.addUniform(GrGLSLUniformHandler::kFragment_Visibility,
                                       samplerType, kDefault_GrSLPrecision,
                                       name.c_str());
        SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLSLTextureSampler,
                               (localSamplerUniforms[t], processor.textureAccess(t)));
        if (kSamplerExternal_GrSLType == samplerType) {
            const char* externalFeatureString = this->glslCaps()->externalTextureExtensionString();
            // We shouldn't ever create a GrGLTexture that requires external sampler type 
            SkASSERT(externalFeatureString);
            fFS.addFeature(1 << GrGLSLFragmentShaderBuilder::kExternalTexture_GLSLPrivateFeature,
                           externalFeatureString);
        }
    }
}
示例#16
0
/**
* A function which emits a meta key into the key builder.  This is required because shader code may
* be dependent on properties of the effect that the effect itself doesn't use
* in its key (e.g. the pixel format of textures used). So we create a meta-key for
* every effect using this function. It is also responsible for inserting the effect's class ID
* which must be different for every GrProcessor subclass. It can fail if an effect uses too many
* transforms, etc, for the space allotted in the meta-key.  NOTE, both FPs and GPs share this
* function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
*/
static bool gen_meta_key(const GrProcessor& proc,
                         const GrGLSLCaps& glslCaps,
                         uint32_t transformKey,
                         GrProcessorKeyBuilder* b) {
    size_t processorKeySize = b->size();
    uint32_t classID = proc.classID();

    // Currently we allow 16 bits for the class id and the overall processor key size.
    static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)SK_MaxU16);
    if ((processorKeySize | classID) & kMetaKeyInvalidMask) {
        return false;
    }

    add_texture_key(b, proc, glslCaps);

    uint32_t* key = b->add32n(2);
    key[0] = (classID << 16) | SkToU32(processorKeySize);
    key[1] = transformKey;
    return true;
}
示例#17
0
/**
 * A function which emits a meta key into the key builder.  This is required because shader code may
 * be dependent on properties of the effect that the effect itself doesn't use
 * in its key (e.g. the pixel format of textures used). So we create a meta-key for
 * every effect using this function. It is also responsible for inserting the effect's class ID
 * which must be different for every GrProcessor subclass. It can fail if an effect uses too many
 * textures, transforms, etc, for the space allotted in the meta-key.  NOTE, both FPs and GPs share
 * this function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
 */
static bool get_meta_key(const GrProcessor& proc,
                         const GrGLCaps& caps,
                         uint32_t transformKey,
                         GrProcessorKeyBuilder* b) {
    size_t processorKeySize = b->size();
    uint32_t textureKey = gen_texture_key(proc, caps);
    uint32_t classID = proc.classID();

    // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
    // don't fit.
    static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
    if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) {
        return false;
    }
    if (processorKeySize > SK_MaxU16) {
        return false;
    }

    uint32_t* key = b->add32n(2);
    key[0] = (textureKey << 16 | transformKey);
    key[1] = (classID << 16 | SkToU16(processorKeySize));
    return true;
}