Refactor how we store and use samplers in Ganesh

The main goal of this refactorization is to allow Vulkan to use separate
sampler and texture objects in the shader and descriptor sets and combine
them into a sampler2d in the shader where needed.

A large part of this is separating how we store samplers and uniforms in the
UniformHandler. We no longer need to store handles to samplers besides when
we are initially emitting code. After we emit code all we ever do is loop over
all samplers and do some processor independent work on them, so we have no need
for direct access to individual samplers.

In the GLProgram all we ever do is set the sampler uniforms in the ctor and never
touch them again, so no need to save sampler info there. The texture access on
program reuse just assume that they come in the same order as we set the texture
units for the samplers

For Vulkan, it is a similar story. We create the descriptor set layouts with the samplers,
then when we get new textures, we just assume they come in in the same order as we
set the samplers on the descriptor sets. Thus no need to save direct vulkan info.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1885863004

Review URL: https://codereview.chromium.org/1885863004
This commit is contained in:
egdaniel 2016-04-19 14:45:57 -07:00 committed by Commit bot
parent 4c13db2a6b
commit 45b61a1c4c
30 changed files with 368 additions and 175 deletions

View File

@ -344,6 +344,7 @@
'<(skia_src_path)/gpu/gl/GrGLProgramDataManager.h',
'<(skia_src_path)/gpu/gl/GrGLRenderTarget.cpp',
'<(skia_src_path)/gpu/gl/GrGLRenderTarget.h',
'<(skia_src_path)/gpu/gl/GrGLSampler.h',
'<(skia_src_path)/gpu/gl/GrGLStencilAttachment.cpp',
'<(skia_src_path)/gpu/gl/GrGLStencilAttachment.h',
'<(skia_src_path)/gpu/gl/GrGLTestInterface.cpp',
@ -441,6 +442,7 @@
'<(skia_src_path)/gpu/vk/GrVkExtensions.h',
'<(skia_src_path)/gpu/vk/GrVkFramebuffer.cpp',
'<(skia_src_path)/gpu/vk/GrVkFramebuffer.h',
'<(skia_src_path)/gpu/vk/GrVkGLSLSampler.h',
'<(skia_src_path)/gpu/vk/GrVkGpu.cpp',
'<(skia_src_path)/gpu/vk/GrVkGpu.h',
'<(skia_src_path)/gpu/vk/GrVkImage.cpp',

View File

@ -691,7 +691,7 @@ private:
};
void OutputRectBlurProfileLookup(GrGLSLFPFragmentBuilder* fragBuilder,
const GrGLSLSampler& sampler,
GrGLSLFragmentProcessor::SamplerHandle sampler,
const char *output,
const char *profileSize, const char *loc,
const char *blurred_width,

View File

@ -1027,7 +1027,7 @@ void GrGLGradientEffect::emitColor(GrGLSLFPFragmentBuilder* fragBuilder,
const char* gradientTValue,
const char* outputColor,
const char* inputColor,
const SamplerArray& texSamplers) {
const SamplerHandle* texSamplers) {
if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()){
fragBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
uniformHandler->getUniformVariable(fColorStartUni).c_str(),

View File

@ -423,7 +423,7 @@ protected:
const char* gradientTValue,
const char* outputColor,
const char* inputColor,
const SamplerArray& texSamplers);
const SamplerHandle* texSamplers);
private:
enum {

View File

@ -49,7 +49,7 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder,
const GrTextureDomain& textureDomain,
const char* outColor,
const SkString& inCoords,
const GrGLSLSampler& sampler,
GrGLSLFragmentProcessor::SamplerHandle sampler,
const char* inModulateColor) {
SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode);
SkDEBUGCODE(fMode = textureDomain.mode();)

View File

