Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Mesa
piglit
Commits
b6a0fc0f
Commit
b6a0fc0f
authored
Jan 21, 2011
by
Jian Zhao
Committed by
root
Jan 21, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
glx: Add test for glx swap event's receive and its asynchronization.
parent
f447d5e2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
519 additions
and
0 deletions
+519
-0
tests/all.tests
tests/all.tests
+3
-0
tests/glx/CMakeLists.txt
tests/glx/CMakeLists.txt
+1
-0
tests/glx/glx-swap-event.c
tests/glx/glx-swap-event.c
+515
-0
No files found.
tests/all.tests
View file @
b6a0fc0f
...
...
@@ -810,6 +810,9 @@ add_plain_test(glx, 'glx-destroycontext-2')
add_plain_test
(
glx
,
'glx-multithread'
)
add_plain_test
(
glx
,
'glx-shader-sharing'
)
add_plain_test
(
glx
,
'glx-swap-exchange'
)
glx
[
'glx-swap-event_event'
]
=
PlainExecTest
([
'glx-swap-event'
,
'-auto'
,
'--event'
])
glx
[
'glx-swap-event_async'
]
=
PlainExecTest
([
'glx-swap-event'
,
'-auto'
,
'--async'
])
glx
[
'glx-swap-event_interval'
]
=
PlainExecTest
([
'glx-swap-event'
,
'-auto'
,
'--interval'
])
add_plain_test
(
glx
,
'glx-make-current'
)
add_plain_test
(
glx
,
'glx-make-glxdrawable-current'
)
add_plain_test
(
glx
,
'glx-tfp'
)
...
...
tests/glx/CMakeLists.txt
View file @
b6a0fc0f
...
...
@@ -26,6 +26,7 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
add_executable
(
glx-destroycontext-2 glx-destroycontext-2.c
)
add_executable
(
glx-multithread glx-multithread.c
)
add_executable
(
glx-make-current glx-make-current.c
)
add_executable
(
glx-swap-event glx-swap-event.c
)
add_executable
(
glx-make-glxdrawable-current glx-make-glxdrawable-current.c
)
target_link_libraries
(
glx-multithread pthread X11
)
add_executable
(
glx-swap-exchange glx-swap-exchange.c
)
...
...
tests/glx/glx-swap-event.c
0 → 100644
View file @
b6a0fc0f
/*
* Copyright © 2010 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* jian.j.zhao@intel.com
*/
/*
* Simple test case on the intel_swap_event.
*
*/
#include "piglit-util.h"
#include "GL/glx.h"
#include <sys/time.h>
/* return current time (in seconds) */
static
double
current_time
(
void
)
{
struct
timeval
tv
;
#ifdef __VMS
(
void
)
gettimeofday
(
&
tv
,
NULL
);
#else
struct
timezone
tz
;
(
void
)
gettimeofday
(
&
tv
,
&
tz
);
#endif
return
(
double
)
tv
.
tv_sec
+
tv
.
tv_usec
/
1000000
.
0
;
}
PFNGLXSWAPINTERVALMESAPROC
pglXSwapIntervalMESA
;
PFNGLXGETSWAPINTERVALMESAPROC
pglXGetSwapIntervalMESA
;
#define STACK_L 10
static
GLboolean
fullscreen
=
GL_FALSE
;
/* Create a fullscreen window */
static
GLboolean
verbose
=
GL_FALSE
;
/* Disable verbose. */
static
GLboolean
Automatic
=
GL_FALSE
;
/* Disable verbose. */
static
GLboolean
test_events
=
GL_FALSE
;
/* Disable verbose. */
static
GLboolean
interval_diff
=
GL_FALSE
;
/* Disable verbose. */
static
GLboolean
async
=
GL_FALSE
;
/* Disable verbose. */
int
event_base
,
Glx_event
,
count
=
0
,
swap_count
=
0
,
event_count
=
0
;
static
int
Intel_swap_event
=
0
;
int
event_count_total
=
0
,
frames_total
=
0
,
message_count
=
0
;
static
double
time_call
=
0
.
0
,
time_fin
=
0
.
0
,
time_val
=
0
.
0
;
double
swap_start
[
STACK_L
],
swap_returned
[
STACK_L
];
int
interval
=
1
;
char
*
swap_event_type
=
NULL
;
/**
* Determine whether or not a GLX extension is supported.
*/
static
int
is_glx_extension_supported
(
Display
*
dpy
,
const
char
*
query
)
{
const
int
scrnum
=
DefaultScreen
(
dpy
);
const
char
*
glx_extensions
=
NULL
;
const
size_t
len
=
strlen
(
query
);
const
char
*
ptr
;
if
(
glx_extensions
==
NULL
)
{
glx_extensions
=
glXQueryExtensionsString
(
dpy
,
scrnum
);
}
ptr
=
strstr
(
glx_extensions
,
query
);
return
((
ptr
!=
NULL
)
&&
((
ptr
[
len
]
==
' '
)
||
(
ptr
[
len
]
==
'\0'
)));
}
static
void
query_swap_event
(
Display
*
dpy
)
{
if
(
!
is_glx_extension_supported
(
dpy
,
"GLX_INTEL_swap_event"
))
{
printf
(
"The GLX_INTEL_swap_event is not supported in current version.
\n
"
);
piglit_report_result
(
PIGLIT_SKIP
);
}
else
{
printf
(
"The GLX_INTEL_swap_event is supported in current version.
\n
"
);
}
if
(
interval_diff
)
{
if
(
!
is_glx_extension_supported
(
dpy
,
"GLX_MESA_swap_control"
))
{
printf
(
"GLX_MESA_swap_control was not supported by the driver.
\n
"
);
piglit_report_result
(
PIGLIT_SKIP
);
}
else
{
pglXGetSwapIntervalMESA
=
(
PFNGLXGETSWAPINTERVALMESAPROC
)
glXGetProcAddressARB
((
const
GLubyte
*
)
"glXGetSwapIntervalMESA"
);
pglXSwapIntervalMESA
=
(
PFNGLXSWAPINTERVALMESAPROC
)
glXGetProcAddressARB
((
const
GLubyte
*
)
"glXSwapIntervalMESA"
);
}
}
}
/** Draw single frame, do SwapBuffers, compute FPS */
static
void
draw_frame
(
Display
*
dpy
,
Window
win
)
{
static
int
frames
=
0
,
async_swap
;
static
double
tRot0
=
-
1
.
0
,
tRate0
=
-
1
.
0
;
static
double
swap_freq
[
2
];
double
dt
,
t
=
current_time
();
int
tem
;
if
(
tRot0
<
0
.
0
)
tRot0
=
t
;
dt
=
t
-
tRot0
;
tRot0
=
t
;
if
(
tRate0
<
0
.
0
)
tRate0
=
t
;
if
(
t
-
tRate0
>=
3
.
0
)
{
if
(
interval_diff
)
{
if
(
message_count
&
0x1
)
{
(
*
pglXSwapIntervalMESA
)(
1
);
interval
=
(
*
pglXGetSwapIntervalMESA
)();
if
(
!
interval
==
1
)
{
printf
(
"Failed to set swap interval to 1.
\n
"
);
piglit_report_result
(
PIGLIT_FAILURE
);
}
}
else
{
(
*
pglXSwapIntervalMESA
)(
0
);
interval
=
(
*
pglXGetSwapIntervalMESA
)();
if
(
!
interval
==
0
)
{
printf
(
"Failed to set swap interval to 0.
\n
"
);
piglit_report_result
(
PIGLIT_FAILURE
);
}
}
}
message_count
++
;
GLfloat
seconds
=
t
-
tRate0
;
if
(
(
time_val
/
frames
)
<
0
.
0016
)
{
// 0.0016 <=> 60Hz * 10 or 100Hz * 6
async_swap
=
1
;
}
else
{
async_swap
=
0
;
}
interval
=
1
-
interval
;
swap_freq
[
interval
]
=
frames
/
seconds
;
if
(
Automatic
)
{
if
(
message_count
==
2
)
{
if
(
test_events
)
{
if
(
!
Intel_swap_event
==
0
)
{
if
(
verbose
)
{
printf
(
"glXSwapBuffers is called %d times and there\
is %d Intel_swap_event received in past %3.1f seconds.
\n
"
,
swap_count
,
event_count
,
seconds
);
printf
(
"There is swap event received, and the swap \
type is %s.
\n
"
,
swap_event_type
);
}
piglit_report_result
(
PIGLIT_SUCCESS
);
}
else
{
if
(
verbose
)
{
printf
(
"glXSwapBuffers is called %d times and there\
is %d Intel_swap_event received in past %3.1f seconds.
\n
"
,
swap_count
,
event_count
,
seconds
);
printf
(
"There is no swap event received, and the \
swap type is %s.
\n
"
,
swap_event_type
);
}
piglit_report_result
(
PIGLIT_FAILURE
);
}
}
if
(
interval_diff
)
{
tem
=
1
.
5
*
swap_freq
[
1
];
if
(
swap_freq
[
0
]
>=
tem
)
{
if
(
verbose
)
{
printf
(
"The swap frequency of no swap interval is \
much larger than swap interval being 1.
\n
"
);
}
piglit_report_result
(
PIGLIT_SUCCESS
);
}
else
{
if
(
fullscreen
)
{
if
(
verbose
)
printf
(
"In fullscreen mode, the swap frequency of \
no swap interval is limited under fresh rate.
\n
"
);
piglit_report_result
(
PIGLIT_SUCCESS
);
}
if
(
verbose
)
{
printf
(
"The swap frequency of no swap interval is \
not much larger than swap interval being 1. They are %lf and %lf.
\n
"
,
swap_freq
[
0
],
swap_freq
[
1
]);
}
piglit_report_result
(
PIGLIT_FAILURE
);
}
}
if
(
async
)
{
if
(
verbose
)
{
printf
(
"It takes about %lf seconds returning back from\
the glXSwapBuffers call on average.
\n
"
,
(
time_val
/
frames
));
}
if
(
async_swap
==
1
)
{
piglit_report_result
(
PIGLIT_SUCCESS
);
}
else
{
piglit_report_result
(
PIGLIT_FAILURE
);
}
}
}
}
tRate0
=
t
;
frames
=
0
;
time_val
=
0
;
swap_count
=
0
;
event_count
=
0
;
}
if
(
frames_total
&
1
)
{
glClearColor
(
1
.
0
f
,
1
.
0
f
,
1
.
0
f
,
1
.
0
f
);
glColor3f
(
1
.
0
f
,
1
.
0
f
,
1
.
0
f
);
}
else
{
glClearColor
(
1
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
glColor3f
(
1
.
0
f
,
0
.
0
f
,
0
.
0
f
);
}
glClear
(
GL_COLOR_BUFFER_BIT
|
GL_DEPTH_BUFFER_BIT
);
count
=
frames_total
%
STACK_L
;
time_call
=
current_time
();
swap_start
[
count
]
=
time_call
;
glXSwapBuffers
(
dpy
,
win
);
time_fin
=
current_time
();
swap_returned
[
count
]
=
time_fin
;
time_val
+=
(
time_fin
-
time_call
);
frames
++
;
frames_total
++
;
swap_count
++
;
}
/**
* Remove window border/decorations.
*/
static
void
no_border
(
Display
*
dpy
,
Window
w
)
{
static
const
unsigned
MWM_HINTS_DECORATIONS
=
(
1
<<
1
);
static
const
int
PROP_MOTIF_WM_HINTS_ELEMENTS
=
5
;
typedef
struct
{
unsigned
long
flags
;
unsigned
long
functions
;
unsigned
long
decorations
;
long
inputMode
;
unsigned
long
status
;
}
PropMotifWmHints
;
PropMotifWmHints
motif_hints
;
Atom
prop
,
proptype
;
unsigned
long
flags
=
0
;
/* setup the property */
motif_hints
.
flags
=
MWM_HINTS_DECORATIONS
;
motif_hints
.
decorations
=
flags
;
/* get the atom for the property */
prop
=
XInternAtom
(
dpy
,
"_MOTIF_WM_HINTS"
,
True
);
if
(
!
prop
)
{
/* something went wrong! */
return
;
}
/* not sure this is correct, seems to work, XA_WM_HINTS didn't work */
proptype
=
prop
;
XChangeProperty
(
dpy
,
w
,
/* display, window */
prop
,
proptype
,
/* property, type */
32
,
/* format: 32-bit datums */
PropModeReplace
,
/* mode */
(
unsigned
char
*
)
&
motif_hints
,
/* data */
PROP_MOTIF_WM_HINTS_ELEMENTS
/* nelements */
);
}
/*
* Create an RGB, double-buffered window.
* Return the window and context handles.
*/
static
void
make_window
(
Display
*
dpy
,
const
char
*
name
,
int
x
,
int
y
,
int
width
,
int
height
,
Window
*
winRet
,
GLXContext
*
ctxRet
,
GLXWindow
*
glxWinRet
)
{
int
attribs
[]
=
{
GLX_DRAWABLE_TYPE
,
GLX_WINDOW_BIT
,
GLX_RENDER_TYPE
,
GLX_RGBA_BIT
,
GLX_DOUBLEBUFFER
,
True
,
/* Request a double-buffered color buffer with */
GLX_RED_SIZE
,
1
,
/* the maximum number of bits per component */
GLX_GREEN_SIZE
,
1
,
GLX_BLUE_SIZE
,
1
,
None
};
int
scrnum
,
nelements
;
XSetWindowAttributes
attr
;
unsigned
long
mask
;
Window
root
;
Window
win
;
GLXContext
ctx
;
XVisualInfo
*
visinfo
;
GLXFBConfig
*
fbc
;
GLXWindow
gwin
;
scrnum
=
DefaultScreen
(
dpy
);
root
=
RootWindow
(
dpy
,
scrnum
);
if
(
fullscreen
)
{
x
=
0
;
y
=
0
;
width
=
DisplayWidth
(
dpy
,
scrnum
);
height
=
DisplayHeight
(
dpy
,
scrnum
);
}
fbc
=
glXChooseFBConfig
(
dpy
,
scrnum
,
attribs
,
&
nelements
);
visinfo
=
glXGetVisualFromFBConfig
(
dpy
,
fbc
[
0
]);
if
(
!
visinfo
)
{
printf
(
"Error: couldn't get an RGB, Double-buffered visual
\n
"
);
piglit_report_result
(
PIGLIT_SKIP
);
}
ctx
=
glXCreateNewContext
(
dpy
,
fbc
[
0
],
GLX_RGBA_TYPE
,
0
,
GL_TRUE
);
/* window attributes */
attr
.
background_pixel
=
0
;
attr
.
border_pixel
=
0
;
attr
.
colormap
=
XCreateColormap
(
dpy
,
root
,
visinfo
->
visual
,
AllocNone
);
attr
.
event_mask
=
StructureNotifyMask
|
ExposureMask
|
KeyPressMask
;
/* XXX this is a bad way to get a borderless window! */
mask
=
CWBackPixel
|
CWBorderPixel
|
CWColormap
|
CWEventMask
;
win
=
XCreateWindow
(
dpy
,
root
,
x
,
y
,
width
,
height
,
0
,
visinfo
->
depth
,
InputOutput
,
visinfo
->
visual
,
mask
,
&
attr
);
XMapWindow
(
dpy
,
win
);
gwin
=
glXCreateWindow
(
dpy
,
fbc
[
0
],
win
,
attribs
);
glXMakeContextCurrent
(
dpy
,
gwin
,
gwin
,
ctx
);
glXSelectEvent
(
dpy
,
gwin
,
GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK
);
if
(
fullscreen
)
no_border
(
dpy
,
win
);
XFree
(
visinfo
);
*
winRet
=
win
;
*
ctxRet
=
ctx
;
*
glxWinRet
=
gwin
;
}
/**
* Only handle one glx event.
*/
void
handle_event
(
Display
*
dpy
,
Window
win
,
XEvent
*
event
)
{
(
void
)
dpy
;
(
void
)
win
;
if
(
Glx_event
==
event
->
type
)
{
XEvent
*
event_p
=
event
;
GLXBufferSwapComplete
*
glx_event
=
(
GLXBufferSwapComplete
*
)
event_p
;
static
double
t_last
=-
1
.
0
;
time_fin
=
current_time
();
if
(
t_last
<
0
)
{
t_last
=
time_fin
;
}
if
(
time_fin
-
t_last
>=
3
.
0
)
{
if
(
verbose
)
{
count
=
event_count_total
%
STACK_L
;
printf
(
"It receives the recent event at %lf seconds, and that\
glXSwapBuffers was called at %lf seconds, its swap returned at %lf seconds, so\
the total time of glXSwapBuffers takes is %lf seconds.
\n
"
,
time_fin
,
swap_start
[
count
],
swap_returned
[
count
],
(
time_fin
-
swap_start
[
count
]));
}
t_last
=
time_fin
;
}
switch
(
glx_event
->
event_type
)
{
case
GLX_EXCHANGE_COMPLETE_INTEL
:
Intel_swap_event
=
GLX_EXCHANGE_COMPLETE_INTEL
;
swap_event_type
=
"GLX_EXCHANGE_COMPLETE_INTEL"
;
event_count
++
;
event_count_total
++
;
break
;
case
GLX_COPY_COMPLETE_INTEL
:
Intel_swap_event
=
GLX_COPY_COMPLETE_INTEL
;
swap_event_type
=
"GLX_COPY_COMPLETE_INTEL"
;
event_count
++
;
event_count_total
++
;
break
;
case
GLX_FLIP_COMPLETE_INTEL
:
Intel_swap_event
=
GLX_FLIP_COMPLETE_INTEL
;
swap_event_type
=
"GLX_FLIP_COMPLETE_INTEL"
;
event_count
++
;
event_count_total
++
;
break
;
}
}
}
static
void
event_loop
(
Display
*
dpy
,
GLXWindow
win
)
{
while
(
1
)
{
while
(
XPending
(
dpy
)
>
0
)
{
XEvent
event
;
XNextEvent
(
dpy
,
&
event
);
Glx_event
=
event_base
+
GLX_BufferSwapComplete
;
handle_event
(
dpy
,
win
,
&
event
);
}
draw_frame
(
dpy
,
win
);
}
}
static
void
usage
(
void
)
{
printf
(
"Usage:
\n
"
);
printf
(
" -fullscreen run in fullscreen mode
\n
"
);
printf
(
" -v verbose mode, have more log
\n
"
);
printf
(
" -auto test automatically
\n
"
);
printf
(
" --event test whether we can get swap events
\n
"
);
printf
(
" --interval we expect that swap interval set to 0 should \
have higher swap frequency than interval to 1
\n
"
);
printf
(
" --async test whether glXSwapBuffers is done asynchronously
\n
"
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
unsigned
int
winWidth
=
30
,
winHeight
=
30
;
int
x
=
0
,
y
=
0
;
Display
*
dpy
;
Window
win
;
GLXWindow
glxWin
;
GLXContext
ctx
;
char
*
dpyName
=
NULL
;
int
i
,
error_base
;
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
strcmp
(
argv
[
i
],
"-auto"
)
==
0
)
{
Automatic
=
GL_TRUE
;
}
else
if
(
strcmp
(
argv
[
i
],
"-v"
)
==
0
)
{
verbose
=
GL_TRUE
;
}
else
if
(
strcmp
(
argv
[
i
],
"-fullscreen"
)
==
0
)
{
fullscreen
=
GL_TRUE
;
}
else
if
(
strcmp
(
argv
[
i
],
"--event"
)
==
0
)
{
test_events
=
GL_TRUE
;
}
else
if
(
strcmp
(
argv
[
i
],
"--async"
)
==
0
)
{
async
=
GL_TRUE
;
}
else
if
(
strcmp
(
argv
[
i
],
"--interval"
)
==
0
)
{
interval_diff
=
GL_TRUE
;
}
else
{
usage
();
piglit_report_result
(
PIGLIT_SKIP
);
}
}
if
(
!
(
interval_diff
||
async
||
test_events
))
{
printf
(
"Which do you want to test, events? asynchronous? or swap interval?
\n
"
);
usage
();
piglit_report_result
(
PIGLIT_SKIP
);
}
dpy
=
XOpenDisplay
(
dpyName
);
if
(
!
dpy
)
{
printf
(
"Error: couldn't open display %s
\n
"
,
dpyName
?
dpyName
:
getenv
(
"DISPLAY"
));
piglit_report_result
(
PIGLIT_FAILURE
);
}
make_window
(
dpy
,
"Swap event test"
,
x
,
y
,
winWidth
,
winHeight
,
&
win
,
&
ctx
,
&
glxWin
);
query_swap_event
(
dpy
);
glXQueryExtension
(
dpy
,
&
error_base
,
&
event_base
);
if
(
interval_diff
)
{
(
*
pglXSwapIntervalMESA
)(
1
);
interval
=
(
*
pglXGetSwapIntervalMESA
)();
if
(
!
interval
==
1
)
{
printf
(
"Failed to set swap interval to 1.
\n
"
);
piglit_report_result
(
PIGLIT_FAILURE
);
}
}
event_loop
(
dpy
,
glxWin
);
glXDestroyContext
(
dpy
,
ctx
);
XDestroyWindow
(
dpy
,
win
);
XCloseDisplay
(
dpy
);
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment