Add half-float vertex attribute caps bit and benchmark
Updates the existing vertex color bench with a half-float mode. Vanilla GL2/ES2 don't have half-float attributes. The extension (OES_vertex_half_float) uses a different enum value for the type parameter. For now, just support GL3/ES3. Otherwise, we could add a check in GrGLGpu::setupGeometry to re-map GL_HALF_FLOAT to GL_HALF_FLOAT_OES, based on caps? Bug: skia: Change-Id: I1325087db4e615023cceffe1c5b051232769d0ac Reviewed-on: https://skia-review.googlesource.com/154822 Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
4c709a2fab
commit
499bf1a599
@ -15,6 +15,7 @@
|
||||
#include "GrRenderTargetContextPriv.h"
|
||||
#include "SkColorSpacePriv.h"
|
||||
#include "SkGr.h"
|
||||
#include "SkHalf.h"
|
||||
#include "SkString.h"
|
||||
#include "glsl/GrGLSLColorSpaceXformHelper.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
@ -28,6 +29,7 @@ namespace {
|
||||
enum Mode {
|
||||
kBaseline_Mode, // Do the wrong thing, but quickly.
|
||||
kFloat_Mode, // Transform colors on CPU, use float4 attributes.
|
||||
kHalf_Mode, // Transform colors on CPU, use half4 attributes.
|
||||
kShader_Mode, // Use ubyte4 attributes, transform colors on GPU (vertex shader).
|
||||
};
|
||||
|
||||
@ -38,10 +40,17 @@ public:
|
||||
, fMode(mode)
|
||||
, fColorSpaceXform(std::move(colorSpaceXform)) {
|
||||
fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
|
||||
if (kFloat_Mode == fMode) {
|
||||
fInColor = {"inColor", kFloat4_GrVertexAttribType, kFloat4_GrSLType};
|
||||
} else {
|
||||
fInColor = {"inColor", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
|
||||
switch (fMode) {
|
||||
case kBaseline_Mode:
|
||||
case kShader_Mode:
|
||||
fInColor = {"inColor", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
|
||||
break;
|
||||
case kFloat_Mode:
|
||||
fInColor = {"inColor", kFloat4_GrVertexAttribType, kHalf4_GrSLType};
|
||||
break;
|
||||
case kHalf_Mode:
|
||||
fInColor = {"inColor", kHalf4_GrVertexAttribType, kHalf4_GrSLType};
|
||||
break;
|
||||
}
|
||||
this->setVertexAttributeCnt(2);
|
||||
}
|
||||
@ -126,10 +135,11 @@ public:
|
||||
this->setBounds(SkRect::MakeWH(100.f, 100.f), HasAABloat::kNo, IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
Op(GrColor4f color4f)
|
||||
Op(GrColor4f color4f, Mode mode)
|
||||
: INHERITED(ClassID())
|
||||
, fMode(kFloat_Mode)
|
||||
, fMode(mode)
|
||||
, fColor4f(color4f) {
|
||||
SkASSERT(kFloat_Mode == fMode || kHalf_Mode == mode);
|
||||
this->setBounds(SkRect::MakeWH(100.f, 100.f), HasAABloat::kNo, IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
@ -155,8 +165,17 @@ private:
|
||||
void onPrepareDraws(Target* target) override {
|
||||
sk_sp<GrGeometryProcessor> gp(new GP(fMode, fColorSpaceXform));
|
||||
|
||||
size_t vertexStride = sizeof(SkPoint) +
|
||||
((kFloat_Mode == fMode) ? sizeof(GrColor4f) : sizeof(uint32_t));
|
||||
size_t vertexStride = sizeof(SkPoint);
|
||||
switch (fMode) {
|
||||
case kFloat_Mode:
|
||||
vertexStride += sizeof(GrColor4f);
|
||||
break;
|
||||
case kHalf_Mode:
|
||||
vertexStride += sizeof(uint64_t);
|
||||
break;
|
||||
default:
|
||||
vertexStride += sizeof(uint32_t);
|
||||
}
|
||||
SkASSERT(vertexStride == gp->debugOnly_vertexStride());
|
||||
|
||||
const int kVertexCount = 1024;
|
||||
@ -182,6 +201,25 @@ private:
|
||||
v[i + 1].fPos.set(dx * i, 100.0f);
|
||||
v[i + 1].fColor = fColor4f;
|
||||
}
|
||||
} else if (kHalf_Mode == fMode) {
|
||||
struct V {
|
||||
SkPoint fPos;
|
||||
uint64_t fColor;
|
||||
};
|
||||
SkASSERT(sizeof(V) == vertexStride);
|
||||
uint64_t color;
|
||||
Sk4h halfColor = SkFloatToHalf_finite_ftz(Sk4f::Load(&fColor));
|
||||
color = (uint64_t)halfColor[0] << 48 |
|
||||
(uint64_t)halfColor[1] << 32 |
|
||||
(uint64_t)halfColor[2] << 16 |
|
||||
(uint64_t)halfColor[3] << 0;
|
||||
V* v = (V*)verts;
|
||||
for (int i = 0; i < kVertexCount; i += 2) {
|
||||
v[i + 0].fPos.set(dx * i, 0.0f);
|
||||
v[i + 0].fColor = color;
|
||||
v[i + 1].fPos.set(dx * i, 100.0f);
|
||||
v[i + 1].fColor = color;
|
||||
}
|
||||
} else {
|
||||
struct V {
|
||||
SkPoint fPos;
|
||||
@ -226,9 +264,15 @@ public:
|
||||
|
||||
void onDraw(int loops, SkCanvas* canvas) override {
|
||||
GrContext* context = canvas->getGrContext();
|
||||
SkASSERT(context);
|
||||
|
||||
if (kHalf_Mode == fMode &&
|
||||
!context->contextPriv().caps()->halfFloatVertexAttributeSupport()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
|
||||
|
||||
SkASSERT(context);
|
||||
auto p3 = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
|
||||
SkColorSpace::kDCIP3_D65_Gamut);
|
||||
auto xform = GrColorSpaceXform::Make(sk_srgb_singleton(), kUnpremul_SkAlphaType,
|
||||
@ -254,10 +298,11 @@ public:
|
||||
case kShader_Mode:
|
||||
op = pool->allocate<Op>(SkColorToUnpremulGrColor(c), xform);
|
||||
break;
|
||||
case kHalf_Mode:
|
||||
case kFloat_Mode: {
|
||||
GrColor4f c4f = GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c));
|
||||
c4f = xform->apply(c4f);
|
||||
op = pool->allocate<Op>(c4f);
|
||||
op = pool->allocate<Op>(c4f, fMode);
|
||||
}
|
||||
}
|
||||
rtc->priv().testingOnly_addDrawOp(std::move(op));
|
||||
@ -276,4 +321,5 @@ private:
|
||||
|
||||
DEF_BENCH(return new VertexColorSpaceBench(kBaseline_Mode, "baseline"));
|
||||
DEF_BENCH(return new VertexColorSpaceBench(kFloat_Mode, "float"));
|
||||
DEF_BENCH(return new VertexColorSpaceBench(kHalf_Mode, "half"));
|
||||
DEF_BENCH(return new VertexColorSpaceBench(kShader_Mode, "shader"));
|
||||
|
@ -62,6 +62,7 @@ GrCaps::GrCaps(const GrContextOptions& options) {
|
||||
fSampleShadingSupport = false;
|
||||
fFenceSyncSupport = false;
|
||||
fCrossContextTextureSupport = false;
|
||||
fHalfFloatVertexAttributeSupport = false;
|
||||
|
||||
fBlendEquationSupport = kBasic_BlendEquationSupport;
|
||||
fAdvBlendEqBlacklist = 0;
|
||||
@ -174,6 +175,7 @@ void GrCaps::dumpJSON(SkJSONWriter* writer) const {
|
||||
writer->appendBool("Sample shading support", fSampleShadingSupport);
|
||||
writer->appendBool("Fence sync support", fFenceSyncSupport);
|
||||
writer->appendBool("Cross context texture support", fCrossContextTextureSupport);
|
||||
writer->appendBool("Half float vertex attribute support", fHalfFloatVertexAttributeSupport);
|
||||
|
||||
writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]",
|
||||
fBlacklistCoverageCounting);
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
|
||||
bool instanceAttribSupport() const { return fInstanceAttribSupport; }
|
||||
bool usesMixedSamples() const { return fUsesMixedSamples; }
|
||||
bool halfFloatVertexAttributeSupport() const { return fHalfFloatVertexAttributeSupport; }
|
||||
|
||||
// Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some
|
||||
// systems. This cap is only set if primitive restart will improve performance.
|
||||
@ -322,6 +323,7 @@ protected:
|
||||
bool fPreferFullscreenClears : 1;
|
||||
bool fMustClearUploadedBufferData : 1;
|
||||
bool fSupportsAHardwareBufferImages : 1;
|
||||
bool fHalfFloatVertexAttributeSupport : 1;
|
||||
|
||||
// Driver workaround
|
||||
bool fBlacklistCoverageCounting : 1;
|
||||
|
@ -576,6 +576,16 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
||||
// Safely moving textures between contexts requires fences.
|
||||
fCrossContextTextureSupport = fFenceSyncSupport;
|
||||
|
||||
// Half float vertex attributes requires GL3 or ES3
|
||||
// It can also work with OES_VERTEX_HALF_FLOAT, but that requires a different enum.
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
if (version >= GR_GL_VER(3, 0)) {
|
||||
fHalfFloatVertexAttributeSupport = true;
|
||||
}
|
||||
} else if (version >= GR_GL_VER(3, 0)) {
|
||||
fHalfFloatVertexAttributeSupport = true;
|
||||
}
|
||||
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
if (version >= GR_GL_VER(4, 1)) {
|
||||
fProgramBinarySupport = true;
|
||||
|
@ -255,6 +255,7 @@ void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
|
||||
|
||||
fFenceSyncSupport = true; // always available in Metal
|
||||
fCrossContextTextureSupport = false;
|
||||
fHalfFloatVertexAttributeSupport = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,6 +35,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
|
||||
fBlacklistCoverageCounting = true; // blacklisting ccpr until we work through a few issues.
|
||||
fFenceSyncSupport = true; // always available in Vulkan
|
||||
fCrossContextTextureSupport = true;
|
||||
fHalfFloatVertexAttributeSupport = true;
|
||||
|
||||
fMapBufferFlags = kNone_MapFlags; //TODO: figure this out
|
||||
fBufferMapThreshold = SK_MaxS32; //TODO: figure this out
|
||||
|
Loading…
Reference in New Issue
Block a user