Commit 09932e04 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Support emulated pre-rotation in dEQP testing

Similarly to end2end tests, the window dimensions are swapped with emulated prerotation at 90 and 270 degrees, while maintaining to the application that dimensions are as requested. The following new command line argument can be used to select an emulated prerotation: --emulated-pre-rotation=90 --emulated-pre-rotation=180 --emulated-pre-rotation=270 For example: $ ./angle_deqp_gles2_tests --use-angle=vulkan \ --deqp-case=*draw* \ --emulated-pre-rotation=270 Additionally, the deqp test expectations can be marked with the following new tags to add suppressions for failing tests under prerotation: PREROTATION PREROTATION90 PREROTATION180 PREROTATION270 Bug: angleproject:4901 Change-Id: I7a68c1a1e7da4366cde981469c589d8d900c40c5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2506810 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent bef8124f
...@@ -1685,6 +1685,13 @@ angle::Result WindowSurfaceVk::getUserExtentsImpl(DisplayVk *displayVk, ...@@ -1685,6 +1685,13 @@ angle::Result WindowSurfaceVk::getUserExtentsImpl(DisplayVk *displayVk,
ANGLE_VK_TRY(displayVk, ANGLE_VK_TRY(displayVk,
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, mSurface, surfaceCaps)); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, mSurface, surfaceCaps));
// With real prerotation, the surface reports the rotated sizes. With emulated prerotation,
// adjust the window extents to match what real pre-rotation would have reported.
if (Is90DegreeRotation(mEmulatedPreTransform))
{
std::swap(surfaceCaps->currentExtent.width, surfaceCaps->currentExtent.height);
}
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -34,6 +34,7 @@ reflect the reality of the situation. The expected format for every line in the ...@@ -34,6 +34,7 @@ reflect the reality of the situation. The expected format for every line in the
NEXUS5X PIXEL2ORXL NEXUS5X PIXEL2ORXL
QUADROP400 QUADROP400
SWIFTSHADER SWIFTSHADER
PREROTATION PREROTATION90 PREROTATION180 PREROTATION270
`TEST_NAME` can be a specific test name, or set of test names using `'*'` as wildcard anywhere in `TEST_NAME` can be a specific test name, or set of test names using `'*'` as wildcard anywhere in
the name. Examples: the name. Examples:
...@@ -50,3 +51,9 @@ the name. Examples: ...@@ -50,3 +51,9 @@ the name. Examples:
// Failing test in Nvidia's OpenGL implementation on windows: // Failing test in Nvidia's OpenGL implementation on windows:
1665 WIN NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.negative.command_offset_not_in_buffer_unsigned32_wrap = FAIL 1665 WIN NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.negative.command_offset_not_in_buffer_unsigned32_wrap = FAIL
// Failing when emulated pre-rotation is enabled, no matter which angle:
1234 PREROTATION : dEQP-GLES3.*blit* = FAIL
// Failing when emulated pre-rotation is enabled with 270 degree angle:
1234 PREROTATION270 : dEQP-GLES3.*blit* = FAIL
...@@ -99,14 +99,16 @@ constexpr APIInfo kEGLDisplayAPIs[] = { ...@@ -99,14 +99,16 @@ constexpr APIInfo kEGLDisplayAPIs[] = {
{"angle-vulkan", GPUTestConfig::kAPIVulkan}, {"angle-vulkan", GPUTestConfig::kAPIVulkan},
}; };
constexpr char kdEQPEGLString[] = "--deqp-egl-display-type="; constexpr char kdEQPEGLString[] = "--deqp-egl-display-type=";
constexpr char kANGLEEGLString[] = "--use-angle="; constexpr char kANGLEEGLString[] = "--use-angle=";
constexpr char kdEQPCaseString[] = "--deqp-case="; constexpr char kANGLEPreRotation[] = "--emulated-pre-rotation=";
constexpr char kBatchIdString[] = "--batch-id="; constexpr char kdEQPCaseString[] = "--deqp-case=";
constexpr char kBatchIdString[] = "--batch-id=";
std::array<char, 500> gCaseStringBuffer; std::array<char, 500> gCaseStringBuffer;
const APIInfo *gInitAPI = nullptr; const APIInfo *gInitAPI = nullptr;
uint32_t gPreRotation = 0;
constexpr const char *gdEQPEGLConfigNameString = "--deqp-gl-config-name="; constexpr const char *gdEQPEGLConfigNameString = "--deqp-gl-config-name=";
...@@ -265,7 +267,7 @@ void dEQPCaseList::initialize() ...@@ -265,7 +267,7 @@ void dEQPCaseList::initialize()
api = gInitAPI->second; api = gInitAPI->second;
} }
GPUTestConfig testConfig = GPUTestConfig(api); GPUTestConfig testConfig = GPUTestConfig(api, gPreRotation);
#if !defined(ANGLE_PLATFORM_ANDROID) #if !defined(ANGLE_PLATFORM_ANDROID)
// Note: These prints mess up parsing of test list when running on Android. // Note: These prints mess up parsing of test list when running on Android.
...@@ -541,7 +543,7 @@ void dEQPTest<TestModuleIndex>::SetUpTestCase() ...@@ -541,7 +543,7 @@ void dEQPTest<TestModuleIndex>::SetUpTestCase()
// Init the platform. // Init the platform.
if (!deqp_libtester_init_platform(static_cast<int>(argv.size()), argv.data(), if (!deqp_libtester_init_platform(static_cast<int>(argv.size()), argv.data(),
reinterpret_cast<void *>(&HandlePlatformError))) reinterpret_cast<void *>(&HandlePlatformError), gPreRotation))
{ {
std::cout << "Aborting test due to dEQP initialization error." << std::endl; std::cout << "Aborting test due to dEQP initialization error." << std::endl;
exit(1); exit(1);
...@@ -621,6 +623,24 @@ void HandleDisplayType(const char *displayTypeString) ...@@ -621,6 +623,24 @@ void HandleDisplayType(const char *displayTypeString)
} }
} }
void HandlePreRotation(const char *preRotationString)
{
std::istringstream argStream(preRotationString);
uint32_t preRotation = 0;
argStream >> preRotation;
if (!argStream ||
(preRotation != 0 && preRotation != 90 && preRotation != 180 && preRotation != 270))
{
std::cout << "Invalid PreRotation '" << preRotationString
<< "'; must be either 0, 90, 180 or 270" << std::endl;
exit(1);
}
gPreRotation = preRotation;
}
void HandleEGLConfigName(const char *configNameString) void HandleEGLConfigName(const char *configNameString)
{ {
gEGLConfigName = configNameString; gEGLConfigName = configNameString;
...@@ -665,6 +685,10 @@ void InitTestHarness(int *argc, char **argv) ...@@ -665,6 +685,10 @@ void InitTestHarness(int *argc, char **argv)
{ {
HandleDisplayType(argv[argIndex] + strlen(kANGLEEGLString)); HandleDisplayType(argv[argIndex] + strlen(kANGLEEGLString));
} }
else if (strncmp(argv[argIndex], kANGLEPreRotation, strlen(kANGLEPreRotation)) == 0)
{
HandlePreRotation(argv[argIndex] + strlen(kANGLEPreRotation));
}
else if (strncmp(argv[argIndex], gdEQPEGLConfigNameString, else if (strncmp(argv[argIndex], gdEQPEGLConfigNameString,
strlen(gdEQPEGLConfigNameString)) == 0) strlen(gdEQPEGLConfigNameString)) == 0)
{ {
...@@ -680,5 +704,17 @@ void InitTestHarness(int *argc, char **argv) ...@@ -680,5 +704,17 @@ void InitTestHarness(int *argc, char **argv)
} }
argIndex++; argIndex++;
} }
GPUTestConfig::API api = GetDefaultAPIInfo()->second;
if (gInitAPI)
{
api = gInitAPI->second;
}
if (gPreRotation != 0 && api != GPUTestConfig::kAPIVulkan &&
api != GPUTestConfig::kAPISwiftShader)
{
std::cout << "PreRotation is only supported on Vulkan" << std::endl;
exit(1);
}
} }
} // namespace angle } // namespace angle
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#ifndef ANGLE_DEQP_LIBTESTER_H_ #ifndef ANGLE_DEQP_LIBTESTER_H_
#define ANGLE_DEQP_LIBTESTER_H_ #define ANGLE_DEQP_LIBTESTER_H_
#include <stdint.h>
#if defined(_WIN32) #if defined(_WIN32)
# if defined(ANGLE_DEQP_LIBTESTER_IMPLEMENTATION) # if defined(ANGLE_DEQP_LIBTESTER_IMPLEMENTATION)
# define ANGLE_LIBTESTER_EXPORT __declspec(dllexport) # define ANGLE_LIBTESTER_EXPORT __declspec(dllexport)
...@@ -39,7 +41,8 @@ enum class TestResult ...@@ -39,7 +41,8 @@ enum class TestResult
ANGLE_LIBTESTER_EXPORT int deqp_libtester_main(int argc, const char *argv[]); ANGLE_LIBTESTER_EXPORT int deqp_libtester_main(int argc, const char *argv[]);
ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc, ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc,
const char *argv[], const char *argv[],
void *logErrorFunc); void *logErrorFunc,
uint32_t preRotation);
ANGLE_LIBTESTER_EXPORT void deqp_libtester_shutdown_platform(); ANGLE_LIBTESTER_EXPORT void deqp_libtester_shutdown_platform();
ANGLE_LIBTESTER_EXPORT TestResult deqp_libtester_run(const char *caseName); ANGLE_LIBTESTER_EXPORT TestResult deqp_libtester_run(const char *caseName);
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "tcuResource.hpp" #include "tcuResource.hpp"
#include "tcuTestLog.hpp" #include "tcuTestLog.hpp"
tcu::Platform *CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc); tcu::Platform *CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc, uint32_t preRotation);
namespace namespace
{ {
...@@ -77,7 +77,8 @@ std::string GetLogFileName(std::string deqpDataDir) ...@@ -77,7 +77,8 @@ std::string GetLogFileName(std::string deqpDataDir)
ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc, ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc,
const char *argv[], const char *argv[],
void *logErrorFunc) void *logErrorFunc,
uint32_t preRotation)
{ {
try try
{ {
...@@ -85,7 +86,8 @@ ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc, ...@@ -85,7 +86,8 @@ ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc,
// Set stdout to line-buffered mode (will be fully buffered by default if stdout is pipe). // Set stdout to line-buffered mode (will be fully buffered by default if stdout is pipe).
setvbuf(stdout, DE_NULL, _IOLBF, 4 * 1024); setvbuf(stdout, DE_NULL, _IOLBF, 4 * 1024);
#endif #endif
g_platform = CreateANGLEPlatform(reinterpret_cast<angle::LogErrorFunc>(logErrorFunc)); g_platform =
CreateANGLEPlatform(reinterpret_cast<angle::LogErrorFunc>(logErrorFunc), preRotation);
if (!deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN)) if (!deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN))
{ {
...@@ -119,7 +121,7 @@ ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc, ...@@ -119,7 +121,7 @@ ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc,
// Exported to the tester app. // Exported to the tester app.
ANGLE_LIBTESTER_EXPORT int deqp_libtester_main(int argc, const char *argv[]) ANGLE_LIBTESTER_EXPORT int deqp_libtester_main(int argc, const char *argv[])
{ {
if (!deqp_libtester_init_platform(argc, argv, nullptr)) if (!deqp_libtester_init_platform(argc, argv, nullptr, 0))
{ {
tcu::die("Could not initialize the dEQP platform"); tcu::die("Could not initialize the dEQP platform");
} }
...@@ -166,7 +168,7 @@ ANGLE_LIBTESTER_EXPORT void deqp_libtester_shutdown_platform() ...@@ -166,7 +168,7 @@ ANGLE_LIBTESTER_EXPORT void deqp_libtester_shutdown_platform()
ANGLE_LIBTESTER_EXPORT TestResult deqp_libtester_run(const char *caseName) ANGLE_LIBTESTER_EXPORT TestResult deqp_libtester_run(const char *caseName)
{ {
const char *emptyString = ""; const char *emptyString = "";
if (g_platform == nullptr && !deqp_libtester_init_platform(1, &emptyString, nullptr)) if (g_platform == nullptr && !deqp_libtester_init_platform(1, &emptyString, nullptr, 0))
{ {
tcu::die("Failed to initialize platform."); tcu::die("Failed to initialize platform.");
} }
......
...@@ -143,7 +143,7 @@ class NativePixmap : public eglu::NativePixmap ...@@ -143,7 +143,7 @@ class NativePixmap : public eglu::NativePixmap
class NativeWindowFactory : public eglu::NativeWindowFactory class NativeWindowFactory : public eglu::NativeWindowFactory
{ {
public: public:
explicit NativeWindowFactory(EventState *eventState); explicit NativeWindowFactory(EventState *eventState, uint32_t preRotation);
~NativeWindowFactory() override = default; ~NativeWindowFactory() override = default;
eglu::NativeWindow *createWindow(eglu::NativeDisplay *nativeDisplay, eglu::NativeWindow *createWindow(eglu::NativeDisplay *nativeDisplay,
...@@ -156,6 +156,7 @@ class NativeWindowFactory : public eglu::NativeWindowFactory ...@@ -156,6 +156,7 @@ class NativeWindowFactory : public eglu::NativeWindowFactory
private: private:
EventState *mEvents; EventState *mEvents;
uint32_t mPreRotation;
}; };
class NativeWindow : public eglu::NativeWindow class NativeWindow : public eglu::NativeWindow
...@@ -163,7 +164,8 @@ class NativeWindow : public eglu::NativeWindow ...@@ -163,7 +164,8 @@ class NativeWindow : public eglu::NativeWindow
public: public:
NativeWindow(ANGLENativeDisplay *nativeDisplay, NativeWindow(ANGLENativeDisplay *nativeDisplay,
const eglu::WindowParams &params, const eglu::WindowParams &params,
EventState *eventState); EventState *eventState,
uint32_t preRotation);
~NativeWindow() override; ~NativeWindow() override;
eglw::EGLNativeWindowType getLegacyNative() override; eglw::EGLNativeWindowType getLegacyNative() override;
...@@ -177,6 +179,7 @@ class NativeWindow : public eglu::NativeWindow ...@@ -177,6 +179,7 @@ class NativeWindow : public eglu::NativeWindow
private: private:
OSWindow *mWindow; OSWindow *mWindow;
EventState *mEvents; EventState *mEvents;
uint32_t mPreRotation;
}; };
// ANGLE NativeDisplay // ANGLE NativeDisplay
...@@ -254,8 +257,10 @@ eglu::NativePixmap *NativePixmapFactory::createPixmap(eglu::NativeDisplay *nativ ...@@ -254,8 +257,10 @@ eglu::NativePixmap *NativePixmapFactory::createPixmap(eglu::NativeDisplay *nativ
// NativeWindowFactory // NativeWindowFactory
NativeWindowFactory::NativeWindowFactory(EventState *eventState) NativeWindowFactory::NativeWindowFactory(EventState *eventState, uint32_t preRotation)
: eglu::NativeWindowFactory("window", "ANGLE Window", kWindowCapabilities), mEvents(eventState) : eglu::NativeWindowFactory("window", "ANGLE Window", kWindowCapabilities),
mEvents(eventState),
mPreRotation(preRotation)
{} {}
eglu::NativeWindow *NativeWindowFactory::createWindow(eglu::NativeDisplay *nativeDisplay, eglu::NativeWindow *NativeWindowFactory::createWindow(eglu::NativeDisplay *nativeDisplay,
...@@ -271,21 +276,33 @@ eglu::NativeWindow *NativeWindowFactory::createWindow(eglu::NativeDisplay *nativ ...@@ -271,21 +276,33 @@ eglu::NativeWindow *NativeWindowFactory::createWindow(eglu::NativeDisplay *nativ
const eglw::EGLAttrib *attribList, const eglw::EGLAttrib *attribList,
const eglu::WindowParams &params) const const eglu::WindowParams &params) const
{ {
return new NativeWindow(dynamic_cast<ANGLENativeDisplay *>(nativeDisplay), params, mEvents); return new NativeWindow(dynamic_cast<ANGLENativeDisplay *>(nativeDisplay), params, mEvents,
mPreRotation);
} }
// NativeWindow // NativeWindow
NativeWindow::NativeWindow(ANGLENativeDisplay *nativeDisplay, NativeWindow::NativeWindow(ANGLENativeDisplay *nativeDisplay,
const eglu::WindowParams &params, const eglu::WindowParams &params,
EventState *eventState) EventState *eventState,
: eglu::NativeWindow(kWindowCapabilities), mWindow(OSWindow::New()), mEvents(eventState) uint32_t preRotation)
: eglu::NativeWindow(kWindowCapabilities),
mWindow(OSWindow::New()),
mEvents(eventState),
mPreRotation(preRotation)
{ {
bool initialized = mWindow->initialize( int osWindowWidth =
"dEQP ANGLE Tests", params.width == eglu::WindowParams::SIZE_DONT_CARE ? DEFAULT_SURFACE_WIDTH : params.width;
params.width == eglu::WindowParams::SIZE_DONT_CARE ? DEFAULT_SURFACE_WIDTH : params.width, int osWindowHeight = params.height == eglu::WindowParams::SIZE_DONT_CARE
params.height == eglu::WindowParams::SIZE_DONT_CARE ? DEFAULT_SURFACE_HEIGHT ? DEFAULT_SURFACE_HEIGHT
: params.height); : params.height;
if (mPreRotation == 90 || mPreRotation == 270)
{
std::swap(osWindowWidth, osWindowHeight);
}
bool initialized = mWindow->initialize("dEQP ANGLE Tests", osWindowWidth, osWindowHeight);
TCU_CHECK(initialized); TCU_CHECK(initialized);
if (params.visibility != eglu::WindowParams::VISIBILITY_DONT_CARE) if (params.visibility != eglu::WindowParams::VISIBILITY_DONT_CARE)
...@@ -322,7 +339,17 @@ eglw::EGLNativeWindowType NativeWindow::getLegacyNative() ...@@ -322,7 +339,17 @@ eglw::EGLNativeWindowType NativeWindow::getLegacyNative()
IVec2 NativeWindow::getSurfaceSize() const IVec2 NativeWindow::getSurfaceSize() const
{ {
return IVec2(mWindow->getWidth(), mWindow->getHeight()); int width = mWindow->getWidth();
int height = mWindow->getHeight();
if (mPreRotation == 90 || mPreRotation == 270)
{
// Return the original dimensions dEQP asked for. This ensures that the dEQP code is never
// aware of the window actually being rotated.
std::swap(width, height);
}
return IVec2(width, height);
} }
void NativeWindow::processEvents() void NativeWindow::processEvents()
...@@ -342,7 +369,15 @@ void NativeWindow::processEvents() ...@@ -342,7 +369,15 @@ void NativeWindow::processEvents()
void NativeWindow::setSurfaceSize(IVec2 size) void NativeWindow::setSurfaceSize(IVec2 size)
{ {
mWindow->resize(size.x(), size.y()); int osWindowWidth = size.x();
int osWindowHeight = size.y();
if (mPreRotation == 90 || mPreRotation == 270)
{
std::swap(osWindowWidth, osWindowHeight);
}
mWindow->resize(osWindowWidth, osWindowHeight);
} }
void NativeWindow::readScreenPixels(tcu::TextureLevel *dst) const void NativeWindow::readScreenPixels(tcu::TextureLevel *dst) const
...@@ -353,6 +388,12 @@ void NativeWindow::readScreenPixels(tcu::TextureLevel *dst) const ...@@ -353,6 +388,12 @@ void NativeWindow::readScreenPixels(tcu::TextureLevel *dst) const
{ {
throw InternalError("Failed to read screen pixels", DE_NULL, __FILE__, __LINE__); throw InternalError("Failed to read screen pixels", DE_NULL, __FILE__, __LINE__);
} }
if (mPreRotation != 0)
{
throw InternalError("Read screen pixels with prerotation is not supported", DE_NULL,
__FILE__, __LINE__);
}
} }
} // namespace } // namespace
...@@ -376,7 +417,41 @@ ANGLENativeDisplayFactory::ANGLENativeDisplayFactory( ...@@ -376,7 +417,41 @@ ANGLENativeDisplayFactory::ANGLENativeDisplayFactory(
mNativeDisplay = bitCast<eglw::EGLNativeDisplayType>(XOpenDisplay(nullptr)); mNativeDisplay = bitCast<eglw::EGLNativeDisplayType>(XOpenDisplay(nullptr));
#endif // (DE_OS == DE_OS_UNIX) #endif // (DE_OS == DE_OS_UNIX)
m_nativeWindowRegistry.registerFactory(new NativeWindowFactory(eventState)); // If pre-rotating, let NativeWindowFactory know.
uint32_t preRotation = 0;
for (size_t attrIndex = 0;
attrIndex < mPlatformAttributes.size() && mPlatformAttributes[attrIndex] != EGL_NONE;
attrIndex += 2)
{
if (mPlatformAttributes[attrIndex] != EGL_FEATURE_OVERRIDES_ENABLED_ANGLE)
{
continue;
}
const char **preRotationFeatures =
reinterpret_cast<const char **>(mPlatformAttributes[attrIndex + 1]);
DE_ASSERT(preRotationFeatures != nullptr && preRotationFeatures[0] != nullptr);
if (strcmp(preRotationFeatures[0], "emulated_prerotation_90") == 0)
{
preRotation = 90;
}
else if (strcmp(preRotationFeatures[0], "emulated_prerotation_180") == 0)
{
preRotation = 180;
}
else if (strcmp(preRotationFeatures[0], "emulated_prerotation_270") == 0)
{
preRotation = 270;
}
else
{
DE_ASSERT(DE_FALSE);
}
break;
}
m_nativeWindowRegistry.registerFactory(new NativeWindowFactory(eventState, preRotation));
m_nativePixmapRegistry.registerFactory(new NativePixmapFactory()); m_nativePixmapRegistry.registerFactory(new NativePixmapFactory());
} }
......
...@@ -32,12 +32,32 @@ static_assert(EGL_DONT_CARE == -1, "Unexpected value for EGL_DONT_CARE"); ...@@ -32,12 +32,32 @@ static_assert(EGL_DONT_CARE == -1, "Unexpected value for EGL_DONT_CARE");
namespace tcu namespace tcu
{ {
ANGLEPlatform::ANGLEPlatform(angle::LogErrorFunc logErrorFunc) ANGLEPlatform::ANGLEPlatform(angle::LogErrorFunc logErrorFunc, uint32_t preRotation)
{ {
angle::SetLowPriorityProcess(); angle::SetLowPriorityProcess();
mPlatformMethods.logError = logErrorFunc; mPlatformMethods.logError = logErrorFunc;
// Create pre-rotation attributes.
switch (preRotation)
{
case 90:
mEnableFeatureOverrides.push_back("emulated_prerotation_90");
break;
case 180:
mEnableFeatureOverrides.push_back("emulated_prerotation_180");
break;
case 270:
mEnableFeatureOverrides.push_back("emulated_prerotation_270");
break;
default:
break;
}
if (!mEnableFeatureOverrides.empty())
{
mEnableFeatureOverrides.push_back(nullptr);
}
#if (DE_OS == DE_OS_WIN32) #if (DE_OS == DE_OS_WIN32)
{ {
std::vector<eglw::EGLAttrib> d3d11Attribs = initAttribs( std::vector<eglw::EGLAttrib> d3d11Attribs = initAttribs(
...@@ -174,18 +194,24 @@ std::vector<eglw::EGLAttrib> ANGLEPlatform::initAttribs(eglw::EGLAttrib type, ...@@ -174,18 +194,24 @@ std::vector<eglw::EGLAttrib> ANGLEPlatform::initAttribs(eglw::EGLAttrib type,
attribs.push_back(reinterpret_cast<eglw::EGLAttrib>(&mPlatformMethods)); attribs.push_back(reinterpret_cast<eglw::EGLAttrib>(&mPlatformMethods));
} }
if (!mEnableFeatureOverrides.empty())
{
attribs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
attribs.push_back(reinterpret_cast<EGLAttrib>(mEnableFeatureOverrides.data()));
}
attribs.push_back(EGL_NONE); attribs.push_back(EGL_NONE);
return attribs; return attribs;
} }
} // namespace tcu } // namespace tcu
// Create platform // Create platform
tcu::Platform *CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc) tcu::Platform *CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc, uint32_t preRotation)
{ {
return new tcu::ANGLEPlatform(logErrorFunc); return new tcu::ANGLEPlatform(logErrorFunc, preRotation);
} }
tcu::Platform *createPlatform() tcu::Platform *createPlatform()
{ {
return CreateANGLEPlatform(nullptr); return CreateANGLEPlatform(nullptr, 0);
} }
...@@ -38,7 +38,7 @@ namespace tcu ...@@ -38,7 +38,7 @@ namespace tcu
class ANGLEPlatform : public tcu::Platform, private glu::Platform, private eglu::Platform class ANGLEPlatform : public tcu::Platform, private glu::Platform, private eglu::Platform
{ {
public: public:
ANGLEPlatform(angle::LogErrorFunc logErrorFunc); ANGLEPlatform(angle::LogErrorFunc logErrorFunc, uint32_t preRotation);
~ANGLEPlatform(); ~ANGLEPlatform();
bool processEvents() override; bool processEvents() override;
...@@ -61,6 +61,7 @@ class ANGLEPlatform : public tcu::Platform, private glu::Platform, private eglu: ...@@ -61,6 +61,7 @@ class ANGLEPlatform : public tcu::Platform, private glu::Platform, private eglu:
EventState mEvents; EventState mEvents;
angle::PlatformMethods mPlatformMethods; angle::PlatformMethods mPlatformMethods;
std::vector<const char *> mEnableFeatureOverrides;
}; };
} // namespace tcu } // namespace tcu
......
...@@ -567,10 +567,15 @@ GPUTestConfig::GPUTestConfig() ...@@ -567,10 +567,15 @@ GPUTestConfig::GPUTestConfig()
mConditions[kConditionNexus5X] = IsNexus5X(); mConditions[kConditionNexus5X] = IsNexus5X();
mConditions[kConditionPixel2OrXL] = IsPixel2() || IsPixel2XL(); mConditions[kConditionPixel2OrXL] = IsPixel2() || IsPixel2XL();
mConditions[kConditionNVIDIAQuadroP400] = IsNVIDIAQuadroP400(); mConditions[kConditionNVIDIAQuadroP400] = IsNVIDIAQuadroP400();
mConditions[kConditionPreRotation] = false;
mConditions[kConditionPreRotation90] = false;
mConditions[kConditionPreRotation180] = false;
mConditions[kConditionPreRotation270] = false;
} }
// If the constructor is passed an API, load those conditions as well // If the constructor is passed an API, load those conditions as well
GPUTestConfig::GPUTestConfig(const API &api) : GPUTestConfig() GPUTestConfig::GPUTestConfig(const API &api, uint32_t preRotation) : GPUTestConfig()
{ {
mConditions[kConditionD3D9] = IsD3D9(api); mConditions[kConditionD3D9] = IsD3D9(api);
mConditions[kConditionD3D11] = IsD3D11(api); mConditions[kConditionD3D11] = IsD3D11(api);
...@@ -579,6 +584,24 @@ GPUTestConfig::GPUTestConfig(const API &api) : GPUTestConfig() ...@@ -579,6 +584,24 @@ GPUTestConfig::GPUTestConfig(const API &api) : GPUTestConfig()
mConditions[kConditionVulkan] = IsVulkan(api); mConditions[kConditionVulkan] = IsVulkan(api);
mConditions[kConditionSwiftShader] = IsSwiftShader(api); mConditions[kConditionSwiftShader] = IsSwiftShader(api);
mConditions[kConditionMetal] = IsMetal(api); mConditions[kConditionMetal] = IsMetal(api);
switch (preRotation)
{
case 90:
mConditions[kConditionPreRotation] = true;
mConditions[kConditionPreRotation90] = true;
break;
case 180:
mConditions[kConditionPreRotation] = true;
mConditions[kConditionPreRotation180] = true;
break;
case 270:
mConditions[kConditionPreRotation] = true;
mConditions[kConditionPreRotation270] = true;
break;
default:
break;
}
} }
// Return a const reference to the list of all pre-calculated conditions. // Return a const reference to the list of all pre-calculated conditions.
......
...@@ -65,6 +65,10 @@ struct GPUTestConfig ...@@ -65,6 +65,10 @@ struct GPUTestConfig
kConditionPixel2OrXL, kConditionPixel2OrXL,
kConditionNVIDIAQuadroP400, kConditionNVIDIAQuadroP400,
kConditionSwiftShader, kConditionSwiftShader,
kConditionPreRotation,
kConditionPreRotation90,
kConditionPreRotation180,
kConditionPreRotation270,
kNumberOfConditions, kNumberOfConditions,
}; };
...@@ -72,7 +76,7 @@ struct GPUTestConfig ...@@ -72,7 +76,7 @@ struct GPUTestConfig
using ConditionArray = angle::BitSet<GPUTestConfig::kNumberOfConditions>; using ConditionArray = angle::BitSet<GPUTestConfig::kNumberOfConditions>;
GPUTestConfig(); GPUTestConfig();
GPUTestConfig(const API &api); GPUTestConfig(const API &api, uint32_t preRotation);
const GPUTestConfig::ConditionArray &getConditions() const; const GPUTestConfig::ConditionArray &getConditions() const;
......
...@@ -77,6 +77,11 @@ enum Token ...@@ -77,6 +77,11 @@ enum Token
kConfigPixel2, kConfigPixel2,
// GPU devices // GPU devices
kConfigNVIDIAQuadroP400, kConfigNVIDIAQuadroP400,
// PreRotation
kConfigPreRotation,
kConfigPreRotation90,
kConfigPreRotation180,
kConfigPreRotation270,
// expectation // expectation
kExpectationPass, kExpectationPass,
kExpectationFail, kExpectationFail,
...@@ -167,6 +172,10 @@ constexpr TokenInfo kTokenData[kNumberOfTokens] = { ...@@ -167,6 +172,10 @@ constexpr TokenInfo kTokenData[kNumberOfTokens] = {
{"nexus5x", GPUTestConfig::kConditionNexus5X}, {"nexus5x", GPUTestConfig::kConditionNexus5X},
{"pixel2orxl", GPUTestConfig::kConditionPixel2OrXL}, {"pixel2orxl", GPUTestConfig::kConditionPixel2OrXL},
{"quadrop400", GPUTestConfig::kConditionNVIDIAQuadroP400}, {"quadrop400", GPUTestConfig::kConditionNVIDIAQuadroP400},
{"prerotation", GPUTestConfig::kConditionPreRotation},
{"prerotation90", GPUTestConfig::kConditionPreRotation90},
{"prerotation180", GPUTestConfig::kConditionPreRotation180},
{"prerotation270", GPUTestConfig::kConditionPreRotation270},
{"pass", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestPass}, {"pass", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestPass},
{"fail", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestFail}, {"fail", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestFail},
{"flaky", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestFlaky}, {"flaky", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestFlaky},
...@@ -438,6 +447,10 @@ bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config, ...@@ -438,6 +447,10 @@ bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config,
case kConfigNexus5X: case kConfigNexus5X:
case kConfigPixel2: case kConfigPixel2:
case kConfigNVIDIAQuadroP400: case kConfigNVIDIAQuadroP400:
case kConfigPreRotation:
case kConfigPreRotation90:
case kConfigPreRotation180:
case kConfigPreRotation270:
// MODIFIERS, check each condition and add accordingly. // MODIFIERS, check each condition and add accordingly.
if (stage != kLineParserConfigs && stage != kLineParserBugID) if (stage != kLineParserConfigs && stage != kLineParserBugID)
{ {
......
...@@ -36,7 +36,9 @@ class GPUTestConfigTest : public ANGLETest ...@@ -36,7 +36,9 @@ class GPUTestConfigTest : public ANGLETest
EXPECT_EQ(IsRelease(), config.getConditions()[GPUTestConfig::kConditionRelease]); EXPECT_EQ(IsRelease(), config.getConditions()[GPUTestConfig::kConditionRelease]);
} }
void validateConfigAPI(const GPUTestConfig &config, const GPUTestConfig::API &api) void validateConfigAPI(const GPUTestConfig &config,
const GPUTestConfig::API &api,
uint32_t preRotation)
{ {
bool D3D9 = false; bool D3D9 = false;
bool D3D11 = false; bool D3D11 = false;
...@@ -74,6 +76,34 @@ class GPUTestConfigTest : public ANGLETest ...@@ -74,6 +76,34 @@ class GPUTestConfigTest : public ANGLETest
EXPECT_EQ(GLES, config.getConditions()[GPUTestConfig::kConditionGLES]); EXPECT_EQ(GLES, config.getConditions()[GPUTestConfig::kConditionGLES]);
EXPECT_EQ(Vulkan, config.getConditions()[GPUTestConfig::kConditionVulkan]); EXPECT_EQ(Vulkan, config.getConditions()[GPUTestConfig::kConditionVulkan]);
EXPECT_EQ(Metal, config.getConditions()[GPUTestConfig::kConditionMetal]); EXPECT_EQ(Metal, config.getConditions()[GPUTestConfig::kConditionMetal]);
switch (preRotation)
{
case 90:
EXPECT_TRUE(config.getConditions()[GPUTestConfig::kConditionPreRotation]);
EXPECT_TRUE(config.getConditions()[GPUTestConfig::kConditionPreRotation90]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation180]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation270]);
break;
case 180:
EXPECT_TRUE(config.getConditions()[GPUTestConfig::kConditionPreRotation]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation90]);
EXPECT_TRUE(config.getConditions()[GPUTestConfig::kConditionPreRotation180]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation270]);
break;
case 270:
EXPECT_TRUE(config.getConditions()[GPUTestConfig::kConditionPreRotation]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation90]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation180]);
EXPECT_TRUE(config.getConditions()[GPUTestConfig::kConditionPreRotation270]);
break;
default:
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation90]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation180]);
EXPECT_FALSE(config.getConditions()[GPUTestConfig::kConditionPreRotation270]);
break;
}
} }
}; };
...@@ -89,38 +119,56 @@ TEST_P(GPUTestConfigTest, GPUTestConfigConditions) ...@@ -89,38 +119,56 @@ TEST_P(GPUTestConfigTest, GPUTestConfigConditions)
// condition flags are set correctly. // condition flags are set correctly.
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_D3D9) TEST_P(GPUTestConfigTest, GPUTestConfigConditions_D3D9)
{ {
GPUTestConfig config(GPUTestConfig::kAPID3D9); GPUTestConfig config(GPUTestConfig::kAPID3D9, 0);
validateConfigAPI(config, GPUTestConfig::kAPID3D9); validateConfigAPI(config, GPUTestConfig::kAPID3D9, 0);
} }
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_D3D11) TEST_P(GPUTestConfigTest, GPUTestConfigConditions_D3D11)
{ {
GPUTestConfig config(GPUTestConfig::kAPID3D11); GPUTestConfig config(GPUTestConfig::kAPID3D11, 0);
validateConfigAPI(config, GPUTestConfig::kAPID3D11); validateConfigAPI(config, GPUTestConfig::kAPID3D11, 0);
} }
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_Metal) TEST_P(GPUTestConfigTest, GPUTestConfigConditions_Metal)
{ {
GPUTestConfig config(GPUTestConfig::kAPIMetal); GPUTestConfig config(GPUTestConfig::kAPIMetal, 0);
validateConfigAPI(config, GPUTestConfig::kAPIMetal); validateConfigAPI(config, GPUTestConfig::kAPIMetal, 0);
} }
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_GLDesktop) TEST_P(GPUTestConfigTest, GPUTestConfigConditions_GLDesktop)
{ {
GPUTestConfig config(GPUTestConfig::kAPIGLDesktop); GPUTestConfig config(GPUTestConfig::kAPIGLDesktop, 0);
validateConfigAPI(config, GPUTestConfig::kAPIGLDesktop); validateConfigAPI(config, GPUTestConfig::kAPIGLDesktop, 0);
} }
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_GLES) TEST_P(GPUTestConfigTest, GPUTestConfigConditions_GLES)
{ {
GPUTestConfig config(GPUTestConfig::kAPIGLES); GPUTestConfig config(GPUTestConfig::kAPIGLES, 0);
validateConfigAPI(config, GPUTestConfig::kAPIGLES); validateConfigAPI(config, GPUTestConfig::kAPIGLES, 0);
} }
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_Vulkan) TEST_P(GPUTestConfigTest, GPUTestConfigConditions_Vulkan)
{ {
GPUTestConfig config(GPUTestConfig::kAPIVulkan); GPUTestConfig config(GPUTestConfig::kAPIVulkan, 0);
validateConfigAPI(config, GPUTestConfig::kAPIVulkan); validateConfigAPI(config, GPUTestConfig::kAPIVulkan, 0);
}
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_Vulkan_PreRotation90)
{
GPUTestConfig config(GPUTestConfig::kAPIVulkan, 90);
validateConfigAPI(config, GPUTestConfig::kAPIVulkan, 90);
}
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_Vulkan_PreRotation180)
{
GPUTestConfig config(GPUTestConfig::kAPIVulkan, 180);
validateConfigAPI(config, GPUTestConfig::kAPIVulkan, 180);
}
TEST_P(GPUTestConfigTest, GPUTestConfigConditions_Vulkan_PreRotation270)
{
GPUTestConfig config(GPUTestConfig::kAPIVulkan, 270);
validateConfigAPI(config, GPUTestConfig::kAPIVulkan, 270);
} }
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
......
...@@ -219,17 +219,19 @@ std::ostream &operator<<(std::ostream &stream, const PlatformParameters &pp) ...@@ -219,17 +219,19 @@ std::ostream &operator<<(std::ostream &stream, const PlatformParameters &pp)
stream << "_NoGenMultipleMipsPerPass"; stream << "_NoGenMultipleMipsPerPass";
} }
if (pp.eglParameters.emulatedPrerotation == 90) switch (pp.eglParameters.emulatedPrerotation)
{ {
stream << "_PreRotation90"; case 90:
} stream << "_PreRotate90";
else if (pp.eglParameters.emulatedPrerotation == 180) break;
{ case 180:
stream << "_PreRotation180"; stream << "_PreRotate180";
} break;
else if (pp.eglParameters.emulatedPrerotation == 270) case 270:
{ stream << "_PreRotate270";
stream << "_PreRotation270"; break;
default:
break;
} }
return stream; return stream;
......
...@@ -206,17 +206,19 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow, ...@@ -206,17 +206,19 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow,
disabledFeatureOverrides.push_back("gen_multiple_mips_per_pass"); disabledFeatureOverrides.push_back("gen_multiple_mips_per_pass");
} }
if (params.emulatedPrerotation == 90) switch (params.emulatedPrerotation)
{ {
enabledFeatureOverrides.push_back("emulated_prerotation_90"); case 90:
} enabledFeatureOverrides.push_back("emulated_prerotation_90");
else if (params.emulatedPrerotation == 180) break;
{ case 180:
enabledFeatureOverrides.push_back("emulated_prerotation_180"); enabledFeatureOverrides.push_back("emulated_prerotation_180");
} break;
else if (params.emulatedPrerotation == 270) case 270:
{ enabledFeatureOverrides.push_back("emulated_prerotation_270");
enabledFeatureOverrides.push_back("emulated_prerotation_270"); break;
default:
break;
} }
if (!disabledFeatureOverrides.empty()) if (!disabledFeatureOverrides.empty())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment