Skip to content

Commit 6038c71

Browse files
committed
[ganesh] Apply buffer binding restriction
WebGL has buffer binding restriction that mixing index buffer and other data is invalid.
1 parent 552ab72 commit 6038c71

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

src/gpu/ganesh/gl/GrGLBuffer.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,37 @@ inline static GrGLenum gr_to_gl_access_pattern(GrGpuBufferType bufferType,
100100
return usageType(bufferType, accessPattern);
101101
}
102102

103+
#ifdef SK_DEBUG
104+
bool GrGLBuffer::validBindingTarget(GrGLenum target) const {
105+
if (!this->glCaps().bufferBindingRestriction()) {
106+
return true;
107+
}
108+
/* This restriction implies that a given buffer object may contain
109+
* either indices or other data, but not both.
110+
*/
111+
if (GR_GL_ELEMENT_ARRAY_BUFFER == target) {
112+
switch (this->fBindingCategory) {
113+
case kUndefined_BindingCategory:
114+
this->fBindingCategory = kIndexBuffer_BindingCategory;
115+
[[fallthrough]];
116+
case kIndexBuffer_BindingCategory:
117+
return true;
118+
default:
119+
return false;
120+
}
121+
}
122+
switch (this->fBindingCategory) {
123+
case kUndefined_BindingCategory:
124+
this->fBindingCategory = kOtherData_BindingCategory;
125+
[[fallthrough]];
126+
case kOtherData_BindingCategory:
127+
return true;
128+
default:
129+
return false;
130+
}
131+
}
132+
#endif // SK_DEBUG
133+
103134
GrGLBuffer::GrGLBuffer(GrGLGpu* gpu,
104135
size_t size,
105136
GrGpuBufferType intendedType,

src/gpu/ganesh/gl/GrGLBuffer.h

+13
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class GrGLBuffer : public GrGpuBuffer {
3131
void setHasAttachedToTexture() { fHasAttachedToTexture = true; }
3232
bool hasAttachedToTexture() const { return fHasAttachedToTexture; }
3333

34+
#ifdef SK_DEBUG
35+
bool validBindingTarget(GrGLenum target) const;
36+
#endif // SK_DEBUG
37+
3438
protected:
3539
GrGLBuffer(GrGLGpu*,
3640
size_t size,
@@ -59,6 +63,15 @@ class GrGLBuffer : public GrGpuBuffer {
5963
GrGLenum fUsage;
6064
bool fHasAttachedToTexture;
6165

66+
#ifdef SK_DEBUG
67+
enum BindingCategory {
68+
kUndefined_BindingCategory,
69+
kIndexBuffer_BindingCategory,
70+
kOtherData_BindingCategory,
71+
};
72+
mutable BindingCategory fBindingCategory;
73+
#endif // SK_DEBUG
74+
6275
using INHERITED = GrGpuBuffer;
6376
};
6477

src/gpu/ganesh/gl/GrGLCaps.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,12 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
261261
fClientCanDisableMultisample = false;
262262
}
263263

264+
if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
265+
fBufferBindingRestriction = false;
266+
} else if (GR_IS_GR_WEBGL(standard)) {
267+
fBufferBindingRestriction = true;
268+
}
269+
264270
if (GR_IS_GR_GL(standard)) {
265271
// 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
266272
// instanced arrays, but we could make this more granular if we wanted

src/gpu/ganesh/gl/GrGLCaps.h

+4
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,9 @@ class GrGLCaps : public GrCaps {
515515

516516
bool clientCanDisableMultisample() const { return fClientCanDisableMultisample; }
517517

518+
/* https://registry.khronos.org/webgl/specs/latest/2.0/#BUFFER_OBJECT_BINDING */
519+
bool bufferBindingRestriction() const { return fBufferBindingRestriction; }
520+
518521
GrBackendFormat getBackendFormatFromCompressionType(SkTextureCompressionType) const override;
519522

520523
skgpu::Swizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override;
@@ -630,6 +633,7 @@ class GrGLCaps : public GrCaps {
630633
bool fSRGBWriteControl : 1;
631634
bool fSkipErrorChecks : 1;
632635
bool fClientCanDisableMultisample : 1;
636+
bool fBufferBindingRestriction: 1;
633637

634638
// Driver workarounds
635639
bool fDoManualMipmapping : 1;

src/gpu/ganesh/gl/GrGLGpu.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2158,6 +2158,7 @@ GrGLenum GrGLGpu::bindBuffer(GrGpuBufferType type, const GrBuffer* buffer) {
21582158
} else if (static_cast<const GrGpuBuffer*>(buffer)->uniqueID() !=
21592159
bufferState->fBoundBufferUniqueID) {
21602160
const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(buffer);
2161+
SkASSERT(glBuffer->validBindingTarget(bufferState->fGLTarget));
21612162
GL_CALL(BindBuffer(bufferState->fGLTarget, glBuffer->bufferID()));
21622163
bufferState->fBufferZeroKnownBound = false;
21632164
bufferState->fBoundBufferUniqueID = glBuffer->uniqueID();

0 commit comments

Comments
 (0)