@ -120,7 +120,7 @@ public:
const GrTextureDomain& textureDomain,
const char* outColor,
const SkString& inCoords,
const GrGLSLSampler& sampler,
GrGLSLFragmentProcessor::SamplerHandle sampler,
const char* inModulateColor = nullptr);
/**

View File

@ -31,11 +31,11 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
const SkTArray<GrGLSampler>& samplers,
const VaryingInfoArray& pathProcVaryings,
GrGLSLPrimitiveProcessor* geometryProcessor,
GrGLSLXferProcessor* xferProcessor,
const GrGLSLFragProcs& fragmentProcessors,
SkTArray<UniformHandle>* passSamplerUniforms)
const GrGLSLFragProcs& fragmentProcessors)
: fBuiltinUniformHandles(builtinUniforms)
, fProgramID(programID)
, fGeometryProcessor(geometryProcessor)
@ -44,12 +44,9 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu,
, fDesc(desc)
, fGpu(gpu)
, fProgramDataManager(gpu, programID, uniforms, pathProcVaryings) {
fSamplerUniforms.swap(passSamplerUniforms);
// Assign texture units to sampler uniforms one time up front.
GL_CALL(UseProgram(fProgramID));
for (int i = 0; i < fSamplerUniforms.count(); i++) {
fProgramDataManager.setSampler(fSamplerUniforms[i], i);
}
fProgramDataManager.setSamplers(samplers);
}
GrGLProgram::~GrGLProgram() {

View File

@ -106,11 +106,11 @@ protected:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
const SkTArray<GrGLSampler>&,
const VaryingInfoArray&, // used for NVPR only currently
GrGLSLPrimitiveProcessor* geometryProcessor,
GrGLSLXferProcessor* xferProcessor,
const GrGLSLFragProcs& fragmentProcessors,
SkTArray<UniformHandle>* passSamplerUniforms);
const GrGLSLFragProcs& fragmentProcessors);
// A helper to loop over effects, set the transforms (via subclass) and bind textures
void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextSamplerIdx);
@ -135,7 +135,6 @@ protected:
GrProgramDesc fDesc;
GrGLGpu* fGpu;
GrGLProgramDataManager fProgramDataManager;
SkTArray<UniformHandle> fSamplerUniforms;
friend class GrGLProgramBuilder;

View File

@ -61,19 +61,31 @@ GrGLProgramDataManager::GrGLProgramDataManager(GrGLGpu* gpu, GrGLuint programID,
}
}
void GrGLProgramDataManager::setSampler(UniformHandle u, int texUnit) const {
const Uniform& uni = fUniforms[u.toIndex()];
SkASSERT(GrSLTypeIsSamplerType(uni.fType));
SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
void GrGLProgramDataManager::setSamplers(const SkTArray<GrGLSampler>& samplers) const {
for (int i = 0; i < samplers.count(); ++i) {
GrGLint vsLocation;
GrGLint fsLocation;
const GrGLSampler& sampler = samplers[i];
if (kVertex_GrShaderFlag & sampler.visibility()) {
vsLocation = sampler.location();
} else {
vsLocation = kUnusedUniform;
}
if (kFragment_GrShaderFlag & sampler.visibility()) {
fsLocation = sampler.location();
} else {
fsLocation = kUnusedUniform;
}
// FIXME: We still insert a single sampler uniform for every stage. If the shader does not
// reference the sampler then the compiler may have optimized it out. Uncomment this assert
// once stages insert their own samplers.
// this->printUnused(uni);
if (kUnusedUniform != uni.fFSLocation) {
GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fFSLocation, texUnit));
if (kUnusedUniform != fsLocation) {
GR_GL_CALL(fGpu->glInterface(), Uniform1i(fsLocation, i));
}
if (kUnusedUniform != vsLocation && vsLocation != fsLocation) {
GR_GL_CALL(fGpu->glInterface(), Uniform1i(vsLocation, i));
}
if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fVSLocation, texUnit));
}
}

View File

@ -11,6 +11,7 @@
#include "glsl/GrGLSLProgramDataManager.h"
#include "GrAllocator.h"
#include "gl/GrGLSampler.h"
#include "gl/GrGLTypes.h"
#include "glsl/GrGLSLShaderVar.h"
@ -46,11 +47,12 @@ public:
GrGLProgramDataManager(GrGLGpu*, GrGLuint programID, const UniformInfoArray&,
const VaryingInfoArray&);
void setSamplers(const SkTArray<GrGLSampler>& samplers) const;
/** Functions for uploading uniform values. The varities ending in v can be used to upload to an
* array of uniforms. arrayCount must be <= the array count of the uniform.
*/
void setSampler(UniformHandle, int texUnit) const;
void set1f(UniformHandle, float v0) const override;
void set1fv(UniformHandle, int arrayCount, const float v[]) const override;
void set2f(UniformHandle, float, float) const override;

45
src/gpu/gl/GrGLSampler.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrGLSampler_DEFINED
#define GrGLSampler_DEFINED
#include "glsl/GrGLSLSampler.h"
#include "gl/GrGLTypes.h"
#include "glsl/GrGLSLShaderVar.h"
class GrGLSampler : public GrGLSLSampler {
public:
GrGLSampler(uint32_t visibility,
GrPixelConfig config,
GrSLType type,
GrSLPrecision precision,
const char* name) : INHERITED(visibility, config) {
SkASSERT(GrSLTypeIsSamplerType(type));
fShaderVar.setType(type);
fShaderVar.setTypeModifier(GrGLSLShaderVar::kUniform_TypeModifier);
fShaderVar.setPrecision(precision);
fShaderVar.accessName()->set(name);
}
GrGLint location() const { return fLocation; }
GrSLType type() const override { return fShaderVar.getType(); }
const char* onGetSamplerNameForTexture2D() const override { return fShaderVar.c_str(); }
const char* getSamplerNameForTexelFetch() const override { return fShaderVar.c_str(); }
private:
GrGLSLShaderVar fShaderVar;
GrGLint fLocation;
friend class GrGLUniformHandler;
typedef GrGLSLSampler INHERITED;
};
#endif

View File

@ -52,6 +52,22 @@ GrGLSLUniformHandler::UniformHandle GrGLUniformHandler::internalAddUniformArray(
return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1);
}
GrGLSLUniformHandler::SamplerHandle GrGLUniformHandler::internalAddSampler(uint32_t visibility,
GrPixelConfig config,
GrSLType type,
GrSLPrecision precision,
const char* name) {
SkASSERT(name && strlen(name));
SkDEBUGCODE(static const uint32_t kVisMask = kVertex_GrShaderFlag | kFragment_GrShaderFlag);
SkASSERT(0 == (~kVisMask & visibility));
SkASSERT(0 != visibility);
SkString mangleName;
char prefix = 'u';
fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
fSamplers.emplace_back(visibility, config, type, precision, mangleName.c_str());
return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
}
void GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
for (int i = 0; i < fUniforms.count(); ++i) {
if (fUniforms[i].fVisibility & visibility) {
@ -59,6 +75,12 @@ void GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString*
out->append(";\n");
}
}
for (int i = 0; i < fSamplers.count(); ++i) {
if (fSamplers[i].visibility() & visibility) {
fSamplers[i].fShaderVar.appendDecl(fProgramBuilder->glslCaps(), out);
out->append(";\n");
}
}
}
void GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) {
@ -68,6 +90,10 @@ void GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps
GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
fUniforms[i].fLocation = i;
}
for (int i = 0; i < fSamplers.count(); ++i) {
GL_CALL(BindUniformLocation(programID, i, fSamplers[i].fShaderVar.c_str()));
fSamplers[i].fLocation = i;
}
}
}
@ -79,6 +105,11 @@ void GrGLUniformHandler::getUniformLocations(GrGLuint programID, const GrGLCaps&
GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str()));
fUniforms[i].fLocation = location;
}
for (int i = 0; i < fSamplers.count(); ++i) {
GrGLint location;
GL_CALL_RET(location, GetUniformLocation(programID, fSamplers[i].fShaderVar.c_str()));
fSamplers[i].fLocation = location;
}
}
}

View File

