Remove support for image load/store
This isn't used and has become a maintenance burden. Change-Id: I5f3af8f91e5c4f073fe4ea30e0a7f1f61efeea47 Reviewed-on: https://skia-review.googlesource.com/70640 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
33d17cbb00
commit
559f556d9d
@ -113,7 +113,6 @@ tests_sources = [
|
||||
"$_tests/ImageGeneratorTest.cpp",
|
||||
"$_tests/ImageIsOpaqueTest.cpp",
|
||||
"$_tests/ImageNewShaderTest.cpp",
|
||||
"$_tests/ImageStorageTest.cpp",
|
||||
"$_tests/ImageTest.cpp",
|
||||
"$_tests/IndexedPngOverflowTest.cpp",
|
||||
"$_tests/InfRectTest.cpp",
|
||||
|
@ -147,7 +147,6 @@ public:
|
||||
virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0;
|
||||
// Returns whether a texture of the given config can be copied to a texture of the same config.
|
||||
virtual bool isConfigCopyable(GrPixelConfig config) const = 0;
|
||||
virtual bool canConfigBeImageStorage(GrPixelConfig config) const = 0;
|
||||
|
||||
bool suppressPrints() const { return fSuppressPrints; }
|
||||
|
||||
|
@ -244,14 +244,6 @@ public:
|
||||
|
||||
int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
|
||||
|
||||
int maxVertexImageStorages() const { return fMaxVertexImageStorages; }
|
||||
|
||||
int maxGeometryImageStorages() const { return fMaxGeometryImageStorages; }
|
||||
|
||||
int maxFragmentImageStorages() const { return fMaxFragmentImageStorages; }
|
||||
|
||||
int maxCombinedImageStorages() const { return fMaxCombinedImageStorages; }
|
||||
|
||||
bool disableImageMultitexturingSupport() const { return fDisableImageMultitexturing; }
|
||||
|
||||
/**
|
||||
@ -342,11 +334,6 @@ private:
|
||||
int fMaxFragmentSamplers;
|
||||
int fMaxCombinedSamplers;
|
||||
|
||||
int fMaxVertexImageStorages;
|
||||
int fMaxGeometryImageStorages;
|
||||
int fMaxFragmentImageStorages;
|
||||
int fMaxCombinedImageStorages;
|
||||
|
||||
AdvBlendEqInteraction fAdvBlendEqInteraction;
|
||||
|
||||
GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
|
||||
|
@ -29,14 +29,6 @@ public:
|
||||
|
||||
GrSamplerState::Filter highestFilterMode() const;
|
||||
|
||||
GrSLType imageStorageType() const {
|
||||
if (GrPixelConfigIsSint(this->config())) {
|
||||
return kIImageStorage2D_GrSLType;
|
||||
} else {
|
||||
return kImageStorage2D_GrSLType;
|
||||
}
|
||||
}
|
||||
|
||||
GrMipMapped mipMapped() const { return fMipMapped; }
|
||||
|
||||
/**
|
||||
|
@ -140,8 +140,6 @@ enum GrSLType {
|
||||
kBufferSampler_GrSLType,
|
||||
kTexture2D_GrSLType,
|
||||
kSampler_GrSLType,
|
||||
kImageStorage2D_GrSLType,
|
||||
kIImageStorage2D_GrSLType,
|
||||
};
|
||||
|
||||
enum GrShaderType {
|
||||
@ -225,8 +223,6 @@ static inline bool GrSLTypeIsFloatType(GrSLType type) {
|
||||
case kUint2_GrSLType:
|
||||
case kTexture2D_GrSLType:
|
||||
case kSampler_GrSLType:
|
||||
case kImageStorage2D_GrSLType:
|
||||
case kIImageStorage2D_GrSLType:
|
||||
return false;
|
||||
}
|
||||
SK_ABORT("Unexpected type");
|
||||
@ -274,8 +270,6 @@ static inline bool GrSLTypeIs2DCombinedSamplerType(GrSLType type) {
|
||||
case kUShort4_GrSLType:
|
||||
case kTexture2D_GrSLType:
|
||||
case kSampler_GrSLType:
|
||||
case kImageStorage2D_GrSLType:
|
||||
case kIImageStorage2D_GrSLType:
|
||||
return false;
|
||||
}
|
||||
SK_ABORT("Unexpected type");
|
||||
@ -323,57 +317,6 @@ static inline bool GrSLTypeIsCombinedSamplerType(GrSLType type) {
|
||||
case kUShort4_GrSLType:
|
||||
case kTexture2D_GrSLType:
|
||||
case kSampler_GrSLType:
|
||||
case kImageStorage2D_GrSLType:
|
||||
case kIImageStorage2D_GrSLType:
|
||||
return false;
|
||||
}
|
||||
SK_ABORT("Unexpected type");
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool GrSLTypeIsImageStorage(GrSLType type) {
|
||||
switch (type) {
|
||||
case kImageStorage2D_GrSLType:
|
||||
case kIImageStorage2D_GrSLType:
|
||||
return true;
|
||||
|
||||
case kVoid_GrSLType:
|
||||
case kFloat_GrSLType:
|
||||
case kFloat2_GrSLType:
|
||||
case kFloat3_GrSLType:
|
||||
case kFloat4_GrSLType:
|
||||
case kFloat2x2_GrSLType:
|
||||
case kFloat3x3_GrSLType:
|
||||
case kFloat4x4_GrSLType:
|
||||
case kHalf_GrSLType:
|
||||
case kHalf2_GrSLType:
|
||||
case kHalf3_GrSLType:
|
||||
case kHalf4_GrSLType:
|
||||
case kHalf2x2_GrSLType:
|
||||
case kHalf3x3_GrSLType:
|
||||
case kHalf4x4_GrSLType:
|
||||
case kInt_GrSLType:
|
||||
case kInt2_GrSLType:
|
||||
case kInt3_GrSLType:
|
||||
case kInt4_GrSLType:
|
||||
case kUint_GrSLType:
|
||||
case kUint2_GrSLType:
|
||||
case kBool_GrSLType:
|
||||
case kShort_GrSLType:
|
||||
case kShort2_GrSLType:
|
||||
case kShort3_GrSLType:
|
||||
case kShort4_GrSLType:
|
||||
case kUShort_GrSLType:
|
||||
case kUShort2_GrSLType:
|
||||
case kUShort3_GrSLType:
|
||||
case kUShort4_GrSLType:
|
||||
case kTexture2D_GrSLType:
|
||||
case kSampler_GrSLType:
|
||||
case kTexture2DSampler_GrSLType:
|
||||
case kITexture2DSampler_GrSLType:
|
||||
case kTextureExternalSampler_GrSLType:
|
||||
case kTexture2DRectSampler_GrSLType:
|
||||
case kBufferSampler_GrSLType:
|
||||
return false;
|
||||
}
|
||||
SK_ABORT("Unexpected type");
|
||||
@ -389,8 +332,6 @@ static inline bool GrSLTypeAcceptsPrecision(GrSLType type) {
|
||||
case kBufferSampler_GrSLType:
|
||||
case kTexture2D_GrSLType:
|
||||
case kSampler_GrSLType:
|
||||
case kImageStorage2D_GrSLType:
|
||||
case kIImageStorage2D_GrSLType:
|
||||
return true;
|
||||
|
||||
case kVoid_GrSLType:
|
||||
@ -462,8 +403,6 @@ static inline bool GrSLTypeTemporarilyAcceptsPrecision(GrSLType type) {
|
||||
case kBufferSampler_GrSLType:
|
||||
case kTexture2D_GrSLType:
|
||||
case kSampler_GrSLType:
|
||||
case kImageStorage2D_GrSLType:
|
||||
case kIImageStorage2D_GrSLType:
|
||||
return true;
|
||||
|
||||
case kVoid_GrSLType:
|
||||
@ -605,40 +544,6 @@ static inline GrSLType GrVertexAttribTypeToSLType(GrVertexAttribType type) {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum class GrImageStorageFormat {
|
||||
kRGBA8,
|
||||
kRGBA8i,
|
||||
kRGBA16f,
|
||||
kRGBA32f,
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes types of caching and compiler optimizations allowed for certain variable types
|
||||
* (currently only image storages).
|
||||
**/
|
||||
enum class GrSLMemoryModel {
|
||||
/** No special restrctions on memory accesses or compiler optimizations */
|
||||
kNone,
|
||||
/** Cache coherent across shader invocations */
|
||||
kCoherent,
|
||||
/**
|
||||
* Disallows compiler from eliding loads or stores that appear redundant in a single
|
||||
* invocation. Implies coherent.
|
||||
*/
|
||||
kVolatile
|
||||
};
|
||||
|
||||
/**
|
||||
* If kYes then the memory backing the varialble is only accessed via the variable. This is
|
||||
* currently only used with image storages.
|
||||
*/
|
||||
enum class GrSLRestrict {
|
||||
kYes,
|
||||
kNo,
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const int kGrClipEdgeTypeCnt = (int) GrClipEdgeType::kLast + 1;
|
||||
|
||||
static inline bool GrProcessorEdgeTypeIsFill(const GrClipEdgeType edgeType) {
|
||||
|
@ -376,8 +376,6 @@
|
||||
"image",
|
||||
"_",
|
||||
".SRW",
|
||||
"--match",
|
||||
"~ImageStorageLoad",
|
||||
"--nonativeFonts",
|
||||
"--verbose"
|
||||
],
|
||||
|
@ -687,9 +687,6 @@ def dm_flags(api, bot):
|
||||
# skia:6857
|
||||
blacklist(['angle_d3d9_es2', 'gm', '_', 'lighting'])
|
||||
|
||||
if 'IntelBayTrail' in bot and api.vars.is_linux:
|
||||
match.append('~ImageStorageLoad') # skia:6358
|
||||
|
||||
if 'PowerVRGX6250' in bot:
|
||||
match.append('~gradients_view_perspective_nodither') #skia:6972
|
||||
|
||||
|
@ -133,10 +133,6 @@ void GrResourceIOProcessor::addBufferAccess(const BufferAccess* access) {
|
||||
fBufferAccesses.push_back(access);
|
||||
}
|
||||
|
||||
void GrResourceIOProcessor::addImageStorageAccess(const ImageStorageAccess* access) {
|
||||
fImageStorageAccesses.push_back(access);
|
||||
}
|
||||
|
||||
void GrResourceIOProcessor::addPendingIOs() const {
|
||||
for (const auto& sampler : fTextureSamplers) {
|
||||
sampler->programProxy()->markPendingIO();
|
||||
@ -144,9 +140,6 @@ void GrResourceIOProcessor::addPendingIOs() const {
|
||||
for (const auto& buffer : fBufferAccesses) {
|
||||
buffer->programBuffer()->markPendingIO();
|
||||
}
|
||||
for (const auto& imageStorage : fImageStorageAccesses) {
|
||||
imageStorage->programProxy()->markPendingIO();
|
||||
}
|
||||
}
|
||||
|
||||
void GrResourceIOProcessor::removeRefs() const {
|
||||
@ -156,9 +149,6 @@ void GrResourceIOProcessor::removeRefs() const {
|
||||
for (const auto& buffer : fBufferAccesses) {
|
||||
buffer->programBuffer()->removeRef();
|
||||
}
|
||||
for (const auto& imageStorage : fImageStorageAccesses) {
|
||||
imageStorage->programProxy()->removeRef();
|
||||
}
|
||||
}
|
||||
|
||||
void GrResourceIOProcessor::pendingIOComplete() const {
|
||||
@ -168,9 +158,6 @@ void GrResourceIOProcessor::pendingIOComplete() const {
|
||||
for (const auto& buffer : fBufferAccesses) {
|
||||
buffer->programBuffer()->pendingIOComplete();
|
||||
}
|
||||
for (const auto& imageStorage : fImageStorageAccesses) {
|
||||
imageStorage->programProxy()->pendingIOComplete();
|
||||
}
|
||||
}
|
||||
|
||||
bool GrResourceIOProcessor::instantiate(GrResourceProvider* resourceProvider) const {
|
||||
@ -182,19 +169,12 @@ bool GrResourceIOProcessor::instantiate(GrResourceProvider* resourceProvider) co
|
||||
|
||||
// MDB TODO: instantiate 'fBufferAccesses' here as well
|
||||
|
||||
for (const auto& imageStorage : fImageStorageAccesses) {
|
||||
if (!imageStorage->instantiate(resourceProvider)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrResourceIOProcessor::hasSameSamplersAndAccesses(const GrResourceIOProcessor& that) const {
|
||||
if (this->numTextureSamplers() != that.numTextureSamplers() ||
|
||||
this->numBuffers() != that.numBuffers() ||
|
||||
this->numImageStorages() != that.numImageStorages()) {
|
||||
this->numBuffers() != that.numBuffers()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < this->numTextureSamplers(); ++i) {
|
||||
@ -207,11 +187,6 @@ bool GrResourceIOProcessor::hasSameSamplersAndAccesses(const GrResourceIOProcess
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < this->numImageStorages(); ++i) {
|
||||
if (this->imageStorageAccess(i) != that.imageStorageAccess(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -249,37 +224,3 @@ void GrResourceIOProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
|
||||
fSamplerState = GrSamplerState(wrapXAndY, filterMode);
|
||||
fVisibility = visibility;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrResourceIOProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTextureProxy> proxy,
|
||||
GrIOType ioType,
|
||||
GrSLMemoryModel memoryModel,
|
||||
GrSLRestrict restrict,
|
||||
GrShaderFlags visibility)
|
||||
: fProxyRef(std::move(proxy), ioType) {
|
||||
SkASSERT(fProxyRef.get());
|
||||
|
||||
fMemoryModel = memoryModel;
|
||||
fRestrict = restrict;
|
||||
fVisibility = visibility;
|
||||
// We currently infer this from the config. However, we could allow the client to specify
|
||||
// a format that is different but compatible with the config.
|
||||
switch (fProxyRef.get()->config()) {
|
||||
case kRGBA_8888_GrPixelConfig:
|
||||
fFormat = GrImageStorageFormat::kRGBA8;
|
||||
break;
|
||||
case kRGBA_8888_sint_GrPixelConfig:
|
||||
fFormat = GrImageStorageFormat::kRGBA8i;
|
||||
break;
|
||||
case kRGBA_half_GrPixelConfig:
|
||||
fFormat = GrImageStorageFormat::kRGBA16f;
|
||||
break;
|
||||
case kRGBA_float_GrPixelConfig:
|
||||
fFormat = GrImageStorageFormat::kRGBA32f;
|
||||
break;
|
||||
default:
|
||||
SK_ABORT("Config is not (yet) supported as image storage.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -227,7 +227,6 @@ class GrResourceIOProcessor : public GrProcessor {
|
||||
public:
|
||||
class TextureSampler;
|
||||
class BufferAccess;
|
||||
class ImageStorageAccess;
|
||||
|
||||
int numTextureSamplers() const { return fTextureSamplers.count(); }
|
||||
|
||||
@ -241,14 +240,6 @@ public:
|
||||
numBuffers(). */
|
||||
const BufferAccess& bufferAccess(int index) const { return *fBufferAccesses[index]; }
|
||||
|
||||
int numImageStorages() const { return fImageStorageAccesses.count(); }
|
||||
|
||||
/** Returns the access object for the image at index. index must be valid according to
|
||||
numImages(). */
|
||||
const ImageStorageAccess& imageStorageAccess(int index) const {
|
||||
return *fImageStorageAccesses[index];
|
||||
}
|
||||
|
||||
bool instantiate(GrResourceProvider* resourceProvider) const;
|
||||
|
||||
protected:
|
||||
@ -256,14 +247,13 @@ protected:
|
||||
: INHERITED(classID) {}
|
||||
|
||||
/**
|
||||
* Subclasses call these from their constructor to register sampler/image sources. The processor
|
||||
* Subclasses call these from their constructor to register sampler sources. The processor
|
||||
* subclass manages the lifetime of the objects (these functions only store pointers). The
|
||||
* TextureSampler and/or BufferAccess instances are typically member fields of the GrProcessor
|
||||
* subclass. These must only be called from the constructor because GrProcessors are immutable.
|
||||
*/
|
||||
void addTextureSampler(const TextureSampler*);
|
||||
void addBufferAccess(const BufferAccess*);
|
||||
void addImageStorageAccess(const ImageStorageAccess*);
|
||||
|
||||
bool hasSameSamplersAndAccesses(const GrResourceIOProcessor&) const;
|
||||
|
||||
@ -275,7 +265,6 @@ protected:
|
||||
private:
|
||||
SkSTArray<4, const TextureSampler*, true> fTextureSamplers;
|
||||
SkSTArray<1, const BufferAccess*, true> fBufferAccesses;
|
||||
SkSTArray<1, const ImageStorageAccess*, true> fImageStorageAccesses;
|
||||
|
||||
typedef GrProcessor INHERITED;
|
||||
};
|
||||
@ -408,65 +397,4 @@ private:
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is used by a GrProcessor to access a texture using image load/store in its shader code.
|
||||
* ImageStorageAccesses don't perform any coord manipulation to account for texture origin.
|
||||
* Currently the format of the load/store data in the shader is inferred from the texture config,
|
||||
* though it could be made explicit.
|
||||
*/
|
||||
class GrResourceIOProcessor::ImageStorageAccess {
|
||||
public:
|
||||
ImageStorageAccess(sk_sp<GrTextureProxy>, GrIOType, GrSLMemoryModel, GrSLRestrict,
|
||||
GrShaderFlags visibility = kFragment_GrShaderFlag);
|
||||
/**
|
||||
* This copy constructor is used by GrFragmentProcessor::clone() implementations. The copy
|
||||
* always takes a new ref on the surface proxy as the new fragment processor will not yet be
|
||||
* in pending execution state.
|
||||
*/
|
||||
explicit ImageStorageAccess(const ImageStorageAccess& that)
|
||||
: fProxyRef(sk_ref_sp(that.fProxyRef.get()), that.fProxyRef.ioType())
|
||||
, fVisibility(that.fVisibility)
|
||||
, fFormat(that.fFormat)
|
||||
, fMemoryModel(that.fMemoryModel)
|
||||
, fRestrict(that.fRestrict) {}
|
||||
|
||||
ImageStorageAccess& operator=(const ImageStorageAccess&) = delete;
|
||||
|
||||
bool operator==(const ImageStorageAccess& that) const {
|
||||
return this->proxy() == that.proxy() && fVisibility == that.fVisibility;
|
||||
}
|
||||
|
||||
bool operator!=(const ImageStorageAccess& that) const { return !(*this == that); }
|
||||
|
||||
GrTextureProxy* proxy() const { return fProxyRef.get()->asTextureProxy(); }
|
||||
GrShaderFlags visibility() const { return fVisibility; }
|
||||
GrIOType ioType() const { return fProxyRef.ioType(); }
|
||||
GrImageStorageFormat format() const { return fFormat; }
|
||||
GrSLMemoryModel memoryModel() const { return fMemoryModel; }
|
||||
GrSLRestrict restrict() const { return fRestrict; }
|
||||
|
||||
// 'instantiate' should only ever be called at flush time.
|
||||
bool instantiate(GrResourceProvider* resourceProvider) const {
|
||||
return SkToBool(fProxyRef.get()->instantiate(resourceProvider));
|
||||
}
|
||||
// 'peekTexture' should only ever be called after a successful 'instantiate' call
|
||||
GrTexture* peekTexture() const {
|
||||
SkASSERT(fProxyRef.get()->priv().peekTexture());
|
||||
return fProxyRef.get()->priv().peekTexture();
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use by GrProcessor.
|
||||
*/
|
||||
const GrSurfaceProxyRef* programProxy() const { return &fProxyRef; }
|
||||
|
||||
private:
|
||||
GrSurfaceProxyRef fProxyRef;
|
||||
GrShaderFlags fVisibility;
|
||||
GrImageStorageFormat fFormat;
|
||||
GrSLMemoryModel fMemoryModel;
|
||||
GrSLRestrict fRestrict;
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -37,12 +37,6 @@ static inline uint16_t image_storage_or_sampler_uniform_type_key(GrSLType type )
|
||||
case kBufferSampler_GrSLType:
|
||||
value = 4;
|
||||
break;
|
||||
case kImageStorage2D_GrSLType:
|
||||
value = 5;
|
||||
break;
|
||||
case kIImageStorage2D_GrSLType:
|
||||
value = 6;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -61,18 +55,11 @@ static uint16_t sampler_key(GrSLType samplerType, GrPixelConfig config, GrShader
|
||||
(caps.samplerPrecision(config, visibility) << (8 + kSamplerOrImageTypeKeyBits)));
|
||||
}
|
||||
|
||||
static uint16_t storage_image_key(const GrResourceIOProcessor::ImageStorageAccess& imageAccess) {
|
||||
GrSLType type = imageAccess.proxy()->imageStorageType();
|
||||
return image_storage_or_sampler_uniform_type_key(type) |
|
||||
(int)imageAccess.format() << kSamplerOrImageTypeKeyBits;
|
||||
}
|
||||
|
||||
static void add_sampler_and_image_keys(GrProcessorKeyBuilder* b, const GrResourceIOProcessor& proc,
|
||||
const GrShaderCaps& caps) {
|
||||
int numTextureSamplers = proc.numTextureSamplers();
|
||||
int numBuffers = proc.numBuffers();
|
||||
int numImageStorages = proc.numImageStorages();
|
||||
int numUniforms = numTextureSamplers + numBuffers + numImageStorages;
|
||||
int numUniforms = numTextureSamplers + numBuffers;
|
||||
// Need two bytes per key.
|
||||
int word32Count = (numUniforms + 1) / 2;
|
||||
if (0 == word32Count) {
|
||||
@ -92,9 +79,6 @@ static void add_sampler_and_image_keys(GrProcessorKeyBuilder* b, const GrResourc
|
||||
k16[j] = sampler_key(kBufferSampler_GrSLType, access.texelConfig(), access.visibility(),
|
||||
caps);
|
||||
}
|
||||
for (int i = 0; i < numImageStorages; ++i, ++j) {
|
||||
k16[j] = storage_image_key(proc.imageStorageAccess(i));
|
||||
}
|
||||
// zero the last 16 bits if the number of uniforms for samplers and image storages is odd.
|
||||
if (numUniforms & 0x1) {
|
||||
k16[numUniforms] = 0;
|
||||
|
@ -91,10 +91,6 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
|
||||
fMaxGeometrySamplers = 0;
|
||||
fMaxFragmentSamplers = 0;
|
||||
fMaxCombinedSamplers = 0;
|
||||
fMaxVertexImageStorages = 0;
|
||||
fMaxGeometryImageStorages = 0;
|
||||
fMaxFragmentImageStorages = 0;
|
||||
fMaxCombinedImageStorages = 0;
|
||||
fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
@ -175,10 +171,6 @@ void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const {
|
||||
writer->appendS32("Max GS Samplers", fMaxGeometrySamplers);
|
||||
writer->appendS32("Max FS Samplers", fMaxFragmentSamplers);
|
||||
writer->appendS32("Max Combined Samplers", fMaxFragmentSamplers);
|
||||
writer->appendS32("Max VS Image Storages", fMaxVertexImageStorages);
|
||||
writer->appendS32("Max GS Image Storages", fMaxGeometryImageStorages);
|
||||
writer->appendS32("Max FS Image Storages", fMaxFragmentImageStorages);
|
||||
writer->appendS32("Max Combined Image Storages", fMaxFragmentImageStorages);
|
||||
writer->appendString("Advanced blend equation interaction",
|
||||
kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]);
|
||||
writer->appendBool("Disable image multitexturing", fDisableImageMultitexturing);
|
||||
|
@ -21,51 +21,6 @@ static const char* type_modifier_string(GrShaderVar::TypeModifier t) {
|
||||
return "";
|
||||
}
|
||||
|
||||
void GrShaderVar::setImageStorageFormat(GrImageStorageFormat format) {
|
||||
const char* formatStr = nullptr;
|
||||
switch (format) {
|
||||
case GrImageStorageFormat::kRGBA8:
|
||||
formatStr = "rgba8";
|
||||
break;
|
||||
case GrImageStorageFormat::kRGBA8i:
|
||||
formatStr = "rgba8i";
|
||||
break;
|
||||
case GrImageStorageFormat::kRGBA16f:
|
||||
formatStr = "rgba16f";
|
||||
break;
|
||||
case GrImageStorageFormat::kRGBA32f:
|
||||
formatStr = "rgba32f";
|
||||
break;
|
||||
}
|
||||
this->addLayoutQualifier(formatStr);
|
||||
SkASSERT(formatStr);
|
||||
}
|
||||
|
||||
void GrShaderVar::setMemoryModel(GrSLMemoryModel model) {
|
||||
switch (model) {
|
||||
case GrSLMemoryModel::kNone:
|
||||
return;
|
||||
case GrSLMemoryModel::kCoherent:
|
||||
this->addModifier("coherent");
|
||||
return;
|
||||
case GrSLMemoryModel::kVolatile:
|
||||
this->addModifier("volatile");
|
||||
return;
|
||||
}
|
||||
SK_ABORT("Unknown memory model.");
|
||||
}
|
||||
|
||||
void GrShaderVar::setRestrict(GrSLRestrict restrict) {
|
||||
switch (restrict) {
|
||||
case GrSLRestrict::kNo:
|
||||
return;
|
||||
case GrSLRestrict::kYes:
|
||||
this->addModifier("restrict");
|
||||
return;
|
||||
}
|
||||
SK_ABORT("Unknown restrict.");
|
||||
}
|
||||
|
||||
void GrShaderVar::setIOType(GrIOType ioType) {
|
||||
switch (ioType) {
|
||||
case kRW_GrIOType:
|
||||
|
@ -283,12 +283,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void setImageStorageFormat(GrImageStorageFormat format);
|
||||
|
||||
void setMemoryModel(GrSLMemoryModel);
|
||||
|
||||
void setRestrict(GrSLRestrict);
|
||||
|
||||
void setIOType(GrIOType);
|
||||
|
||||
void addModifier(const char* modifier) {
|
||||
|
@ -44,14 +44,6 @@ public:
|
||||
return fTexture->fMaxMipMapLevel;
|
||||
}
|
||||
|
||||
GrSLType imageStorageType() const {
|
||||
if (GrPixelConfigIsSint(fTexture->config())) {
|
||||
return kIImageStorage2D_GrSLType;
|
||||
} else {
|
||||
return kImageStorage2D_GrSLType;
|
||||
}
|
||||
}
|
||||
|
||||
GrSLType samplerType() const { return fTexture->fSamplerType; }
|
||||
|
||||
/** The filter used is clamped to this value in GrProcessor::TextureSampler. */
|
||||
|
@ -358,42 +358,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
|
||||
shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
|
||||
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(4, 2);
|
||||
if (!shaderCaps->fImageLoadStoreSupport &&
|
||||
ctxInfo.hasExtension("GL_ARB_shader_image_load_store")) {
|
||||
shaderCaps->fImageLoadStoreSupport = true;
|
||||
shaderCaps->fImageLoadStoreExtensionString = "GL_ARB_shader_image_load_store";
|
||||
}
|
||||
} else {
|
||||
shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(3, 1);
|
||||
}
|
||||
if (shaderCaps->fImageLoadStoreSupport) {
|
||||
// Protect ourselves against tracking huge amounts of image state.
|
||||
static constexpr int kMaxSaneImages = 4;
|
||||
GrGLint maxUnits;
|
||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_IMAGE_UNITS, &maxUnits);
|
||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS,
|
||||
&shaderCaps->fMaxVertexImageStorages);
|
||||
if (shaderCaps->fGeometryShaderSupport) {
|
||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
|
||||
&shaderCaps->fMaxGeometryImageStorages);
|
||||
}
|
||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
|
||||
&shaderCaps->fMaxFragmentImageStorages);
|
||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS,
|
||||
&shaderCaps->fMaxCombinedImageStorages);
|
||||
// We use one unit for every image uniform
|
||||
shaderCaps->fMaxCombinedImageStorages = SkTMin(SkTMin(shaderCaps->fMaxCombinedImageStorages,
|
||||
maxUnits), kMaxSaneImages);
|
||||
shaderCaps->fMaxVertexImageStorages = SkTMin(maxUnits,
|
||||
shaderCaps->fMaxVertexImageStorages);
|
||||
shaderCaps->fMaxGeometryImageStorages = SkTMin(maxUnits,
|
||||
shaderCaps->fMaxGeometryImageStorages);
|
||||
shaderCaps->fMaxFragmentImageStorages = SkTMin(maxUnits,
|
||||
shaderCaps->fMaxFragmentImageStorages);
|
||||
}
|
||||
|
||||
// SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
|
||||
// frequently changing VBOs. We've measured a performance increase using non-VBO vertex
|
||||
// data for dynamic content on these GPUs. Perhaps we should read the renderer string and
|
||||
@ -2243,24 +2207,6 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
|
||||
}
|
||||
}
|
||||
|
||||
// We currently only support images on rgba textures formats. We could add additional formats
|
||||
// if desired. The shader builder would have to be updated to add swizzles where appropriate
|
||||
// (e.g. where we use GL_RED textures to implement alpha configs).
|
||||
if (this->shaderCaps()->imageLoadStoreSupport()) {
|
||||
fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
|
||||
ConfigInfo::kCanUseAsImageStorage_Flag;
|
||||
// In OpenGL ES a texture may only be used with BindImageTexture if it has been made
|
||||
// immutable via TexStorage. We create non-integer textures as mutable textures using
|
||||
// TexImage because we may lazily add MIP levels. Thus, on ES we currently disable image
|
||||
// storage support for non-integer textures.
|
||||
if (kGL_GrGLStandard == ctxInfo.standard()) {
|
||||
fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
|
||||
fConfigTable[kRGBA_float_GrPixelConfig].fFlags |=
|
||||
ConfigInfo::kCanUseAsImageStorage_Flag;
|
||||
fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < kGrPixelConfigCnt; ++i) {
|
||||
if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
|
||||
if ((kGL_GrGLStandard == ctxInfo.standard() &&
|
||||
|
@ -134,9 +134,6 @@ public:
|
||||
return this->isConfigRenderable(config, false);
|
||||
}
|
||||
|
||||
bool canConfigBeImageStorage(GrPixelConfig config) const override {
|
||||
return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseAsImageStorage_Flag);
|
||||
}
|
||||
bool canConfigBeFBOColorAttachment(GrPixelConfig config) const {
|
||||
return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kFBOColorAttachment_Flag);
|
||||
}
|
||||
@ -568,7 +565,6 @@ private:
|
||||
kFBOColorAttachment_Flag = 0x10,
|
||||
kCanUseTexStorage_Flag = 0x20,
|
||||
kCanUseWithTexelBuffer_Flag = 0x40,
|
||||
kCanUseAsImageStorage_Flag = 0x80,
|
||||
};
|
||||
uint32_t fFlags;
|
||||
|
||||
|
@ -223,7 +223,6 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
|
||||
fCaps.reset(SkRef(ctx->caps()));
|
||||
|
||||
fHWBoundTextureUniqueIDs.reset(this->caps()->shaderCaps()->maxCombinedSamplers());
|
||||
fHWBoundImageStorages.reset(this->caps()->shaderCaps()->maxCombinedImageStorages());
|
||||
|
||||
fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER;
|
||||
fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER;
|
||||
@ -451,10 +450,6 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
|
||||
SkASSERT(this->caps()->shaderCaps()->texelBufferSupport());
|
||||
fHWBufferTextures[b].fKnownBound = false;
|
||||
}
|
||||
for (int i = 0; i < fHWBoundImageStorages.count(); ++i) {
|
||||
SkASSERT(this->caps()->shaderCaps()->imageLoadStoreSupport());
|
||||
fHWBoundImageStorages[i].fTextureUniqueID.makeInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
if (resetBits & kBlend_GrGLBackendState) {
|
||||
@ -3182,27 +3177,6 @@ void GrGLGpu::bindTexelBuffer(int unitIdx, GrPixelConfig texelConfig, GrGLBuffer
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLGpu::bindImageStorage(int unitIdx, GrIOType ioType, GrGLTexture *texture) {
|
||||
SkASSERT(texture);
|
||||
if (texture->uniqueID() != fHWBoundImageStorages[unitIdx].fTextureUniqueID ||
|
||||
ioType != fHWBoundImageStorages[unitIdx].fIOType) {
|
||||
GrGLenum access = GR_GL_READ_ONLY;
|
||||
switch (ioType) {
|
||||
case kRead_GrIOType:
|
||||
access = GR_GL_READ_ONLY;
|
||||
break;
|
||||
case kWrite_GrIOType:
|
||||
access = GR_GL_WRITE_ONLY;
|
||||
break;
|
||||
case kRW_GrIOType:
|
||||
access = GR_GL_READ_WRITE;
|
||||
break;
|
||||
}
|
||||
GrGLenum format = this->glCaps().getImageFormat(texture->config());
|
||||
GL_CALL(BindImageTexture(unitIdx, texture->textureID(), 0, GR_GL_FALSE, 0, access, format));
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLGpu::generateMipmaps(const GrSamplerState& params, bool allowSRGBInputs,
|
||||
GrGLTexture* texture, GrSurfaceOrigin textureOrigin) {
|
||||
SkASSERT(texture);
|
||||
|
@ -64,8 +64,6 @@ public:
|
||||
|
||||
void bindTexelBuffer(int unitIdx, GrPixelConfig, GrGLBuffer*);
|
||||
|
||||
void bindImageStorage(int unitIdx, GrIOType, GrGLTexture *);
|
||||
|
||||
void generateMipmaps(const GrSamplerState& params, bool allowSRGBInputs, GrGLTexture* texture,
|
||||
GrSurfaceOrigin textureOrigin);
|
||||
|
||||
@ -592,12 +590,6 @@ private:
|
||||
TriState fHWSRGBFramebuffer;
|
||||
SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs;
|
||||
|
||||
struct Image {
|
||||
GrGpuResource::UniqueID fTextureUniqueID;
|
||||
GrIOType fIOType;
|
||||
};
|
||||
SkTArray<Image, true> fHWBoundImageStorages;
|
||||
|
||||
struct BufferTexture {
|
||||
BufferTexture() : fTextureID(0), fKnownBound(false),
|
||||
fAttachedBufferUniqueID(SK_InvalidUniqueID),
|
||||
|
@ -32,7 +32,6 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu,
|
||||
const UniformInfoArray& uniforms,
|
||||
const UniformInfoArray& textureSamplers,
|
||||
const UniformInfoArray& texelBuffers,
|
||||
const UniformInfoArray& imageStorages,
|
||||
const VaryingInfoArray& pathProcVaryings,
|
||||
std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
|
||||
std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
|
||||
@ -51,7 +50,6 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu,
|
||||
GL_CALL(UseProgram(fProgramID));
|
||||
fProgramDataManager.setSamplerUniforms(textureSamplers, 0);
|
||||
fProgramDataManager.setSamplerUniforms(texelBuffers, fNumTextureSamplers);
|
||||
fProgramDataManager.setImageStorages(imageStorages);
|
||||
}
|
||||
|
||||
GrGLProgram::~GrGLProgram() {
|
||||
@ -77,18 +75,15 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline
|
||||
|
||||
// We must bind to texture units in the same order in which we set the uniforms in
|
||||
// GrGLProgramDataManager. That is first all texture samplers and then texel buffers.
|
||||
// ImageStorages are bound to their own image units so they are tracked separately.
|
||||
// Within each group we will bind them in primProc, fragProcs, XP order.
|
||||
int nextTexSamplerIdx = 0;
|
||||
int nextTexelBufferIdx = fNumTextureSamplers;
|
||||
int nextImageStorageIdx = 0;
|
||||
fGeometryProcessor->setData(fProgramDataManager, primProc,
|
||||
GrFragmentProcessor::CoordTransformIter(pipeline));
|
||||
this->bindTextures(primProc, pipeline.getAllowSRGBInputs(), &nextTexSamplerIdx,
|
||||
&nextTexelBufferIdx, &nextImageStorageIdx);
|
||||
&nextTexelBufferIdx);
|
||||
|
||||
this->setFragmentData(primProc, pipeline, &nextTexSamplerIdx, &nextTexelBufferIdx,
|
||||
&nextImageStorageIdx);
|
||||
this->setFragmentData(primProc, pipeline, &nextTexSamplerIdx, &nextTexelBufferIdx);
|
||||
|
||||
const GrXferProcessor& xp = pipeline.getXferProcessor();
|
||||
SkIPoint offset;
|
||||
@ -117,8 +112,7 @@ void GrGLProgram::generateMipmaps(const GrPrimitiveProcessor& primProc,
|
||||
void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
int* nextTexSamplerIdx,
|
||||
int* nextTexelBufferIdx,
|
||||
int* nextImageStorageIdx) {
|
||||
int* nextTexelBufferIdx) {
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.begin(),
|
||||
fFragmentProcessors.count());
|
||||
@ -127,7 +121,7 @@ void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
|
||||
while (fp && glslFP) {
|
||||
glslFP->setData(fProgramDataManager, *fp);
|
||||
this->bindTextures(*fp, pipeline.getAllowSRGBInputs(), nextTexSamplerIdx,
|
||||
nextTexelBufferIdx, nextImageStorageIdx);
|
||||
nextTexelBufferIdx);
|
||||
fp = iter.next();
|
||||
glslFP = glslIter.next();
|
||||
}
|
||||
@ -168,8 +162,7 @@ void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
|
||||
void GrGLProgram::bindTextures(const GrResourceIOProcessor& processor,
|
||||
bool allowSRGBInputs,
|
||||
int* nextTexSamplerIdx,
|
||||
int* nextTexelBufferIdx,
|
||||
int* nextImageStorageIdx) {
|
||||
int* nextTexelBufferIdx) {
|
||||
for (int i = 0; i < processor.numTextureSamplers(); ++i) {
|
||||
const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
|
||||
fGpu->bindTexture((*nextTexSamplerIdx)++, sampler.samplerState(), allowSRGBInputs,
|
||||
@ -181,11 +174,6 @@ void GrGLProgram::bindTextures(const GrResourceIOProcessor& processor,
|
||||
fGpu->bindTexelBuffer((*nextTexelBufferIdx)++, access.texelConfig(),
|
||||
static_cast<GrGLBuffer*>(access.buffer()));
|
||||
}
|
||||
for (int i = 0; i < processor.numImageStorages(); ++i) {
|
||||
const GrResourceIOProcessor::ImageStorageAccess& access = processor.imageStorageAccess(i);
|
||||
fGpu->bindImageStorage((*nextImageStorageIdx)++, access.ioType(),
|
||||
static_cast<GrGLTexture *>(access.peekTexture()));
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgram::generateMipmaps(const GrResourceIOProcessor& processor, bool allowSRGBInputs) {
|
||||
|
@ -113,7 +113,6 @@ protected:
|
||||
const UniformInfoArray& uniforms,
|
||||
const UniformInfoArray& textureSamplers,
|
||||
const UniformInfoArray& texelBuffers,
|
||||
const UniformInfoArray& imageStorages,
|
||||
const VaryingInfoArray&, // used for NVPR only currently
|
||||
std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
|
||||
std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
|
||||
@ -121,14 +120,14 @@ protected:
|
||||
|
||||
// A helper to loop over effects, set the transforms (via subclass) and bind textures
|
||||
void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextTexSamplerIdx,
|
||||
int* nextTexelBufferIdx, int* nextImageStorageIdx);
|
||||
int* nextTexelBufferIdx);
|
||||
|
||||
// Helper for setData() that sets the view matrix and loads the render target height uniform
|
||||
void setRenderTargetState(const GrPrimitiveProcessor&, const GrRenderTargetProxy*);
|
||||
|
||||
// Helper for setData() that binds textures and texel buffers to the appropriate texture units
|
||||
void bindTextures(const GrResourceIOProcessor&, bool allowSRGBInputs, int* nextSamplerIdx,
|
||||
int* nextTexelBufferIdx, int* nextImageStorageIdx);
|
||||
int* nextTexelBufferIdx);
|
||||
|
||||
// Helper for generateMipmaps() that ensures mipmaps are up to date
|
||||
void generateMipmaps(const GrResourceIOProcessor&, bool allowSRGBInputs);
|
||||
@ -149,7 +148,6 @@ protected:
|
||||
|
||||
int fNumTextureSamplers;
|
||||
int fNumTexelBuffers;
|
||||
int fNumImageStorages;
|
||||
|
||||
friend class GrGLProgramBuilder;
|
||||
|
||||
|
@ -61,16 +61,6 @@ void GrGLProgramDataManager::setSamplerUniforms(const UniformInfoArray& samplers
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgramDataManager::setImageStorages(const UniformInfoArray& images) const {
|
||||
for (int i = 0; i < images.count(); ++i) {
|
||||
const UniformInfo& image = images[i];
|
||||
SkASSERT(image.fVisibility);
|
||||
if (kUnusedUniform != image.fLocation) {
|
||||
GR_GL_CALL(fGpu->glInterface(), Uniform1i(image.fLocation, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgramDataManager::set1i(UniformHandle u, int32_t i) const {
|
||||
const Uniform& uni = fUniforms[u.toIndex()];
|
||||
SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
|
||||
|
@ -46,7 +46,6 @@ public:
|
||||
const VaryingInfoArray&);
|
||||
|
||||
void setSamplerUniforms(const UniformInfoArray& samplers, int startUnit) const;
|
||||
void setImageStorages(const UniformInfoArray& images) 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.
|
||||
|
@ -96,31 +96,6 @@ GrGLSLUniformHandler::TexelBufferHandle GrGLUniformHandler::addTexelBuffer(uint3
|
||||
return GrGLSLUniformHandler::TexelBufferHandle(fTexelBuffers.count() - 1);
|
||||
}
|
||||
|
||||
GrGLSLUniformHandler::ImageStorageHandle GrGLUniformHandler::addImageStorage(
|
||||
uint32_t visibility, GrSLType type, GrImageStorageFormat format, GrSLMemoryModel model,
|
||||
GrSLRestrict restrict, GrIOType ioType, const char* name) {
|
||||
SkASSERT(name && strlen(name));
|
||||
SkASSERT(0 != visibility);
|
||||
SkString mangleName;
|
||||
char prefix = 'u';
|
||||
fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
|
||||
|
||||
UniformInfo& imageStorage = fImageStorages.push_back();
|
||||
imageStorage.fVariable.setName(mangleName);
|
||||
|
||||
SkASSERT(GrSLTypeIsImageStorage(type));
|
||||
imageStorage.fVariable.setType(type);
|
||||
imageStorage.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
|
||||
imageStorage.fVariable.setImageStorageFormat(format);
|
||||
imageStorage.fVariable.setMemoryModel(model);
|
||||
imageStorage.fVariable.setRestrict(restrict);
|
||||
imageStorage.fVariable.setIOType(ioType);
|
||||
imageStorage.fVariable.setPrecision(kHigh_GrSLPrecision);
|
||||
imageStorage.fLocation = -1;
|
||||
imageStorage.fVisibility = visibility;
|
||||
return GrGLSLUniformHandler::ImageStorageHandle(fImageStorages.count() - 1);
|
||||
}
|
||||
|
||||
void GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
|
||||
for (int i = 0; i < fUniforms.count(); ++i) {
|
||||
if (fUniforms[i].fVisibility & visibility) {
|
||||
@ -140,12 +115,6 @@ void GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString*
|
||||
out->append(";\n");
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < fImageStorages.count(); ++i) {
|
||||
if (fImageStorages[i].fVisibility & visibility) {
|
||||
fImageStorages[i].fVariable.appendDecl(fProgramBuilder->shaderCaps(), out);
|
||||
out->append(";");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) {
|
||||
@ -164,11 +133,6 @@ void GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps
|
||||
fTexelBuffers[i].fVariable.c_str()));
|
||||
fTexelBuffers[i].fLocation = currUniform;
|
||||
}
|
||||
for (int i = 0; i < fImageStorages.count(); ++i, ++currUniform) {
|
||||
GL_CALL(BindUniformLocation(programID, currUniform,
|
||||
fImageStorages[i].fVariable.c_str()));
|
||||
fImageStorages[i].fLocation = currUniform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,12 +155,6 @@ void GrGLUniformHandler::getUniformLocations(GrGLuint programID, const GrGLCaps&
|
||||
fTexelBuffers[i].fVariable.c_str()));
|
||||
fTexelBuffers[i].fLocation = location;
|
||||
}
|
||||
for (int i = 0; i < fImageStorages.count(); ++i) {
|
||||
GrGLint location;
|
||||
GL_CALL_RET(location, GetUniformLocation(programID,
|
||||
fImageStorages[i].fVariable.c_str()));
|
||||
fImageStorages[i].fLocation = location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,7 @@ private:
|
||||
: INHERITED(program)
|
||||
, fUniforms(kUniformsPerBlock)
|
||||
, fSamplers(kUniformsPerBlock)
|
||||
, fTexelBuffers(kUniformsPerBlock)
|
||||
, fImageStorages(kUniformsPerBlock) {}
|
||||
, fTexelBuffers(kUniformsPerBlock) {}
|
||||
|
||||
UniformHandle internalAddUniformArray(uint32_t visibility,
|
||||
GrSLType type,
|
||||
@ -59,14 +58,6 @@ private:
|
||||
return fTexelBuffers[handle.toIndex()].fVariable;
|
||||
}
|
||||
|
||||
ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType, GrImageStorageFormat,
|
||||
GrSLMemoryModel, GrSLRestrict, GrIOType,
|
||||
const char* name) override;
|
||||
|
||||
const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const override {
|
||||
return fImageStorages[handle.toIndex()].fVariable;
|
||||
}
|
||||
|
||||
void appendUniformDecls(GrShaderFlags visibility, SkString*) const override;
|
||||
|
||||
// Manually set uniform locations for all our uniforms.
|
||||
@ -84,7 +75,6 @@ private:
|
||||
UniformInfoArray fSamplers;
|
||||
SkTArray<GrSwizzle> fSamplerSwizzles;
|
||||
UniformInfoArray fTexelBuffers;
|
||||
UniformInfoArray fImageStorages;
|
||||
|
||||
friend class GrGLProgramBuilder;
|
||||
|
||||
|
@ -369,7 +369,6 @@ GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
|
||||
fUniformHandler.fUniforms,
|
||||
fUniformHandler.fSamplers,
|
||||
fUniformHandler.fTexelBuffers,
|
||||
fUniformHandler.fImageStorages,
|
||||
fVaryingHandler.fPathProcVaryingInfos,
|
||||
std::move(fGeometryProcessor),
|
||||
std::move(fXferProcessor),
|
||||
|
@ -109,10 +109,6 @@ const char* GrGLSLTypeString(const GrShaderCaps* shaderCaps, GrSLType t) {
|
||||
return "texture2D";
|
||||
case kSampler_GrSLType:
|
||||
return "sampler";
|
||||
case kImageStorage2D_GrSLType:
|
||||
return "image2D";
|
||||
case kIImageStorage2D_GrSLType:
|
||||
return "iimage2D";
|
||||
}
|
||||
SK_ABORT("Unknown shader var type.");
|
||||
return ""; // suppress warning
|
||||
|
@ -49,7 +49,6 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
|
||||
TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
|
||||
TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
|
||||
TexelBuffers texelBuffers = args.fTexelBuffers.childInputs(childIndex);
|
||||
ImageStorages imageStorages = args.fImageStorages.childInputs(childIndex);
|
||||
EmitArgs childArgs(fragBuilder,
|
||||
args.fUniformHandler,
|
||||
args.fShaderCaps,
|
||||
@ -58,8 +57,7 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
|
||||
inputColor,
|
||||
coordVars,
|
||||
textureSamplers,
|
||||
texelBuffers,
|
||||
imageStorages);
|
||||
texelBuffers);
|
||||
this->childProcessor(childIndex)->emitCode(childArgs);
|
||||
fragBuilder->codeAppend("}\n");
|
||||
|
||||
|
@ -31,7 +31,6 @@ public:
|
||||
using UniformHandle = GrGLSLUniformHandler::UniformHandle;
|
||||
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
|
||||
using TexelBufferHandle = GrGLSLUniformHandler::TexelBufferHandle;
|
||||
using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -75,8 +74,6 @@ public:
|
||||
&GrResourceIOProcessor::numTextureSamplers>;
|
||||
using TexelBuffers = BuilderInputProvider<TexelBufferHandle, GrResourceIOProcessor,
|
||||
&GrResourceIOProcessor::numBuffers>;
|
||||
using ImageStorages = BuilderInputProvider<ImageStorageHandle, GrResourceIOProcessor,
|
||||
&GrResourceIOProcessor::numImageStorages>;
|
||||
|
||||
/** 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
|
||||
@ -102,9 +99,6 @@ public:
|
||||
@param bufferSamplers Contains one entry for each BufferAccess of the GrProcessor. These
|
||||
can be passed to the builder to emit buffer reads in the generated
|
||||
code.
|
||||
@param imageStorages Contains one entry for each ImageStorageAccess of the GrProcessor.
|
||||
These can be passed to the builder to emit image loads and stores
|
||||
in the generated code.
|
||||
*/
|
||||
struct EmitArgs {
|
||||
EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
|
||||
@ -115,8 +109,7 @@ public:
|
||||
const char* inputColor,
|
||||
const TransformedCoordVars& transformedCoordVars,
|
||||
const TextureSamplers& textureSamplers,
|
||||
const TexelBuffers& texelBuffers,
|
||||
const ImageStorages& imageStorages)
|
||||
const TexelBuffers& texelBuffers)
|
||||
: fFragBuilder(fragBuilder)
|
||||
, fUniformHandler(uniformHandler)
|
||||
, fShaderCaps(caps)
|
||||
@ -125,8 +118,7 @@ public:
|
||||
, fInputColor(inputColor)
|
||||
, fTransformedCoords(transformedCoordVars)
|
||||
, fTexSamplers(textureSamplers)
|
||||
, fTexelBuffers(texelBuffers)
|
||||
, fImageStorages(imageStorages) {}
|
||||
, fTexelBuffers(texelBuffers) {}
|
||||
GrGLSLFPFragmentBuilder* fFragBuilder;
|
||||
GrGLSLUniformHandler* fUniformHandler;
|
||||
const GrShaderCaps* fShaderCaps;
|
||||
@ -136,7 +128,6 @@ public:
|
||||
const TransformedCoordVars& fTransformedCoords;
|
||||
const TextureSamplers& fTexSamplers;
|
||||
const TexelBuffers& fTexelBuffers;
|
||||
const ImageStorages& fImageStorages;
|
||||
};
|
||||
|
||||
virtual void emitCode(EmitArgs&) = 0;
|
||||
|
@ -30,7 +30,6 @@ public:
|
||||
using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
|
||||
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
|
||||
using TexelBufferHandle = GrGLSLUniformHandler::TexelBufferHandle;
|
||||
using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
|
||||
|
||||
/**
|
||||
* This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
|
||||
@ -78,7 +77,6 @@ public:
|
||||
const char* rtAdjustName,
|
||||
const SamplerHandle* texSamplers,
|
||||
const TexelBufferHandle* texelBuffers,
|
||||
const ImageStorageHandle* imageStorages,
|
||||
FPCoordTransformHandler* transformHandler)
|
||||
: fVertBuilder(vertBuilder)
|
||||
, fGeomBuilder(geomBuilder)
|
||||
@ -92,7 +90,6 @@ public:
|
||||
, fRTAdjustName(rtAdjustName)
|
||||
, fTexSamplers(texSamplers)
|
||||
, fTexelBuffers(texelBuffers)
|
||||
, fImageStorages(imageStorages)
|
||||
, fFPCoordTransformHandler(transformHandler) {}
|
||||
GrGLSLVertexBuilder* fVertBuilder;
|
||||
GrGLSLGeometryBuilder* fGeomBuilder;
|
||||
@ -106,7 +103,6 @@ public:
|
||||
const char* fRTAdjustName;
|
||||
const SamplerHandle* fTexSamplers;
|
||||
const TexelBufferHandle* fTexelBuffers;
|
||||
const ImageStorageHandle* fImageStorages;
|
||||
FPCoordTransformHandler* fFPCoordTransformHandler;
|
||||
};
|
||||
|
||||
|
@ -32,10 +32,7 @@ GrGLSLProgramBuilder::GrGLSLProgramBuilder(const GrPipeline& pipeline,
|
||||
, fXferProcessor(nullptr)
|
||||
, fNumVertexSamplers(0)
|
||||
, fNumGeometrySamplers(0)
|
||||
, fNumFragmentSamplers(0)
|
||||
, fNumVertexImageStorages(0)
|
||||
, fNumGeometryImageStorages(0)
|
||||
, fNumFragmentImageStorages(0) {
|
||||
, fNumFragmentSamplers(0) {
|
||||
}
|
||||
|
||||
void GrGLSLProgramBuilder::addFeature(GrShaderFlags shaders,
|
||||
@ -65,7 +62,7 @@ bool GrGLSLProgramBuilder::emitAndInstallProcs() {
|
||||
this->emitAndInstallXferProc(inputColor, inputCoverage);
|
||||
this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput());
|
||||
|
||||
return this->checkSamplerCounts() && this->checkImageStorageCounts();
|
||||
return this->checkSamplerCounts();
|
||||
}
|
||||
|
||||
void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& proc,
|
||||
@ -98,8 +95,7 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
||||
|
||||
SkSTArray<4, SamplerHandle> texSamplers(proc.numTextureSamplers());
|
||||
SkSTArray<2, TexelBufferHandle> texelBuffers(proc.numBuffers());
|
||||
SkSTArray<2, ImageStorageHandle> imageStorages(proc.numImageStorages());
|
||||
this->emitSamplersAndImageStorages(proc, &texSamplers, &texelBuffers, &imageStorages);
|
||||
this->emitSamplers(proc, &texSamplers, &texelBuffers);
|
||||
|
||||
GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
|
||||
&fTransformedCoordVars);
|
||||
@ -115,7 +111,6 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
||||
rtAdjustName,
|
||||
texSamplers.begin(),
|
||||
texelBuffers.begin(),
|
||||
imageStorages.begin(),
|
||||
&transformHandler);
|
||||
fGeometryProcessor->emitCode(args);
|
||||
|
||||
@ -165,18 +160,15 @@ SkString GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor&
|
||||
|
||||
SkSTArray<4, SamplerHandle> textureSamplerArray(fp.numTextureSamplers());
|
||||
SkSTArray<2, TexelBufferHandle> texelBufferArray(fp.numBuffers());
|
||||
SkSTArray<2, ImageStorageHandle> imageStorageArray(fp.numImageStorages());
|
||||
GrFragmentProcessor::Iter iter(&fp);
|
||||
while (const GrFragmentProcessor* subFP = iter.next()) {
|
||||
this->emitSamplersAndImageStorages(*subFP, &textureSamplerArray, &texelBufferArray,
|
||||
&imageStorageArray);
|
||||
this->emitSamplers(*subFP, &textureSamplerArray, &texelBufferArray);
|
||||
}
|
||||
|
||||
const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
|
||||
GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
|
||||
GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, textureSamplerArray.begin());
|
||||
GrGLSLFragmentProcessor::TexelBuffers texelBuffers(&fp, texelBufferArray.begin());
|
||||
GrGLSLFragmentProcessor::ImageStorages imageStorages(&fp, imageStorageArray.begin());
|
||||
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
|
||||
this->uniformHandler(),
|
||||
this->shaderCaps(),
|
||||
@ -185,8 +177,7 @@ SkString GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor&
|
||||
input.c_str(),
|
||||
coords,
|
||||
textureSamplers,
|
||||
texelBuffers,
|
||||
imageStorages);
|
||||
texelBuffers);
|
||||
|
||||
fragProc->emitCode(args);
|
||||
|
||||
@ -252,11 +243,10 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
|
||||
fFS.codeAppend("}");
|
||||
}
|
||||
|
||||
void GrGLSLProgramBuilder::emitSamplersAndImageStorages(
|
||||
void GrGLSLProgramBuilder::emitSamplers(
|
||||
const GrResourceIOProcessor& processor,
|
||||
SkTArray<SamplerHandle>* outTexSamplerHandles,
|
||||
SkTArray<TexelBufferHandle>* outTexelBufferHandles,
|
||||
SkTArray<ImageStorageHandle>* outImageStorageHandles) {
|
||||
SkTArray<TexelBufferHandle>* outTexelBufferHandles) {
|
||||
SkString name;
|
||||
int numTextureSamplers = processor.numTextureSamplers();
|
||||
for (int t = 0; t < numTextureSamplers; ++t) {
|
||||
@ -293,14 +283,6 @@ void GrGLSLProgramBuilder::emitSamplersAndImageStorages(
|
||||
extension);
|
||||
}
|
||||
}
|
||||
int numImageStorages = processor.numImageStorages();
|
||||
for (int i = 0; i < numImageStorages; ++i) {
|
||||
const GrResourceIOProcessor::ImageStorageAccess& imageStorageAccess =
|
||||
processor.imageStorageAccess(i);
|
||||
name.printf("Image_%d", outImageStorageHandles->count());
|
||||
outImageStorageHandles->emplace_back(
|
||||
this->emitImageStorage(imageStorageAccess, name.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLSLProgramBuilder::updateSamplerCounts(GrShaderFlags visibility) {
|
||||
@ -333,24 +315,6 @@ GrGLSLProgramBuilder::TexelBufferHandle GrGLSLProgramBuilder::emitTexelBuffer(
|
||||
return this->uniformHandler()->addTexelBuffer(visibility, precision, name);
|
||||
}
|
||||
|
||||
GrGLSLProgramBuilder::ImageStorageHandle GrGLSLProgramBuilder::emitImageStorage(
|
||||
const GrResourceIOProcessor::ImageStorageAccess& access, const char* name) {
|
||||
if (access.visibility() & kVertex_GrShaderFlag) {
|
||||
++fNumVertexImageStorages;
|
||||
}
|
||||
if (access.visibility() & kGeometry_GrShaderFlag) {
|
||||
SkASSERT(this->primitiveProcessor().willUseGeoShader());
|
||||
++fNumGeometryImageStorages;
|
||||
}
|
||||
if (access.visibility() & kFragment_GrShaderFlag) {
|
||||
++fNumFragmentImageStorages;
|
||||
}
|
||||
GrSLType uniformType = access.proxy()->imageStorageType();
|
||||
return this->uniformHandler()->addImageStorage(access.visibility(), uniformType,
|
||||
access.format(), access.memoryModel(),
|
||||
access.restrict(), access.ioType(), name);
|
||||
}
|
||||
|
||||
void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
|
||||
// Swizzle the fragment shader outputs if necessary.
|
||||
GrSwizzle swizzle;
|
||||
@ -390,30 +354,6 @@ bool GrGLSLProgramBuilder::checkSamplerCounts() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrGLSLProgramBuilder::checkImageStorageCounts() {
|
||||
const GrShaderCaps& shaderCaps = *this->shaderCaps();
|
||||
if (fNumVertexImageStorages > shaderCaps.maxVertexImageStorages()) {
|
||||
GrCapsDebugf(this->caps(), "Program would use too many vertex images\n");
|
||||
return false;
|
||||
}
|
||||
if (fNumGeometryImageStorages > shaderCaps.maxGeometryImageStorages()) {
|
||||
GrCapsDebugf(this->caps(), "Program would use too many geometry images\n");
|
||||
return false;
|
||||
}
|
||||
if (fNumFragmentImageStorages > shaderCaps.maxFragmentImageStorages()) {
|
||||
GrCapsDebugf(this->caps(), "Program would use too many fragment images\n");
|
||||
return false;
|
||||
}
|
||||
// If the same image is used in two different shaders, it counts as two combined images.
|
||||
int numCombinedImages = fNumVertexImageStorages + fNumGeometryImageStorages +
|
||||
fNumFragmentImageStorages;
|
||||
if (numCombinedImages > shaderCaps.maxCombinedImageStorages()) {
|
||||
GrCapsDebugf(this->caps(), "Program would use too many combined images\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void GrGLSLProgramBuilder::verify(const GrPrimitiveProcessor& gp) {
|
||||
SkASSERT(fFS.usedProcessorFeatures() == gp.requiredFeatures());
|
||||
|
@ -31,7 +31,6 @@ public:
|
||||
using UniformHandle = GrGLSLUniformHandler::UniformHandle;
|
||||
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
|
||||
using TexelBufferHandle = GrGLSLUniformHandler::TexelBufferHandle;
|
||||
using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
|
||||
|
||||
virtual ~GrGLSLProgramBuilder() {}
|
||||
|
||||
@ -57,10 +56,6 @@ public:
|
||||
return this->uniformHandler()->texelBufferVariable(handle);
|
||||
}
|
||||
|
||||
const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const {
|
||||
return this->uniformHandler()->imageStorageVariable(handle);
|
||||
}
|
||||
|
||||
// Handles for program uniforms (other than per-effect uniforms)
|
||||
struct BuiltinUniformHandles {
|
||||
UniformHandle fRTAdjustmentUni;
|
||||
@ -156,19 +151,15 @@ private:
|
||||
const SkString& input,
|
||||
SkString output);
|
||||
void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
|
||||
void emitSamplersAndImageStorages(const GrResourceIOProcessor& processor,
|
||||
SkTArray<SamplerHandle>* outTexSamplerHandles,
|
||||
SkTArray<TexelBufferHandle>* outTexelBufferHandles,
|
||||
SkTArray<ImageStorageHandle>* outImageStorageHandles);
|
||||
void emitSamplers(const GrResourceIOProcessor& processor,
|
||||
SkTArray<SamplerHandle>* outTexSamplerHandles,
|
||||
SkTArray<TexelBufferHandle>* outTexelBufferHandles);
|
||||
SamplerHandle emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
|
||||
GrShaderFlags visibility);
|
||||
TexelBufferHandle emitTexelBuffer(GrPixelConfig, const char* name, GrShaderFlags visibility);
|
||||
ImageStorageHandle emitImageStorage(const GrResourceIOProcessor::ImageStorageAccess&,
|
||||
const char* name);
|
||||
void emitFSOutputSwizzle(bool hasSecondaryOutput);
|
||||
void updateSamplerCounts(GrShaderFlags visibility);
|
||||
bool checkSamplerCounts();
|
||||
bool checkImageStorageCounts();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void verify(const GrPrimitiveProcessor&);
|
||||
@ -181,9 +172,6 @@ private:
|
||||
int fNumVertexSamplers;
|
||||
int fNumGeometrySamplers;
|
||||
int fNumFragmentSamplers;
|
||||
int fNumVertexImageStorages;
|
||||
int fNumGeometryImageStorages;
|
||||
int fNumFragmentImageStorages;
|
||||
SkSTArray<4, GrShaderVar> fTransformedCoordVars;
|
||||
};
|
||||
|
||||
|
@ -213,16 +213,6 @@ void GrGLSLShaderBuilder::appendTexelFetch(TexelBufferHandle texelBufferHandle,
|
||||
this->appendTexelFetch(&this->code(), texelBufferHandle, coordExpr);
|
||||
}
|
||||
|
||||
void GrGLSLShaderBuilder::appendImageStorageLoad(SkString* out, ImageStorageHandle handle,
|
||||
const char* coordExpr) {
|
||||
const GrShaderVar& imageStorage = fProgramBuilder->imageStorageVariable(handle);
|
||||
out->appendf("imageLoad(%s, %s)", imageStorage.c_str(), coordExpr);
|
||||
}
|
||||
|
||||
void GrGLSLShaderBuilder::appendImageStorageLoad(ImageStorageHandle handle, const char* coordExpr) {
|
||||
this->appendImageStorageLoad(&this->code(), handle, coordExpr);
|
||||
}
|
||||
|
||||
bool GrGLSLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) {
|
||||
if (featureBit & fFeaturesAddedMask) {
|
||||
return false;
|
||||
|
@ -27,7 +27,6 @@ public:
|
||||
|
||||
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
|
||||
using TexelBufferHandle = GrGLSLUniformHandler::TexelBufferHandle;
|
||||
using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
|
||||
|
||||
/** 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
|
||||
@ -74,11 +73,6 @@ public:
|
||||
/** Version of above that appends the result to the shader code instead.*/
|
||||
void appendTexelFetch(TexelBufferHandle, const char* coordExpr);
|
||||
|
||||
/** Creates a string of shader code that performs an image load. */
|
||||
void appendImageStorageLoad(SkString* out, ImageStorageHandle, const char* coordExpr);
|
||||
/** Version of above that appends the result to the shader code instead. */
|
||||
void appendImageStorageLoad(ImageStorageHandle, const char* coordExpr);
|
||||
|
||||
/**
|
||||
* Adds a constant declaration to the top of the shader.
|
||||
*/
|
||||
|
@ -21,7 +21,6 @@ public:
|
||||
using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
|
||||
GR_DEFINE_RESOURCE_HANDLE_CLASS(SamplerHandle);
|
||||
GR_DEFINE_RESOURCE_HANDLE_CLASS(TexelBufferHandle);
|
||||
GR_DEFINE_RESOURCE_HANDLE_CLASS(ImageStorageHandle);
|
||||
|
||||
/** 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
|
||||
@ -90,11 +89,6 @@ private:
|
||||
virtual TexelBufferHandle addTexelBuffer(uint32_t visibility, GrSLPrecision,
|
||||
const char* name) = 0;
|
||||
|
||||
virtual const GrShaderVar& imageStorageVariable(ImageStorageHandle) const = 0;
|
||||
virtual ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType type,
|
||||
GrImageStorageFormat, GrSLMemoryModel, GrSLRestrict,
|
||||
GrIOType, const char* name) = 0;
|
||||
|
||||
virtual UniformHandle internalAddUniformArray(uint32_t visibility,
|
||||
GrSLType type,
|
||||
GrSLPrecision precision,
|
||||
|
@ -24,7 +24,6 @@ public:
|
||||
virtual ~GrGLSLXferProcessor() {}
|
||||
|
||||
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
|
||||
using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
|
||||
|
||||
struct EmitArgs {
|
||||
EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
|
@ -45,7 +45,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool canConfigBeImageStorage(GrPixelConfig) const override { return false; }
|
||||
bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
|
||||
bool* rectsMustMatch, bool* disallowSubrect) const override {
|
||||
return false;
|
||||
|
@ -43,8 +43,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canConfigBeImageStorage(GrPixelConfig) const override { return false; }
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Returns both a supported and most prefered stencil format to use in draws.
|
||||
|
@ -43,8 +43,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canConfigBeImageStorage(GrPixelConfig) const override { return false; }
|
||||
|
||||
bool isConfigTexturableLinearly(GrPixelConfig config) const {
|
||||
return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags);
|
||||
}
|
||||
|
@ -209,8 +209,6 @@ static void append_texture_bindings(
|
||||
const GrResourceIOProcessor& processor,
|
||||
SkTArray<const GrResourceIOProcessor::TextureSampler*>* textureBindings,
|
||||
SkTArray<const GrResourceIOProcessor::BufferAccess*>* bufferAccesses) {
|
||||
// We don't support image storages in VK.
|
||||
SkASSERT(!processor.numImageStorages());
|
||||
if (int numTextureSamplers = processor.numTextureSamplers()) {
|
||||
const GrResourceIOProcessor::TextureSampler** bindings =
|
||||
textureBindings->push_back_n(numTextureSamplers);
|
||||
|
@ -72,8 +72,6 @@ uint32_t grsltype_to_alignment_mask(GrSLType type) {
|
||||
case kBufferSampler_GrSLType:
|
||||
case kTexture2D_GrSLType:
|
||||
case kSampler_GrSLType:
|
||||
case kImageStorage2D_GrSLType:
|
||||
case kIImageStorage2D_GrSLType:
|
||||
break;
|
||||
}
|
||||
SK_ABORT("Unexpected type");
|
||||
@ -144,8 +142,6 @@ static inline uint32_t grsltype_to_vk_size(GrSLType type) {
|
||||
case kBufferSampler_GrSLType:
|
||||
case kTexture2D_GrSLType:
|
||||
case kSampler_GrSLType:
|
||||
case kImageStorage2D_GrSLType:
|
||||
case kIImageStorage2D_GrSLType:
|
||||
break;
|
||||
}
|
||||
SK_ABORT("Unexpected type");
|
||||
|
@ -88,19 +88,6 @@ private:
|
||||
return fTexelBuffers[handle.toIndex()].fVisibility;
|
||||
}
|
||||
|
||||
ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType, GrImageStorageFormat,
|
||||
GrSLMemoryModel, GrSLRestrict, GrIOType,
|
||||
const char* name) override {
|
||||
SK_ABORT("Image storages not implemented for Vulkan.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const override {
|
||||
SK_ABORT("Image storages not implemented for Vulkan.");
|
||||
static const GrShaderVar* gVar = nullptr;
|
||||
return *gVar;
|
||||
}
|
||||
|
||||
void appendUniformDecls(GrShaderFlags, SkString*) const override;
|
||||
|
||||
bool hasGeometryUniforms() const { return fCurrentGeometryUBOOffset > 0; }
|
||||
|
@ -70,10 +70,6 @@ static inline int grsltype_to_location_size(GrSLType type) {
|
||||
return 0;
|
||||
case kSampler_GrSLType:
|
||||
return 0;
|
||||
case kImageStorage2D_GrSLType:
|
||||
return 0;
|
||||
case kIImageStorage2D_GrSLType:
|
||||
return 0;
|
||||
}
|
||||
SK_ABORT("Unexpected type");
|
||||
return -1;
|
||||
|
@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "Test.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
#include "GrClip.h"
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrRenderTargetContext.h"
|
||||
#include "GrTexture.h"
|
||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
|
||||
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageStorageLoad, reporter, ctxInfo) {
|
||||
class TestFP : public GrFragmentProcessor {
|
||||
public:
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
|
||||
GrSLMemoryModel mm,
|
||||
GrSLRestrict restrict) {
|
||||
return std::unique_ptr<GrFragmentProcessor>(new TestFP(std::move(proxy), mm, restrict));
|
||||
}
|
||||
|
||||
const char* name() const override { return "Image Load Test FP"; }
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> clone() const override {
|
||||
return std::unique_ptr<GrFragmentProcessor>(new TestFP(*this));
|
||||
}
|
||||
|
||||
private:
|
||||
TestFP(sk_sp<GrTextureProxy> proxy, GrSLMemoryModel mm, GrSLRestrict restrict)
|
||||
: INHERITED(kTestFP_ClassID, kNone_OptimizationFlags)
|
||||
, fImageStorageAccess(std::move(proxy), kRead_GrIOType, mm, restrict) {
|
||||
this->addImageStorageAccess(&fImageStorageAccess);
|
||||
}
|
||||
|
||||
explicit TestFP(const TestFP& that)
|
||||
: INHERITED(kTestFP_ClassID, that.optimizationFlags())
|
||||
, fImageStorageAccess(that.fImageStorageAccess) {
|
||||
this->addImageStorageAccess(&fImageStorageAccess);
|
||||
}
|
||||
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
|
||||
|
||||
bool onIsEqual(const GrFragmentProcessor& that) const override { return true; }
|
||||
|
||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
|
||||
class GLSLProcessor : public GrGLSLFragmentProcessor {
|
||||
public:
|
||||
GLSLProcessor() = default;
|
||||
void emitCode(EmitArgs& args) override {
|
||||
const TestFP& tfp = args.fFp.cast<TestFP>();
|
||||
GrGLSLFPFragmentBuilder* fb = args.fFragBuilder;
|
||||
SkString imageLoadStr;
|
||||
fb->codeAppend("float2 coord = sk_FragCoord.xy;");
|
||||
fb->appendImageStorageLoad(&imageLoadStr, args.fImageStorages[0],
|
||||
"int2(coord)");
|
||||
if (GrPixelConfigIsSint(tfp.fImageStorageAccess.peekTexture()->config())) {
|
||||
// Map the signed bytes so that when then get read back as unorm values they
|
||||
// will have their original bit pattern.
|
||||
fb->codeAppendf("int4 ivals = %s;", imageLoadStr.c_str());
|
||||
// NV gives a linker error for this:
|
||||
// fb->codeAppend("ivals +=
|
||||
// "mix(int4(0), int4(256), lessThan(ivals, int4(0)));");
|
||||
fb->codeAppend("if (ivals.r < 0) { ivals.r += 256; }");
|
||||
fb->codeAppend("if (ivals.g < 0) { ivals.g += 256; }");
|
||||
fb->codeAppend("if (ivals.b < 0) { ivals.b += 256; }");
|
||||
fb->codeAppend("if (ivals.a < 0) { ivals.a += 256; }");
|
||||
fb->codeAppendf("%s = half4(ivals)/255;", args.fOutputColor);
|
||||
} else {
|
||||
fb->codeAppendf("%s = %s;", args.fOutputColor, imageLoadStr.c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
return new GLSLProcessor;
|
||||
}
|
||||
|
||||
ImageStorageAccess fImageStorageAccess;
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
};
|
||||
|
||||
static constexpr int kS = 256;
|
||||
GrContext* context = ctxInfo.grContext();
|
||||
if (context->caps()->shaderCaps()->maxFragmentImageStorages() < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<uint32_t[]> data(new uint32_t[kS * kS]);
|
||||
for (int j = 0; j < kS; ++j) {
|
||||
for (int i = 0; i < kS; ++i) {
|
||||
data[i + kS * j] = GrColorPackRGBA(i, j, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<uint32_t[]> idata(new uint32_t[kS * kS]);
|
||||
for (int j = 0; j < kS; ++j) {
|
||||
for (int i = 0; i < kS; ++i) {
|
||||
int8_t r = i - 128;
|
||||
int8_t g = j - 128;
|
||||
int8_t b = -128;
|
||||
int8_t a = -128;
|
||||
idata[i + kS * j] = ((uint8_t)a << 24) | ((uint8_t)b << 16) |
|
||||
((uint8_t)g << 8) | (uint8_t)r;
|
||||
}
|
||||
}
|
||||
|
||||
// Currently image accesses always have "top left" semantics.
|
||||
GrSurfaceDesc desc;
|
||||
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
|
||||
desc.fWidth = kS;
|
||||
desc.fHeight = kS;
|
||||
struct {
|
||||
GrPixelConfig fConfig;
|
||||
std::unique_ptr<uint32_t[]> fData;
|
||||
} tests[] = {
|
||||
{
|
||||
kRGBA_8888_GrPixelConfig,
|
||||
std::move(data)
|
||||
},
|
||||
{
|
||||
kRGBA_8888_sint_GrPixelConfig,
|
||||
std::move(idata)
|
||||
},
|
||||
};
|
||||
for (const auto& test : tests) {
|
||||
// This test should work with any memory model and with or without restrict
|
||||
for (auto mm : {GrSLMemoryModel::kNone,
|
||||
GrSLMemoryModel::kCoherent,
|
||||
GrSLMemoryModel::kVolatile}) {
|
||||
for (auto restrict : {GrSLRestrict::kNo, GrSLRestrict::kYes}) {
|
||||
if (!context->caps()->canConfigBeImageStorage(test.fConfig)) {
|
||||
continue;
|
||||
}
|
||||
desc.fConfig = test.fConfig;
|
||||
sk_sp<GrTextureProxy> imageStorageTexture =
|
||||
GrSurfaceProxy::MakeDeferred(context->resourceProvider(), desc,
|
||||
SkBudgeted::kYes, test.fData.get(), 0);
|
||||
|
||||
sk_sp<GrRenderTargetContext> rtContext =
|
||||
context->makeDeferredRenderTargetContext(SkBackingFit::kExact, kS, kS,
|
||||
kRGBA_8888_GrPixelConfig, nullptr);
|
||||
// We make a clone to test that copying GrFragmentProcessor::ImageStorageAccess
|
||||
// works.
|
||||
std::unique_ptr<GrFragmentProcessor> fps[2];
|
||||
fps[0] = TestFP::Make(imageStorageTexture, mm, restrict);
|
||||
fps[1] = fps[0]->clone();
|
||||
for (auto& fp : fps) {
|
||||
GrPaint paint;
|
||||
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
|
||||
paint.addColorFragmentProcessor(std::move(fp));
|
||||
rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
|
||||
std::unique_ptr<uint32_t[]> readData(new uint32_t[kS * kS]);
|
||||
SkImageInfo info = SkImageInfo::Make(kS, kS, kRGBA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
rtContext->readPixels(info, readData.get(), 0, 0, 0);
|
||||
int failed = false;
|
||||
for (int j = 0; j < kS && !failed; ++j) {
|
||||
for (int i = 0; i < kS && !failed; ++i) {
|
||||
uint32_t d = test.fData[j * kS + i];
|
||||
uint32_t rd = readData[j * kS + i];
|
||||
if (d != rd) {
|
||||
failed = true;
|
||||
ERRORF(reporter, "Expected 0x%08x, got 0x%08x at %d, %d.",
|
||||
d, rd, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -67,18 +67,12 @@ private:
|
||||
*/
|
||||
class TestFP : public GrFragmentProcessor {
|
||||
public:
|
||||
struct Image {
|
||||
Image(sk_sp<GrTextureProxy> proxy, GrIOType ioType) : fProxy(proxy), fIOType(ioType) {}
|
||||
sk_sp<GrTextureProxy> fProxy;
|
||||
GrIOType fIOType;
|
||||
};
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
|
||||
return std::unique_ptr<GrFragmentProcessor>(new TestFP(std::move(child)));
|
||||
}
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(const SkTArray<sk_sp<GrTextureProxy>>& proxies,
|
||||
const SkTArray<sk_sp<GrBuffer>>& buffers,
|
||||
const SkTArray<Image>& images) {
|
||||
return std::unique_ptr<GrFragmentProcessor>(new TestFP(proxies, buffers, images));
|
||||
const SkTArray<sk_sp<GrBuffer>>& buffers) {
|
||||
return std::unique_ptr<GrFragmentProcessor>(new TestFP(proxies, buffers));
|
||||
}
|
||||
|
||||
const char* name() const override { return "test"; }
|
||||
@ -94,33 +88,23 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TestFP(const SkTArray<sk_sp<GrTextureProxy>>& proxies,
|
||||
const SkTArray<sk_sp<GrBuffer>>& buffers,
|
||||
const SkTArray<Image>& images)
|
||||
: INHERITED(kTestFP_ClassID, kNone_OptimizationFlags), fSamplers(4), fBuffers(4),
|
||||
fImages(4) {
|
||||
TestFP(const SkTArray<sk_sp<GrTextureProxy>>& proxies, const SkTArray<sk_sp<GrBuffer>>& buffers)
|
||||
: INHERITED(kTestFP_ClassID, kNone_OptimizationFlags), fSamplers(4), fBuffers(4) {
|
||||
for (const auto& proxy : proxies) {
|
||||
this->addTextureSampler(&fSamplers.emplace_back(proxy));
|
||||
}
|
||||
for (const auto& buffer : buffers) {
|
||||
this->addBufferAccess(&fBuffers.emplace_back(kRGBA_8888_GrPixelConfig, buffer.get()));
|
||||
}
|
||||
for (const Image& image : images) {
|
||||
fImages.emplace_back(image.fProxy, image.fIOType,
|
||||
GrSLMemoryModel::kNone, GrSLRestrict::kNo);
|
||||
this->addImageStorageAccess(&fImages.back());
|
||||
}
|
||||
}
|
||||
|
||||
TestFP(std::unique_ptr<GrFragmentProcessor> child)
|
||||
: INHERITED(kTestFP_ClassID, kNone_OptimizationFlags), fSamplers(4), fBuffers(4),
|
||||
fImages(4) {
|
||||
: INHERITED(kTestFP_ClassID, kNone_OptimizationFlags), fSamplers(4), fBuffers(4) {
|
||||
this->registerChildProcessor(std::move(child));
|
||||
}
|
||||
|
||||
explicit TestFP(const TestFP& that)
|
||||
: INHERITED(kTestFP_ClassID, that.optimizationFlags()), fSamplers(4), fBuffers(4),
|
||||
fImages(4) {
|
||||
: INHERITED(kTestFP_ClassID, that.optimizationFlags()), fSamplers(4), fBuffers(4) {
|
||||
for (int i = 0; i < that.fSamplers.count(); ++i) {
|
||||
fSamplers.emplace_back(that.fSamplers[i]);
|
||||
this->addTextureSampler(&fSamplers.back());
|
||||
@ -129,10 +113,6 @@ private:
|
||||
fBuffers.emplace_back(that.fBuffers[i]);
|
||||
this->addBufferAccess(&fBuffers.back());
|
||||
}
|
||||
for (int i = 0; i < that.fImages.count(); ++i) {
|
||||
fImages.emplace_back(that.fImages[i]);
|
||||
this->addImageStorageAccess(&fImages.back());
|
||||
}
|
||||
for (int i = 0; i < that.numChildProcessors(); ++i) {
|
||||
this->registerChildProcessor(that.childProcessor(i).clone());
|
||||
}
|
||||
@ -156,7 +136,6 @@ private:
|
||||
|
||||
GrTAllocator<TextureSampler> fSamplers;
|
||||
GrTAllocator<BufferAccess> fBuffers;
|
||||
GrTAllocator<ImageStorageAccess> fImages;
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
};
|
||||
}
|
||||
@ -190,7 +169,6 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
|
||||
kRGBA_8888_GrPixelConfig, nullptr));
|
||||
{
|
||||
bool texelBufferSupport = context->caps()->shaderCaps()->texelBufferSupport();
|
||||
bool imageLoadStoreSupport = context->caps()->shaderCaps()->imageLoadStoreSupport();
|
||||
sk_sp<GrTextureProxy> proxy1(
|
||||
GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
|
||||
desc, SkBackingFit::kExact,
|
||||
@ -215,18 +193,11 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
|
||||
{
|
||||
SkTArray<sk_sp<GrTextureProxy>> proxies;
|
||||
SkTArray<sk_sp<GrBuffer>> buffers;
|
||||
SkTArray<TestFP::Image> images;
|
||||
proxies.push_back(proxy1);
|
||||
if (texelBufferSupport) {
|
||||
buffers.push_back(buffer);
|
||||
}
|
||||
if (imageLoadStoreSupport) {
|
||||
images.emplace_back(proxy2, GrIOType::kRead_GrIOType);
|
||||
images.emplace_back(proxy3, GrIOType::kWrite_GrIOType);
|
||||
images.emplace_back(proxy4, GrIOType::kRW_GrIOType);
|
||||
}
|
||||
auto fp = TestFP::Make(std::move(proxies), std::move(buffers),
|
||||
std::move(images));
|
||||
auto fp = TestFP::Make(std::move(proxies), std::move(buffers));
|
||||
for (int i = 0; i < parentCnt; ++i) {
|
||||
fp = TestFP::Make(std::move(fp));
|
||||
}
|
||||
@ -257,23 +228,6 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
|
||||
REPORTER_ASSERT(reporter, ioRefMul * 0 == writeCnt);
|
||||
}
|
||||
|
||||
if (imageLoadStoreSupport) {
|
||||
testingOnly_getIORefCnts(proxy2.get(), &refCnt, &readCnt, &writeCnt);
|
||||
REPORTER_ASSERT(reporter, 1 == refCnt);
|
||||
REPORTER_ASSERT(reporter, ioRefMul * 1 == readCnt);
|
||||
REPORTER_ASSERT(reporter, ioRefMul * 0 == writeCnt);
|
||||
|
||||
testingOnly_getIORefCnts(proxy3.get(), &refCnt, &readCnt, &writeCnt);
|
||||
REPORTER_ASSERT(reporter, 1 == refCnt);
|
||||
REPORTER_ASSERT(reporter, ioRefMul * 0 == readCnt);
|
||||
REPORTER_ASSERT(reporter, ioRefMul * 1 == writeCnt);
|
||||
|
||||
testingOnly_getIORefCnts(proxy4.get(), &refCnt, &readCnt, &writeCnt);
|
||||
REPORTER_ASSERT(reporter, 1 == refCnt);
|
||||
REPORTER_ASSERT(reporter, ioRefMul * 1 == readCnt);
|
||||
REPORTER_ASSERT(reporter, ioRefMul * 1 == writeCnt);
|
||||
}
|
||||
|
||||
context->flush();
|
||||
|
||||
testingOnly_getIORefCnts(proxy1.get(), &refCnt, &readCnt, &writeCnt);
|
||||
|
Loading…
Reference in New Issue
Block a user