am aae22498: am b34a078e: Merge "Update EGL wrappers and utilities to latest spec." into mnc-dev
* commit 'aae22498e1eeccd01689e9c789a5c51c79c51ca7':
Update EGL wrappers and utilities to latest spec.
diff --git a/android/package/src/com/drawelements/deqp/testercore/DeqpInstrumentation.java b/android/package/src/com/drawelements/deqp/testercore/DeqpInstrumentation.java
index 466c6fd..f104310 100644
--- a/android/package/src/com/drawelements/deqp/testercore/DeqpInstrumentation.java
+++ b/android/package/src/com/drawelements/deqp/testercore/DeqpInstrumentation.java
@@ -35,6 +35,7 @@
private static final long LAUNCH_TIMEOUT_MS = 10000;
private static final long NO_DATA_TIMEOUT_MS = 1000;
private static final long NO_ACTIVITY_SLEEP_MS = 100;
+ private static final long REMOTE_DEAD_SLEEP_MS = 100;
private String m_cmdLine;
private String m_logFileName;
@@ -105,6 +106,20 @@
parser.init(this, m_logFileName, m_logData);
+ // parse until tester dies
+ {
+ while (true)
+ {
+ if (!parser.parse())
+ {
+ Thread.sleep(NO_ACTIVITY_SLEEP_MS);
+ if (!remoteApi.isRunning())
+ break;
+ }
+ }
+ }
+
+ // parse remaining messages
{
long lastDataMs = System.currentTimeMillis();
@@ -112,15 +127,16 @@
{
if (parser.parse())
lastDataMs = System.currentTimeMillis();
- else if (!remoteApi.isRunning())
+ else
{
final long timeSinceLastDataMs = System.currentTimeMillis()-lastDataMs;
if (timeSinceLastDataMs > NO_DATA_TIMEOUT_MS)
break; // Assume no data is available for reading any more
+
+ // Remote is dead, wait a bit until trying to read again
+ Thread.sleep(REMOTE_DEAD_SLEEP_MS);
}
- else
- Thread.sleep(NO_ACTIVITY_SLEEP_MS);
}
}
diff --git a/android/package/src/com/drawelements/deqp/testercore/RemoteAPI.java b/android/package/src/com/drawelements/deqp/testercore/RemoteAPI.java
index 3c7fd7a..b1c515d 100644
--- a/android/package/src/com/drawelements/deqp/testercore/RemoteAPI.java
+++ b/android/package/src/com/drawelements/deqp/testercore/RemoteAPI.java
@@ -38,11 +38,13 @@
private Context m_context;
private String m_processName;
private String m_logFileName;
+ private boolean m_canBeRunning;
public RemoteAPI (Context context, String logFileName) {
m_context = context;
m_processName = m_context.getPackageName() + ":testercore";
m_logFileName = logFileName;
+ m_canBeRunning = false;
}
private ComponentName getDefaultTesterComponent () {
@@ -101,12 +103,15 @@
return false;
}
+ m_canBeRunning = true;
return true;
}
public boolean kill () {
ActivityManager.RunningAppProcessInfo processInfo = findProcess(m_processName);
+ // \note not mutating m_canBeRunning yet since process does not die immediately
+
if (processInfo != null) {
Log.d(LOG_TAG, "Killing " + m_processName);
Process.killProcess(processInfo.pid);
@@ -119,7 +124,15 @@
}
public boolean isRunning () {
- return isProcessRunning(m_processName);
+ if (!m_canBeRunning) {
+ return false;
+ } else if (isProcessRunning(m_processName)) {
+ return true;
+ } else {
+ // Cache result. Safe, because only start() can spawn the process
+ m_canBeRunning = false;
+ return false;
+ }
}
public String getLogFileName () {
diff --git a/framework/common/tcuResultCollector.hpp b/framework/common/tcuResultCollector.hpp
index d4af499..7fb8ed2 100644
--- a/framework/common/tcuResultCollector.hpp
+++ b/framework/common/tcuResultCollector.hpp
@@ -43,24 +43,25 @@
class ResultCollector
{
public:
- ResultCollector (void);
- ResultCollector (TestLog& log, const std::string& prefix = "");
+ ResultCollector (void);
+ ResultCollector (TestLog& log, const std::string& prefix = "");
- qpTestResult getResult (void) const { return m_result; }
+ qpTestResult getResult (void) const { return m_result; }
+ const std::string getMessage (void) const { return m_message; }
- void fail (const std::string& msg);
- bool check (bool condition, const std::string& msg);
+ void fail (const std::string& msg);
+ bool check (bool condition, const std::string& msg);
- void addResult (qpTestResult result, const std::string& msg);
- bool checkResult (bool condition, qpTestResult result, const std::string& msg);
+ void addResult (qpTestResult result, const std::string& msg);
+ bool checkResult (bool condition, qpTestResult result, const std::string& msg);
- void setTestContextResult (TestContext& testCtx);
+ void setTestContextResult (TestContext& testCtx);
private:
- TestLog* m_log;
- std::string m_prefix;
- qpTestResult m_result;
- std::string m_message;
+ TestLog* const m_log;
+ const std::string m_prefix;
+ qpTestResult m_result;
+ std::string m_message;
} DE_WARN_UNUSED_TYPE;
} // tcu
diff --git a/framework/common/tcuTexLookupVerifier.cpp b/framework/common/tcuTexLookupVerifier.cpp
index 4a70168..7f3e277 100644
--- a/framework/common/tcuTexLookupVerifier.cpp
+++ b/framework/common/tcuTexLookupVerifier.cpp
@@ -293,6 +293,8 @@
{
DE_ASSERT(xBounds.x() <= xBounds.y());
DE_ASSERT(yBounds.x() <= yBounds.y());
+ DE_ASSERT(xBounds.x() + searchStep > xBounds.x()); // step is not effectively 0
+ DE_ASSERT(xBounds.y() + searchStep > xBounds.y());
if (!isInColorBounds(prec, quad, result))
return false;
@@ -322,6 +324,10 @@
DE_ASSERT(xBounds.x() <= xBounds.y());
DE_ASSERT(yBounds.x() <= yBounds.y());
DE_ASSERT(zBounds.x() <= zBounds.y());
+ DE_ASSERT(xBounds.x() + searchStep > xBounds.x()); // step is not effectively 0
+ DE_ASSERT(xBounds.y() + searchStep > xBounds.y());
+ DE_ASSERT(yBounds.x() + searchStep > yBounds.x());
+ DE_ASSERT(yBounds.y() + searchStep > yBounds.y());
if (!isInColorBounds(prec, quad0, quad1, result))
return false;
@@ -354,6 +360,10 @@
{
DE_ASSERT(xBounds0.x() <= xBounds0.y());
DE_ASSERT(xBounds1.x() <= xBounds1.y());
+ DE_ASSERT(xBounds0.x() + searchStep > xBounds0.x()); // step is not effectively 0
+ DE_ASSERT(xBounds0.y() + searchStep > xBounds0.y());
+ DE_ASSERT(xBounds1.x() + searchStep > xBounds1.x());
+ DE_ASSERT(xBounds1.y() + searchStep > xBounds1.y());
if (!isInColorBounds(prec, line0, line1, result))
return false;
@@ -391,6 +401,14 @@
DE_ASSERT(yBounds0.x() <= yBounds0.y());
DE_ASSERT(xBounds1.x() <= xBounds1.y());
DE_ASSERT(yBounds1.x() <= yBounds1.y());
+ DE_ASSERT(xBounds0.x() + searchStep > xBounds0.x()); // step is not effectively 0
+ DE_ASSERT(xBounds0.y() + searchStep > xBounds0.y());
+ DE_ASSERT(yBounds0.x() + searchStep > yBounds0.x());
+ DE_ASSERT(yBounds0.y() + searchStep > yBounds0.y());
+ DE_ASSERT(xBounds1.x() + searchStep > xBounds1.x());
+ DE_ASSERT(xBounds1.y() + searchStep > xBounds1.y());
+ DE_ASSERT(yBounds1.x() + searchStep > yBounds1.x());
+ DE_ASSERT(yBounds1.y() + searchStep > yBounds1.y());
if (!isInColorBounds(prec, quad0, quad1, result))
return false;
@@ -442,6 +460,18 @@
DE_ASSERT(xBounds1.x() <= xBounds1.y());
DE_ASSERT(yBounds1.x() <= yBounds1.y());
DE_ASSERT(zBounds1.x() <= zBounds1.y());
+ DE_ASSERT(xBounds0.x() + searchStep > xBounds0.x()); // step is not effectively 0
+ DE_ASSERT(xBounds0.y() + searchStep > xBounds0.y());
+ DE_ASSERT(yBounds0.x() + searchStep > yBounds0.x());
+ DE_ASSERT(yBounds0.y() + searchStep > yBounds0.y());
+ DE_ASSERT(zBounds0.x() + searchStep > zBounds0.x());
+ DE_ASSERT(zBounds0.y() + searchStep > zBounds0.y());
+ DE_ASSERT(xBounds1.x() + searchStep > xBounds1.x());
+ DE_ASSERT(xBounds1.y() + searchStep > xBounds1.y());
+ DE_ASSERT(yBounds1.x() + searchStep > yBounds1.x());
+ DE_ASSERT(yBounds1.y() + searchStep > yBounds1.y());
+ DE_ASSERT(zBounds1.x() + searchStep > zBounds1.x());
+ DE_ASSERT(zBounds1.y() + searchStep > zBounds1.y());
if (!isInColorBounds(prec, quad00, quad01, quad10, quad11, result))
return false;
@@ -603,6 +633,15 @@
const int w = level.getWidth();
+ const TextureFormat format = level.getFormat();
+ const TextureChannelClass texClass = getTextureChannelClass(format.type);
+
+ DE_ASSERT(texClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_FLOATING_POINT);
+ DE_UNREF(texClass);
+ DE_UNREF(format);
+
for (int i = minI; i <= maxI; i++)
{
// Wrapped coordinates
@@ -647,6 +686,10 @@
texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ? computeBilinearSearchStepForSnorm(prec) :
0.0f; // Step is computed for floating-point quads based on texel values.
+ DE_ASSERT(texClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_FLOATING_POINT);
+
// \todo [2013-07-03 pyry] This could be optimized by first computing ranges based on wrap mode.
for (int j = minJ; j <= maxJ; j++)
@@ -706,6 +749,10 @@
texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ? computeBilinearSearchStepForSnorm(prec) :
0.0f; // Step is computed for floating-point quads based on texel values.
+ DE_ASSERT(texClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_FLOATING_POINT);
+
// \todo [2013-07-03 pyry] This could be optimized by first computing ranges based on wrap mode.
for (int k = minK; k <= maxK; k++)
@@ -910,8 +957,8 @@
const int w0 = level0.getWidth();
const int w1 = level1.getWidth();
- const Vec2 uBounds0 = computeNonNormalizedCoordBounds(sampler.normalizedCoords, w0, coordX, prec.coordBits.x(), prec.uvwBits.x());
- const Vec2 uBounds1 = computeNonNormalizedCoordBounds(sampler.normalizedCoords, w1, coordX, prec.coordBits.x(), prec.uvwBits.x());
+ const Vec2 uBounds0 = computeNonNormalizedCoordBounds(sampler.normalizedCoords, w0, coordX, prec.coordBits.x(), prec.uvwBits.x());
+ const Vec2 uBounds1 = computeNonNormalizedCoordBounds(sampler.normalizedCoords, w1, coordX, prec.coordBits.x(), prec.uvwBits.x());
// Integer coordinates - without wrap mode
const int minI0 = deFloorFloatToInt32(uBounds0.x()-0.5f);
@@ -924,6 +971,10 @@
texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ? computeBilinearSearchStepForSnorm(prec) :
0.0f; // Step is computed for floating-point quads based on texel values.
+ DE_ASSERT(texClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_FLOATING_POINT);
+
for (int i0 = minI0; i0 <= maxI0; i0++)
{
ColorLine line0;
@@ -1007,6 +1058,10 @@
texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ? computeBilinearSearchStepForSnorm(prec) :
0.0f; // Step is computed for floating-point quads based on texel values.
+ DE_ASSERT(texClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_FLOATING_POINT);
+
for (int j0 = minJ0; j0 <= maxJ0; j0++)
{
for (int i0 = minI0; i0 <= maxI0; i0++)
@@ -1112,6 +1167,10 @@
texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ? computeBilinearSearchStepForSnorm(prec) :
0.0f; // Step is computed for floating-point quads based on texel values.
+ DE_ASSERT(texClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_FLOATING_POINT);
+
for (int k0 = minK0; k0 <= maxK0; k0++)
{
for (int j0 = minJ0; j0 <= maxJ0; j0++)
@@ -1403,6 +1462,10 @@
texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ? computeBilinearSearchStepForSnorm(prec) :
0.0f; // Step is computed for floating-point quads based on texel values.
+ DE_ASSERT(texClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_FLOATING_POINT);
+
for (int j = minJ; j <= maxJ; j++)
{
for (int i = minI; i <= maxI; i++)
@@ -1474,6 +1537,10 @@
texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ? computeBilinearSearchStepForSnorm(prec) :
0.0f; // Step is computed for floating-point quads based on texel values.
+ DE_ASSERT(texClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
+ texClass == TEXTURECHANNELCLASS_FLOATING_POINT);
+
for (int j0 = minJ0; j0 <= maxJ0; j0++)
{
for (int i0 = minI0; i0 <= maxI0; i0++)
@@ -1570,7 +1637,7 @@
}
static bool isCubeMipmapLinearSampleResultValid (const ConstPixelBufferAccess (&faces0)[CUBEFACE_LAST],
- const ConstPixelBufferAccess (&faces1)[CUBEFACE_LAST],
+ const ConstPixelBufferAccess (&faces1)[CUBEFACE_LAST],
const Sampler& sampler,
const Sampler::FilterMode levelFilter,
const LookupPrecision& prec,
@@ -2264,8 +2331,8 @@
const IVec2 (&offsets)[4],
const Vector<ScalarType, 4>& result)
{
- const Vec2 uBounds = computeNonNormalizedCoordBounds(sampler.normalizedCoords, level.getWidth(), coord.x(), prec.coordBits.x(), prec.uvwBits.x());
- const Vec2 vBounds = computeNonNormalizedCoordBounds(sampler.normalizedCoords, level.getHeight(), coord.y(), prec.coordBits.y(), prec.uvwBits.y());
+ const Vec2 uBounds = computeNonNormalizedCoordBounds(sampler.normalizedCoords, level.getWidth(), coord.x(), prec.coordBits.x(), prec.uvwBits.x());
+ const Vec2 vBounds = computeNonNormalizedCoordBounds(sampler.normalizedCoords, level.getHeight(), coord.y(), prec.coordBits.y(), prec.uvwBits.y());
// Integer coordinate bounds for (x0, y0) - without wrap mode
const int minI = deFloorFloatToInt32(uBounds.x()-0.5f);
diff --git a/framework/common/tcuTexture.cpp b/framework/common/tcuTexture.cpp
index 6fb69f0..d546cee 100644
--- a/framework/common/tcuTexture.cpp
+++ b/framework/common/tcuTexture.cpp
@@ -405,7 +405,6 @@
static const TextureSwizzle ARGB = {{ TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_0 }};
static const TextureSwizzle D = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ONE }};
static const TextureSwizzle S = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ONE }};
- static const TextureSwizzle DS = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_1 }};
switch (order)
{
@@ -426,7 +425,11 @@
case TextureFormat::sRGBA: return RGBA;
case TextureFormat::D: return D;
case TextureFormat::S: return S;
- case TextureFormat::DS: return DS;
+
+ case TextureFormat::DS:
+ DE_ASSERT(false); // combined formats cannot be read from
+ return INV;
+
default:
DE_ASSERT(DE_FALSE);
return INV;
@@ -452,7 +455,6 @@
static const TextureSwizzle ARGB = {{ TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_2 }};
static const TextureSwizzle D = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }};
static const TextureSwizzle S = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }};
- static const TextureSwizzle DS = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }};
switch (order)
{
@@ -473,7 +475,11 @@
case TextureFormat::sRGBA: return RGBA;
case TextureFormat::D: return D;
case TextureFormat::S: return S;
- case TextureFormat::DS: return DS;
+
+ case TextureFormat::DS:
+ DE_ASSERT(false); // combined formats cannot be written to
+ return INV;
+
default:
DE_ASSERT(DE_FALSE);
return INV;
@@ -610,8 +616,10 @@
DE_ASSERT(de::inBounds(x, 0, m_size.x()));
DE_ASSERT(de::inBounds(y, 0, m_size.y()));
DE_ASSERT(de::inBounds(z, 0, m_size.z()));
+ DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
+ DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
- const deUint8* pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
+ const deUint8* pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
// Optimized fomats.
if (m_format.type == TextureFormat::UNORM_INT8)
@@ -639,25 +647,6 @@
case TextureFormat::UNSIGNED_INT_1010102_REV: return UVec4(UB32(0, 10), UB32(10, 10), UB32(20, 10), UB32(30, 2)).cast<float>();
case TextureFormat::UNSIGNED_INT_999_E5_REV: return unpackRGB999E5(*((const deUint32*)pixelPtr));
- case TextureFormat::UNSIGNED_INT_24_8:
- switch (m_format.order)
- {
- // \note Stencil is always ignored.
- case TextureFormat::D: return Vec4(NB32(8, 24), 0.0f, 0.0f, 1.0f);
- case TextureFormat::DS: return Vec4(NB32(8, 24), 0.0f, 0.0f, 1.0f /* (float)UB32(0, 8) */);
- default:
- DE_ASSERT(false);
- }
-
- case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
- {
- DE_ASSERT(m_format.order == TextureFormat::DS);
- float d = *((const float*)pixelPtr);
- // \note Stencil is ignored.
-// deUint8 s = *((const deUint32*)(pixelPtr+4)) & 0xff;
- return Vec4(d, 0.0f, 0.0f, 1.0f);
- }
-
case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
return Vec4(Float11(UB32(0, 11)).asFloat(), Float11(UB32(11, 11)).asFloat(), Float10(UB32(22, 10)).asFloat(), 1.0f);
@@ -707,8 +696,10 @@
DE_ASSERT(de::inBounds(x, 0, m_size.x()));
DE_ASSERT(de::inBounds(y, 0, m_size.y()));
DE_ASSERT(de::inBounds(z, 0, m_size.z()));
+ DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
+ DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
- const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
+ const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
IVec4 result;
// Optimized fomats.
@@ -731,25 +722,6 @@
case TextureFormat::UNORM_INT_1010102_REV: return UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)).cast<int>();
case TextureFormat::UNSIGNED_INT_1010102_REV: return UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)).cast<int>();
- case TextureFormat::UNSIGNED_INT_24_8:
- switch (m_format.order)
- {
- case TextureFormat::D: return UVec4(U32(8, 24), 0, 0, 1).cast<int>();
- case TextureFormat::S: return UVec4(0, 0, 0, U32(8, 24)).cast<int>();
- case TextureFormat::DS: return UVec4(U32(8, 24), 0, 0, U32(0, 8)).cast<int>();
- default:
- DE_ASSERT(false);
- }
-
- case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
- {
- DE_ASSERT(m_format.order == TextureFormat::DS);
- float d = *((const float*)pixelPtr);
- deUint8 s = *((const deUint32*)(pixelPtr+4)) & 0xffu;
- // \note Returns bit-representation of depth floating-point value.
- return UVec4(tcu::Float32(d).bits(), 0, 0, s).cast<int>();
- }
-
default:
break; // To generic path.
}
@@ -812,7 +784,7 @@
DE_ASSERT(de::inBounds(y, 0, getHeight()));
DE_ASSERT(de::inBounds(z, 0, getDepth()));
- const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
+ const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
#define UB32(OFFS, COUNT) ((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
#define NB32(OFFS, COUNT) channelToNormFloat(UB32(OFFS, COUNT), (COUNT))
@@ -837,7 +809,7 @@
return *((const float*)pixelPtr);
default:
- DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
+ DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
return channelToFloat(pixelPtr, m_format.type);
}
@@ -851,7 +823,7 @@
DE_ASSERT(de::inBounds(y, 0, getHeight()));
DE_ASSERT(de::inBounds(z, 0, getDepth()));
- const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
+ const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
switch (m_format.type)
{
@@ -872,14 +844,8 @@
default:
{
- if (m_format.order == TextureFormat::S)
- return channelToInt(pixelPtr, m_format.type);
- else
- {
- DE_ASSERT(m_format.order == TextureFormat::DS);
- const int stencilChannelIndex = 3;
- return channelToInt(pixelPtr + getChannelSize(m_format.type)*stencilChannelIndex, m_format.type);
- }
+ DE_ASSERT(m_format.order == TextureFormat::S); // no other combined depth stencil types
+ return channelToInt(pixelPtr, m_format.type);
}
}
}
@@ -889,8 +855,10 @@
DE_ASSERT(de::inBounds(x, 0, getWidth()));
DE_ASSERT(de::inBounds(y, 0, getHeight()));
DE_ASSERT(de::inBounds(z, 0, getDepth()));
+ DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
+ DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
- deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
+ deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
// Optimized fomats.
if (m_format.type == TextureFormat::UNORM_INT8)
@@ -934,31 +902,6 @@
*((deUint32*)pixelPtr) = packRGB999E5(color);
break;
- case TextureFormat::UNSIGNED_INT_24_8:
- switch (m_format.order)
- {
- case TextureFormat::D: *((deUint32*)pixelPtr) = PN(color[0], 8, 24); break;
- case TextureFormat::S: *((deUint32*)pixelPtr) = PN(color[3], 8, 24); break;
- case TextureFormat::DS: *((deUint32*)pixelPtr) = PN(color[0], 8, 24) | PU((deUint32)color[3], 0, 8); break;
- default:
- DE_ASSERT(false);
- }
- break;
-
- case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
- DE_ASSERT(m_format.order == TextureFormat::DS);
- *((float*)pixelPtr) = color[0];
- *((deUint32*)(pixelPtr+4)) = PU((deUint32)color[3], 0, 8);
- break;
-
- case TextureFormat::FLOAT:
- if (m_format.order == TextureFormat::D)
- {
- *((float*)pixelPtr) = color[0];
- break;
- }
- // else fall-through to default case!
-
default:
{
// Generic path.
@@ -984,8 +927,10 @@
DE_ASSERT(de::inBounds(x, 0, getWidth()));
DE_ASSERT(de::inBounds(y, 0, getHeight()));
DE_ASSERT(de::inBounds(z, 0, getDepth()));
+ DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
+ DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
- deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
+ deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
// Optimized fomats.
if (m_format.type == TextureFormat::UNORM_INT8)
@@ -1006,23 +951,6 @@
case TextureFormat::UNORM_INT_1010102_REV: *((deUint32*)pixelPtr) = PU(color[0], 0, 10) | PU(color[1], 10, 10) | PU(color[2], 20, 10) | PU(color[3], 30, 2); break;
case TextureFormat::UNSIGNED_INT_1010102_REV: *((deUint32*)pixelPtr) = PU(color[0], 0, 10) | PU(color[1], 10, 10) | PU(color[2], 20, 10) | PU(color[3], 30, 2); break;
- case TextureFormat::UNSIGNED_INT_24_8:
- switch (m_format.order)
- {
- case TextureFormat::D: *((deUint32*)pixelPtr) = PU(color[0], 8, 24); break;
- case TextureFormat::S: *((deUint32*)pixelPtr) = PU(color[3], 8, 24); break;
- case TextureFormat::DS: *((deUint32*)pixelPtr) = PU(color[0], 8, 24) | PU((deUint32)color[3], 0, 8); break;
- default:
- DE_ASSERT(false);
- }
- break;
-
- case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
- DE_ASSERT(m_format.order == TextureFormat::DS);
- *((deUint32*)pixelPtr) = color[0];
- *((deUint32*)(pixelPtr+4)) = PU((deUint32)color[3], 0, 8);
- break;
-
default:
{
// Generic path.
@@ -1048,7 +976,7 @@
DE_ASSERT(de::inBounds(y, 0, getHeight()));
DE_ASSERT(de::inBounds(z, 0, getDepth()));
- deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
+ deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
#define PN(VAL, OFFS, BITS) (normFloatToChannel((VAL), (BITS)) << (OFFS))
@@ -1070,7 +998,7 @@
break;
default:
- DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
+ DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
floatToChannel(pixelPtr, depth, m_format.type);
break;
}
@@ -1084,7 +1012,7 @@
DE_ASSERT(de::inBounds(y, 0, getHeight()));
DE_ASSERT(de::inBounds(z, 0, getDepth()));
- deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
+ deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
#define PU(VAL, OFFS, BITS) (uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
@@ -1106,15 +1034,8 @@
break;
default:
- if (m_format.order == TextureFormat::S)
- intToChannel(pixelPtr, stencil, m_format.type);
- else
- {
- DE_ASSERT(m_format.order == TextureFormat::DS);
- const int stencilChannelIndex = 3;
- intToChannel(pixelPtr + getChannelSize(m_format.type)*stencilChannelIndex, stencil, m_format.type);
- }
-
+ DE_ASSERT(m_format.order == TextureFormat::S); // no other combined depth stencil types
+ intToChannel(pixelPtr, stencil, m_format.type);
break;
}
@@ -1201,31 +1122,18 @@
static bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
{
+ DE_ASSERT(format.order == TextureFormat::D);
+
const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
-
- if (format.order == TextureFormat::D)
+ if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
+ return false;
+ else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
+ return true;
+ else
{
- // depth internal formats cannot be non-normalized integers
- return channelClass != tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
+ DE_ASSERT(false);
+ return false;
}
- else if (format.order == TextureFormat::DS)
- {
- // combined formats have no single channel class, detect format manually
- switch (format.type)
- {
- case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: return false;
- case tcu::TextureFormat::UNSIGNED_INT_24_8: return true;
-
- default:
- {
- // unknown format
- DE_ASSERT(false);
- return true;
- }
- }
- }
-
- return false;
}
// Texel lookup with color conversion.
diff --git a/framework/delibs/decpp/deSpinBarrier.cpp b/framework/delibs/decpp/deSpinBarrier.cpp
index 150bbc2..efba57b 100644
--- a/framework/delibs/decpp/deSpinBarrier.cpp
+++ b/framework/delibs/decpp/deSpinBarrier.cpp
@@ -32,9 +32,11 @@
{
SpinBarrier::SpinBarrier (deInt32 numThreads)
- : m_numThreads (numThreads)
+ : m_numCores (deGetNumAvailableLogicalCores())
+ , m_numThreads (numThreads)
, m_numEntered (0)
, m_numLeaving (0)
+ , m_numRemoved (0)
{
DE_ASSERT(numThreads > 0);
}
@@ -44,12 +46,41 @@
DE_ASSERT(m_numEntered == 0 && m_numLeaving == 0);
}
-void SpinBarrier::sync (WaitMode mode)
+void SpinBarrier::reset (deUint32 numThreads)
{
- DE_ASSERT(mode == WAIT_MODE_YIELD || mode == WAIT_MODE_BUSY);
+ // If last threads were removed, m_numEntered > 0 && m_numRemoved > 0
+ DE_ASSERT(m_numLeaving == 0);
+ DE_ASSERT(numThreads > 0);
+ m_numThreads = numThreads;
+ m_numEntered = 0;
+ m_numLeaving = 0;
+ m_numRemoved = 0;
+}
+
+inline SpinBarrier::WaitMode getWaitMode (SpinBarrier::WaitMode requested, deUint32 numCores, deInt32 numThreads)
+{
+ if (requested == SpinBarrier::WAIT_MODE_AUTO)
+ return ((deUint32)numThreads <= numCores) ? SpinBarrier::WAIT_MODE_BUSY : SpinBarrier::WAIT_MODE_YIELD;
+ else
+ return requested;
+}
+
+inline void wait (SpinBarrier::WaitMode mode)
+{
+ DE_ASSERT(mode == SpinBarrier::WAIT_MODE_YIELD || mode == SpinBarrier::WAIT_MODE_BUSY);
+
+ if (mode == SpinBarrier::WAIT_MODE_YIELD)
+ deYield();
+}
+
+void SpinBarrier::sync (WaitMode requestedMode)
+{
+ const WaitMode waitMode = getWaitMode(requestedMode, m_numCores, m_numThreads);
deMemoryReadWriteFence();
+ // m_numEntered must not be touched until all threads have had
+ // a chance to observe it being 0.
if (m_numLeaving > 0)
{
for (;;)
@@ -57,16 +88,25 @@
if (m_numLeaving == 0)
break;
- if (mode == WAIT_MODE_YIELD)
- deYield();
+ wait(waitMode);
}
}
if (deAtomicIncrement32(&m_numEntered) == m_numThreads)
{
- m_numLeaving = m_numThreads;
+ m_numLeaving = m_numThreads;
deMemoryReadWriteFence();
- m_numEntered = 0;
+
+ // m_numLeaving must be set > 0 when manipulating m_numRemoved
+ // to prevent other threads from touching m_numRemoved.
+ // Since this thread has not been removed, m_numLeaving will be >= 1
+ // until m_numLeaving is decremented at the end of this function.
+ m_numThreads -= m_numRemoved;
+ m_numLeaving -= m_numRemoved;
+ m_numRemoved = 0;
+
+ deMemoryReadWriteFence();
+ m_numEntered = 0;
}
else
{
@@ -75,8 +115,7 @@
if (m_numEntered == 0)
break;
- if (mode == WAIT_MODE_YIELD)
- deYield();
+ wait(waitMode);
}
}
@@ -84,6 +123,44 @@
deMemoryReadWriteFence();
}
+void SpinBarrier::removeThread (WaitMode requestedMode)
+{
+ const WaitMode waitMode = getWaitMode(requestedMode, m_numCores, m_numThreads);
+
+ // Wait for other threads exiting previous barrier
+ if (m_numLeaving > 0)
+ {
+ for (;;)
+ {
+ if (m_numLeaving == 0)
+ break;
+
+ wait(waitMode);
+ }
+ }
+
+ // Ask for last thread entering barrier to adjust thread count
+ deAtomicIncrement32(&m_numRemoved);
+
+ if (deAtomicIncrement32(&m_numEntered) == m_numThreads)
+ {
+ m_numLeaving = m_numThreads;
+ deMemoryReadWriteFence();
+
+ // See sync() - m_numLeaving > 0 when manipulating m_numRemoved.
+ // This thread must not be removed from m_numLeaving until
+ // m_numRemoved has been updated.
+ m_numThreads -= m_numRemoved;
+ m_numLeaving -= (m_numRemoved-1);
+ m_numRemoved = 0;
+
+ deMemoryReadWriteFence();
+ m_numEntered = 0;
+
+ deAtomicDecrement32(&m_numLeaving);
+ }
+}
+
namespace
{
@@ -99,12 +176,12 @@
class TestThread : public de::Thread
{
public:
- TestThread (SpinBarrier& barrier, volatile deInt32* sharedVar, int numThreads, int threadNdx, bool busyOk)
+ TestThread (SpinBarrier& barrier, volatile deInt32* sharedVar, int numThreads, int threadNdx)
: m_barrier (barrier)
, m_sharedVar (sharedVar)
, m_numThreads (numThreads)
, m_threadNdx (threadNdx)
- , m_busyOk (busyOk)
+ , m_busyOk ((deUint32)m_numThreads <= deGetNumAvailableLogicalCores())
{
}
@@ -138,18 +215,23 @@
}
private:
- SpinBarrier& m_barrier;
- volatile deInt32* m_sharedVar;
- int m_numThreads;
- int m_threadNdx;
- bool m_busyOk;
+ SpinBarrier& m_barrier;
+ volatile deInt32* const m_sharedVar;
+ const int m_numThreads;
+ const int m_threadNdx;
+ const bool m_busyOk;
SpinBarrier::WaitMode getWaitMode (de::Random& rnd)
{
- if (m_busyOk && rnd.getBool())
- return SpinBarrier::WAIT_MODE_BUSY;
- else
- return SpinBarrier::WAIT_MODE_YIELD;
+ static const SpinBarrier::WaitMode s_allModes[] =
+ {
+ SpinBarrier::WAIT_MODE_YIELD,
+ SpinBarrier::WAIT_MODE_AUTO,
+ SpinBarrier::WAIT_MODE_BUSY,
+ };
+ const int numModes = DE_LENGTH_OF_ARRAY(s_allModes) - (m_busyOk ? 0 : 1);
+
+ return rnd.choose<SpinBarrier::WaitMode>(DE_ARRAY_BEGIN(s_allModes), DE_ARRAY_BEGIN(s_allModes) + numModes);
}
};
@@ -159,14 +241,9 @@
volatile deInt32 sharedVar = 0;
std::vector<TestThread*> threads (numThreads, static_cast<TestThread*>(DE_NULL));
- // Going over logical cores with busy-waiting will cause priority inversion and make tests take
- // excessive amount of time. Use busy waiting only when number of threads is at most one per
- // core.
- const bool busyOk = (deUint32)numThreads <= deGetNumAvailableLogicalCores();
-
for (int ndx = 0; ndx < numThreads; ndx++)
{
- threads[ndx] = new TestThread(barrier, &sharedVar, numThreads, ndx, busyOk);
+ threads[ndx] = new TestThread(barrier, &sharedVar, numThreads, ndx);
DE_TEST_ASSERT(threads[ndx]);
threads[ndx]->start();
}
@@ -180,17 +257,104 @@
DE_TEST_ASSERT(sharedVar == 0);
}
-} // namespace
+void singleThreadRemoveTest (SpinBarrier::WaitMode mode)
+{
+ SpinBarrier barrier(3);
+
+ barrier.removeThread(mode);
+ barrier.removeThread(mode);
+ barrier.sync(mode);
+ barrier.removeThread(mode);
+
+ barrier.reset(1);
+ barrier.sync(mode);
+
+ barrier.reset(2);
+ barrier.removeThread(mode);
+ barrier.sync(mode);
+}
+
+class TestExitThread : public de::Thread
+{
+public:
+ TestExitThread (SpinBarrier& barrier, int numThreads, int threadNdx, SpinBarrier::WaitMode waitMode)
+ : m_barrier (barrier)
+ , m_numThreads (numThreads)
+ , m_threadNdx (threadNdx)
+ , m_waitMode (waitMode)
+ {
+ }
+
+ void run (void)
+ {
+ const int numIters = 10000;
+ de::Random rnd (deInt32Hash(m_numThreads) ^ deInt32Hash(m_threadNdx) ^ deInt32Hash((deInt32)m_waitMode));
+ const int invExitProb = 1000;
+
+ for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
+ {
+ if (rnd.getInt(0, invExitProb) == 0)
+ {
+ m_barrier.removeThread(m_waitMode);
+ break;
+ }
+ else
+ m_barrier.sync(m_waitMode);
+ }
+ }
+
+private:
+ SpinBarrier& m_barrier;
+ const int m_numThreads;
+ const int m_threadNdx;
+ const SpinBarrier::WaitMode m_waitMode;
+};
+
+void multiThreadRemoveTest (int numThreads, SpinBarrier::WaitMode waitMode)
+{
+ SpinBarrier barrier (numThreads);
+ std::vector<TestExitThread*> threads (numThreads, static_cast<TestExitThread*>(DE_NULL));
+
+ for (int ndx = 0; ndx < numThreads; ndx++)
+ {
+ threads[ndx] = new TestExitThread(barrier, numThreads, ndx, waitMode);
+ DE_TEST_ASSERT(threads[ndx]);
+ threads[ndx]->start();
+ }
+
+ for (int ndx = 0; ndx < numThreads; ndx++)
+ {
+ threads[ndx]->join();
+ delete threads[ndx];
+ }
+}
+
+} // anonymous
void SpinBarrier_selfTest (void)
{
singleThreadTest(SpinBarrier::WAIT_MODE_YIELD);
singleThreadTest(SpinBarrier::WAIT_MODE_BUSY);
+ singleThreadTest(SpinBarrier::WAIT_MODE_AUTO);
multiThreadTest(1);
multiThreadTest(2);
multiThreadTest(4);
multiThreadTest(8);
multiThreadTest(16);
+
+ singleThreadRemoveTest(SpinBarrier::WAIT_MODE_YIELD);
+ singleThreadRemoveTest(SpinBarrier::WAIT_MODE_BUSY);
+ singleThreadRemoveTest(SpinBarrier::WAIT_MODE_AUTO);
+ multiThreadRemoveTest(1, SpinBarrier::WAIT_MODE_BUSY);
+ multiThreadRemoveTest(2, SpinBarrier::WAIT_MODE_AUTO);
+ multiThreadRemoveTest(4, SpinBarrier::WAIT_MODE_AUTO);
+ multiThreadRemoveTest(8, SpinBarrier::WAIT_MODE_AUTO);
+ multiThreadRemoveTest(16, SpinBarrier::WAIT_MODE_AUTO);
+ multiThreadRemoveTest(1, SpinBarrier::WAIT_MODE_YIELD);
+ multiThreadRemoveTest(2, SpinBarrier::WAIT_MODE_YIELD);
+ multiThreadRemoveTest(4, SpinBarrier::WAIT_MODE_YIELD);
+ multiThreadRemoveTest(8, SpinBarrier::WAIT_MODE_YIELD);
+ multiThreadRemoveTest(16, SpinBarrier::WAIT_MODE_YIELD);
}
} // de
diff --git a/framework/delibs/decpp/deSpinBarrier.hpp b/framework/delibs/decpp/deSpinBarrier.hpp
index 6679f8d..484d57a 100644
--- a/framework/delibs/decpp/deSpinBarrier.hpp
+++ b/framework/delibs/decpp/deSpinBarrier.hpp
@@ -35,14 +35,21 @@
* SpinBarrier provides barrier implementation that uses spin loop for
* waiting for other threads. Threads may choose to wait in tight loop
* (WAIT_MODE_BUSY) or yield between iterations (WAIT_MODE_YIELD).
+ *
+ * It is not recommended to use WAIT_MODE_BUSY when there are more threads
+ * than number of cores participating in the barrier as it will lead to
+ * priority inversion and dramatic slowdown. For that reason WAIT_MODE_AUTO
+ * is provided, which selects between busy and yielding waiting based on
+ * number of threads.
*//*--------------------------------------------------------------------*/
class SpinBarrier
{
public:
enum WaitMode
{
- WAIT_MODE_BUSY = 0,
- WAIT_MODE_YIELD,
+ WAIT_MODE_BUSY = 0, //! Wait in tight spin loop.
+ WAIT_MODE_YIELD, //! Call deYield() between spin loop iterations.
+ WAIT_MODE_AUTO, //! Use WAIT_MODE_BUSY loop if #threads <= #cores, otherwise WAIT_MODE_YIELD.
WAIT_MODE_LAST
};
@@ -50,15 +57,28 @@
SpinBarrier (deInt32 numThreads);
~SpinBarrier (void);
+ //! Reset barrier. Not thread-safe, e.g. no other thread can
+ //! be calling sync() or removeThread() at the same time.
+ void reset (deUint32 numThreads);
+
+ //! Wait until all threads (determined by active thread count)
+ //! have entered sync().
void sync (WaitMode mode);
+ //! Remove thread from barrier (decrements active thread count).
+ //! Can be called concurrently with sync() or removeThread().
+ void removeThread (WaitMode mode);
+
private:
SpinBarrier (const SpinBarrier&);
SpinBarrier operator= (const SpinBarrier&);
- const deInt32 m_numThreads;
+ const deUint32 m_numCores;
+
+ volatile deInt32 m_numThreads;
volatile deInt32 m_numEntered;
volatile deInt32 m_numLeaving;
+ volatile deInt32 m_numRemoved;
};
void SpinBarrier_selfTest (void);
diff --git a/framework/platform/null/tcuNullRenderContext.cpp b/framework/platform/null/tcuNullRenderContext.cpp
index f82267a..b91d2ee 100644
--- a/framework/platform/null/tcuNullRenderContext.cpp
+++ b/framework/platform/null/tcuNullRenderContext.cpp
@@ -92,6 +92,7 @@
string shadingLanguageVersion;
string extensions;
vector<string> extensionList;
+ vector<deUint32> compressedTextureList;
GLenum lastError;
@@ -146,7 +147,7 @@
addExtension("GL_OES_sample_shading");
addExtension("GL_OES_sample_variables");
addExtension("GL_OES_shader_multisample_interpolation");
- addExtension("GL_OES_shader_image_atomics");
+ addExtension("GL_OES_shader_image_atomic");
addExtension("GL_OES_texture_storage_multisample_2d_array");
addExtension("GL_KHR_blend_equation_advanced");
addExtension("GL_KHR_blend_equation_advanced_coherent");
@@ -156,6 +157,16 @@
addExtension("GL_EXT_tessellation_shader");
addExtension("GL_EXT_tessellation_point_size");
addExtension("GL_EXT_gpu_shader5");
+ addExtension("GL_EXT_shader_implicit_conversions");
+ addExtension("GL_EXT_texture_buffer");
+ addExtension("GL_EXT_texture_cube_map_array");
+ addExtension("GL_EXT_draw_buffers_indexed");
+ addExtension("GL_EXT_texture_sRGB_decode");
+ addExtension("GL_EXT_texture_border_clamp");
+ addExtension("GL_KHR_debug");
+ addExtension("GL_EXT_primitive_bounding_box");
+ addExtension("GL_ANDROID_extension_pack_es31a");
+ addExtension("GL_EXT_copy_image");
}
else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 3)
{
@@ -171,7 +182,61 @@
throw tcu::NotSupportedError("Unsupported GL version", "", __FILE__, __LINE__);
if (isContextTypeES(ctxType))
+ {
addExtension("GL_EXT_color_buffer_float");
+ addExtension("GL_EXT_color_buffer_half_float");
+ }
+
+ // support compressed formats
+ {
+ static deUint32 compressedFormats[] =
+ {
+ GL_ETC1_RGB8_OES,
+ GL_COMPRESSED_R11_EAC,
+ GL_COMPRESSED_SIGNED_R11_EAC,
+ GL_COMPRESSED_RG11_EAC,
+ GL_COMPRESSED_SIGNED_RG11_EAC,
+ GL_COMPRESSED_RGB8_ETC2,
+ GL_COMPRESSED_SRGB8_ETC2,
+ GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ GL_COMPRESSED_RGBA8_ETC2_EAC,
+ GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
+ GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
+ GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
+ GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
+ GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
+ GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
+ GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
+ GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
+ GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
+ GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
+ GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
+ GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
+ GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
+ GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
+ GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
+ };
+
+ addExtension("GL_KHR_texture_compression_astc_hdr");
+ addExtension("GL_KHR_texture_compression_astc_ldr");
+ for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(compressedFormats); ++ndx)
+ compressedTextureList.push_back(compressedFormats[ndx]);
+ }
}
Context::~Context (void)
@@ -234,13 +299,52 @@
case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS:
case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS:
- *params = 16;
+ *params = 32;
+ break;
+
+ case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
+ case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
+ case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS:
+ case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS:
+ case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS:
+ case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
+ *params = 8;
+ break;
+
+ case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS:
+ case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
+ *params = 8;
+ break;
+
+ case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
+ *params = 1u << 25;
+ break;
+
+ case GL_MAX_GEOMETRY_OUTPUT_VERTICES:
+ *params = 256;
+ break;
+
+ case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
+ *params = 2048;
+ break;
+
+ case GL_MAX_GEOMETRY_SHADER_INVOCATIONS:
+ *params = 4;
+ break;
+
+ case GL_MAX_COLOR_TEXTURE_SAMPLES:
+ *params = 8;
break;
case GL_MAX_TEXTURE_SIZE:
case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
case GL_MAX_3D_TEXTURE_SIZE:
case GL_MAX_RENDERBUFFER_SIZE:
+ case GL_MAX_TEXTURE_BUFFER_SIZE:
*params = 2048;
break;
@@ -253,7 +357,11 @@
break;
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
- *params = 0;
+ *params = (int)ctx->compressedTextureList.size();
+ break;
+
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ deMemcpy(params, &ctx->compressedTextureList[0], (int)ctx->compressedTextureList.size());
break;
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
@@ -313,6 +421,29 @@
}
}
+GLW_APICALL void GLW_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
+{
+ static const int s_sampleCounts[] = { 16, 8, 4, 2, 1 };
+
+ DE_UNREF(internalformat);
+ DE_UNREF(target);
+
+ switch (pname)
+ {
+ case GL_NUM_SAMPLE_COUNTS:
+ if (bufSize >= 1)
+ *params = DE_LENGTH_OF_ARRAY(s_sampleCounts);
+ break;
+
+ case GL_SAMPLES:
+ deMemcpy(params, s_sampleCounts, de::min(bufSize, DE_LENGTH_OF_ARRAY(s_sampleCounts)));
+ break;
+
+ default:
+ break;
+ }
+}
+
GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetString (GLenum name)
{
Context* const ctx = getCurrentContext();
@@ -579,6 +710,12 @@
ctx->pixelPackBufferBufferBinding = 0;
}
+GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name)
+{
+ DE_UNREF(program);
+ return (GLint)(deStringHash(name) & 0x7FFFFFFF);
+}
+
void initFunctions (glw::Functions* gl)
{
# include "tcuNullRenderContextInitFuncs.inl"
diff --git a/framework/platform/null/tcuNullRenderContextFuncs.inl b/framework/platform/null/tcuNullRenderContextFuncs.inl
index 60c4a71..46e7d7e 100644
--- a/framework/platform/null/tcuNullRenderContextFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextFuncs.inl
@@ -1591,14 +1591,6 @@
}
-GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name)
-{
- DE_UNREF(program);
- DE_UNREF(name);
-
- return (GLint)0;
-}
-
GLW_APICALL void GLW_APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data)
{
DE_UNREF(target);
@@ -1781,16 +1773,6 @@
}
-GLW_APICALL void GLW_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params)
-{
- DE_UNREF(target);
- DE_UNREF(internalformat);
- DE_UNREF(pname);
- DE_UNREF(bufSize);
- DE_UNREF(params);
-
-}
-
GLW_APICALL void GLW_APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val)
{
DE_UNREF(pname);
diff --git a/scripts/opengl/gen_null_render_context.py b/scripts/opengl/gen_null_render_context.py
index 36a2d5e..3693433 100644
--- a/scripts/opengl/gen_null_render_context.py
+++ b/scripts/opengl/gen_null_render_context.py
@@ -43,11 +43,13 @@
"glGenSamplers",
"glGenTransformFeedbacks",
"glGenProgramPipelines",
+ "glGetInternalformativ",
"glMapBufferRange",
"glCheckFramebufferStatus",
"glReadPixels",
"glBindBuffer",
- "glDeleteBuffers"
+ "glDeleteBuffers",
+ "glGetAttribLocation",
])
NULL_PLATFORM_DIR = os.path.normpath(os.path.join(SCRIPTS_DIR, "..", "..", "framework", "platform", "null"))