@ -11,6 +11,7 @@
#include "glsl/GrGLSLUniformHandler.h"
#include "gl/GrGLProgramDataManager.h"
#include "gl/GrGLSampler.h"
class GrGLCaps;
@ -38,6 +39,17 @@ private:
int arrayCount,
const char** outName) override;
SamplerHandle internalAddSampler(uint32_t visibility,
GrPixelConfig config,
GrSLType type,
GrSLPrecision precision,
const char* name) override;
int numSamplers() const override { return fSamplers.count(); }
const GrGLSLSampler& getSampler(SamplerHandle handle) const override {
return fSamplers[handle.toIndex()];
}
void appendUniformDecls(GrShaderFlags visibility, SkString*) const override;
// Manually set uniform locations for all our uniforms.
@ -53,6 +65,8 @@ private:
UniformInfoArray fUniforms;
SkTArray<GrGLSampler> fSamplers;
friend class GrGLProgramBuilder;
typedef GrGLSLUniformHandler INHERITED;

View File

@ -233,9 +233,9 @@ GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
fUniformHandles,
programID,
fUniformHandler.fUniforms,
fUniformHandler.fSamplers,
fVaryingHandler.fPathProcVaryingInfos,
fGeometryProcessor,
fXferProcessor,
fFragmentProcessors,
&fSamplerUniforms);
fFragmentProcessors);
}

View File

@ -83,17 +83,16 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
firstBufferAt += args.fFp.childProcessor(i).numBuffers();
}
GrGLSLTransformedCoordsArray childCoords;
SamplerArray childTexSamplers;
SamplerArray childBufferSamplers;
const SamplerHandle* childTexSamplers = nullptr;
const SamplerHandle* childBufferSamplers = nullptr;
if (childProc.numTransforms() > 0) {
childCoords.push_back_n(childProc.numTransforms(), &args.fCoords[firstCoordAt]);
}
if (childProc.numTextures() > 0) {
childTexSamplers.push_back_n(childProc.numTextures(), &args.fTexSamplers[firstTextureAt]);
childTexSamplers = &args.fTexSamplers[firstTextureAt];
}
if (childProc.numBuffers() > 0) {
childBufferSamplers.push_back_n(childProc.numBuffers(),
&args.fBufferSamplers[firstBufferAt]);
childBufferSamplers = &args.fBufferSamplers[firstBufferAt];
}
// emit the code for the child in its own scope

View File

