aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrPrimitiveProcessor.h
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2017-05-31 12:51:23 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-31 20:40:20 +0000
commit1d6163577c8a4f1372208e2c9e03b1a69906d385 (patch)
treefdacaa2e860d507bafca16cef0cb6e6e7861a1aa /src/gpu/GrPrimitiveProcessor.h
parentfa6d865215b48fac4ee24c120736e500d418f641 (diff)
Add support for instanced draws
Adds an instance buffer to GrMesh and instance attribs to GrPrimitiveProcessor. Implements support in GL and Vulkan. Adds unit tests for instanced rendering with GrMesh. Bug: skia: Change-Id: If1a9920feb9366f346b8c37cf914713c49129b3a Reviewed-on: https://skia-review.googlesource.com/16200 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu/GrPrimitiveProcessor.h')
-rw-r--r--src/gpu/GrPrimitiveProcessor.h82
1 files changed, 56 insertions, 26 deletions
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index d078ac5072..63265f02a6 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -40,33 +40,45 @@ class GrGLSLPrimitiveProcessor;
*/
class GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement {
public:
- // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
- // we put these calls on the base class to prevent having to cast
- virtual bool willUseGeoShader() const = 0;
-
struct Attribute {
- Attribute()
- : fName(nullptr)
- , fType(kFloat_GrVertexAttribType)
- , fOffset(0) {}
- Attribute(const char* name, GrVertexAttribType type, GrSLPrecision precision)
- : fName(name)
- , fType(type)
- , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
- , fPrecision(precision) {}
- const char* fName;
- GrVertexAttribType fType;
- size_t fOffset;
- GrSLPrecision fPrecision;
+ enum class InputRate : bool {
+ kPerVertex,
+ kPerInstance
+ };
+
+ const char* fName;
+ GrVertexAttribType fType;
+ int fOffsetInRecord;
+ GrSLPrecision fPrecision;
+ InputRate fInputRate;
};
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
- // GrOpList based off of the stride, and to populate this memory using an implicit array of
- // structs. In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
- size_t getVertexStride() const { return fVertexStride; }
+ bool hasVertexAttribs() const { return SkToBool(fVertexStride); }
+ bool hasInstanceAttribs() const { return SkToBool(fInstanceStride); }
+
+ /**
+ * These return the strides of the vertex and instance buffers. Attributes are expected to be
+ * laid out interleaved in their corresponding buffer (vertex or instance). fOffsetInRecord
+ * indicates an attribute's location in bytes relative to the first attribute. (These are padded
+ * to the nearest 4 bytes for performance reasons.)
+ *
+ * A common practice is to populate the buffer's memory using an implicit array of structs. In
+ * this case, it is best to assert:
+ *
+ * stride == sizeof(struct) and
+ * offsetof(struct, field[i]) == attrib[i].fOffsetInRecord
+ *
+ * NOTE: for instanced draws the vertex buffer has a single record that each instance reuses.
+ */
+ int getVertexStride() const { return fVertexStride; }
+ int getInstanceStride() const { return fInstanceStride; }
+
+ // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
+ // we put these calls on the base class to prevent having to cast
+ virtual bool willUseGeoShader() const = 0;
/**
* Computes a transformKey from an array of coord transforms. Will only look at the first
@@ -107,11 +119,25 @@ public:
virtual bool implementsDistanceVector() const { return false; }
protected:
- GrPrimitiveProcessor() : fVertexStride(0) {}
-
- enum { kPreallocAttribCnt = 8 };
- SkSTArray<kPreallocAttribCnt, Attribute> fAttribs;
- size_t fVertexStride;
+ /**
+ * Subclasses call these from their constructor to register vertex and instance attributes.
+ */
+ const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type,
+ GrSLPrecision precision = kDefault_GrSLPrecision) {
+ precision = (kDefault_GrSLPrecision == precision) ? kMedium_GrSLPrecision : precision;
+ fAttribs.push_back() = {name, type, fVertexStride, precision,
+ Attribute::InputRate::kPerVertex};
+ fVertexStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
+ return fAttribs.back();
+ }
+ const Attribute& addInstanceAttrib(const char* name, GrVertexAttribType type,
+ GrSLPrecision precision = kDefault_GrSLPrecision) {
+ precision = (kDefault_GrSLPrecision == precision) ? kMedium_GrSLPrecision : precision;
+ fAttribs.push_back() = {name, type, fInstanceStride, precision,
+ Attribute::InputRate::kPerInstance};
+ fInstanceStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
+ return fAttribs.back();
+ }
private:
void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
@@ -120,6 +146,10 @@ private:
void notifyRefCntIsZero() const final {}
virtual bool hasExplicitLocalCoords() const = 0;
+ SkSTArray<8, Attribute> fAttribs;
+ int fVertexStride = 0;
+ int fInstanceStride = 0;
+
typedef GrProcessor INHERITED;
};