added support for glMinSampleShading
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1812223002
Review URL: https://codereview.chromium.org/1812223002
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index 398517c..9c62adf 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -269,6 +269,8 @@
is not initialized (even if not read by draw calls). */
bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; }
+ bool sampleShadingSupport() const { return fSampleShadingSupport; }
+
protected:
/** Subclasses must call this at the end of their constructors in order to apply caps
overrides requested by the client. Note that overrides will only reduce the caps never
@@ -303,6 +305,8 @@
// ANGLE workaround
bool fPreferVRAMUseOverFlushes : 1;
+ bool fSampleShadingSupport : 1;
+
BlendEquationSupport fBlendEquationSupport;
uint32_t fAdvBlendEqBlacklist;
GR_STATIC_ASSERT(kLast_GrBlendEquation < 32);
diff --git a/include/gpu/gl/GrGLFunctions.h b/include/gpu/gl/GrGLFunctions.h
index 5708cce..ea1ed65 100644
--- a/include/gpu/gl/GrGLFunctions.h
+++ b/include/gpu/gl/GrGLFunctions.h
@@ -235,6 +235,9 @@
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLProgramUniformHandleui64Proc)(GrGLuint program, GrGLint location, GrGLuint64 v0);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLProgramUniformHandleui64vProc)(GrGLuint program, GrGLint location, GrGLsizei count, const GrGLuint64 *value);
+/* ARB_sample_shading */
+typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLMinSampleShadingProc)(GrGLfloat value);
+
/* EXT_direct_state_access */
// (In the future some of these methods may be omitted)
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLTextureParameteriProc)(GrGLuint texture, GrGLenum target, GrGLenum pname, GrGLint param);
diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
index 545a66d..1e2ac8f 100644
--- a/include/gpu/gl/GrGLInterface.h
+++ b/include/gpu/gl/GrGLInterface.h
@@ -369,6 +369,9 @@
GrGLFunction<GrGLProgramUniformHandleui64Proc> fProgramUniformHandleui64;
GrGLFunction<GrGLProgramUniformHandleui64vProc> fProgramUniformHandleui64v;
+ /* ARB_sample_shading */
+ GrGLFunction<GrGLMinSampleShadingProc> fMinSampleShading;
+
/* EXT_direct_state_access */
// We use the EXT verson because it is more expansive and interacts with more extensions
// than the ARB or core (4.5) versions. We may switch and/or omit methods in the future.
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 784e401..c192c68 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -98,6 +98,7 @@
fSupportsInstancedDraws = false;
fFullClearIsFree = false;
fMustClearUploadedBufferData = false;
+ fSampleShadingSupport = false;
fUseDrawInsteadOfClear = false;
diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h
index 05afd53..1dbf153 100644
--- a/src/gpu/GrGeometryProcessor.h
+++ b/src/gpu/GrGeometryProcessor.h
@@ -21,7 +21,8 @@
public:
GrGeometryProcessor()
: fWillUseGeoShader(false)
- , fLocalCoordsType(kUnused_LocalCoordsType) {}
+ , fLocalCoordsType(kUnused_LocalCoordsType)
+ , fSampleShading(0.0) {}
bool willUseGeoShader() const override { return fWillUseGeoShader; }
@@ -33,6 +34,15 @@
return kHasExplicit_LocalCoordsType == fLocalCoordsType;
}
+ /**
+ * Returns the minimum fraction of samples for which the fragment shader will be run. For
+ * instance, if sampleShading is 0.5 in MSAA16 mode, the fragment shader will run a minimum of
+ * 8 times per pixel. The default value is zero.
+ */
+ float getSampleShading() const override {
+ return fSampleShading;
+ }
+
protected:
/**
* Subclasses call this from their constructor to register vertex attributes. Attributes
@@ -74,9 +84,14 @@
fLocalCoordsType = kHasTransformed_LocalCoordsType;
}
+ void setSampleShading(float sampleShading) {
+ fSampleShading = sampleShading;
+ }
+
private:
bool fWillUseGeoShader;
LocalCoordsType fLocalCoordsType;
+ float fSampleShading;
typedef GrPrimitiveProcessor INHERITED;
};
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index e8bb449..3300ec7 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -217,6 +217,10 @@
*/
virtual const char* getDestColorOverride() const { return nullptr; }
+ virtual float getSampleShading() const {
+ return 0.0;
+ }
+
protected:
GrPrimitiveProcessor() : fVertexStride(0) {}
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp
index 6672d22..d1b2fb6 100644
--- a/src/gpu/gl/GrGLAssembleInterface.cpp
+++ b/src/gpu/gl/GrGLAssembleInterface.cpp
@@ -515,6 +515,10 @@
GET_EGL_PROC_SUFFIX(DestroyImage, KHR);
}
+ if (glVer >= GR_GL_VER(4,0) || extensions.has("GL_ARB_sample_shading")) {
+ GET_PROC(MinSampleShading);
+ }
+
interface->fStandard = kGL_GrGLStandard;
interface->fExtensions.swap(&extensions);
@@ -893,6 +897,10 @@
GET_EGL_PROC_SUFFIX(DestroyImage, KHR);
}
+ if (extensions.has("GL_OES_sample_shading")) {
+ GET_PROC_SUFFIX(MinSampleShading, OES);
+ }
+
interface->fStandard = kGLES_GrGLStandard;
interface->fExtensions.swap(&extensions);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index faccbd1..599a0e0 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -533,6 +533,14 @@
fTextureSwizzleSupport = false;
}
+ if (kGL_GrGLStandard == standard) {
+ if (version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) {
+ fSampleShadingSupport = true;
+ }
+ } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
+ fSampleShadingSupport = true;
+ }
+
// Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
// already been detected.
this->initConfigTable(ctxInfo, gli, glslCaps);
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index ff4c457..98b328b 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -165,7 +165,8 @@
#define GR_GL_LINE_STIPPLE 0x0B24
#define GR_GL_FRAMEBUFFER_SRGB 0x8DB9
#define GR_GL_SHADER_PIXEL_LOCAL_STORAGE 0x8F64
-
+#define GR_GL_SAMPLE_SHADING 0x8C36
+
/* ErrorCode */
#define GR_GL_NO_ERROR 0
#define GR_GL_INVALID_ENUM 0x0500
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 3bbc77a..349ef9a 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -233,6 +233,7 @@
}
fHWPLSEnabled = false;
fPLSHasBeenUsed = false;
+ fHWMinSampleShading = 0.0;
}
GrGLGpu::~GrGLGpu() {
@@ -2070,12 +2071,26 @@
this->disableScissor();
}
+void GrGLGpu::flushMinSampleShading(float minSampleShading) {
+ if (fHWMinSampleShading != minSampleShading) {
+ if (minSampleShading > 0.0) {
+ GL_CALL(Enable(GR_GL_SAMPLE_SHADING));
+ GL_CALL(MinSampleShading(minSampleShading));
+ }
+ else {
+ GL_CALL(Disable(GR_GL_SAMPLE_SHADING));
+ }
+ fHWMinSampleShading = minSampleShading;
+ }
+}
+
bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc) {
GrXferProcessor::BlendInfo blendInfo;
pipeline.getXferProcessor().getBlendInfo(&blendInfo);
this->flushColorWrite(blendInfo.fWriteColor);
this->flushDrawFace(pipeline.getDrawFace());
+ this->flushMinSampleShading(primProc.getSampleShading());
SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc));
if (!program) {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 61fdb8f..c527b53 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -340,6 +340,8 @@
// rt is used only if useHWAA is true.
void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled);
+ void flushMinSampleShading(float minSampleShading);
+
// helper for onCreateTexture and writeTexturePixels
enum UploadType {
kNewTexture_UploadType, // we are creating a new texture
@@ -619,6 +621,8 @@
bool fHWPLSEnabled;
bool fPLSHasBeenUsed;
+ float fHWMinSampleShading;
+
typedef GrGpu INHERITED;
friend class GrGLPathRendering; // For accessing setTextureUnit.
};
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index 728fb3f..32d85b6 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -781,6 +781,17 @@
}
}
+ if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,0)) ||
+ fExtensions.has("GL_ARB_sample_shading")) {
+ if (nullptr == fFunctions.fMinSampleShading) {
+ RETURN_FALSE_INTERFACE
+ }
+ } else if (kGL_GrGLStandard == fStandard && fExtensions.has("GL_OES_sample_shading")) {
+ if (nullptr == fFunctions.fMinSampleShading) {
+ RETURN_FALSE_INTERFACE
+ }
+ }
+
if (fExtensions.has("EGL_KHR_image") || fExtensions.has("EGL_KHR_image_base")) {
if (nullptr == fFunctions.fEGLCreateImage ||
nullptr == fFunctions.fEGLDestroyImage) {
diff --git a/src/gpu/gl/GrGLTestInterface.cpp b/src/gpu/gl/GrGLTestInterface.cpp
index 7200981..c992587 100644
--- a/src/gpu/gl/GrGLTestInterface.cpp
+++ b/src/gpu/gl/GrGLTestInterface.cpp
@@ -116,6 +116,7 @@
fFunctions.fMapBufferRange = bind_to_member(this, &GrGLTestInterface::mapBufferRange);
fFunctions.fMapBufferSubData = bind_to_member(this, &GrGLTestInterface::mapBufferSubData);
fFunctions.fMapTexSubImage2D = bind_to_member(this, &GrGLTestInterface::mapTexSubImage2D);
+ fFunctions.fMinSampleShading = bind_to_member(this, &GrGLTestInterface::minSampleShading);
fFunctions.fPixelStorei = bind_to_member(this, &GrGLTestInterface::pixelStorei);
fFunctions.fPopGroupMarker = bind_to_member(this, &GrGLTestInterface::popGroupMarker);
fFunctions.fPushGroupMarker = bind_to_member(this, &GrGLTestInterface::pushGroupMarker);
diff --git a/src/gpu/gl/GrGLTestInterface.h b/src/gpu/gl/GrGLTestInterface.h
index f8c5801..6af71fe 100644
--- a/src/gpu/gl/GrGLTestInterface.h
+++ b/src/gpu/gl/GrGLTestInterface.h
@@ -113,6 +113,7 @@
virtual GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length, GrGLbitfield access) { return nullptr; }
virtual GrGLvoid* mapBufferSubData(GrGLuint target, GrGLintptr offset, GrGLsizeiptr size, GrGLenum access) { return nullptr; }
virtual GrGLvoid* mapTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLenum access) { return nullptr; }
+ virtual GrGLvoid minSampleShading(GrGLfloat value) {}
virtual GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) {}
virtual GrGLvoid popGroupMarker() {}
virtual GrGLvoid pushGroupMarker(GrGLsizei length, const char* marker) {}
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 89a5a73..3126ca0 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -116,6 +116,7 @@
fStencilWrapOpsSupport = true;
fOversizedStencilSupport = true;
+ fSampleShadingSupport = SkToBool(featureFlags & kSampleRateShading_GrVkFeatureFlag);
}
void GrVkCaps::initGLSLCaps(const VkPhysicalDeviceProperties& properties,
diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp
index 9c0fd28..794acb0 100644
--- a/src/gpu/vk/GrVkPipeline.cpp
+++ b/src/gpu/vk/GrVkPipeline.cpp
@@ -203,7 +203,9 @@
SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount);
}
-void setup_multisample_state(const GrPipeline& pipeline,
+void setup_multisample_state(const GrPipeline& pipeline,
+ const GrPrimitiveProcessor& primProc,
+ const GrCaps* caps,
VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
@@ -212,8 +214,10 @@
int numSamples = pipeline.getRenderTarget()->numColorSamples();
SkAssertResult(GrSampleCountToVkSampleCount(numSamples,
&multisampleInfo->rasterizationSamples));
- multisampleInfo->sampleShadingEnable = VK_FALSE;
- multisampleInfo->minSampleShading = 0;
+ float sampleShading = primProc.getSampleShading();
+ SkASSERT(sampleShading == 0.0f || caps->sampleShadingSupport());
+ multisampleInfo->sampleShadingEnable = sampleShading > 0.0f;
+ multisampleInfo->minSampleShading = sampleShading;
multisampleInfo->pSampleMask = nullptr;
multisampleInfo->alphaToCoverageEnable = VK_FALSE;
multisampleInfo->alphaToOneEnable = VK_FALSE;
@@ -427,7 +431,7 @@
setup_viewport_scissor_state(gpu, pipeline, vkRT, &viewportInfo);
VkPipelineMultisampleStateCreateInfo multisampleInfo;
- setup_multisample_state(pipeline, &multisampleInfo);
+ setup_multisample_state(pipeline, primProc, gpu->caps(), &multisampleInfo);
// We will only have one color attachment per pipeline.
VkPipelineColorBlendAttachmentState attachmentStates[1];
diff --git a/src/views/mac/SkNSView.mm b/src/views/mac/SkNSView.mm
index ada79f8..3a096f6 100644
--- a/src/views/mac/SkNSView.mm
+++ b/src/views/mac/SkNSView.mm
@@ -337,6 +337,7 @@
kCGLPFAStencilSize, (CGLPixelFormatAttribute) 8,
kCGLPFAAccelerated,
kCGLPFADoubleBuffer,
+ kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
(CGLPixelFormatAttribute)0
};