2014-07-16 20:32:56 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2014 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This is a straightforward test of floating point textures, which are
|
|
|
|
* supported on some platforms. As of right now, this test only supports
|
|
|
|
* 32 bit floating point textures, and indeed floating point test values
|
|
|
|
* have been selected to require 32 bits of precision and full IEEE conformance
|
|
|
|
*/
|
2015-04-30 21:18:54 +00:00
|
|
|
|
2014-07-16 20:32:56 +00:00
|
|
|
#include <float.h>
|
|
|
|
#include "Test.h"
|
2015-12-01 12:35:26 +00:00
|
|
|
|
2015-04-30 21:18:54 +00:00
|
|
|
#if SK_SUPPORT_GPU
|
2014-07-16 20:32:56 +00:00
|
|
|
#include "GrContext.h"
|
2017-04-06 11:59:41 +00:00
|
|
|
#include "GrContextPriv.h"
|
2017-03-04 13:12:46 +00:00
|
|
|
#include "GrResourceProvider.h"
|
2017-06-15 18:01:04 +00:00
|
|
|
#include "GrTextureProxy.h"
|
2014-12-05 21:06:35 +00:00
|
|
|
#include "SkHalf.h"
|
2014-07-16 20:32:56 +00:00
|
|
|
|
|
|
|
static const int DEV_W = 100, DEV_H = 100;
|
|
|
|
|
2015-05-21 15:12:27 +00:00
|
|
|
template <typename T>
|
2015-12-01 12:35:26 +00:00
|
|
|
void runFPTest(skiatest::Reporter* reporter, GrContext* context,
|
2015-05-21 15:12:27 +00:00
|
|
|
T min, T max, T epsilon, T maxInt, int arraySize, GrPixelConfig config) {
|
2017-02-08 21:14:11 +00:00
|
|
|
if (0 != arraySize % 4) {
|
|
|
|
REPORT_FAILURE(reporter, "(0 != arraySize % 4)",
|
|
|
|
SkString("arraySize must be divisible by 4."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-05-21 15:12:27 +00:00
|
|
|
SkTDArray<T> controlPixelData, readBuffer;
|
|
|
|
controlPixelData.setCount(arraySize);
|
|
|
|
readBuffer.setCount(arraySize);
|
|
|
|
|
|
|
|
for (int i = 0; i < arraySize; i += 4) {
|
|
|
|
controlPixelData[i + 0] = min;
|
|
|
|
controlPixelData[i + 1] = max;
|
|
|
|
controlPixelData[i + 2] = epsilon;
|
|
|
|
controlPixelData[i + 3] = maxInt;
|
2014-07-16 20:32:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int origin = 0; origin < 2; ++origin) {
|
2015-12-01 12:35:26 +00:00
|
|
|
GrSurfaceDesc desc;
|
|
|
|
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
2017-07-27 20:16:25 +00:00
|
|
|
desc.fOrigin = 0 == origin ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
|
2015-12-01 12:35:26 +00:00
|
|
|
desc.fWidth = DEV_W;
|
|
|
|
desc.fHeight = DEV_H;
|
|
|
|
desc.fConfig = config;
|
2017-04-06 11:59:41 +00:00
|
|
|
sk_sp<GrTextureProxy> fpProxy = GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
|
|
|
|
desc, SkBudgeted::kNo,
|
|
|
|
controlPixelData.begin(), 0);
|
2015-12-01 12:35:26 +00:00
|
|
|
// Floating point textures are NOT supported everywhere
|
2017-04-06 11:59:41 +00:00
|
|
|
if (!fpProxy) {
|
2015-12-01 12:35:26 +00:00
|
|
|
continue;
|
2014-07-16 20:32:56 +00:00
|
|
|
}
|
2017-04-18 11:48:58 +00:00
|
|
|
|
|
|
|
sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
|
|
|
|
std::move(fpProxy), nullptr);
|
|
|
|
REPORTER_ASSERT(reporter, sContext);
|
|
|
|
|
|
|
|
bool result = context->contextPriv().readSurfacePixels(sContext.get(),
|
2017-04-06 11:59:41 +00:00
|
|
|
0, 0, DEV_W, DEV_H,
|
|
|
|
desc.fConfig, nullptr,
|
|
|
|
readBuffer.begin(), 0);
|
|
|
|
REPORTER_ASSERT(reporter, result);
|
2015-12-01 12:35:26 +00:00
|
|
|
REPORTER_ASSERT(reporter,
|
|
|
|
0 == memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
|
2014-07-16 20:32:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-08 21:14:11 +00:00
|
|
|
static const int RGBA32F_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 4;
|
2015-05-21 15:12:27 +00:00
|
|
|
static const float kMaxIntegerRepresentableInSPFloatingPoint = 16777216; // 2 ^ 24
|
2014-12-05 21:06:35 +00:00
|
|
|
|
2016-04-12 16:59:58 +00:00
|
|
|
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FloatingPointTextureTest, reporter, ctxInfo) {
|
2016-05-11 13:33:06 +00:00
|
|
|
runFPTest<float>(reporter, ctxInfo.grContext(), FLT_MIN, FLT_MAX, FLT_EPSILON,
|
2016-03-29 16:03:52 +00:00
|
|
|
kMaxIntegerRepresentableInSPFloatingPoint,
|
2017-02-08 21:14:11 +00:00
|
|
|
RGBA32F_CONTROL_ARRAY_SIZE, kRGBA_float_GrPixelConfig);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const int RG32F_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 2;
|
|
|
|
|
|
|
|
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FloatingPointTextureTest_RG, reporter, ctxInfo) {
|
|
|
|
runFPTest<float>(reporter, ctxInfo.grContext(), FLT_MIN, FLT_MAX, FLT_EPSILON,
|
|
|
|
kMaxIntegerRepresentableInSPFloatingPoint,
|
|
|
|
RG32F_CONTROL_ARRAY_SIZE, kRG_float_GrPixelConfig);
|
2015-05-21 15:12:27 +00:00
|
|
|
}
|
2015-01-22 21:50:35 +00:00
|
|
|
|
2015-05-21 15:12:27 +00:00
|
|
|
static const int HALF_ALPHA_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 1 /*alpha-only*/;
|
|
|
|
static const SkHalf kMaxIntegerRepresentableInHalfFloatingPoint = 0x6800; // 2 ^ 11
|
2014-12-18 13:44:55 +00:00
|
|
|
|
Always use GL_HALF_FLOAT_OES on ANGLE, even with ES3.
In the past, ANGLE always used GL_HALF_FLOAT. I filed a bug about that,
and they switched to HALF_FLOAT_OES. However, ES3 has direct support for
HALF_FLOAT, so we expect that as the format for read pixels.
The better solution would be to remember and return the value we get
back from IMPLEMENTATION_COLOR_READ_TYPE, but there are subtleties that
create additional bugs when we do that. In particular:
If trying to read Alpha8 from RGBA, the current sequence is:
1. readPixelsSupported asks for the format to use. getExternalFormat
switches out the format (assuming we're using GL_RED). This creates
a format/type pair that fails the ES3.2 rules (16.1.2), so we ask
the driver for the secondary format, which matches the one that we
expect (from our config table).
2. Then we *actually* do the readPixels, and here we just call
getReadPixelsFormat, which does the remapping, but skips the follow
up checks in readPixelsSupported. So we end up passing a format/type
pair that our code in readPixelsSupported thinks is illegal (and
which is neither the pair that our config table stores, *nor* the
pair returned by the implementation).
A straightforward solution of the original problem is to notice that
we had to ask the implementation (because the values are filled in),
so we should trust those and not the ones in the config table. But then
we miss out on the chance to overwrite the values for the alpha only
from RGBA case. Sigh.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4963
Change-Id: Icb0c151c9f07ffc178ed3a597fa8ab0ed3c6cb94
Reviewed-on: https://skia-review.googlesource.com/4963
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2016-11-17 18:27:31 +00:00
|
|
|
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(HalfFloatAlphaTextureTest, reporter, ctxInfo) {
|
2016-05-11 13:33:06 +00:00
|
|
|
runFPTest<SkHalf>(reporter, ctxInfo.grContext(), SK_HalfMin, SK_HalfMax, SK_HalfEpsilon,
|
2015-05-21 15:12:27 +00:00
|
|
|
kMaxIntegerRepresentableInHalfFloatingPoint,
|
|
|
|
HALF_ALPHA_CONTROL_ARRAY_SIZE, kAlpha_half_GrPixelConfig);
|
|
|
|
}
|
2014-12-18 13:44:55 +00:00
|
|
|
|
2015-05-21 15:12:27 +00:00
|
|
|
static const int HALF_RGBA_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 4 /*RGBA*/;
|
2014-12-18 13:44:55 +00:00
|
|
|
|
Always use GL_HALF_FLOAT_OES on ANGLE, even with ES3.
In the past, ANGLE always used GL_HALF_FLOAT. I filed a bug about that,
and they switched to HALF_FLOAT_OES. However, ES3 has direct support for
HALF_FLOAT, so we expect that as the format for read pixels.
The better solution would be to remember and return the value we get
back from IMPLEMENTATION_COLOR_READ_TYPE, but there are subtleties that
create additional bugs when we do that. In particular:
If trying to read Alpha8 from RGBA, the current sequence is:
1. readPixelsSupported asks for the format to use. getExternalFormat
switches out the format (assuming we're using GL_RED). This creates
a format/type pair that fails the ES3.2 rules (16.1.2), so we ask
the driver for the secondary format, which matches the one that we
expect (from our config table).
2. Then we *actually* do the readPixels, and here we just call
getReadPixelsFormat, which does the remapping, but skips the follow
up checks in readPixelsSupported. So we end up passing a format/type
pair that our code in readPixelsSupported thinks is illegal (and
which is neither the pair that our config table stores, *nor* the
pair returned by the implementation).
A straightforward solution of the original problem is to notice that
we had to ask the implementation (because the values are filled in),
so we should trust those and not the ones in the config table. But then
we miss out on the chance to overwrite the values for the alpha only
from RGBA case. Sigh.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4963
Change-Id: Icb0c151c9f07ffc178ed3a597fa8ab0ed3c6cb94
Reviewed-on: https://skia-review.googlesource.com/4963
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2016-11-17 18:27:31 +00:00
|
|
|
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(HalfFloatRGBATextureTest, reporter, ctxInfo) {
|
2016-05-11 13:33:06 +00:00
|
|
|
runFPTest<SkHalf>(reporter, ctxInfo.grContext(), SK_HalfMin, SK_HalfMax, SK_HalfEpsilon,
|
2015-05-21 15:12:27 +00:00
|
|
|
kMaxIntegerRepresentableInHalfFloatingPoint,
|
|
|
|
HALF_RGBA_CONTROL_ARRAY_SIZE, kRGBA_half_GrPixelConfig);
|
2014-12-05 21:06:35 +00:00
|
|
|
}
|
|
|
|
|
2014-07-16 20:32:56 +00:00
|
|
|
#endif
|