@ -31,7 +31,7 @@ public:
}
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
typedef GrGLSLSampler::SamplerArray SamplerArray;
typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
/** Called when the program stage should insert its code into the shaders. The code in each
shader will be in its own block ({}) and so locally scoped names will not collide across
@ -60,8 +60,8 @@ public:
const char* outputColor,
const char* inputColor,
const GrGLSLTransformedCoordsArray& coords,
const SamplerArray& texSamplers,
const SamplerArray& bufferSamplers)
const SamplerHandle* texSamplers,
const SamplerHandle* bufferSamplers)
: fFragBuilder(fragBuilder)
, fUniformHandler(uniformHandler)
, fGLSLCaps(caps)
@ -78,8 +78,8 @@ public:
const char* fOutputColor;
const char* fInputColor;
const GrGLSLTransformedCoordsArray& fCoords;
const SamplerArray& fTexSamplers;
const SamplerArray& fBufferSamplers;
const SamplerHandle* fTexSamplers;
const SamplerHandle* fBufferSamplers;
};
virtual void emitCode(EmitArgs&) = 0;

View File

@ -27,7 +27,7 @@ public:
virtual ~GrGLSLPrimitiveProcessor() {}
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
typedef GrGLSLSampler::SamplerArray SamplerArray;
typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
typedef SkSTArray<2, const GrCoordTransform*, true> ProcCoords;
typedef SkSTArray<8, ProcCoords> TransformsIn;
@ -42,8 +42,8 @@ public:
const GrPrimitiveProcessor& gp,
const char* outputColor,
const char* outputCoverage,
const SamplerArray& texSamplers,
const SamplerArray& bufferSamplers,
const SamplerHandle* texSamplers,
const SamplerHandle* bufferSamplers,
const TransformsIn& transformsIn,
TransformsOut* transformsOut)
: fVertBuilder(vertBuilder)
@ -66,8 +66,8 @@ public:
const GrPrimitiveProcessor& fGP;
const char* fOutputColor;
const char* fOutputCoverage;
const SamplerArray& fTexSamplers;
const SamplerArray& fBufferSamplers;
const SamplerHandle* fTexSamplers;
const SamplerHandle* fBufferSamplers;
const TransformsIn& fTransformsIn;
TransformsOut* fTransformsOut;
};

View File

@ -27,7 +27,6 @@ GrGLSLProgramBuilder::GrGLSLProgramBuilder(const GrPipeline& pipeline,
, fDesc(desc)
, fGeometryProcessor(nullptr)
, fXferProcessor(nullptr)
, fSamplerUniforms(4)
, fNumVertexSamplers(0)
, fNumGeometrySamplers(0)
, fNumFragmentSamplers(0) {
@ -97,8 +96,8 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
SkASSERT(!fGeometryProcessor);
fGeometryProcessor = proc.createGLSLInstance(*this->glslCaps());
SkSTArray<4, GrGLSLSampler> texSamplers(proc.numTextures());
SkSTArray<2, GrGLSLSampler> bufferSamplers(proc.numBuffers());
SkSTArray<4, SamplerHandle> texSamplers(proc.numTextures());
SkSTArray<2, SamplerHandle> bufferSamplers(proc.numBuffers());
this->emitSamplers(proc, &texSamplers, &bufferSamplers);
GrGLSLGeometryProcessor::EmitArgs args(&fVS,
@ -109,8 +108,8 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
proc,
outputColor->c_str(),
outputCoverage->c_str(),
texSamplers,
bufferSamplers,
texSamplers.begin(),
bufferSamplers.begin(),
fCoordTransforms,
&fOutCoords);
fGeometryProcessor->emitCode(args);
@ -150,8 +149,8 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
GrGLSLFragmentProcessor* fragProc = fp.createGLSLInstance();
SkSTArray<4, GrGLSLSampler> texSamplers(fp.numTextures());
SkSTArray<2, GrGLSLSampler> bufferSamplers(fp.numBuffers());
SkSTArray<4, SamplerHandle> texSamplers(fp.numTextures());
SkSTArray<2, SamplerHandle> bufferSamplers(fp.numBuffers());
this->emitSamplers(fp, &texSamplers, &bufferSamplers);
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
@ -161,8 +160,8 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
output->c_str(),
input.isOnes() ? nullptr : input.c_str(),
fOutCoords[index],
texSamplers,
bufferSamplers);
texSamplers.begin(),
bufferSamplers.begin());
fragProc->emitCode(args);
// We have to check that effects and the code they emit are consistent, ie if an effect
@ -197,8 +196,8 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
fFS.codeAppend(openBrace.c_str());
SkSTArray<4, GrGLSLSampler> texSamplers(xp.numTextures());
SkSTArray<2, GrGLSLSampler> bufferSamplers(xp.numBuffers());
SkSTArray<4, SamplerHandle> texSamplers(xp.numTextures());
SkSTArray<2, SamplerHandle> bufferSamplers(xp.numBuffers());
this->emitSamplers(xp, &texSamplers, &bufferSamplers);
bool usePLSDstRead = (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState);
@ -209,8 +208,8 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
ignoresCoverage ? nullptr : coverageIn.c_str(),
fFS.getPrimaryColorOutputName(),
fFS.getSecondaryColorOutputName(),
texSamplers,
bufferSamplers,
texSamplers.begin(),
bufferSamplers.begin(),
usePLSDstRead);
fXferProcessor->emitCode(args);
@ -221,8 +220,8 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
}
void GrGLSLProgramBuilder::emitSamplers(const GrProcessor& processor,
GrGLSLSampler::SamplerArray* outTexSamplers,
GrGLSLSampler::SamplerArray* outBufferSamplers) {
SkTArray<SamplerHandle>* outTexSamplers,
SkTArray<SamplerHandle>* outBufferSamplers) {
SkString name;
int numTextures = processor.numTextures();
for (int t = 0; t < numTextures; ++t) {
@ -265,7 +264,7 @@ void GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
GrPixelConfig config,
const char* name,
GrShaderFlags visibility,
GrGLSLSampler::SamplerArray* outSamplers) {
SkTArray<SamplerHandle>* outSamplers) {
if (visibility & kVertex_GrShaderFlag) {
++fNumVertexSamplers;
}
@ -277,9 +276,12 @@ void GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
++fNumFragmentSamplers;
}
GrSLPrecision precision = this->glslCaps()->samplerPrecision(config, visibility);
UniformHandle u = this->uniformHandler()->addUniform(visibility, samplerType, precision, name);
fSamplerUniforms.push_back(u);
outSamplers->emplace_back(u, config);
SamplerHandle handle = this->uniformHandler()->addSampler(visibility,
config,
samplerType,
precision,
name);
outSamplers->emplace_back(handle);
}
void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
@ -369,6 +371,10 @@ void GrGLSLProgramBuilder::appendUniformDecls(GrShaderFlags visibility, SkString
this->uniformHandler()->appendUniformDecls(visibility, out);
}
const GrGLSLSampler& GrGLSLProgramBuilder::getSampler(SamplerHandle handle) const {
return this->uniformHandler()->getSampler(handle);
}
void GrGLSLProgramBuilder::addRTAdjustmentUniform(GrSLPrecision precision,
const char* name,
const char** outName) {

View File

@ -41,6 +41,10 @@ public:
void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
typedef GrGLSLUniformHandler::SamplerHandle SamplerHandle;
const GrGLSLSampler& getSampler(SamplerHandle handle) const;
// Handles for program uniforms (other than per-effect uniforms)
struct BuiltinUniformHandles {
UniformHandle fRTAdjustmentUni;
@ -104,8 +108,6 @@ protected:
void finalizeShaders();
SkTArray<UniformHandle> fSamplerUniforms;
private:
// reset is called by program creator between each processor's emit code. It increments the
// stage offset for variable name mangling, and also ensures verfication variables in the
@ -146,14 +148,15 @@ private:
const GrGLSLExpr4& coverageIn,
bool ignoresCoverage,
GrPixelLocalStorageState plsState);
void emitSamplers(const GrProcessor& processor,
GrGLSLSampler::SamplerArray* outTexSamplers,
GrGLSLSampler::SamplerArray* outBufferSamplers);
SkTArray<SamplerHandle>* outTexSamplers,
SkTArray<SamplerHandle>* outBufferSamplers);
void emitSampler(GrSLType samplerType,
GrPixelConfig,
const char* name,
GrShaderFlags visibility,
GrGLSLSampler::SamplerArray* outSamplers);
SkTArray<SamplerHandle>* outSamplers);
void emitFSOutputSwizzle(bool hasSecondaryOutput);
bool checkSamplerCounts();

View File

@ -9,27 +9,37 @@
#define GrGLSLSampler_DEFINED
#include "GrTypes.h"
#include "SkTArray.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "GrTypesPriv.h"
#include "SkString.h"
class GrGLSLSampler {
public:
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
typedef SkTArray<GrGLSLSampler> SamplerArray;
virtual ~GrGLSLSampler() {}
GrGLSLSampler(UniformHandle uniform, GrPixelConfig config)
: fSamplerUniform(uniform)
explicit GrGLSLSampler(uint32_t visibility, GrPixelConfig config)
: fVisibility(visibility)
, fConfig(config) {
SkASSERT(kUnknown_GrPixelConfig != fConfig);
}
uint32_t visibility() const { return fVisibility; }
GrPixelConfig config() const { return fConfig; }
virtual GrSLType type() const = 0;
// Returns the string to be used for the sampler in glsl 2D texture functions (texture,
// texture2D, etc.)
const char* getSamplerNameForTexture2D() const {
SkASSERT(GrSLTypeIs2DTextureType(this->type()));
return this->onGetSamplerNameForTexture2D();
}
// Returns the string to be used for the sampler in glsl texelFetch.
virtual const char* getSamplerNameForTexelFetch() const = 0;
private:
UniformHandle fSamplerUniform;
virtual const char* onGetSamplerNameForTexture2D() const = 0;
uint32_t fVisibility;
GrPixelConfig fConfig;
friend class GrGLSLShaderBuilder;
};
#endif

View File

@ -63,71 +63,68 @@ void GrGLSLShaderBuilder::emitFunction(GrSLType returnType,
}
void GrGLSLShaderBuilder::appendTextureLookup(SkString* out,
const GrGLSLSampler& sampler,
SamplerHandle samplerHandle,
const char* coordName,
GrSLType varyingType) const {
const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps();
GrGLSLUniformHandler* uniformHandler = fProgramBuilder->uniformHandler();
GrSLType samplerType = uniformHandler->getUniformVariable(sampler.fSamplerUniform).getType();
const GrGLSLSampler& sampler = fProgramBuilder->getSampler(samplerHandle);
GrSLType samplerType = sampler.type();
if (samplerType == kSampler2DRect_GrSLType) {
if (varyingType == kVec2f_GrSLType) {
out->appendf("%s(%s, textureSize(%s) * %s)",
GrGLSLTexture2DFunctionName(varyingType, samplerType,
glslCaps->generation()),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
sampler.getSamplerNameForTexture2D(),
sampler.getSamplerNameForTexture2D(),
coordName);
} else {
out->appendf("%s(%s, vec3(textureSize(%s) * %s.xy, %s.z))",
GrGLSLTexture2DFunctionName(varyingType, samplerType,
glslCaps->generation()),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
sampler.getSamplerNameForTexture2D(),
sampler.getSamplerNameForTexture2D(),
coordName,
coordName);
}
} else {
out->appendf("%s(%s, %s)",
GrGLSLTexture2DFunctionName(varyingType, samplerType, glslCaps->generation()),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
sampler.getSamplerNameForTexture2D(),
coordName);
}
this->appendTextureSwizzle(out, sampler.config());
}
void GrGLSLShaderBuilder::appendTextureLookup(const GrGLSLSampler& sampler,
void GrGLSLShaderBuilder::appendTextureLookup(SamplerHandle samplerHandle,
const char* coordName,
GrSLType varyingType) {
this->appendTextureLookup(&this->code(), sampler, coordName, varyingType);
this->appendTextureLookup(&this->code(), samplerHandle, coordName, varyingType);
}
void GrGLSLShaderBuilder::appendTextureLookupAndModulate(const char* modulation,
const GrGLSLSampler& sampler,
SamplerHandle samplerHandle,
const char* coordName,
GrSLType varyingType) {
SkString lookup;
this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
this->appendTextureLookup(&lookup, samplerHandle, coordName, varyingType);
this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
}
void GrGLSLShaderBuilder::appendTexelFetch(SkString* out,
const GrGLSLSampler& sampler,
SamplerHandle samplerHandle,
const char* coordExpr) const {
const GrGLSLUniformHandler* uniformHandler = fProgramBuilder->uniformHandler();
const GrGLSLSampler& sampler = fProgramBuilder->getSampler(samplerHandle);
SkASSERT(fProgramBuilder->glslCaps()->texelFetchSupport());
SkASSERT(GrSLTypeIsSamplerType(
uniformHandler->getUniformVariable(sampler.fSamplerUniform).getType()));
SkASSERT(GrSLTypeIsSamplerType(sampler.type()));
out->appendf("texelFetch(%s, %s)",
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
coordExpr);
out->appendf("texelFetch(%s, %s)", sampler.getSamplerNameForTexelFetch(), coordExpr);
this->appendTextureSwizzle(out, sampler.config());
}
void GrGLSLShaderBuilder::appendTexelFetch(const GrGLSLSampler& sampler, const char* coordExpr) {
this->appendTexelFetch(&this->code(), sampler, coordExpr);
void GrGLSLShaderBuilder::appendTexelFetch(SamplerHandle samplerHandle, const char* coordExpr) {
this->appendTexelFetch(&this->code(), samplerHandle, coordExpr);
}
void GrGLSLShaderBuilder::appendTextureSwizzle(SkString* out, GrPixelConfig config) const {

View File

@ -9,14 +9,12 @@
#define GrGLSLShaderBuilder_DEFINED
#include "GrAllocator.h"
#include "glsl/GrGLSLUniformHandler.h"
#include "glsl/GrGLSLShaderVar.h"
#include "SkTDArray.h"
#include <stdarg.h>
class GrGLSLProgramBuilder;
class GrGLSLSampler;
/**
base class for all shaders builders
*/
@ -25,17 +23,19 @@ public:
GrGLSLShaderBuilder(GrGLSLProgramBuilder* program);
virtual ~GrGLSLShaderBuilder() {}
typedef GrGLSLUniformHandler::SamplerHandle SamplerHandle;
/** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
order of the result depends on the GrTextureAccess associated with the GrGLSLSampler.
*/
void appendTextureLookup(SkString* out,
const GrGLSLSampler&,
SamplerHandle,
const char* coordName,
GrSLType coordType = kVec2f_GrSLType) const;
/** Version of above that appends the result to the shader code instead.*/
void appendTextureLookup(const GrGLSLSampler&,
void appendTextureLookup(SamplerHandle,
const char* coordName,
GrSLType coordType = kVec2f_GrSLType);
@ -45,17 +45,17 @@ public:
vec4 or float. If modulation is "" or nullptr it this function acts as though
appendTextureLookup were called. */
void appendTextureLookupAndModulate(const char* modulation,
const GrGLSLSampler&,
SamplerHandle,
const char* coordName,
GrSLType coordType = kVec2f_GrSLType);
/** Fetches an unfiltered texel from a sampler at integer coordinates. coordExpr must match the
dimensionality of the sampler and must be within the sampler's range. coordExpr is emitted
exactly once, so expressions like "idx++" are acceptable. */
void appendTexelFetch(SkString* out, const GrGLSLSampler&, const char* coordExpr) const;
void appendTexelFetch(SkString* out, SamplerHandle, const char* coordExpr) const;
/** Version of above that appends the result to the shader code instead.*/
void appendTexelFetch(const GrGLSLSampler&, const char* coordExpr);
void appendTexelFetch(SamplerHandle, const char* coordExpr);
/**
* Adds a #define directive to the top of the shader.

View File

@ -12,12 +12,14 @@
#include "GrGLSLShaderVar.h"
class GrGLSLProgramBuilder;
class GrGLSLSampler;
class GrGLSLUniformHandler {
public:
virtual ~GrGLSLUniformHandler() {}
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
/** Add a uniform variable to the current program, that has visibility in one or more shaders.
visibility is a bitfield of GrShaderFlag values indicating from which shaders the uniform
@ -30,6 +32,7 @@ public:
GrSLPrecision precision,
const char* name,
const char** outName = nullptr) {
SkASSERT(!GrSLTypeIsSamplerType(type));
return this->addUniformArray(visibility, type, precision, name, 0, outName);
}
@ -39,6 +42,7 @@ public:
const char* name,
int arrayCount,
const char** outName = nullptr) {
SkASSERT(!GrSLTypeIsSamplerType(type));
return this->internalAddUniformArray(visibility, type, precision, name, true, arrayCount,
outName);
}
@ -49,6 +53,7 @@ public:
* Shortcut for getUniformVariable(u).c_str()
*/
virtual const char* getUniformCStr(UniformHandle u) const = 0;
protected:
explicit GrGLSLUniformHandler(GrGLSLProgramBuilder* program) : fProgramBuilder(program) {}
@ -56,6 +61,23 @@ protected:
GrGLSLProgramBuilder* fProgramBuilder;
private:
virtual int numSamplers() const = 0;
virtual const GrGLSLSampler& getSampler(SamplerHandle handle) const = 0;
SamplerHandle addSampler(uint32_t visibility,
GrPixelConfig config,
GrSLType type,
GrSLPrecision precision,
const char* name) {
return this->internalAddSampler(visibility, config, type, precision, name);
}
virtual SamplerHandle internalAddSampler(uint32_t visibility,
GrPixelConfig config,
GrSLType type,
GrSLPrecision precision,
const char* name) = 0;
virtual UniformHandle internalAddUniformArray(uint32_t visibility,
GrSLType type,
GrSLPrecision precision,

View File

@ -22,7 +22,8 @@ public:
GrGLSLXferProcessor() {}
virtual ~GrGLSLXferProcessor() {}
typedef GrGLSLSampler::SamplerArray SamplerArray;
typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
struct EmitArgs {
EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
GrGLSLUniformHandler* uniformHandler,
@ -32,8 +33,8 @@ public:
const char* inputCoverage,
const char* outputPrimary,
const char* outputSecondary,
const SamplerArray& texSamplers,
const SamplerArray& bufferSamplers,
const SamplerHandle* texSamplers,
const SamplerHandle* bufferSamplers,
const bool usePLSDstRead)
: fXPFragBuilder(fragBuilder)
, fUniformHandler(uniformHandler)
@ -55,8 +56,8 @@ public:
const char* fInputCoverage;
const char* fOutputPrimary;
const char* fOutputSecondary;
const SamplerArray& fTexSamplers;
const SamplerArray& fBufferSamplers;
const SamplerHandle* fTexSamplers;
const SamplerHandle* fBufferSamplers;
bool fUsePLSDstRead;
};
/**

View File

@ -0,0 +1,49 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrVkGLSLSampler_DEFINED
#define GrVkGLSLSampler_DEFINED
#include "glsl/GrGLSLSampler.h"
#include "glsl/GrGLSLShaderVar.h"
class GrVkGLSLSampler : public GrGLSLSampler {
public:
GrVkGLSLSampler(uint32_t visibility,
GrPixelConfig config,
GrSLType type,
GrSLPrecision precision,
const char* name,
uint32_t binding,
uint32_t set) : INHERITED(visibility, config), fBinding(binding) {
SkASSERT(GrSLTypeIsSamplerType(type));
fShaderVar.setType(type);
fShaderVar.setTypeModifier(GrGLSLShaderVar::kUniform_TypeModifier);
fShaderVar.setPrecision(precision);
fShaderVar.accessName()->set(name);
SkString layoutQualifier;
layoutQualifier.appendf("set=%d, binding=%d", set, binding);
fShaderVar.setLayoutQualifier(layoutQualifier.c_str());
}
GrSLType type() const override { return fShaderVar.getType(); }
uint32_t binding() const { return fBinding; }
const char* onGetSamplerNameForTexture2D() const override { return fShaderVar.c_str(); }
const char* getSamplerNameForTexelFetch() const override { return fShaderVar.c_str(); }
private:
GrGLSLShaderVar fShaderVar;
uint32_t fBinding;
friend class GrVkUniformHandler;
typedef GrGLSLSampler INHERITED;
};
#endif

View File

@ -162,20 +162,18 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveT
VkShaderModule vertShaderModule;
VkShaderModule fragShaderModule;
uint32_t numSamplers = fSamplerUniforms.count();
uint32_t numSamplers = (uint32_t)fUniformHandler.numSamplers();
SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings(
new VkDescriptorSetLayoutBinding[numSamplers]);
for (uint32_t i = 0; i < numSamplers; ++i) {
UniformHandle uniHandle = fSamplerUniforms[i];
GrVkUniformHandler::UniformInfo uniformInfo = fUniformHandler.getUniformInfo(uniHandle);
SkASSERT(kSampler2D_GrSLType == uniformInfo.fVariable.getType());
SkASSERT(GrVkUniformHandler::kSamplerDescSet == uniformInfo.fSetNumber);
SkASSERT(uniformInfo.fBinding == i);
dsSamplerBindings[i].binding = uniformInfo.fBinding;
const GrVkGLSLSampler& sampler =
static_cast<const GrVkGLSLSampler&>(fUniformHandler.getSampler(i));
SkASSERT(sampler.binding() == i);
dsSamplerBindings[i].binding = sampler.binding();
dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
dsSamplerBindings[i].descriptorCount = 1;
dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(uniformInfo.fVisibility);
dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(sampler.visibility());
dsSamplerBindings[i].pImmutableSamplers = nullptr;
}
@ -184,11 +182,10 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveT
dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
dsSamplerLayoutCreateInfo.pNext = nullptr;
dsSamplerLayoutCreateInfo.flags = 0;
dsSamplerLayoutCreateInfo.bindingCount = fSamplerUniforms.count();
dsSamplerLayoutCreateInfo.bindingCount = numSamplers;
// Setting to nullptr fixes an error in the param checker validation layer. Even though
// bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null.
dsSamplerLayoutCreateInfo.pBindings = fSamplerUniforms.count() ? dsSamplerBindings.get() :
nullptr;
dsSamplerLayoutCreateInfo.pBindings = numSamplers ? dsSamplerBindings.get() : nullptr;
GR_VK_CALL_ERRCHECK(fGpu->vkInterface(),
CreateDescriptorSetLayout(fGpu->device(),

View File

@ -32,11 +32,10 @@ GrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArra
uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
uniform.fType = uniformInfo.fVariable.getType();
);
uniform.fBinding = uniformInfo.fBinding;
uniform.fBinding =
(kVertex_GrShaderFlag == uniformInfo.fVisibility) ? GrVkUniformHandler::kVertexBinding
: GrVkUniformHandler::kFragBinding;
uniform.fOffset = uniformInfo.fUBOffset;
SkDEBUGCODE(
uniform.fSetNumber = uniformInfo.fSetNumber;
);
}
}
@ -59,7 +58,6 @@ void GrVkPipelineStateDataManager::set1f(UniformHandle u, float v0) const {
const Uniform& uni = fUniforms[u.toIndex()];
SkASSERT(uni.fType == kFloat_GrSLType);
SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer = this->getBufferPtrAndMarkDirty(uni);
SkASSERT(sizeof(float) == 4);
memcpy(buffer, &v0, sizeof(float));
@ -73,7 +71,6 @@ void GrVkPipelineStateDataManager::set1fv(UniformHandle u,
SkASSERT(arrayCount > 0);
SkASSERT(arrayCount <= uni.fArrayCount ||
(1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer = this->getBufferPtrAndMarkDirty(uni);
SkASSERT(sizeof(float) == 4);
@ -88,7 +85,6 @@ void GrVkPipelineStateDataManager::set2f(UniformHandle u, float v0, float v1) co
const Uniform& uni = fUniforms[u.toIndex()];
SkASSERT(uni.fType == kVec2f_GrSLType);
SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer = this->getBufferPtrAndMarkDirty(uni);
SkASSERT(sizeof(float) == 4);
float v[2] = { v0, v1 };
@ -103,7 +99,6 @@ void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
SkASSERT(arrayCount > 0);
SkASSERT(arrayCount <= uni.fArrayCount ||
(1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer = this->getBufferPtrAndMarkDirty(uni);
SkASSERT(sizeof(float) == 4);
@ -118,7 +113,6 @@ void GrVkPipelineStateDataManager::set3f(UniformHandle u, float v0, float v1, fl
const Uniform& uni = fUniforms[u.toIndex()];
SkASSERT(uni.fType == kVec3f_GrSLType);
SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer = this->getBufferPtrAndMarkDirty(uni);
SkASSERT(sizeof(float) == 4);
float v[3] = { v0, v1, v2 };
@ -133,7 +127,6 @@ void GrVkPipelineStateDataManager::set3fv(UniformHandle u,
SkASSERT(arrayCount > 0);
SkASSERT(arrayCount <= uni.fArrayCount ||
(1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer = this->getBufferPtrAndMarkDirty(uni);
SkASSERT(sizeof(float) == 4);
@ -152,7 +145,6 @@ void GrVkPipelineStateDataManager::set4f(UniformHandle u,
const Uniform& uni = fUniforms[u.toIndex()];
SkASSERT(uni.fType == kVec4f_GrSLType);
SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer = this->getBufferPtrAndMarkDirty(uni);
SkASSERT(sizeof(float) == 4);
float v[4] = { v0, v1, v2, v3 };
@ -167,7 +159,6 @@ void GrVkPipelineStateDataManager::set4fv(UniformHandle u,
SkASSERT(arrayCount > 0);
SkASSERT(arrayCount <= uni.fArrayCount ||
(1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer = this->getBufferPtrAndMarkDirty(uni);
SkASSERT(sizeof(float) == 4);
@ -214,7 +205,6 @@ template<int N> inline void GrVkPipelineStateDataManager::setMatrices(UniformHan
SkASSERT(arrayCount > 0);
SkASSERT(arrayCount <= uni.fArrayCount ||
(1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
void* buffer;
if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {

View File

@ -59,7 +59,6 @@ private:
SkDEBUGCODE(
GrSLType fType;
int fArrayCount;
uint32_t fSetNumber;
);
};

View File

@ -136,6 +136,7 @@ GrGLSLUniformHandler::UniformHandle GrVkUniformHandler::internalAddUniformArray(
SkASSERT(0 == (~kVisibilityMask & visibility));
SkASSERT(0 != visibility);
SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
GrSLTypeIsFloatType(type);
UniformInfo& uni = fUniforms.push_back();
uni.fVariable.setType(type);
@ -155,7 +156,6 @@ GrGLSLUniformHandler::UniformHandle GrVkUniformHandler::internalAddUniformArray(
SkASSERT(kVertex_GrShaderFlag == visibility || kFragment_GrShaderFlag == visibility);
uni.fVisibility = visibility;
uni.fVariable.setPrecision(precision);
if (GrSLTypeIsFloatType(type)) {
// When outputing the GLSL, only the outer uniform block will get the Uniform modifier. Thus
// we set the modifier to none for all uniforms declared inside the block.
uni.fVariable.setTypeModifier(GrGLSLShaderVar::kNone_TypeModifier);
@ -163,50 +163,56 @@ GrGLSLUniformHandler::UniformHandle GrVkUniformHandler::internalAddUniformArray(
uint32_t* currentOffset = kVertex_GrShaderFlag == visibility ? &fCurrentVertexUBOOffset
: &fCurrentFragmentUBOOffset;
get_ubo_aligned_offset(&uni.fUBOffset, currentOffset, type, arrayCount);
uni.fSetNumber = kUniformBufferDescSet;
uni.fBinding = kVertex_GrShaderFlag == visibility ? kVertexBinding : kFragBinding;
if (outName) {
*outName = uni.fVariable.c_str();
}
} else {
SkASSERT(type == kSampler2D_GrSLType);
uni.fVariable.setTypeModifier(GrGLSLShaderVar::kUniform_TypeModifier);
uni.fSetNumber = kSamplerDescSet;
uni.fBinding = fCurrentSamplerBinding++;
uni.fUBOffset = 0; // This value will be ignored, but initializing to avoid any errors.
SkString layoutQualifier;
layoutQualifier.appendf("set=%d, binding=%d", uni.fSetNumber, uni.fBinding);
uni.fVariable.setLayoutQualifier(layoutQualifier.c_str());
}
return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1);
}
GrGLSLUniformHandler::SamplerHandle GrVkUniformHandler::internalAddSampler(uint32_t visibility,
GrPixelConfig config,
GrSLType type,
GrSLPrecision precision,
const char* name) {
SkASSERT(name && strlen(name));
SkDEBUGCODE(static const uint32_t kVisMask = kVertex_GrShaderFlag | kFragment_GrShaderFlag);
SkASSERT(0 == (~kVisMask & visibility));
SkASSERT(0 != visibility);
SkString mangleName;
char prefix = 'u';
fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
fSamplers.emplace_back(visibility, config, type, precision, mangleName.c_str(),
(uint32_t)fSamplers.count(), kSamplerDescSet);
return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
}
void GrVkUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
SkTArray<UniformInfo*> uniformBufferUniform;
// Used to collect all the variables that will be place inside the uniform buffer
SkString uniformsString;
SkASSERT(kVertex_GrShaderFlag == visibility || kFragment_GrShaderFlag == visibility);
uint32_t uniformBinding = (visibility == kVertex_GrShaderFlag) ? kVertexBinding : kFragBinding;
for (int i = 0; i < fSamplers.count(); ++i) {
const GrVkGLSLSampler& sampler = fSamplers[i];
SkASSERT(sampler.type() == kSampler2D_GrSLType);
if (visibility == sampler.visibility()) {
sampler.fShaderVar.appendDecl(fProgramBuilder->glslCaps(), out);
out->append(";\n");
}
}
SkString uniformsString;
for (int i = 0; i < fUniforms.count(); ++i) {
const UniformInfo& localUniform = fUniforms[i];
if (visibility == localUniform.fVisibility) {
if (GrSLTypeIsFloatType(localUniform.fVariable.getType())) {
SkASSERT(uniformBinding == localUniform.fBinding);
SkASSERT(kUniformBufferDescSet == localUniform.fSetNumber);
localUniform.fVariable.appendDecl(fProgramBuilder->glslCaps(), &uniformsString);
uniformsString.append(";\n");
} else {
SkASSERT(localUniform.fVariable.getType() == kSampler2D_GrSLType);
SkASSERT(kSamplerDescSet == localUniform.fSetNumber);
localUniform.fVariable.appendDecl(fProgramBuilder->glslCaps(), out);
out->append(";\n");
}
}
}
if (!uniformsString.isEmpty()) {
uint32_t uniformBinding = (visibility == kVertex_GrShaderFlag) ? kVertexBinding
: kFragBinding;
const char* stage = (visibility == kVertex_GrShaderFlag) ? "vertex" : "fragment";
out->appendf("layout (set=%d, binding=%d) uniform %sUniformBuffer\n{\n",
kUniformBufferDescSet, uniformBinding, stage);

View File

@ -11,6 +11,7 @@
#include "glsl/GrGLSLUniformHandler.h"
#include "GrAllocator.h"
#include "GrVkGLSLSampler.h"
#include "glsl/GrGLSLShaderVar.h"
class GrVkUniformHandler : public GrGLSLUniformHandler {
@ -30,8 +31,6 @@ public:
struct UniformInfo {
GrGLSLShaderVar fVariable;
uint32_t fVisibility;
uint32_t fSetNumber;
uint32_t fBinding;
uint32_t fUBOffset;
};
typedef GrTAllocator<UniformInfo> UniformInfoArray;
@ -61,6 +60,17 @@ private:
int arrayCount,
const char** outName) override;
SamplerHandle internalAddSampler(uint32_t visibility,
GrPixelConfig config,
GrSLType type,
GrSLPrecision precision,
const char* name) override;
int numSamplers() const override { return fSamplers.count(); }
const GrGLSLSampler& getSampler(SamplerHandle handle) const override {
return fSamplers[handle.toIndex()];
}
void appendUniformDecls(GrShaderFlags, SkString*) const override;
bool hasVertexUniforms() const { return fCurrentVertexUBOOffset > 0; }
@ -73,6 +83,8 @@ private:
UniformInfoArray fUniforms;
SkTArray<GrVkGLSLSampler> fSamplers;
uint32_t fCurrentVertexUBOOffset;
uint32_t fCurrentFragmentUBOOffset;
uint32_t fCurrentSamplerBinding;