bool reuseScratchTextures() const { return fReuseScratchTextures; }
bool reuseScratchBuffers() const { return fReuseScratchBuffers; }
+ /// maximum number of attribute values per vertex
+ int maxVertexAttributes() const { return fMaxVertexAttributes; }
+
int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
int maxTextureSize() const { return fMaxTextureSize; }
/** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps.
int fGeometryBufferMapThreshold;
int fMaxRenderTargetSize;
+ int fMaxVertexAttributes;
int fMaxTextureSize;
int fMaxTileSize;
int fMaxColorSampleCount;
fMapBufferFlags = kNone_MapFlags;
+ fMaxVertexAttributes = 0;
fMaxRenderTargetSize = 1;
fMaxTextureSize = 1;
fMaxColorSampleCount = 0;
r.appendf("Advanced Blend Equation Blacklist : 0x%x\n", fAdvBlendEqBlacklist);
}
+ r.appendf("Max Vertex Attributes : %d\n", fMaxVertexAttributes);
r.appendf("Max Texture Size : %d\n", fMaxTextureSize);
r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
r.appendf("Max Color Sample Count : %d\n", fMaxColorSampleCount);
* GrGeometryProcessor.
*/
const Attribute& addVertexAttrib(const Attribute& attribute) {
- SkASSERT(fNumAttribs < kMaxVertexAttribs);
fVertexStride += attribute.fOffset;
- fAttribs[fNumAttribs] = attribute;
- return fAttribs[fNumAttribs++];
+ fAttribs.push_back(attribute);
+ return fAttribs.back();
}
void setWillUseGeoShader() { fWillUseGeoShader = true; }
////////////////////////////////////////////////////////////////////////////////
-void GrGpu::draw(const GrPipeline& pipeline,
+bool GrGpu::draw(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrMesh* meshes,
int meshCount) {
+ if (primProc.numAttribs() > this->caps()->maxVertexAttributes()) {
+ return false;
+ }
this->handleDirtyContext();
this->onDraw(pipeline, primProc, meshes, meshCount);
+ return true;
}
// We pass in an array of meshCount GrMesh to the draw. The backend should loop over each
// GrMesh object and emit a draw for it. Each draw will use the same GrPipeline and
- // GrPrimitiveProcessor.
- void draw(const GrPipeline&,
+ // GrPrimitiveProcessor. This may fail if the draw would exceed any resource limits (e.g.
+ // number of vertex attributes is too large).
+ bool draw(const GrPipeline&,
const GrPrimitiveProcessor&,
const GrMesh*,
int meshCount);
// we put these calls on the base class to prevent having to cast
virtual bool willUseGeoShader() const = 0;
- /*
- * This is a safeguard to prevent GrPrimitiveProcessor's from going beyond platform specific
- * attribute limits. This number can almost certainly be raised if required.
- */
- static const int kMaxVertexAttribs = 8;
-
struct Attribute {
Attribute()
: fName(nullptr)
GrSLPrecision fPrecision;
};
- int numAttribs() const { return fNumAttribs; }
- const Attribute& getAttrib(int index) const {
- SkASSERT(index < fNumAttribs);
- return fAttribs[index];
- }
+ int numAttribs() const { return fAttribs.count(); }
+ const Attribute& getAttrib(int index) const { return fAttribs[index]; }
// Returns the vertex stride of the GP. A common use case is to request geometry from a
// drawtarget based off of the stride, and to populate this memory using an implicit array of
virtual const char* getDestColorOverride() const { return nullptr; }
protected:
- GrPrimitiveProcessor()
- : fNumAttribs(0)
- , fVertexStride(0) {}
+ GrPrimitiveProcessor() : fVertexStride(0) {}
- Attribute fAttribs[kMaxVertexAttribs];
- int fNumAttribs;
+ enum { kPreallocAttribCnt = 8 };
+ SkSTArray<kPreallocAttribCnt, Attribute> fAttribs;
size_t fVertexStride;
private:
fMapBufferType = kNone_MapBufferType;
fTransferBufferType = kNone_TransferBufferType;
fMaxFragmentUniformVectors = 0;
- fMaxVertexAttributes = 0;
fUnpackRowLengthSupport = false;
fUnpackFlipYSupport = false;
fPackRowLengthSupport = false;
r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
- r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
/// The maximum number of fragment uniform vectors (GLES has min. 16).
int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; }
- /// maximum number of attribute values per vertex
- int maxVertexAttributes() const { return fMaxVertexAttributes; }
-
/**
* Depending on the ES extensions present the BGRA external format may
* correspond to either a BGRA or RGBA internalFormat. On desktop GL it is
SkTArray<StencilFormat, true> fStencilFormats;
int fMaxFragmentUniformVectors;
- int fMaxVertexAttributes;
MSFBOType fMSFBOType;
InvalidateFBType fInvalidateFBType;
fProgramCache = new ProgramCache(this);
- SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVertexAttribs);
-
fHWProgramID = 0;
fTempSrcFBOID = 0;
fTempDstFBOID = 0;
void GrVkCaps::initGrCaps(const VkPhysicalDeviceProperties& properties,
const VkPhysicalDeviceFeatures& features,
const VkPhysicalDeviceMemoryProperties& memoryProperites) {
+ fMaxVertexAttributes = properties.limits.maxVertexInputAttributes;
// We could actually query and get a max size for each config, however maxImageDimension2D will
// give the minimum max size across all configs. So for simplicity we will use that for now.
fMaxRenderTargetSize = properties.limits.maxImageDimension2D;