mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Fix] (trace-replay): validate OpenRA on both backends
This commit is contained in:
@@ -42,7 +42,7 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev libvulkan-dev libegl1-mesa-dev libgles2-mesa-dev libgl1-mesa-dri mesa-vulkan-drivers
|
sudo apt-get install -y clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev libvulkan-dev libegl1-mesa-dev libgles2-mesa-dev libgl1-mesa-dri mesa-vulkan-drivers xvfb
|
||||||
|
|
||||||
- name: Show installed toolchain
|
- name: Show installed toolchain
|
||||||
run: |
|
run: |
|
||||||
@@ -64,17 +64,22 @@ jobs:
|
|||||||
working-directory: ${{env.TEST_ROOT}}/build-retrace
|
working-directory: ${{env.TEST_ROOT}}/build-retrace
|
||||||
run: cmake --build . --target mobilegl_trace_replay
|
run: cmake --build . --target mobilegl_trace_replay
|
||||||
|
|
||||||
- name: OpenRA retrace
|
- name: Retrace and validate Espryt (DirectGLES)
|
||||||
working-directory: ${{env.TEST_ROOT}}/build-retrace
|
working-directory: ${{env.TEST_ROOT}}/build-retrace
|
||||||
run: ctest -V -R MobileGLTraceReplay.OpenRA.DirectGLES
|
run: ctest -V -R MobileGLTraceReplay.OpenRA.DirectGLES
|
||||||
|
|
||||||
- name: Upload OpenRA actual
|
- name: Retrace and validate Magma (DirectVulkan)
|
||||||
|
working-directory: ${{env.TEST_ROOT}}/build-retrace
|
||||||
|
run: xvfb-run -a ctest -V -R MobileGLTraceReplay.OpenRA.DirectVulkan
|
||||||
|
|
||||||
|
- name: Upload actual image
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: OpenRA-retrace-actual
|
name: OpenRA-retrace-actual
|
||||||
path: |
|
path: |
|
||||||
build-retrace/tools/trace_replay/openra/output/actual.png
|
build-retrace/tools/trace_replay/openra/actual-images/openra-DirectGLES-actual.png
|
||||||
build-retrace/tools/trace_replay/openra/output/result.json
|
build-retrace/tools/trace_replay/openra/actual-images/openra-DirectVulkan-actual.png
|
||||||
build-retrace/tools/trace_replay/openra/output/retrace.log
|
build-retrace/tools/trace_replay/openra/actual-images/*.json
|
||||||
|
build-retrace/tools/trace_replay/openra/actual-images/*.log
|
||||||
if-no-files-found: warn
|
if-no-files-found: warn
|
||||||
|
|||||||
@@ -257,14 +257,21 @@ target_link_libraries(mobilegl_trace_replay PRIVATE
|
|||||||
add_dependencies(mobilegl_trace_replay MobileGL)
|
add_dependencies(mobilegl_trace_replay MobileGL)
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
function(add_openra_trace_replay_test BACKEND)
|
||||||
add_test(
|
add_test(
|
||||||
NAME MobileGLTraceReplay.OpenRA.DirectGLES
|
NAME MobileGLTraceReplay.OpenRA.${BACKEND}
|
||||||
COMMAND "${CMAKE_COMMAND}"
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
-DTRACE_REPLAY_EXE=$<TARGET_FILE:mobilegl_trace_replay>
|
-DTRACE_REPLAY_EXE=$<TARGET_FILE:mobilegl_trace_replay>
|
||||||
-DMOBILEGL_LIBRARY=$<TARGET_FILE:MobileGL>
|
-DMOBILEGL_LIBRARY=$<TARGET_FILE:MobileGL>
|
||||||
-DOPENRA_TRACE_ARCHIVE=${MOBILEGL_TRACE_ROOT}/fixtures/openra.tgz
|
-DOPENRA_TRACE_ARCHIVE=${MOBILEGL_TRACE_ROOT}/fixtures/openra.tgz
|
||||||
-DOPENRA_GOLDEN=${MOBILEGL_TRACE_ROOT}/fixtures/openra.0000031249.png
|
-DOPENRA_GOLDEN=${MOBILEGL_TRACE_ROOT}/fixtures/openra.0000031249.png
|
||||||
-DOPENRA_OUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR}/openra
|
-DOPENRA_BACKEND=${BACKEND}
|
||||||
|
-DOPENRA_OUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR}/openra/${BACKEND}
|
||||||
|
-DOPENRA_ARTIFACT_DIR=${CMAKE_CURRENT_BINARY_DIR}/openra/actual-images
|
||||||
-P ${MOBILEGL_TRACE_ROOT}/run_openra_replay.cmake)
|
-P ${MOBILEGL_TRACE_ROOT}/run_openra_replay.cmake)
|
||||||
set_tests_properties(MobileGLTraceReplay.OpenRA.DirectGLES PROPERTIES
|
set_tests_properties(MobileGLTraceReplay.OpenRA.${BACKEND} PROPERTIES
|
||||||
ENVIRONMENT "EGL_PLATFORM=surfaceless;LIBGL_ALWAYS_SOFTWARE=1;MESA_GL_VERSION_OVERRIDE=3.3;MESA_GLSL_VERSION_OVERRIDE=330")
|
ENVIRONMENT "EGL_PLATFORM=surfaceless;LIBGL_ALWAYS_SOFTWARE=1;MESA_GL_VERSION_OVERRIDE=3.3;MESA_GLSL_VERSION_OVERRIDE=330")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
add_openra_trace_replay_test(DirectGLES)
|
||||||
|
add_openra_trace_replay_test(DirectVulkan)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ cmake --build build-test
|
|||||||
Run the OpenRA fixture test:
|
Run the OpenRA fixture test:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ctest --test-dir build-test -V -R MobileGLTraceReplay.OpenRA.DirectGLES
|
ctest --test-dir build-test -V -R MobileGLTraceReplay.OpenRA
|
||||||
```
|
```
|
||||||
|
|
||||||
Run the CLI directly:
|
Run the CLI directly:
|
||||||
@@ -39,6 +39,5 @@ build-test/tools/trace_replay/mobilegl_trace_replay \
|
|||||||
--fuzz-percent 20
|
--fuzz-percent 20
|
||||||
```
|
```
|
||||||
|
|
||||||
The Linux runner uses an EGL pbuffer shim and loads MobileGL by path with `dlopen`. The current CI test covers the
|
The Linux runner loads MobileGL by path with `dlopen`. It uses an EGL pbuffer for `DirectGLES` and an X11 window
|
||||||
OpenRA core-profile trace through the `DirectGLES` backend. `DirectVulkan` is still available as a CLI argument, but it
|
surface for `DirectVulkan` so Magma can create a Vulkan swapchain under `xvfb-run` in CI.
|
||||||
requires a native window/swapchain path and is not part of the headless CI test yet.
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using PfnEglBindApi = EGLBoolean (*)(EGLenum);
|
|||||||
using PfnEglChooseConfig = EGLBoolean (*)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *);
|
using PfnEglChooseConfig = EGLBoolean (*)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *);
|
||||||
using PfnEglCreateContext = EGLContext (*)(EGLDisplay, EGLConfig, EGLContext, const EGLint *);
|
using PfnEglCreateContext = EGLContext (*)(EGLDisplay, EGLConfig, EGLContext, const EGLint *);
|
||||||
using PfnEglCreatePbufferSurface = EGLSurface (*)(EGLDisplay, EGLConfig, const EGLint *);
|
using PfnEglCreatePbufferSurface = EGLSurface (*)(EGLDisplay, EGLConfig, const EGLint *);
|
||||||
|
using PfnEglCreateWindowSurface = EGLSurface (*)(EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint *);
|
||||||
using PfnEglDestroyContext = EGLBoolean (*)(EGLDisplay, EGLContext);
|
using PfnEglDestroyContext = EGLBoolean (*)(EGLDisplay, EGLContext);
|
||||||
using PfnEglDestroySurface = EGLBoolean (*)(EGLDisplay, EGLSurface);
|
using PfnEglDestroySurface = EGLBoolean (*)(EGLDisplay, EGLSurface);
|
||||||
using PfnEglGetConfigAttrib = EGLBoolean (*)(EGLDisplay, EGLConfig, EGLint, EGLint *);
|
using PfnEglGetConfigAttrib = EGLBoolean (*)(EGLDisplay, EGLConfig, EGLint, EGLint *);
|
||||||
@@ -26,12 +27,14 @@ using PfnEglMakeCurrent = EGLBoolean (*)(EGLDisplay, EGLSurface, EGLSurface, EGL
|
|||||||
using PfnEglQueryString = const char *(*)(EGLDisplay, EGLint);
|
using PfnEglQueryString = const char *(*)(EGLDisplay, EGLint);
|
||||||
using PfnEglSwapBuffers = EGLBoolean (*)(EGLDisplay, EGLSurface);
|
using PfnEglSwapBuffers = EGLBoolean (*)(EGLDisplay, EGLSurface);
|
||||||
using PfnEglTerminate = EGLBoolean (*)(EGLDisplay);
|
using PfnEglTerminate = EGLBoolean (*)(EGLDisplay);
|
||||||
|
using PfnGlGetString = const unsigned char *(*)(unsigned int);
|
||||||
|
|
||||||
struct EglFns {
|
struct EglFns {
|
||||||
PfnEglBindApi bindApi = nullptr;
|
PfnEglBindApi bindApi = nullptr;
|
||||||
PfnEglChooseConfig chooseConfig = nullptr;
|
PfnEglChooseConfig chooseConfig = nullptr;
|
||||||
PfnEglCreateContext createContext = nullptr;
|
PfnEglCreateContext createContext = nullptr;
|
||||||
PfnEglCreatePbufferSurface createPbufferSurface = nullptr;
|
PfnEglCreatePbufferSurface createPbufferSurface = nullptr;
|
||||||
|
PfnEglCreateWindowSurface createWindowSurface = nullptr;
|
||||||
PfnEglDestroyContext destroyContext = nullptr;
|
PfnEglDestroyContext destroyContext = nullptr;
|
||||||
PfnEglDestroySurface destroySurface = nullptr;
|
PfnEglDestroySurface destroySurface = nullptr;
|
||||||
PfnEglGetConfigAttrib getConfigAttrib = nullptr;
|
PfnEglGetConfigAttrib getConfigAttrib = nullptr;
|
||||||
@@ -44,13 +47,39 @@ struct EglFns {
|
|||||||
PfnEglTerminate terminate = nullptr;
|
PfnEglTerminate terminate = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct X11Fns {
|
||||||
|
void *lib = nullptr;
|
||||||
|
void *display = nullptr;
|
||||||
|
using XOpenDisplay = void *(*)(const char *);
|
||||||
|
using XCloseDisplay = int (*)(void *);
|
||||||
|
using XDefaultScreen = int (*)(void *);
|
||||||
|
using XDefaultRootWindow = unsigned long (*)(void *);
|
||||||
|
using XBlackPixel = unsigned long (*)(void *, int);
|
||||||
|
using XCreateSimpleWindow = unsigned long (*)(void *, unsigned long, int, int, unsigned int, unsigned int,
|
||||||
|
unsigned int, unsigned long, unsigned long);
|
||||||
|
using XDestroyWindow = int (*)(void *, unsigned long);
|
||||||
|
using XMapWindow = int (*)(void *, unsigned long);
|
||||||
|
using XFlush = int (*)(void *);
|
||||||
|
XOpenDisplay openDisplay = nullptr;
|
||||||
|
XCloseDisplay closeDisplay = nullptr;
|
||||||
|
XDefaultScreen defaultScreen = nullptr;
|
||||||
|
XDefaultRootWindow defaultRootWindow = nullptr;
|
||||||
|
XBlackPixel blackPixel = nullptr;
|
||||||
|
XCreateSimpleWindow createSimpleWindow = nullptr;
|
||||||
|
XDestroyWindow destroyWindow = nullptr;
|
||||||
|
XMapWindow mapWindow = nullptr;
|
||||||
|
XFlush flush = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
EglFns gEgl;
|
EglFns gEgl;
|
||||||
|
X11Fns gX11;
|
||||||
EGLDisplay gDisplay = EGL_NO_DISPLAY;
|
EGLDisplay gDisplay = EGL_NO_DISPLAY;
|
||||||
void *gMobileGl = nullptr;
|
void *gMobileGl = nullptr;
|
||||||
const glws::Drawable *gCurrentDrawable = nullptr;
|
const glws::Drawable *gCurrentDrawable = nullptr;
|
||||||
EGLContext gCurrentContext = EGL_NO_CONTEXT;
|
EGLContext gCurrentContext = EGL_NO_CONTEXT;
|
||||||
int gRequestedWidth = 0;
|
int gRequestedWidth = 0;
|
||||||
int gRequestedHeight = 0;
|
int gRequestedHeight = 0;
|
||||||
|
bool gPrintedGlIdentity = false;
|
||||||
|
|
||||||
int ResolveWidth(int width) {
|
int ResolveWidth(int width) {
|
||||||
if (gRequestedWidth > 0) {
|
if (gRequestedWidth > 0) {
|
||||||
@@ -106,6 +135,7 @@ bool LoadEgl() {
|
|||||||
Load(gEgl.chooseConfig, "eglChooseConfig") &&
|
Load(gEgl.chooseConfig, "eglChooseConfig") &&
|
||||||
Load(gEgl.createContext, "eglCreateContext") &&
|
Load(gEgl.createContext, "eglCreateContext") &&
|
||||||
Load(gEgl.createPbufferSurface, "eglCreatePbufferSurface") &&
|
Load(gEgl.createPbufferSurface, "eglCreatePbufferSurface") &&
|
||||||
|
Load(gEgl.createWindowSurface, "eglCreateWindowSurface") &&
|
||||||
Load(gEgl.destroyContext, "eglDestroyContext") &&
|
Load(gEgl.destroyContext, "eglDestroyContext") &&
|
||||||
Load(gEgl.destroySurface, "eglDestroySurface") &&
|
Load(gEgl.destroySurface, "eglDestroySurface") &&
|
||||||
Load(gEgl.getConfigAttrib, "eglGetConfigAttrib") &&
|
Load(gEgl.getConfigAttrib, "eglGetConfigAttrib") &&
|
||||||
@@ -118,6 +148,108 @@ bool LoadEgl() {
|
|||||||
Load(gEgl.terminate, "eglTerminate");
|
Load(gEgl.terminate, "eglTerminate");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsDirectVulkanBackend() {
|
||||||
|
const char *backend = std::getenv("MOBILEGL_BACKEND_TYPE");
|
||||||
|
return backend != nullptr && std::strcmp(backend, "DirectVulkan") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool LoadX11(T &slot, const char *name) {
|
||||||
|
slot = reinterpret_cast<T>(dlsym(gX11.lib, name));
|
||||||
|
if (slot == nullptr) {
|
||||||
|
std::cerr << "error: failed to resolve " << name << " from X11\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EnsureX11() {
|
||||||
|
if (gX11.display != nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (gX11.lib == nullptr) {
|
||||||
|
gX11.lib = dlopen("libX11.so.6", RTLD_LOCAL | RTLD_NOW);
|
||||||
|
if (gX11.lib == nullptr) {
|
||||||
|
gX11.lib = dlopen("libX11.so", RTLD_LOCAL | RTLD_NOW);
|
||||||
|
}
|
||||||
|
if (gX11.lib == nullptr) {
|
||||||
|
std::cerr << "error: failed to open libX11 for DirectVulkan trace replay\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!LoadX11(gX11.openDisplay, "XOpenDisplay") ||
|
||||||
|
!LoadX11(gX11.closeDisplay, "XCloseDisplay") ||
|
||||||
|
!LoadX11(gX11.defaultScreen, "XDefaultScreen") ||
|
||||||
|
!LoadX11(gX11.defaultRootWindow, "XDefaultRootWindow") ||
|
||||||
|
!LoadX11(gX11.blackPixel, "XBlackPixel") ||
|
||||||
|
!LoadX11(gX11.createSimpleWindow, "XCreateSimpleWindow") ||
|
||||||
|
!LoadX11(gX11.destroyWindow, "XDestroyWindow") ||
|
||||||
|
!LoadX11(gX11.mapWindow, "XMapWindow") ||
|
||||||
|
!LoadX11(gX11.flush, "XFlush")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gX11.display = gX11.openDisplay(std::getenv("DISPLAY"));
|
||||||
|
if (gX11.display == nullptr) {
|
||||||
|
std::cerr << "error: XOpenDisplay failed for DirectVulkan trace replay\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long CreateX11Window(int width, int height) {
|
||||||
|
if (!EnsureX11()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const int screen = gX11.defaultScreen(gX11.display);
|
||||||
|
const unsigned long root = gX11.defaultRootWindow(gX11.display);
|
||||||
|
const unsigned long black = gX11.blackPixel(gX11.display, screen);
|
||||||
|
const unsigned long window = gX11.createSimpleWindow(gX11.display, root, 0, 0,
|
||||||
|
static_cast<unsigned int>(std::max(width, 1)),
|
||||||
|
static_cast<unsigned int>(std::max(height, 1)),
|
||||||
|
0, black, black);
|
||||||
|
if (window != 0) {
|
||||||
|
gX11.mapWindow(gX11.display, window);
|
||||||
|
gX11.flush(gX11.display);
|
||||||
|
}
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyX11Window(unsigned long window) {
|
||||||
|
if (window != 0 && gX11.display != nullptr && gX11.destroyWindow != nullptr) {
|
||||||
|
gX11.destroyWindow(gX11.display, window);
|
||||||
|
gX11.flush(gX11.display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintGlIdentityOnce() {
|
||||||
|
if (gPrintedGlIdentity) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto glGetString = reinterpret_cast<PfnGlGetString>(Lookup("glGetString"));
|
||||||
|
if (glGetString == nullptr) {
|
||||||
|
std::cerr << "MOBILEGL_TRACE_GL_INFO unavailable: glGetString was not resolved\n";
|
||||||
|
gPrintedGlIdentity = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
constexpr unsigned int GL_VENDOR_ENUM = 0x1F00;
|
||||||
|
constexpr unsigned int GL_RENDERER_ENUM = 0x1F01;
|
||||||
|
constexpr unsigned int GL_VERSION_ENUM = 0x1F02;
|
||||||
|
constexpr unsigned int GL_SHADING_LANGUAGE_VERSION_ENUM = 0x8B8C;
|
||||||
|
auto stringOrUnknown = [glGetString](unsigned int name) {
|
||||||
|
const auto *value = glGetString(name);
|
||||||
|
return value == nullptr ? reinterpret_cast<const unsigned char *>("<null>") : value;
|
||||||
|
};
|
||||||
|
std::cerr << "MOBILEGL_TRACE_GL_VENDOR: "
|
||||||
|
<< reinterpret_cast<const char *>(stringOrUnknown(GL_VENDOR_ENUM)) << "\n"
|
||||||
|
<< "MOBILEGL_TRACE_GL_RENDERER: "
|
||||||
|
<< reinterpret_cast<const char *>(stringOrUnknown(GL_RENDERER_ENUM)) << "\n"
|
||||||
|
<< "MOBILEGL_TRACE_GL_VERSION: "
|
||||||
|
<< reinterpret_cast<const char *>(stringOrUnknown(GL_VERSION_ENUM)) << "\n"
|
||||||
|
<< "MOBILEGL_TRACE_GL_SHADING_LANGUAGE_VERSION: "
|
||||||
|
<< reinterpret_cast<const char *>(stringOrUnknown(GL_SHADING_LANGUAGE_VERSION_ENUM)) << "\n";
|
||||||
|
gPrintedGlIdentity = true;
|
||||||
|
}
|
||||||
|
|
||||||
class EglVisual final : public glws::Visual {
|
class EglVisual final : public glws::Visual {
|
||||||
public:
|
public:
|
||||||
EGLConfig config = nullptr;
|
EGLConfig config = nullptr;
|
||||||
@@ -129,6 +261,7 @@ public:
|
|||||||
class EglDrawable final : public glws::Drawable {
|
class EglDrawable final : public glws::Drawable {
|
||||||
public:
|
public:
|
||||||
EGLSurface surface = EGL_NO_SURFACE;
|
EGLSurface surface = EGL_NO_SURFACE;
|
||||||
|
unsigned long x11Window = 0;
|
||||||
|
|
||||||
EglDrawable(const EglVisual *visual, int width, int height, bool pbuffer)
|
EglDrawable(const EglVisual *visual, int width, int height, bool pbuffer)
|
||||||
: Drawable(visual, width, height, pbuffer) {
|
: Drawable(visual, width, height, pbuffer) {
|
||||||
@@ -176,14 +309,26 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void createSurface() {
|
void createSurface() {
|
||||||
|
const int resolvedWidth = ResolveWidth(width);
|
||||||
|
const int resolvedHeight = ResolveHeight(height);
|
||||||
|
if (IsDirectVulkanBackend()) {
|
||||||
|
x11Window = CreateX11Window(resolvedWidth, resolvedHeight);
|
||||||
|
if (x11Window == 0) {
|
||||||
|
surface = EGL_NO_SURFACE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
surface = gEgl.createWindowSurface(gDisplay, static_cast<const EglVisual *>(visual)->config,
|
||||||
|
reinterpret_cast<EGLNativeWindowType>(x11Window), nullptr);
|
||||||
|
} else {
|
||||||
const EGLint attribs[] = {
|
const EGLint attribs[] = {
|
||||||
EGL_WIDTH, ResolveWidth(width),
|
EGL_WIDTH, resolvedWidth,
|
||||||
EGL_HEIGHT, ResolveHeight(height),
|
EGL_HEIGHT, resolvedHeight,
|
||||||
EGL_NONE,
|
EGL_NONE,
|
||||||
};
|
};
|
||||||
surface = gEgl.createPbufferSurface(gDisplay, static_cast<const EglVisual *>(visual)->config, attribs);
|
surface = gEgl.createPbufferSurface(gDisplay, static_cast<const EglVisual *>(visual)->config, attribs);
|
||||||
|
}
|
||||||
if (surface == EGL_NO_SURFACE) {
|
if (surface == EGL_NO_SURFACE) {
|
||||||
std::cerr << "error: EGL pbuffer creation failed: 0x" << std::hex
|
std::cerr << "error: EGL surface creation failed: 0x" << std::hex
|
||||||
<< gEgl.getError() << std::dec << "\n";
|
<< gEgl.getError() << std::dec << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,6 +338,8 @@ private:
|
|||||||
gEgl.destroySurface(gDisplay, surface);
|
gEgl.destroySurface(gDisplay, surface);
|
||||||
surface = EGL_NO_SURFACE;
|
surface = EGL_NO_SURFACE;
|
||||||
}
|
}
|
||||||
|
DestroyX11Window(x11Window);
|
||||||
|
x11Window = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -337,6 +484,7 @@ bool makeCurrentInternal(Drawable *drawable, Drawable *readable, Context *contex
|
|||||||
}
|
}
|
||||||
gCurrentDrawable = drawable;
|
gCurrentDrawable = drawable;
|
||||||
gCurrentContext = eglContext;
|
gCurrentContext = eglContext;
|
||||||
|
PrintGlIdentityOnce();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
foreach(required TRACE_REPLAY_EXE MOBILEGL_LIBRARY OPENRA_TRACE_ARCHIVE OPENRA_GOLDEN OPENRA_OUTPUT_DIR)
|
foreach(required TRACE_REPLAY_EXE MOBILEGL_LIBRARY OPENRA_TRACE_ARCHIVE OPENRA_GOLDEN OPENRA_OUTPUT_DIR OPENRA_BACKEND)
|
||||||
if(NOT DEFINED ${required} OR "${${required}}" STREQUAL "")
|
if(NOT DEFINED ${required} OR "${${required}}" STREQUAL "")
|
||||||
message(FATAL_ERROR "${required} is required")
|
message(FATAL_ERROR "${required} is required")
|
||||||
endif()
|
endif()
|
||||||
@@ -32,7 +32,7 @@ execute_process(
|
|||||||
--trace "${openra_trace}"
|
--trace "${openra_trace}"
|
||||||
--golden "${OPENRA_GOLDEN}"
|
--golden "${OPENRA_GOLDEN}"
|
||||||
--output "${OPENRA_OUTPUT_DIR}/output"
|
--output "${OPENRA_OUTPUT_DIR}/output"
|
||||||
--backend DirectGLES
|
--backend "${OPENRA_BACKEND}"
|
||||||
--mobilegl-library "${MOBILEGL_LIBRARY}"
|
--mobilegl-library "${MOBILEGL_LIBRARY}"
|
||||||
--target-call 31249
|
--target-call 31249
|
||||||
--width 640
|
--width 640
|
||||||
@@ -58,6 +58,28 @@ else()
|
|||||||
message(FATAL_ERROR "trace replay did not write ${result_json}")
|
message(FATAL_ERROR "trace replay did not write ${result_json}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(retrace_log "${OPENRA_OUTPUT_DIR}/output/retrace.log")
|
||||||
|
if(EXISTS "${retrace_log}")
|
||||||
|
file(STRINGS "${retrace_log}" gl_identity_lines REGEX "MOBILEGL_TRACE_GL_")
|
||||||
|
foreach(line IN LISTS gl_identity_lines)
|
||||||
|
message(STATUS "${line}")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED OPENRA_ARTIFACT_DIR AND NOT "${OPENRA_ARTIFACT_DIR}" STREQUAL "")
|
||||||
|
file(MAKE_DIRECTORY "${OPENRA_ARTIFACT_DIR}")
|
||||||
|
set(actual_png "${OPENRA_OUTPUT_DIR}/output/actual.png")
|
||||||
|
if(EXISTS "${actual_png}")
|
||||||
|
file(COPY_FILE "${actual_png}" "${OPENRA_ARTIFACT_DIR}/openra-${OPENRA_BACKEND}-actual.png")
|
||||||
|
endif()
|
||||||
|
if(EXISTS "${result_json}")
|
||||||
|
file(COPY_FILE "${result_json}" "${OPENRA_ARTIFACT_DIR}/openra-${OPENRA_BACKEND}-result.json")
|
||||||
|
endif()
|
||||||
|
if(EXISTS "${retrace_log}")
|
||||||
|
file(COPY_FILE "${retrace_log}" "${OPENRA_ARTIFACT_DIR}/openra-${OPENRA_BACKEND}-retrace.log")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT replay_result EQUAL 0)
|
if(NOT replay_result EQUAL 0)
|
||||||
message(FATAL_ERROR "OpenRA trace replay failed with status ${replay_result}")
|
message(FATAL_ERROR "OpenRA ${OPENRA_BACKEND} trace replay failed with status ${replay_result}")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
Reference in New Issue
Block a user