diff options
Diffstat (limited to 'tools/guest-diag/test_tri.c')
| -rw-r--r-- | tools/guest-diag/test_tri.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/tools/guest-diag/test_tri.c b/tools/guest-diag/test_tri.c new file mode 100644 index 0000000..dc42876 --- /dev/null +++ b/tools/guest-diag/test_tri.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2026 Open-IOV contributors +// test_tri.c - minimal SDL2 + OpenGL triangle for the offscreen pbuffer +// harness. Intended to be run with SDL_VIDEODRIVER=offscreen and the +// gz_pbuf.so shim preloaded (plus sdl_cap.so to capture the swaps): +// +// SDL_VIDEODRIVER=offscreen DISPLAY=:0 \ +// LD_PRELOAD="/tmp/sdl_cap.so /tmp/gz_pbuf.so" GZCAP=/tmp/testframes.bin \ +// ./test_tri 20 640 480 +// +// It creates an SDL2 GL window/context (the shim turns the context into a +// GLX pbuffer), clears to a colour, draws a rotating triangle, reads the +// centre pixel back (non-black proof), and calls SDL_GL_SwapWindow each +// frame. The sdl_cap.so hook captures the swap; the gz_pbuf.so hook turns +// the swap into glFinish. Build: +// gcc -O2 -o test_tri test_tri.c $(pkg-config --cflags --libs sdl2) -lGL +#include <SDL2/SDL.h> +#include <GL/gl.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char **argv) +{ + int frames = argc > 1 ? atoi(argv[1]) : 20; + int w = argc > 2 ? atoi(argv[2]) : 640; + int h = argc > 3 ? atoi(argv[3]) : 480; + SDL_Window *win; + SDL_GLContext ctx; + int i; + + setvbuf(stdout, NULL, _IONBF, 0); + + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + fprintf(stderr, "test_tri: SDL_Init: %s\n", SDL_GetError()); + return 1; + } + printf("test_tri: videodriver=%s\n", + SDL_GetCurrentVideoDriver() ? SDL_GetCurrentVideoDriver() : "?"); + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + win = SDL_CreateWindow("test_tri", SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, w, h, + SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN); + if (!win) { + fprintf(stderr, "test_tri: SDL_CreateWindow: %s\n", SDL_GetError()); + SDL_Quit(); + return 2; + } + + ctx = SDL_GL_CreateContext(win); + if (!ctx) { + fprintf(stderr, "test_tri: SDL_GL_CreateContext: %s\n", + SDL_GetError()); + SDL_DestroyWindow(win); + SDL_Quit(); + return 3; + } + if (SDL_GL_MakeCurrent(win, ctx) != 0) + fprintf(stderr, "test_tri: SDL_GL_MakeCurrent: %s\n", + SDL_GetError()); + SDL_GL_SetSwapInterval(0); + + printf("test_tri: GL %s | %s | %s\n", + (const char *)glGetString(GL_VENDOR), + (const char *)glGetString(GL_RENDERER), + (const char *)glGetString(GL_VERSION)); + + for (i = 0; i < frames; i++) { + float a = (float)i * 0.10f; + unsigned char px[4] = { 0, 0, 0, 0 }; + + glViewport(0, 0, w, h); + glClearColor(0.05f, 0.05f, 0.10f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glRotatef(a * 57.29578f, 0.0f, 0.0f, 1.0f); + + glBegin(GL_TRIANGLES); + glColor3f(1.0f, 0.2f, 0.1f); + glVertex2f(0.0f, 0.8f); + glColor3f(0.1f, 1.0f, 0.3f); + glVertex2f(-0.8f, -0.6f); + glColor3f(0.2f, 0.3f, 1.0f); + glVertex2f(0.8f, -0.6f); + glEnd(); + glFinish(); + + glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, px); + printf("test_tri: frame=%d centre=%02x%02x%02x%02x err=0x%x\n", + i, px[0], px[1], px[2], px[3], glGetError()); + + SDL_GL_SwapWindow(win); + SDL_Delay(20); + } + + printf("test_tri: done frames=%d %dx%d\n", frames, w, h); + SDL_GL_DeleteContext(ctx); + SDL_DestroyWindow(win); + SDL_Quit(); + return 0; +} |
