Compare commits

..

104 Commits

Author SHA1 Message Date
Eric Anholt
cc8084932c intel: Flush the batch when we're about to subdata into a VBO.
This fixes the clears in openarena with the new metaops clear code, and
the new piglit vbo-subdata-sync test.

Bug #23857.
2009-09-24 16:24:46 -07:00
Eric Anholt
54107a0979 i965: Clean up some mess with the batch cache.
Its flagging of extra state that's already flagged by the vtbl new_batch
when appropriate was confusing my tracking down of the OA clear bug.
2009-09-24 16:24:46 -07:00
Brian Paul
940ca2e837 Merge branch 'mesa_7_5_branch' into mesa_7_6_branch 2009-09-24 16:01:26 -06:00
Vinson Lee
1730b8db12 softpipe: Increase GL_MAX_3D_TEXTURE_SIZE to 256. 2009-09-24 15:59:57 -06:00
Eric Anholt
726a04a2cd i965: Emit zero initialization for NV VP temporaries as required.
This is similar to what r300 does inside the driver, but I've added it as
a generic option since it seems most hardware will want it.

Fixes piglit nv-init-zero-reg.vpfp and nv-init-zero-addr.vpfp.
2009-09-24 13:34:06 -07:00
Eric Anholt
a9a47afe7e i965: Remove assert about NV_vp now that it somewhat works. 2009-09-24 13:34:06 -07:00
Eric Anholt
9018a7dd17 i965: Load NV program matrices when required. 2009-09-24 13:34:06 -07:00
Eric Anholt
601769a2c0 mesa: Initialize NV_vertex_program fields for the parameter lists and such.
This helps let drivers treat NV_vp like ARB_vp.
2009-09-24 13:34:06 -07:00
Brian Paul
60b152a1b3 mesa: remove glEnable(GL_DEPTH_BOUNDS_TEST_EXT) check/warning
At the time of the enable there may not be a Z buffer, but one
may be attached to the FBO later.
2009-09-24 14:24:14 -06:00
Brian Paul
adfa778c8e mesa: remove rgbMode check in enable_texture()
If the currently bound FBO isn't yet validated it's possible for
rgbMode to be zero so we'll lose the texture enable.
This could fix some FBO rendering glitches, but I don't know of
any specific instances.
2009-09-24 14:19:06 -06:00
Brian Paul
b849c6f1b3 intel: use default array/element buffers in intel_generate_mipmap()
If there happened to be a bound VBO when intel_generate_mipmap() was
called we blew up because of a bad vertex array pointer.

Fixes regnumonline, bug 23859.
2009-09-24 12:41:14 -06:00
Brian Paul
f0339f502c mesa: replace assertion with no-op function assignment 2009-09-24 12:37:34 -06:00
Brian Paul
964792b025 mesa: added comment 2009-09-24 12:37:06 -06:00
Brian Paul
1a81611725 vbo: limit number of warnings to 10
Otherwise some apps will emit tons of warnings.
2009-09-24 12:36:05 -06:00
Pauli Nieminen
1d2dca194c radeon: Fix scissors for r600 KMS.
Radeon generic scissors code had problem that some of code was using exclusive
and some inclusive bottom right corner. Only r600 driver is using exclusive
coordinate so changed generic code to pass inclusive coordinate and r600 driver
changes BR coordinate to be exclusive.
2009-09-24 20:37:55 +03:00
Brian Paul
7549a8397b Merge branch 'mesa_7_5_branch' into mesa_7_6_branch 2009-09-24 10:52:15 -06:00
Brian Paul
a64d4516a0 tgsi/sse: Pass the lodbias, not zero. More comments.
This fixes the glean/glsl1 "texture2D(), with bias" test when using SSE.
2009-09-24 10:28:09 -06:00
Brian Paul
a491e25b1f mesa: added default case return to silence warning 2009-09-24 10:28:09 -06:00
Brian Paul
00ddd4f9e9 glsl: init var to silence warning 2009-09-24 10:28:09 -06:00
Brian Paul
e44c084be5 glsl: fix missing initializers warning 2009-09-24 10:28:09 -06:00
Andre Maasikas
2058dfaa47 r600: add support for CUBE textures, also TXP
seems to work here ...
2009-09-24 10:03:37 -04:00
Alex Deucher
639fb1472d r600: fix typo in the last commit
128 gprs, 256 reg-based consts
2009-09-24 10:03:22 -04:00
Alex Deucher
28308c9260 r600: various cleanups
- max texture size is 8k, but mesa doesn't support
that at the moment.
- attempt to set shader limits to what the hw actually
supports
- clean up some old r300 cruft
- no need to explicitly disable irqs.  This is fixed
in the drm now.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
2009-09-24 10:03:08 -04:00
Andre Maasikas
ed91d10347 r600: fix some issues with LIT instruction
- MUL_LIT is ALU.Trans instruction
- some Trans instructions can take 3 arguments
- don't clobber dst.x, use dst.z as temp, it'll get written correct
  value in last insn
- respect source swizzles
2009-09-24 10:02:37 -04:00
Alex Deucher
48559c7605 r600: fix point sizes
registers takes radius
2009-09-24 10:02:22 -04:00
Alex Deucher
095db818c6 r600: fix polygon offset 2009-09-24 10:02:08 -04:00
Alex Deucher
ec14d59afa radeon: don't build non-r600 span code on r600 2009-09-24 10:01:56 -04:00
Alex Deucher
dbec27be85 r600: minor span cleanups 2009-09-24 10:01:41 -04:00
Andre Maasikas
2cd2dc34ac r600: support position_invariant programs 2009-09-24 10:00:58 -04:00
Alex Deucher
9437ac9bcc r600: add span support for 1D tiles
1D tile span support for depth/stencil/color/textures

Z and stencil buffers are always tiled, so this fixes
sw access to Z and stencil buffers.  color and textures
are currently linear, but this adds span support when we
implement 1D tiling.

This fixes the text in progs/demos/engine and progs/tests/z*
2009-09-24 09:59:45 -04:00
Alex Deucher
93a7ea6ba0 r600: fix warning
Noticed by rnoland on IRC.
2009-09-24 09:59:32 -04:00
Andre Maasikas
7f5a958c80 r600: fix texcoords from constants
with some minor updates from Richard.
2009-09-24 09:59:15 -04:00
Andre Maasikas
9edd1a441c r600: enable caching of vertex programs 2009-09-24 09:59:00 -04:00
Alex Deucher
6552a103f9 r600: check if textures are actually enabled before submission
noticed by taiu on IRC.
2009-09-24 09:58:36 -04:00
Alex Deucher
65b01d449c r600: fix ftp for dri1
We use t->bo for dri1 since r600 uses CS for dri1.
2009-09-24 09:58:17 -04:00
Dave Airlie
b1e417413f r600: don't setup hardware state if TFP
if we have a BO here it means TFP and we should have set it
up already.

tested by b0le on #radeon
2009-09-24 09:57:45 -04:00
Alex Deucher
cbab3d7f2a r600: fix dri2 clipping 2009-09-24 09:56:18 -04:00
Maciej Cencora
84c7afd9e0 r300: fallback to software rendering if we are out of free texcoords
Fixes #22741
2009-09-23 23:22:33 +02:00
Brian Paul
2acd5de226 swrast: add lod bias when texture sampling
Mostly fixes progs/demos/lodbias when MESA_TEX_PROG=1.  But the LOD still
seems off by -1 or so.
May be an issue with the params passed to _swrast_compute_lambda()
2009-09-23 13:36:44 -06:00
Brian Paul
890f37d4d9 mesa: don't bias LOD in shader interpreter; do it in swrast 2009-09-23 13:36:44 -06:00
Brian Paul
ad935c3f47 swrast: fix typo in partial derivatives parameter passing 2009-09-23 13:36:43 -06:00
Keith Whitwell
be66ff51ec st/mesa: trim calculated userbuffer size
In get_array_bounds we were previously defining a user buffer sized as
(nr_vertices * stride).  The trouble is that if the vertex data
occupies less than stride bytes, the extra tailing (stride - size)
bytes may extend outside the memory actually allocated by the app and
caused a segfault.

To fix this, define a the buffer bounds to be:

   ptr .. ptr + (nr-1)*stride + element_size
2009-09-23 18:55:46 +01:00
Brian Paul
e41707beca softpipe: added max texture/surface size sanity check 2009-09-23 10:50:38 -06:00
Brian Paul
84b956c29b softpipe: increase MAX_WIDTH/HEIGTH 4096 to match max texture size 2009-09-23 10:46:27 -06:00
Brian Paul
926b965ed5 mesa: don't re-use the meta glDrawPixels VBO; create a new one each time
This should help to work around bugs 24083 and 23670.
2009-09-22 15:58:49 -06:00
Brian Paul
f338de4018 mesa: fix more buffer object error messages 2009-09-22 13:47:49 -06:00
Brian Paul
ba002eb196 Merge branch 'mesa_7_5_branch' into mesa_7_6_branch
Conflicts:

	src/mesa/main/bufferobj.c
2009-09-22 13:44:43 -06:00
Brian Paul
bc75464760 glx: include string.h to silence missing memset() prototype warning 2009-09-22 13:19:15 -06:00
Brian Paul
52cadf7592 mesa: fix error message text 2009-09-22 13:19:11 -06:00
Nicolai Hähnle
8cc12ffb34 r300: Fix crash reported in bug #24066
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-22 21:00:01 +02:00
Tormod Volden
e857303305 GLX: Warn only once about applications calling GLX 1.3 functions
The warnings introduced in 1f309c40b8
would pour out generously from some applications. This patch adds a
"warn once" wrapper macro, heavily inspired by
src/mesa/drivers/dri/r600/radeon_debug.h

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2009-09-21 15:29:52 -07:00
Brian Paul
6559eaef59 Merge branch 'mesa_7_5_branch' into mesa_7_6_branch 2009-09-21 14:49:46 -06:00
Brian Paul
2655d43756 mesa: refine the error checking vbo_exec_DrawRangeElements()
If the 'end' index is out of bounds issue a warning as before.  But instead
of just no-op'ing the draw call, examine the actual array indices to see
if they're OK.  If the max array index is out of bounds, issue another
warning and no-op the draw call.  Otherwise, draw normally.  This is a
debug build-only feature since it could impact performance.

This "fixes" the missing torus in the OGL Distilled / Picking demo.
2009-09-21 14:25:39 -06:00
Brian Paul
44d260329e mesa: make max_buffer_index() a non-static function 2009-09-21 14:25:39 -06:00
Maciej Cencora
ff5535c521 radeon: update buffer map/unmap code for changes introduced in 92033a9516 and 822c796481 2009-09-21 21:13:01 +02:00
Maciej Cencora
db928a5e91 mesa: add some debug info to teximage.c 2009-09-21 21:12:55 +02:00
Maciej Cencora
ab4ec85f6c r300: fix a typo 2009-09-21 21:12:31 +02:00
Eric Anholt
2b83483fb4 intel: Mark the FBO as incomplete if there's no intel_renderbuffer for it.
This happens to rendering with textures with a border, which had resulted
in a segfault on dereferencing the irb.

(cherry-picked from commit 8bba183b9e)
2009-09-21 10:02:38 -06:00
Brian Paul
5a0b29050f softpipe: Fix cube face selection.
If arx and ary are equal, we still want to choose from one of them,
and not arz.

(cherry picked from commit de685b37a9)
2009-09-21 08:36:05 -06:00
Brian Paul
077e3de989 swrast: fix cube face selection
If arx and ary are equal, we still want to choose from one of them,
and not arz.

This is the same as Michal's softpipe fix.
2009-09-21 08:36:05 -06:00
Nicolai Hähnle
526430ade1 r300: Zero-initialize register for NV_vertex_program
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-21 12:56:16 +02:00
Nicolai Hähnle
736e1ae42f r300: Fix handling of NV_vertex_program parameters
The handling is a bit inefficient, unfortunately, but I don't want to make
any intrusive changes for Mesa 7.6.

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-21 12:56:16 +02:00
Michel Dänzer
1d4dbd8d9b Merge branch 'mesa_7_5_branch' into mesa_7_6_branch 2009-09-21 10:39:20 +02:00
Michel Dänzer
999592745f intel: Fix crash in intel_flush().
Since commit 2921a2555d ('intel: Deassociated
drawables from private context struct in intelUnbindContext'),
intel->driDrawable may be NULL in intel_flush().
2009-09-21 10:28:37 +02:00
Pauli Nieminen
284a7af274 radeon: Fix legacy bo not to reuse dma buffers before refcount is 1.
This should help detecting possible memory leaks with dma buffers and prevent
possible visual corruption if data would be overwriten too early.
2009-09-20 22:28:52 +03:00
Nicolai Hähnle
7e3b8b0d8f r300/compiler: Fix trig instructions in R300 fp
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-20 20:43:32 +02:00
Pauli Nieminen
3640e4acde radeon: Fix typo in variable name. 2009-09-20 21:08:42 +03:00
Pauli Nieminen
5fa9a7a9a9 radeon: Improve WARN_ONCE macro to appear as single statement.
Do-while makes macro safe to be used with if and for constructions.

Also remove __LINE__ macro from variable name because scope is local to macro anyway.
2009-09-20 20:15:52 +03:00
Nicolai Hähnle
94a3c5979f radeon: Fix "verts" debugging enable
Copy'n'paste apparently prevented the RADEON_VERTS flag from being enabled.

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-20 18:45:32 +02:00
Nicolai Hähnle
82c2f7756a Merge branch 'mesa_7_5_branch' into mesa_7_6_branch 2009-09-20 16:59:03 +02:00
Nicolai Hähnle
e617dd14ab mesa/st: Create front renderbuffer on the fly when supplied with a surface
Normally, the mesa/st would create a fake front buffer out of a
client-allocated surface.

In the DRI setting, however, st/dri provides a front buffer surface which is
created and maintained by the X server. Prefer to use this surface instead,
so that front buffer rendering and reading works correctly.

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-20 16:58:53 +02:00
Nicolai Hähnle
c4ce6f6a7c mesa/st: Initialize format bits of framebuffer renderbuffers
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-20 16:54:40 +02:00
Nicolai Hähnle
c8c5de9e9a docs: Document new features in radeon/r200/r300 drivers
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-20 16:47:40 +02:00
Nicolai Hähnle
6c323a2473 r300/compiler: Fix R300 fragment program regression introduced by 0723cd1...
We obviously need to move the code addr register backwards because their may
be overlap.

This bug affected in particular the Compiz water plugin.

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
2009-09-20 16:34:47 +02:00
Zou Nan hai
1e4c353511 [i965] add a missing header file 2009-09-18 16:04:41 +08:00
Zou Nan hai
a66bab0e37 [i965] use intel_batchbuffer_flush to flush the clear 2009-09-18 13:29:28 +08:00
Brian Paul
fac38e8c8f mesa: fix clip plane, fog issues 2009-09-16 21:22:02 -06:00
Ian Romanick
9666529b5a glx: Use initstate_r / random_r instead of corrupting global random number state
Previously srandom and random were used.  This cause the global random
number generator state to be modified.  This caused problems for
applications that called srandom before calling into GLX.  By using
local state the global state is left unmodified.

This should fix bug #23774.
2009-09-16 16:43:50 -07:00
Brian Paul
08d39251a7 st/mesa: fix some incorrect branching/clean-up code in TexImage functions
We need to be sure to call the _mesa_unmap_teximage_pbo() function if we
called _mesa_validate_pbo_teximage().
2009-09-16 13:07:15 -06:00
Brian Paul
cfa1a0a609 st/mesa: fix texture memory allocation bug
The following example caused an incorrect GL_OUT_OF_MEMORY error to be
raised in glTexSubImage2D:

   glTexImage2D(level=0, width=32, height=32, pixels=NULL);
   glTexImage2D(level=0, width=64, height=64, pixels=NULL);
   glTexSubImage2D(level=0, pixels!=NULL);

The second glTexImage2D() call needs to cause the first image to be
deallocated then reallocated at the new size.  This was not happening
because we were testing for pixels==NULL too early.
2009-09-16 12:57:26 -06:00
Ian Romanick
88e3a57605 Merge branch 'mesa_7_5_branch' into mesa_7_6_branch
Conflicts:
	src/mesa/main/dlist.c
2009-09-16 07:57:19 -07:00
Ian Romanick
2921a2555d intel: Deassociated drawables from private context struct in intelUnbindContext
The generic DRI infrastructure makes sure that __DRIcontextRec::driDrawablePriv
and __DRIcontextRec::driReadablePriv are set to NULL after unbinding a
context.  However, the intel_context structure keeps cached copies of
these pointers.  If these cached pointers are not NULLed and the
drawable is actually destroyed after unbinding the context (typically
by way of glXDestroyWindow), freed memory will be dereferenced in
intelDestroyContext.

This should fix bug #23418.
2009-09-16 07:39:58 -07:00
Zou Nan hai
76e836a41a i965: do a flush in clear, fix openarena render issue,
fd.o bug# 23857
2009-09-16 13:25:46 +08:00
Brian Paul
d9ddbc3f47 docs: glUniform functions are now compiled into display lists 2009-09-15 15:12:29 -06:00
Brian Paul
41fff1b9a1 mesa: compile glUniformMatrix() functions into display lists
I believe this is the last of the shader-related functions that needed
display list treatment.
2009-09-15 15:10:29 -06:00
Brian Paul
6681981fe1 mesa: implement more glUniform display list functions 2009-09-15 14:56:55 -06:00
Brian Paul
3ad108b77f docs: document glUseProgram display list fix 2009-09-15 14:38:52 -06:00
Brian Paul
f42c66c138 mesa: compile glUniform4f() into display lists
Note: there are more glUniform functions to compile...
2009-09-15 14:37:45 -06:00
Brian Paul
81de9d68f7 mesa: compile glUseProgram/glUseProgramObjectARB into display lists
Fixes bug 23746
2009-09-15 14:37:45 -06:00
Ian Romanick
6c6fe0a704 Merge commit 'origin/mesa_7_5_branch' into mesa_7_6_branch 2009-09-15 13:13:35 -07:00
Ian Romanick
1f309c40b8 GLX: Complain when buggy applications call GLX 1.3 functions. 2009-09-15 13:12:22 -07:00
Brian Paul
5d526ed21a Merge branch 'mesa_7_5_branch' into mesa_7_6_branch 2009-09-15 09:45:18 -06:00
Brian Paul
2b992dc327 gl: restore some PFNGL typedefs
Commit d33c315d9e removed a few too many
typedefs.  We need the typedefs in glext.h which are protected by #ifdef
GL_VERSION_1_2 but we can exclude the ones protected by
GL_VERSION_1_2_DEPRECATED.
2009-09-15 09:36:31 -06:00
Brian Paul
799631acb1 progs/vp: print program and error info when program does not compile 2009-09-14 17:48:17 -06:00
Brian Paul
ac3c8e3b53 glsl: added some link debug code (disabled) 2009-09-14 17:32:03 -06:00
Brian Paul
3129b2403e docs: document linker/preprocessor bug fix 2009-09-14 17:27:47 -06:00
Brian Paul
b8b774c775 glsl: remove extra #version directives from concatenated shader sources
When we concatenate shaders to do our form of poor-man linking, if there's
multiple #version directives, preprocessing fails.  This change disables
the extra #version directives by changing the first two chars to //.

This should help with some Wine issues such as bug 23946.
2009-09-14 17:24:25 -06:00
Vinson Lee
2729db8976 gallium: Add Mac OS to pipe/p_thread.h.
Mac OS also has POSIX threads.
2009-09-14 11:50:48 -06:00
Thierry Vignaud
1402ea8f39 configure: fix comment 2009-09-14 11:48:51 -06:00
Dan Nicholson
9c8b69302c Use CFLAGS as HOST_CFLAGS by default
Unless we're cross compiling, the HOST_CFLAGS should be the same as the
normal CFLAGS. This allows the x86 and x86_64 asm to be built correctly
with a native compiler using -m32/-m64.

Signed-off-by: Dan Nicholson <dbn.lists@gmail.com>
2009-09-12 09:35:43 -07:00
Brian Paul
280933f793 docs: mention the new Gallium llvmpipe driver 2009-09-11 13:43:51 -06:00
Brian Paul
d81086a86b llvmpipe: asst fixes for 'make linux-llvmpipe' 2009-09-11 13:39:14 -06:00
Vinson Lee
0fa1692f14 mesa: raise GL_INVALID_ENUM not GL_INVALID_VALUE for glTexParamter errors
Signed-off-by: Brian Paul <brianp@vmware.com>
2009-09-11 08:04:37 -06:00
Pauli Nieminen
796c96de80 radeon: Remove structure allocation from iterator variable.
dma_bo varaible is only used for iterating so allocating memory for it only
causes memory leaks.
2009-09-11 01:29:07 +03:00
414 changed files with 9302 additions and 56386 deletions

View File

@@ -1 +0,0 @@
include $(call all-subdir-makefiles)

View File

@@ -105,8 +105,6 @@ irix6-n32-static \
irix6-o32 \
irix6-o32-static \
linux \
mine \
mine-dri \
linux-alpha \
linux-alpha-static \
linux-cell \
@@ -184,7 +182,7 @@ ultrix-gcc:
# Rules for making release tarballs
VERSION=7.7-devel
VERSION=7.6-devel
DIRECTORY = Mesa-$(VERSION)
LIB_NAME = MesaLib-$(VERSION)
DEMO_NAME = MesaDemos-$(VERSION)
@@ -305,25 +303,10 @@ MAIN_FILES = \
$(DIRECTORY)/progs/util/sampleMakefile \
$(DIRECTORY)/windows/VC8/
ES_FILES = \
$(DIRECTORY)/include/GLES/*.h \
$(DIRECTORY)/include/GLES2/*.h \
$(DIRECTORY)/src/mesa/glapi/*.xml \
$(DIRECTORY)/src/mesa/glapi/*.py \
$(DIRECTORY)/src/mesa/glapi/*.dtd \
$(DIRECTORY)/src/mesa/es/glapi/Makefile \
$(DIRECTORY)/src/mesa/es/glapi/*.xml \
$(DIRECTORY)/src/mesa/es/glapi/*.py \
$(DIRECTORY)/src/mesa/es/state_tracker/*.[ch] \
$(DIRECTORY)/src/mesa/es/main/*.[ch] \
$(DIRECTORY)/src/mesa/es/main/*.py \
$(DIRECTORY)/src/mesa/es/main/*.txt \
$(DIRECTORY)/src/mesa/es/main/es*_special \
$(DIRECTORY)/src/mesa/es/Makefile \
$(DIRECTORY)/src/mesa/es/sources.mak \
EGL_FILES = \
$(DIRECTORY)/include/EGL/*.h \
$(DIRECTORY)/include/GLES/*.h \
$(DIRECTORY)/include/GLES2/*.h \
$(DIRECTORY)/src/egl/Makefile \
$(DIRECTORY)/src/egl/*/Makefile \
$(DIRECTORY)/src/egl/*/*.[ch] \
@@ -488,7 +471,6 @@ DEPEND_FILES = \
LIB_FILES = \
$(MAIN_FILES) \
$(ES_FILES) \
$(EGL_FILES) \
$(GALLIUM_FILES) \
$(DRI_FILES) \

View File

@@ -59,7 +59,7 @@ def AddOptions(opts):
opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine,
allowed_values=('generic', 'ppc', 'x86', 'x86_64')))
opts.Add(EnumOption('platform', 'target platform', default_platform,
allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin')))
allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince')))
opts.Add(EnumOption('toolchain', 'compiler toolchain', 'default',
allowed_values=('default', 'crossmingw', 'winsdk', 'winddk')))
opts.Add(BoolOption('llvm', 'use LLVM', 'no'))

View File

@@ -9,7 +9,7 @@ CONFIG_NAME = default
# Version info
MESA_MAJOR=7
MESA_MINOR=7
MESA_MINOR=6
MESA_TINY=0
MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY)
@@ -23,6 +23,7 @@ HOST_CC = $(CC)
CFLAGS = -O
CXXFLAGS = -O
LDFLAGS =
HOST_CFLAGS = $(CFLAGS)
GLU_CFLAGS =
# Compiler for building demos/tests/etc

View File

@@ -1,82 +0,0 @@
# -*-makefile-*-
# Configuration for linux-dri: Linux DRI hardware drivers for XFree86 & others
include $(TOP)/configs/default
CONFIG_NAME = mine
# Compiler and flags
CC = ccache gcc
CXX = ccache g++
#MKDEP = /usr/X11R6/bin/makedepend
#MKDEP = gcc -M
#MKDEP_OPTIONS = -MF depend
OPT_FLAGS = -O0 -g
PIC_FLAGS = -fPIC
# Add '-DGLX_USE_TLS' to ARCH_FLAGS to enable TLS support.
ARCH_FLAGS ?=
DEFINES = -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE \
-D_BSD_SOURCE -D_GNU_SOURCE \
-DPTHREADS -DUSE_EXTERNAL_DXTN_LIB=1 \
-DGLX_DIRECT_RENDERING \
-DHAVE_ALIAS -DHAVE_POSIX_MEMALIGN
X11_INCLUDES = -I/usr/X11R6/include
CFLAGS = -Wall -Wmissing-prototypes -std=c99 -ffast-math \
$(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) $(ASM_FLAGS)
CXXFLAGS = -Wall $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES)
GLUT_CFLAGS = -fexceptions
# Work around aliasing bugs - developers should comment this out
CFLAGS += -fno-strict-aliasing
CXXFLAGS += -fno-strict-aliasing
MESA_ASM_SOURCES =
# Library/program dependencies
EXTRA_LIB_PATH=-L/usr/X11R6/lib
DRI_LIB_DEPS = $(EXTRA_LIB_PATH) -lm -lpthread -lexpat -ldl $(LIBDRM_LIB)
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
-lm -lpthread -ldl $(LIBDRM_LIB)
# Directories
SRC_DIRS = egl mesa gallium gallium/winsys
PROGRAM_DIRS := egl openvg/demos demos xdemos
# EGL directories
EGL_DRIVERS_DIRS = glx xdri
ifeq ($(USE_DRI),yes)
DEFINES += -DIN_DRI_DRIVER -DGLX_INDIRECT_RENDERING
LIBDRM_CFLAGS = $(shell pkg-config --cflags libdrm)
LIBDRM_LIB = $(shell pkg-config --libs libdrm)
SRC_DIRS := glx/x11 $(SRC_DIRS)
DRIVER_DIRS = dri
WINDOW_SYSTEM = dri
DRI_DIRS = i915
GALLIUM_WINSYS_DIRS = drm egl_xlib
GALLIUM_WINSYS_DRM_DIRS = intel
GALLIUM_STATE_TRACKERS_DIRS = egl glx vega
else
DRIVER_DIRS =
WINDOW_SYSTEM =
DRI_DIRS =
GALLIUM_WINSYS_DIRS = egl_xlib xlib
GALLIUM_STATE_TRACKERS_DIRS = glx vega
endif

View File

@@ -1,5 +0,0 @@
# -*-makefile-*-
# Configuration for linux-dri: Linux DRI hardware drivers for XFree86 & others
USE_DRI = yes
include $(TOP)/configs/mine

View File

@@ -1202,7 +1202,7 @@ if test "x$enable_gallium_radeon" = xyes; then
fi
dnl
dnl Gallium Radeon configuration
dnl Gallium Nouveau configuration
dnl
AC_ARG_ENABLE([gallium-nouveau],
[AS_HELP_STRING([--enable-gallium-nouveau],

View File

@@ -45,6 +45,10 @@ tbd
<ul>
<li>Assorted bug fixes for i965/i945 drivers
<li>Fixed Gallium glDrawPixels(GL_STENCIL_INDEX) failure.
<li>Fixed GLSL linker/preprocessor version directive issue seen in Wine
(such as bug 23946)
<li>glUseProgram() is now compiled into display lists (bug 23746).
<li>glUniform functions are now compiled into display lists
</ul>

View File

@@ -50,6 +50,8 @@ This was written by Zack Rusin at Tungsten Graphics.
<li>Rewritten radeon/r200/r300 driver using a buffer manager
<li>radeon/r200/r300 GL_EXT_framebuffer_object support when used with
kernel memory manager
<li>radeon/r200/r300 support for GL_ARB_occlusion_query</li>
<li>r300 driver supports OpenGL 1.5</li>
<li>r300 driver support for GL_EXT_vertex_array_bgra, GL_EXT_texture_sRGB
<li>i915/945 driver support for GL_ARB_point_sprite, GL_EXT_stencil_two_side
and GL_ATI_separate_stencil extensions
@@ -57,6 +59,10 @@ This was written by Zack Rusin at Tungsten Graphics.
GL_ARB_fragment_program.</li>
<li>Added configure --with-max-width=W, --with-max-height=H options to specify
max framebuffer, viewport size.
<li>Initial version of Gallium llvmpipe driver. This is a new driver based
on LLVM which makes exensive use of run-time code generation. This is
an "alpha" stage driver. See the src/gallium/drivers/llvmpipe/README
file for more information.
</ul>

View File

@@ -1,53 +0,0 @@
<HTML>
<TITLE>Mesa Release Notes</TITLE>
<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
<BODY>
<body bgcolor="#eeeeee">
<H1>Mesa 7.7 Release Notes / date TBD</H1>
<p>
Mesa 7.7 is a new development release.
People who are concerned with stability and reliability should stick
with a previous release or wait for Mesa 7.7.1.
</p>
<p>
Mesa 7.7 implements the OpenGL 2.1 API, but the version reported by
glGetString(GL_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 2.1.
</p>
<p>
See the <a href="install.html">Compiling/Installing page</a> for prerequisites
for DRI hardware acceleration.
</p>
<h2>MD5 checksums</h2>
<pre>
tbd
</pre>
<h2>New features</h2>
<ul>
<li>GL_ARB_draw_elements_base_vertex (supported in Intel i965 and software drivers)</li>
<li>GL_ARB_depth_clamp (supported in Intel i965 DRI and software drivers)</li>
<li>GL_NV_depth_clamp (supported in Intel i965 DRI and software drivers)</li>
</ul>
<h2>Bug fixes</h2>
<ul>
</ul>
<h2>Changes</h2>
<ul>
</ul>
</body>
</html>

View File

@@ -13,7 +13,6 @@ The release notes summarize what's new or changed in each Mesa release.
</p>
<UL>
<LI><A HREF="relnotes-7.7.html">7.7 release notes</A>
<LI><A HREF="relnotes-7.6.html">7.6 release notes</A>
<LI><A HREF="relnotes-7.5.2.html">7.5.2 release notes</A>
<LI><A HREF="relnotes-7.5.1.html">7.5.1 release notes</A>

View File

@@ -6,7 +6,7 @@ extern "C" {
#endif
/*
** Copyright (c) 2007-2009 The Khronos Group Inc.
** Copyright (c) 2007 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
@@ -33,9 +33,9 @@ extern "C" {
/*************************************************************/
/* Header file version number */
/* eglext.h last updated 2007/11/20 */
/* Current version at http://www.khronos.org/registry/egl/ */
/* $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $ */
#define EGL_EGLEXT_VERSION 3
#define EGL_EGLEXT_VERSION 1
#ifndef EGL_KHR_config_attribs
#define EGL_KHR_config_attribs 1
@@ -79,12 +79,12 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display
#define EGL_KHR_image 1
#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */
typedef void *EGLImageKHR;
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
extern const EGLImageKHR EGL_NO_IMAGE_KHR;
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, EGLint *attr_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, EGLint *attr_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
#endif
@@ -179,17 +179,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLCont
#endif /* EGL_MESA_copy_context */
#ifndef EGL_KHR_image_base
#define EGL_KHR_image_base 1
/* Most interfaces defined by EGL_KHR_image_pixmap above */
#define EGL_IMAGE_PRESERVED_KHR 0x30D2 /* eglCreateImageKHR attribute */
#endif
#ifndef EGL_KHR_image_pixmap
#define EGL_KHR_image_pixmap 1
/* Interfaces defined by EGL_KHR_image above */
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -1,27 +0,0 @@
#ifndef EGLIMAGE_DRI_INCLUDED
#define EGLIMAGE_DRI_INCLUDED
#include "GL/internal/dri_interface.h"
#define __DRI_EGL_IMAGE_MAGIC \
(('D' << 24) | \
('R' << 16) | \
('I' << 8) | \
('0'))
typedef void *__DRIEGLImageHandle;
typedef struct __DRIEGLImageRec __DRIEGLImage;
struct __DRIEGLImageRec {
GLint magic;
__DRIdrawable *drawable;
GLboolean texture_format_rgba;
GLint level;
GLint __pad[4];
};
extern __DRIEGLImage *_eglClientGetImageData(__DRIEGLImageHandle handle);
#endif /* EGLIMAGE_DRI_INCLUDED */

View File

@@ -1740,6 +1740,9 @@ GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target,
GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format,
GLenum type, GLvoid *row, GLvoid *column, GLvoid *span );
typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
/*
@@ -1945,6 +1948,18 @@ GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] );
GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert );
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
/*
* GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1)
*/

View File

@@ -708,19 +708,6 @@ struct __DRIdri2LoaderExtensionRec {
int *out_count, void *loaderPrivate);
};
#define __DRI_COPY_BUFFER "DRI_CopyBuffer"
#define __DRI_COPY_BUFFER_VERSION 1
typedef struct __DRIcopyBufferExtensionRec __DRIcopyBufferExtension;
struct __DRIcopyBufferExtensionRec {
__DRIextension base;
int (*copyBuffer)(__DRIcontext *context,
__DRIbuffer *dst, int dst_x, int dst_y,
__DRIdrawable *src, unsigned int src_attachment,
int x, int y, int width, int height);
};
/**
* This extension provides alternative screen, drawable and context
* constructors for DRI2.

View File

@@ -26,7 +26,6 @@ static int Scissor = 0;
static float Xzoom, Yzoom;
static GLboolean DrawFront = GL_FALSE;
static GLboolean Dither = GL_TRUE;
static GLboolean Invert = GL_FALSE;
static void Reset( void )
@@ -60,15 +59,6 @@ static void Display( void )
if (Scissor)
glEnable(GL_SCISSOR_TEST);
if (Invert) {
glPixelTransferf(GL_RED_SCALE, -1.0);
glPixelTransferf(GL_GREEN_SCALE, -1.0);
glPixelTransferf(GL_BLUE_SCALE, -1.0);
glPixelTransferf(GL_RED_BIAS, 1.0);
glPixelTransferf(GL_GREEN_BIAS, 1.0);
glPixelTransferf(GL_BLUE_BIAS, 1.0);
}
/* draw copy */
glPixelZoom(Xzoom, Yzoom);
glWindowPos2iARB(Xpos, Ypos);
@@ -77,15 +67,6 @@ static void Display( void )
glDisable(GL_SCISSOR_TEST);
if (Invert) {
glPixelTransferf(GL_RED_SCALE, 1.0);
glPixelTransferf(GL_GREEN_SCALE, 1.0);
glPixelTransferf(GL_BLUE_SCALE, 1.0);
glPixelTransferf(GL_RED_BIAS, 0.0);
glPixelTransferf(GL_GREEN_BIAS, 0.0);
glPixelTransferf(GL_BLUE_BIAS, 0.0);
}
if (DrawFront)
glFinish();
else
@@ -124,9 +105,6 @@ static void Key( unsigned char key, int x, int y )
else
glDisable(GL_DITHER);
break;
case 'i':
Invert = !Invert;
break;
case 's':
Scissor = !Scissor;
break;

View File

@@ -1,77 +0,0 @@
# progs/es1/xegl/Makefile
TOP = ../../..
include $(TOP)/configs/current
INCLUDE_DIRS = \
-I$(TOP)/include \
HEADERS = $(TOP)/include/GLES/egl.h
ES1_LIB_DEPS = \
$(TOP)/$(LIB_DIR)/libEGL.so \
$(TOP)/$(LIB_DIR)/libGLESv1_CM.so
ES1_LIBS = \
-L$(TOP)/$(LIB_DIR) -lEGL \
-L$(TOP)/$(LIB_DIR) -lGLESv1_CM $(LIBDRM_LIB) -lX11
PROGRAMS = \
drawtex \
es1_info \
msaa \
pbuffer \
render_tex \
torus \
tri \
two_win
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: $(PROGRAMS)
drawtex: drawtex.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) drawtex.o $(ES1_LIBS) -o $@
es1_info: es1_info.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) es1_info.o $(ES1_LIBS) -o $@
msaa: msaa.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) msaa.o $(ES1_LIBS) -o $@
pbuffer: pbuffer.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) pbuffer.o $(ES1_LIBS) -o $@
render_tex: render_tex.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) render_tex.o $(ES1_LIBS) -o $@
torus: torus.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) torus.o $(ES1_LIBS) -o $@
two_win: two_win.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) two_win.o $(ES1_LIBS) -o $@
tri: tri.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) tri.o $(ES1_LIBS) -o $@
clean:
rm -f *.o *~
rm -f $(PROGRAMS)

View File

@@ -1,427 +0,0 @@
/*
* Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved.
*/
/*
* Test GL_OES_draw_texture
* Brian Paul
* August 2008
*/
#define GL_GLEXT_PROTOTYPES
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
static GLfloat view_posx = 10.0, view_posy = 20.0;
static GLfloat width = 200, height = 200;
static void
draw(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawTexfOES(view_posx, view_posy, 0.0, width, height);
}
/* new window size or exposure */
static void
reshape(int width, int height)
{
GLfloat ar = (GLfloat) width / (GLfloat) height;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef GL_VERSION_ES_CM_1_0
glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
#else
glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
#endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -15.0);
}
static float
dist(GLuint i, GLuint j, float x, float y)
{
return sqrt((i-x) * (i-x) + (j-y) * (j-y));
}
static void
make_smile_texture(void)
{
#define SZ 128
GLenum Filter = GL_LINEAR;
GLubyte image[SZ][SZ][4];
GLuint i, j;
GLint cropRect[4];
for (i = 0; i < SZ; i++) {
for (j = 0; j < SZ; j++) {
GLfloat d_mouth = dist(i, j, SZ/2, SZ/2);
GLfloat d_rt_eye = dist(i, j, SZ*3/4, SZ*3/4);
GLfloat d_lt_eye = dist(i, j, SZ*3/4, SZ*1/4);
if (d_rt_eye < SZ / 8 || d_lt_eye < SZ / 8) {
image[i][j][0] = 20;
image[i][j][1] = 50;
image[i][j][2] = 255;
image[i][j][3] = 255;
}
else if (i < SZ/2 && d_mouth < SZ/3) {
image[i][j][0] = 255;
image[i][j][1] = 20;
image[i][j][2] = 20;
image[i][j][3] = 255;
}
else {
image[i][j][0] = 200;
image[i][j][1] = 200;
image[i][j][2] = 200;
image[i][j][3] = 255;
}
}
}
glActiveTexture(GL_TEXTURE0); /* unit 0 */
glBindTexture(GL_TEXTURE_2D, 42);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
cropRect[0] = 0;
cropRect[1] = 0;
cropRect[2] = SZ;
cropRect[3] = SZ;
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
#undef SZ
}
static void
init(void)
{
const char *ext = (char *) glGetString(GL_EXTENSIONS);
if (!strstr(ext, "GL_OES_draw_texture")) {
fprintf(stderr, "Sorry, this program requires GL_OES_draw_texture");
exit(1);
}
glClearColor(0.4, 0.4, 0.4, 0.0);
make_smile_texture();
glEnable(GL_TEXTURE_2D);
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, 0, 0, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
eglBindAPI(EGL_OPENGL_ES_API);
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
XFree(visInfo);
*winRet = win;
*ctxRet = ctx;
}
static void
event_loop(Display *dpy, Window win,
EGLDisplay egl_dpy, EGLSurface egl_surf)
{
int anim = 0;
while (1) {
int redraw = 0;
if (!anim || XPending(dpy)) {
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw = 1;
break;
case ConfigureNotify:
reshape(event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
view_posx -= 1.0;
}
else if (code == XK_Right) {
view_posx += 1.0;
}
else if (code == XK_Up) {
view_posy += 1.0;
}
else if (code == XK_Down) {
view_posy -= 1.0;
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == ' ') {
anim = !anim;
}
else if (buffer[0] == 'w') {
width -= 1.0f;
}
else if (buffer[0] == 'W') {
width += 1.0f;
}
else if (buffer[0] == 'h') {
height -= 1.0f;
}
else if (buffer[0] == 'H') {
height += 1.0f;
}
else if (buffer[0] == 27) {
/* escape */
return;
}
}
}
redraw = 1;
break;
default:
; /*no-op*/
}
}
if (anim) {
view_posx += 1.0;
view_posy += 2.0;
redraw = 1;
}
if (redraw) {
draw();
eglSwapBuffers(egl_dpy, egl_surf);
}
}
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
printf(" -info display OpenGL renderer info\n");
}
int
main(int argc, char *argv[])
{
const int winWidth = 400, winHeight = 300;
Display *x_dpy;
Window win;
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
EGLint egl_major, egl_minor;
int i;
const char *s;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
make_x_window(x_dpy, egl_dpy,
"drawtex", 0, 0, winWidth, winHeight,
&win, &egl_ctx, &egl_surf);
XMapWindow(x_dpy, win);
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
if (printInfo) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
init();
/* Set initial projection/viewing transformation.
* We can't be sure we'll get a ConfigureNotify event when the window
* first appears.
*/
reshape(winWidth, winHeight);
event_loop(x_dpy, win, egl_dpy, egl_surf);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -1,274 +0,0 @@
/*
* Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved.
*/
/*
* List OpenGL ES extensions.
* Print ES 1 or ES 2 extensions depending on which library we're
* linked with: libGLESv1_CM.so vs libGLESv2.so
*/
#define GL_GLEXT_PROTOTYPES
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
/*
* Print a list of extensions, with word-wrapping.
*/
static void
print_extension_list(const char *ext)
{
const char *indentString = " ";
const int indent = 4;
const int max = 79;
int width, i, j;
if (!ext || !ext[0])
return;
width = indent;
printf(indentString);
i = j = 0;
while (1) {
if (ext[j] == ' ' || ext[j] == 0) {
/* found end of an extension name */
const int len = j - i;
if (width + len > max) {
/* start a new line */
printf("\n");
width = indent;
printf(indentString);
}
/* print the extension name between ext[i] and ext[j] */
while (i < j) {
printf("%c", ext[i]);
i++;
}
/* either we're all done, or we'll continue with next extension */
width += len + 1;
if (ext[j] == 0) {
break;
}
else {
i++;
j++;
if (ext[j] == 0)
break;
printf(", ");
width += 2;
}
}
j++;
}
printf("\n");
}
static void
info(EGLDisplay egl_dpy)
{
const char *s;
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_EXTENSIONS:\n");
print_extension_list((char *) glGetString(GL_EXTENSIONS));
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, 0, 0, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
eglBindAPI(EGL_OPENGL_ES_API);
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
XFree(visInfo);
*winRet = win;
*ctxRet = ctx;
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
}
int
main(int argc, char *argv[])
{
const int winWidth = 400, winHeight = 300;
Display *x_dpy;
Window win;
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
EGLint egl_major, egl_minor;
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
make_x_window(x_dpy, egl_dpy,
"ES info", 0, 0, winWidth, winHeight,
&win, &egl_ctx, &egl_surf);
/*XMapWindow(x_dpy, win);*/
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
info(egl_dpy);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -1,442 +0,0 @@
/*
* Copyright (C) 2008 Brian Paul All Rights Reserved.
*
* 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 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
* BRIAN PAUL 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.
*/
/*
* Test MSAA with X/EGL and OpenGL ES 1.x
* Brian Paul
* 15 September 2008
*/
#define USE_FULL_GL 0
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#if USE_FULL_GL
#include <GL/gl.h> /* use full OpenGL */
#else
#include <GLES/gl.h> /* use OpenGL ES 1.x */
#include <GLES/glext.h>
#endif
#include <EGL/egl.h>
static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
static GLboolean AA = 0*GL_TRUE;
static void
draw(void)
{
float a;
static const GLfloat verts[4][2] = {
{ -1, -.1 },
{ 1, -.1 },
{ -1, .1 },
{ 1, .1 }
};
static const GLfloat colors[4][4] = {
{ 1, 0, 0, 1 },
{ 0, 1, 0, 1 },
{ 0, 0, 1, 1 },
{ 1, 0, 1, 1 }
};
if (AA) {
printf("MSAA enabled\n");
glEnable(GL_MULTISAMPLE);
}
else {
printf("MSAA disabled\n");
glDisable(GL_MULTISAMPLE);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(view_rotx, 1, 0, 0);
glRotatef(view_roty, 0, 1, 0);
glRotatef(view_rotz, 0, 0, 1);
{
glVertexPointer(2, GL_FLOAT, 0, verts);
glColorPointer(4, GL_FLOAT, 0, colors);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
for (a = 0; a < 360; a += 20.0) {
glPushMatrix();
glRotatef(a, 0, 0, 1);
glTranslatef(1.5, 0, 0);
/* draw triangle */
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glPopMatrix();
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
glPopMatrix();
}
/* new window size or exposure */
static void
reshape(int width, int height)
{
GLfloat ary = 3.0;
GLfloat arx = ary * (GLfloat) width / (GLfloat) height;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef GL_VERSION_ES_CM_1_0
glOrthof(-arx, arx, -ary, ary, -1.0, 1.0);
#else
glOrtho(-arx, arx, -ary, ary, -1.0, 1.0);
#endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void
init(void)
{
printf("Press 'a' to toggle multisample antialiasing\n");
printf("Press 'Esc' to exit\n");
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_SAMPLES, 1,
EGL_SAMPLE_BUFFERS, 1,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
if (num_configs < 1) {
printf("Error: Unable to find multisample pixel format.\n");
printf("Try running glxinfo to see if your server supports MSAA.\n");
exit(1);
}
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, 0, 0, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
#if USE_FULL_GL
eglBindAPI(EGL_OPENGL_API);
#else
eglBindAPI(EGL_OPENGL_ES_API);
#endif
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
XFree(visInfo);
*winRet = win;
*ctxRet = ctx;
}
static void
event_loop(Display *dpy, Window win,
EGLDisplay egl_dpy, EGLSurface egl_surf)
{
while (1) {
int redraw = 0;
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw = 1;
break;
case ConfigureNotify:
reshape(event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
view_roty += 5.0;
}
else if (code == XK_Right) {
view_roty -= 5.0;
}
else if (code == XK_Up) {
view_rotx += 5.0;
}
else if (code == XK_Down) {
view_rotx -= 5.0;
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == 'a') {
AA = !AA;
redraw = 1;
}
else if (buffer[0] == 27) {
/* escape */
return;
}
}
}
redraw = 1;
break;
default:
; /*no-op*/
}
if (redraw) {
draw();
eglSwapBuffers(egl_dpy, egl_surf);
}
}
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
printf(" -info display OpenGL renderer info\n");
}
int
main(int argc, char *argv[])
{
const int winWidth = 600, winHeight = 600;
Display *x_dpy;
Window win;
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
EGLint egl_major, egl_minor;
int i;
const char *s;
static struct {
char *name;
GLenum value;
enum {GetString, GetInteger} type;
} info_items[] = {
{"GL_RENDERER", GL_RENDERER, GetString},
{"GL_VERSION", GL_VERSION, GetString},
{"GL_VENDOR", GL_VENDOR, GetString},
{"GL_EXTENSIONS", GL_EXTENSIONS, GetString},
{"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger},
{"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger},
};
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
make_x_window(x_dpy, egl_dpy,
"msaa", 0, 0, winWidth, winHeight,
&win, &egl_ctx, &egl_surf);
XMapWindow(x_dpy, win);
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
if (printInfo) {
for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) {
switch (info_items[i].type) {
case GetString:
printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value));
break;
case GetInteger: {
GLint rv = -1;
glGetIntegerv(info_items[i].value, &rv);
printf("%s = %d\n", info_items[i].name, rv);
break;
}
}
}
};
init();
/* Set initial projection/viewing transformation.
* We can't be sure we'll get a ConfigureNotify event when the window
* first appears.
*/
reshape(winWidth, winHeight);
event_loop(x_dpy, win, egl_dpy, egl_surf);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -1,607 +0,0 @@
/*
* Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved.
*/
/*
* Test EGL Pbuffers
* Brian Paul
* August 2008
*/
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
static int WinWidth = 300, WinHeight = 300;
static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
static void
Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz)
{
n[0] = nx;
n[1] = ny;
n[2] = nz;
}
static void
Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz)
{
v[0] = vx;
v[1] = vy;
v[2] = vz;
}
static void
Texcoord(GLfloat *v, GLfloat s, GLfloat t)
{
v[0] = s;
v[1] = t;
}
/* Borrowed from glut, adapted */
static void
draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
GLfloat varray[100][3], narray[100][3], tarray[100][2];
int vcount;
glVertexPointer(3, GL_FLOAT, 0, varray);
glNormalPointer(GL_FLOAT, 0, narray);
glTexCoordPointer(2, GL_FLOAT, 0, tarray);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
vcount = 0; /* glBegin(GL_QUAD_STRIP); */
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat s0, s1, t;
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
s0 = 20.0 * theta / (2.0 * M_PI);
s1 = 20.0 * theta1 / (2.0 * M_PI);
t = 8.0 * phi / (2.0 * M_PI);
Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
Texcoord(tarray[vcount], s1, t);
Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
vcount++;
Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
Texcoord(tarray[vcount], s0, t);
Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi);
vcount++;
}
/*glEnd();*/
assert(vcount <= 100);
glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount);
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
static void
draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(view_rotx, 1, 0, 0);
glRotatef(view_roty, 0, 1, 0);
glRotatef(view_rotz, 0, 0, 1);
glScalef(0.5, 0.5, 0.5);
draw_torus(1.0, 3.0, 30, 60);
glPopMatrix();
glFinish();
}
/**
* Draw to both the window and pbuffer and compare results.
*/
static void
draw_both(EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf,
EGLContext egl_ctx)
{
unsigned *wbuf, *pbuf;
int x = 100, y = 110;
int i, dif;
wbuf = (unsigned *) malloc(WinWidth * WinHeight * 4);
pbuf = (unsigned *) malloc(WinWidth * WinHeight * 4);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
/* first draw to window */
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent(window) failed\n");
return;
}
draw();
glReadPixels(0, 0, WinWidth, WinHeight, GL_RGBA, GL_UNSIGNED_BYTE, wbuf);
printf("Window[%d,%d] = 0x%08x\n", x, y, wbuf[y*WinWidth+x]);
/* then draw to pbuffer */
if (!eglMakeCurrent(egl_dpy, egl_pbuf, egl_pbuf, egl_ctx)) {
printf("Error: eglMakeCurrent(pbuffer) failed\n");
return;
}
draw();
glReadPixels(0, 0, WinWidth, WinHeight, GL_RGBA, GL_UNSIGNED_BYTE, pbuf);
printf("Pbuffer[%d,%d] = 0x%08x\n", x, y, pbuf[y*WinWidth+x]);
eglSwapBuffers(egl_dpy, egl_surf);
/* compare renderings */
for (dif = i = 0; i < WinWidth * WinHeight; i++) {
if (wbuf[i] != pbuf[i]) {
dif = 1;
break;
}
}
if (dif)
printf("Difference at %d: 0x%08x vs. 0x%08x\n", i, wbuf[i], pbuf[i]);
else
printf("Window rendering matches Pbuffer rendering!\n");
free(wbuf);
free(pbuf);
}
/* new window size or exposure */
static void
reshape(int width, int height)
{
GLfloat ar = (GLfloat) width / (GLfloat) height;
WinWidth = width;
WinHeight = height;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef GL_VERSION_ES_CM_1_0
glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
#else
glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
#endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -15.0);
}
static void
make_texture(void)
{
#define SZ 64
GLenum Filter = GL_LINEAR;
GLubyte image[SZ][SZ][4];
GLuint i, j;
for (i = 0; i < SZ; i++) {
for (j = 0; j < SZ; j++) {
GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2);
d = sqrt(d);
if (d < SZ/3) {
image[i][j][0] = 255;
image[i][j][1] = 255;
image[i][j][2] = 255;
image[i][j][3] = 255;
}
else {
image[i][j][0] = 127;
image[i][j][1] = 127;
image[i][j][2] = 127;
image[i][j][3] = 255;
}
}
}
glActiveTexture(GL_TEXTURE0); /* unit 0 */
glBindTexture(GL_TEXTURE_2D, 42);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
#undef SZ
}
static void
init(void)
{
static const GLfloat red[4] = {1, 0, 0, 0};
static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0};
static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0};
static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0};
static const GLfloat pos[4] = {20, 20, 50, 1};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glClearColor(0.4, 0.4, 0.4, 0.0);
glEnable(GL_DEPTH_TEST);
make_texture();
glEnable(GL_TEXTURE_2D);
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, 0, 0, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
eglBindAPI(EGL_OPENGL_ES_API);
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
XFree(visInfo);
*winRet = win;
*ctxRet = ctx;
}
static EGLSurface
make_pbuffer(Display *x_dpy, EGLDisplay egl_dpy, int width, int height)
{
static const EGLint config_attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
EGLConfig config;
EGLSurface pbuf;
EGLint num_configs;
EGLint pbuf_attribs[5];
pbuf_attribs[0] = EGL_WIDTH;
pbuf_attribs[1] = width;
pbuf_attribs[2] = EGL_HEIGHT;
pbuf_attribs[3] = height;
pbuf_attribs[4] = EGL_NONE;
if (!eglChooseConfig( egl_dpy, config_attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL config for pbuffer\n");
exit(1);
}
pbuf = eglCreatePbufferSurface(egl_dpy, config, pbuf_attribs);
return pbuf;
}
static void
event_loop(Display *dpy, Window win,
EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf,
EGLContext egl_ctx)
{
int anim = 0;
while (1) {
int redraw = 0;
if (!anim || XPending(dpy)) {
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw = 1;
break;
case ConfigureNotify:
if (event.xconfigure.window == win)
reshape(event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
view_roty += 5.0;
}
else if (code == XK_Right) {
view_roty -= 5.0;
}
else if (code == XK_Up) {
view_rotx += 5.0;
}
else if (code == XK_Down) {
view_rotx -= 5.0;
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == ' ') {
anim = !anim;
}
else if (buffer[0] == 27) {
/* escape */
return;
}
}
}
redraw = 1;
break;
default:
; /*no-op*/
}
}
if (anim) {
view_rotx += 1.0;
view_roty += 2.0;
redraw = 1;
}
if (redraw) {
draw_both(egl_dpy, egl_surf, egl_pbuf, egl_ctx);
}
}
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
printf(" -info display OpenGL renderer info\n");
}
int
main(int argc, char *argv[])
{
Display *x_dpy;
Window win;
EGLSurface egl_surf, egl_pbuf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
EGLint egl_major, egl_minor;
int i;
const char *s;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
make_x_window(x_dpy, egl_dpy,
"pbuffer", 0, 0, WinWidth, WinHeight,
&win, &egl_ctx, &egl_surf);
egl_pbuf = make_pbuffer(x_dpy, egl_dpy, WinWidth, WinHeight);
if (!egl_pbuf) {
printf("Error: eglCreatePBufferSurface() failed\n");
return -1;
}
XMapWindow(x_dpy, win);
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
if (printInfo) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
init();
/* Set initial projection/viewing transformation.
* We can't be sure we'll get a ConfigureNotify event when the window
* first appears.
*/
reshape(WinWidth, WinHeight);
event_loop(x_dpy, win, egl_dpy, egl_surf, egl_pbuf, egl_ctx);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -1,657 +0,0 @@
/*
* Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved.
*/
/*
* Test EGL render to texture.
* Brian Paul
* August 2008
*/
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
static int TexWidth = 256, TexHeight = 256;
static int WinWidth = 300, WinHeight = 300;
static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
static GLuint DotTexture, RenderTexture;
static void
Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz)
{
n[0] = nx;
n[1] = ny;
n[2] = nz;
}
static void
Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz)
{
v[0] = vx;
v[1] = vy;
v[2] = vz;
}
static void
Texcoord(GLfloat *v, GLfloat s, GLfloat t)
{
v[0] = s;
v[1] = t;
}
/* Borrowed from glut, adapted */
static void
draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
GLfloat varray[100][3], narray[100][3], tarray[100][2];
int vcount;
glVertexPointer(3, GL_FLOAT, 0, varray);
glNormalPointer(GL_FLOAT, 0, narray);
glTexCoordPointer(2, GL_FLOAT, 0, tarray);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
vcount = 0; /* glBegin(GL_QUAD_STRIP); */
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat s0, s1, t;
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
s0 = 20.0 * theta / (2.0 * M_PI);
s1 = 20.0 * theta1 / (2.0 * M_PI);
t = 8.0 * phi / (2.0 * M_PI);
Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
Texcoord(tarray[vcount], s1, t);
Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
vcount++;
Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
Texcoord(tarray[vcount], s0, t);
Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi);
vcount++;
}
/*glEnd();*/
assert(vcount <= 100);
glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount);
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
static void
draw_torus_to_texture(void)
{
glViewport(0, 0, TexWidth, TexHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-1, 1, -1, 1, 5.0, 60.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -15.0);
glClearColor(0.4, 0.4, 0.4, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, DotTexture);
glEnable(GL_LIGHTING);
glPushMatrix();
glRotatef(view_roty, 0, 1, 0);
glScalef(0.5, 0.5, 0.5);
draw_torus(1.0, 3.0, 30, 60);
glPopMatrix();
glDisable(GL_LIGHTING);
#if 0
glBindTexture(GL_TEXTURE_2D, RenderTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TexWidth, TexHeight);
#endif
glFinish();
}
static void
draw_textured_quad(void)
{
GLfloat ar = (GLfloat) WinWidth / (GLfloat) WinHeight;
glViewport(0, 0, WinWidth, WinHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -8.0);
glClearColor(0.4, 0.4, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, RenderTexture);
glPushMatrix();
glRotatef(view_rotx, 1, 0, 0);
glRotatef(view_rotz, 0, 0, 1);
{
static const GLfloat texcoord[4][2] = {
{ 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 }
};
static const GLfloat vertex[4][2] = {
{ -1, -1 }, { 1, -1 }, { -1, 1 }, { 1, 1 }
};
glVertexPointer(2, GL_FLOAT, 0, vertex);
glTexCoordPointer(2, GL_FLOAT, 0, texcoord);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
glPopMatrix();
}
static void
draw(EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf,
EGLContext egl_ctx)
{
/*printf("Begin draw\n");*/
/* first draw torus to pbuffer /texture */
#if 01
if (!eglMakeCurrent(egl_dpy, egl_pbuf, egl_pbuf, egl_ctx)) {
#else
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
#endif
printf("Error: eglMakeCurrent(pbuf) failed\n");
return;
}
glBindTexture(GL_TEXTURE_2D, RenderTexture);
eglBindTexImage(egl_dpy, egl_pbuf, EGL_BACK_BUFFER);
draw_torus_to_texture();
eglReleaseTexImage(egl_dpy, egl_pbuf, EGL_BACK_BUFFER);
/* draw textured quad to window */
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent(pbuffer) failed\n");
return;
}
draw_textured_quad();
eglSwapBuffers(egl_dpy, egl_surf);
/*printf("End draw\n");*/
}
static void
make_dot_texture(void)
{
#define SZ 64
GLenum Filter = GL_LINEAR;
GLubyte image[SZ][SZ][4];
GLuint i, j;
for (i = 0; i < SZ; i++) {
for (j = 0; j < SZ; j++) {
GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2);
d = sqrt(d);
if (d < SZ/3) {
image[i][j][0] = 255;
image[i][j][1] = 255;
image[i][j][2] = 255;
image[i][j][3] = 255;
}
else {
image[i][j][0] = 127;
image[i][j][1] = 127;
image[i][j][2] = 127;
image[i][j][3] = 255;
}
}
}
glGenTextures(1, &DotTexture);
glBindTexture(GL_TEXTURE_2D, DotTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
#undef SZ
}
static void
make_render_texture(void)
{
GLenum Filter = GL_LINEAR;
glGenTextures(1, &RenderTexture);
glBindTexture(GL_TEXTURE_2D, RenderTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
static void
init(void)
{
static const GLfloat red[4] = {1, 0, 0, 0};
static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0};
static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0};
static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0};
static const GLfloat pos[4] = {20, 20, 50, 1};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glEnable(GL_DEPTH_TEST);
make_dot_texture();
make_render_texture();
printf("DotTexture=%u RenderTexture=%u\n", DotTexture, RenderTexture);
glEnable(GL_TEXTURE_2D);
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, 0, 0, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
eglBindAPI(EGL_OPENGL_ES_API);
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
XFree(visInfo);
*winRet = win;
*ctxRet = ctx;
}
static EGLSurface
make_pbuffer(Display *x_dpy, EGLDisplay egl_dpy, int width, int height)
{
static const EGLint config_attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
EGLConfig config;
EGLSurface pbuf;
EGLint num_configs;
EGLint pbuf_attribs[15];
int i = 0;
pbuf_attribs[i++] = EGL_WIDTH;
pbuf_attribs[i++] = width;
pbuf_attribs[i++] = EGL_HEIGHT;
pbuf_attribs[i++] = height;
pbuf_attribs[i++] = EGL_TEXTURE_FORMAT;
pbuf_attribs[i++] = EGL_TEXTURE_RGBA;
pbuf_attribs[i++] = EGL_TEXTURE_TARGET;
pbuf_attribs[i++] = EGL_TEXTURE_2D;
pbuf_attribs[i++] = EGL_MIPMAP_TEXTURE;
pbuf_attribs[i++] = EGL_FALSE;
pbuf_attribs[i++] = EGL_NONE;
assert(i <= 15);
if (!eglChooseConfig( egl_dpy, config_attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL config for pbuffer\n");
exit(1);
}
pbuf = eglCreatePbufferSurface(egl_dpy, config, pbuf_attribs);
return pbuf;
}
static void
event_loop(Display *dpy, Window win,
EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf,
EGLContext egl_ctx)
{
int anim = 0;
while (1) {
int redraw = 0;
if (!anim || XPending(dpy)) {
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw = 1;
break;
case ConfigureNotify:
if (event.xconfigure.window == win) {
WinWidth = event.xconfigure.width;
WinHeight = event.xconfigure.height;
}
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
view_roty += 5.0;
}
else if (code == XK_Right) {
view_roty -= 5.0;
}
else if (code == XK_Up) {
view_rotx += 5.0;
}
else if (code == XK_Down) {
view_rotx -= 5.0;
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == ' ') {
anim = !anim;
}
else if (buffer[0] == 'z') {
view_rotz += 5.0;
}
else if (buffer[0] == 'Z') {
view_rotz -= 5.0;
}
else if (buffer[0] == 27) {
/* escape */
return;
}
}
}
redraw = 1;
break;
default:
; /*no-op*/
}
}
if (anim) {
view_rotx += 1.0;
view_roty += 2.0;
redraw = 1;
}
if (redraw) {
draw(egl_dpy, egl_surf, egl_pbuf, egl_ctx);
}
}
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
printf(" -info display OpenGL renderer info\n");
}
int
main(int argc, char *argv[])
{
Display *x_dpy;
Window win;
EGLSurface egl_surf, egl_pbuf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
EGLint egl_major, egl_minor;
int i;
const char *s;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
make_x_window(x_dpy, egl_dpy,
"render_tex", 0, 0, WinWidth, WinHeight,
&win, &egl_ctx, &egl_surf);
egl_pbuf = make_pbuffer(x_dpy, egl_dpy, TexWidth, TexHeight);
if (!egl_pbuf) {
printf("Error: eglCreatePBufferSurface() failed\n");
return -1;
}
XMapWindow(x_dpy, win);
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
if (printInfo) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
init();
event_loop(x_dpy, win, egl_dpy, egl_surf, egl_pbuf, egl_ctx);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -1,509 +0,0 @@
/*
* Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved.
*/
/*
* Draw a lit, textured torus with X/EGL and OpenGL ES 1.x
* Brian Paul
* July 2008
*/
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
static void
Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz)
{
n[0] = nx;
n[1] = ny;
n[2] = nz;
}
static void
Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz)
{
v[0] = vx;
v[1] = vy;
v[2] = vz;
}
static void
Texcoord(GLfloat *v, GLfloat s, GLfloat t)
{
v[0] = s;
v[1] = t;
}
/* Borrowed from glut, adapted */
static void
draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
GLfloat varray[100][3], narray[100][3], tarray[100][2];
int vcount;
glVertexPointer(3, GL_FLOAT, 0, varray);
glNormalPointer(GL_FLOAT, 0, narray);
glTexCoordPointer(2, GL_FLOAT, 0, tarray);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
vcount = 0; /* glBegin(GL_QUAD_STRIP); */
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat s0, s1, t;
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
s0 = 20.0 * theta / (2.0 * M_PI);
s1 = 20.0 * theta1 / (2.0 * M_PI);
t = 8.0 * phi / (2.0 * M_PI);
Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
Texcoord(tarray[vcount], s1, t);
Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
vcount++;
Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
Texcoord(tarray[vcount], s0, t);
Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi);
vcount++;
}
/*glEnd();*/
assert(vcount <= 100);
glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount);
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
static void
draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(view_rotx, 1, 0, 0);
glRotatef(view_roty, 0, 1, 0);
glRotatef(view_rotz, 0, 0, 1);
glScalef(0.5, 0.5, 0.5);
draw_torus(1.0, 3.0, 30, 60);
glPopMatrix();
}
/* new window size or exposure */
static void
reshape(int width, int height)
{
GLfloat ar = (GLfloat) width / (GLfloat) height;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef GL_VERSION_ES_CM_1_0
glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
#else
glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
#endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -15.0);
}
static void
make_texture(void)
{
#define SZ 64
GLenum Filter = GL_LINEAR;
GLubyte image[SZ][SZ][4];
GLuint i, j;
for (i = 0; i < SZ; i++) {
for (j = 0; j < SZ; j++) {
GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2);
d = sqrt(d);
if (d < SZ/3) {
image[i][j][0] = 255;
image[i][j][1] = 255;
image[i][j][2] = 255;
image[i][j][3] = 255;
}
else {
image[i][j][0] = 127;
image[i][j][1] = 127;
image[i][j][2] = 127;
image[i][j][3] = 255;
}
}
}
glActiveTexture(GL_TEXTURE0); /* unit 0 */
glBindTexture(GL_TEXTURE_2D, 42);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
#undef SZ
}
static void
init(void)
{
static const GLfloat red[4] = {1, 0, 0, 0};
static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0};
static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0};
static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0};
static const GLfloat pos[4] = {20, 20, 50, 1};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glClearColor(0.4, 0.4, 0.4, 0.0);
glEnable(GL_DEPTH_TEST);
make_texture();
glEnable(GL_TEXTURE_2D);
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, 0, 0, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
eglBindAPI(EGL_OPENGL_ES_API);
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
XFree(visInfo);
*winRet = win;
*ctxRet = ctx;
}
static void
event_loop(Display *dpy, Window win,
EGLDisplay egl_dpy, EGLSurface egl_surf)
{
int anim = 1;
while (1) {
int redraw = 0;
if (!anim || XPending(dpy)) {
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw = 1;
break;
case ConfigureNotify:
reshape(event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
view_roty += 5.0;
}
else if (code == XK_Right) {
view_roty -= 5.0;
}
else if (code == XK_Up) {
view_rotx += 5.0;
}
else if (code == XK_Down) {
view_rotx -= 5.0;
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == ' ') {
anim = !anim;
}
else if (buffer[0] == 27) {
/* escape */
return;
}
}
}
redraw = 1;
break;
default:
; /*no-op*/
}
}
if (anim) {
view_rotx += 1.0;
view_roty += 2.0;
redraw = 1;
}
if (redraw) {
draw();
eglSwapBuffers(egl_dpy, egl_surf);
}
}
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
printf(" -info display OpenGL renderer info\n");
}
int
main(int argc, char *argv[])
{
const int winWidth = 300, winHeight = 300;
Display *x_dpy;
Window win;
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
EGLint egl_major, egl_minor;
int i;
const char *s;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
make_x_window(x_dpy, egl_dpy,
"torus", 0, 0, winWidth, winHeight,
&win, &egl_ctx, &egl_surf);
XMapWindow(x_dpy, win);
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
if (printInfo) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
init();
/* Set initial projection/viewing transformation.
* We can't be sure we'll get a ConfigureNotify event when the window
* first appears.
*/
reshape(winWidth, winHeight);
event_loop(x_dpy, win, egl_dpy, egl_surf);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -1,473 +0,0 @@
/*
* Copyright (C) 2008 Brian Paul All Rights Reserved.
*
* 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 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
* BRIAN PAUL 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.
*/
/*
* Draw a triangle with X/EGL and OpenGL ES 1.x
* Brian Paul
* 5 June 2008
*/
#define USE_FULL_GL 0
#define USE_FIXED_POINT 0
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#if USE_FULL_GL
#include <GL/gl.h> /* use full OpenGL */
#else
#include <GLES/gl.h> /* use OpenGL ES 1.x */
#include <GLES/glext.h>
#endif
#include <EGL/egl.h>
#define FLOAT_TO_FIXED(X) ((X) * 65535.0)
static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
static void
draw(void)
{
#if USE_FIXED_POINT
static const GLfixed verts[3][2] = {
{ -65536, -65536 },
{ 65536, -65536 },
{ 0, 65536 }
};
static const GLfixed colors[3][4] = {
{ 65536, 0, 0, 65536 },
{ 0, 65536, 0 , 65536},
{ 0, 0, 65536 , 65536}
};
#else
static const GLfloat verts[3][2] = {
{ -1, -1 },
{ 1, -1 },
{ 0, 1 }
};
static const GLfloat colors[3][4] = {
{ 1, 0, 0, 1 },
{ 0, 1, 0, 1 },
{ 0, 0, 1, 1 }
};
#endif
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(view_rotx, 1, 0, 0);
glRotatef(view_roty, 0, 1, 0);
glRotatef(view_rotz, 0, 0, 1);
{
#if USE_FIXED_POINT
glVertexPointer(2, GL_FIXED, 0, verts);
glColorPointer(4, GL_FIXED, 0, colors);
#else
glVertexPointer(2, GL_FLOAT, 0, verts);
glColorPointer(4, GL_FLOAT, 0, colors);
#endif
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
/* draw triangle */
glDrawArrays(GL_TRIANGLES, 0, 3);
/* draw some points */
glPointSizex(FLOAT_TO_FIXED(15.5));
glDrawArrays(GL_POINTS, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
if (0) {
/* test code */
GLfixed size;
glGetFixedv(GL_POINT_SIZE, &size);
printf("GL_POINT_SIZE = 0x%x %f\n", size, size / 65536.0);
}
glPopMatrix();
}
/* new window size or exposure */
static void
reshape(int width, int height)
{
GLfloat ar = (GLfloat) width / (GLfloat) height;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef GL_VERSION_ES_CM_1_0
glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
#else
glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
#endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
}
static void
test_query_matrix(void)
{
PFNGLQUERYMATRIXXOESPROC procQueryMatrixx;
typedef void (*voidproc)();
GLfixed mantissa[16];
GLint exponent[16];
GLbitfield rv;
int i;
voidproc p = eglGetProcAddress("eglCreateContext");
assert(p);
procQueryMatrixx = (PFNGLQUERYMATRIXXOESPROC) eglGetProcAddress("glQueryMatrixxOES");
assert(procQueryMatrixx);
/* Actually try out this one */
rv = (*procQueryMatrixx)(mantissa, exponent);
for (i = 0; i < 16; i++) {
if (rv & (1<<i)) {
printf("matrix[%d] invalid\n", i);
}
else {
printf("matrix[%d] = %f * 2^(%d)\n", i, mantissa[i]/65536.0, exponent[i]);
}
}
p = eglGetProcAddress("glFoo");
assert(!p);
}
static void
init(void)
{
glClearColor(0.4, 0.4, 0.4, 0.0);
if (0)
test_query_matrix();
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, 0, 0, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
#if USE_FULL_GL
eglBindAPI(EGL_OPENGL_API);
#else
eglBindAPI(EGL_OPENGL_ES_API);
#endif
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
XFree(visInfo);
*winRet = win;
*ctxRet = ctx;
}
static void
event_loop(Display *dpy, Window win,
EGLDisplay egl_dpy, EGLSurface egl_surf)
{
while (1) {
int redraw = 0;
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw = 1;
break;
case ConfigureNotify:
reshape(event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
view_roty += 5.0;
}
else if (code == XK_Right) {
view_roty -= 5.0;
}
else if (code == XK_Up) {
view_rotx += 5.0;
}
else if (code == XK_Down) {
view_rotx -= 5.0;
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == 27) {
/* escape */
return;
}
}
}
redraw = 1;
break;
default:
; /*no-op*/
}
if (redraw) {
draw();
eglSwapBuffers(egl_dpy, egl_surf);
}
}
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
printf(" -info display OpenGL renderer info\n");
}
int
main(int argc, char *argv[])
{
const int winWidth = 300, winHeight = 300;
Display *x_dpy;
Window win;
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
EGLint egl_major, egl_minor;
int i;
const char *s;
static struct {
char *name;
GLenum value;
enum {GetString, GetInteger} type;
} info_items[] = {
{"GL_RENDERER", GL_RENDERER, GetString},
{"GL_VERSION", GL_VERSION, GetString},
{"GL_VENDOR", GL_VENDOR, GetString},
{"GL_EXTENSIONS", GL_EXTENSIONS, GetString},
{"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger},
{"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger},
};
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
make_x_window(x_dpy, egl_dpy,
"OpenGL ES 1.x tri", 0, 0, winWidth, winHeight,
&win, &egl_ctx, &egl_surf);
XMapWindow(x_dpy, win);
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
if (printInfo) {
for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) {
switch (info_items[i].type) {
case GetString:
printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value));
break;
case GetInteger: {
GLint rv = -1;
glGetIntegerv(info_items[i].value, &rv);
printf("%s = %d\n", info_items[i].name, rv);
break;
}
}
}
};
init();
/* Set initial projection/viewing transformation.
* We can't be sure we'll get a ConfigureNotify event when the window
* first appears.
*/
reshape(winWidth, winHeight);
event_loop(x_dpy, win, egl_dpy, egl_surf);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -1,433 +0,0 @@
/*
* Copyright (C) 2008 Brian Paul All Rights Reserved.
*
* 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 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
* BRIAN PAUL 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.
*/
/*
* Test drawing to two windows.
* Brian Paul
* August 2008
*/
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
static int WinWidth[2] = {150, 300}, WinHeight[2] = {150, 300};
static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
/* new window size or exposure */
static void
reshape(int width, int height)
{
GLfloat ar = (GLfloat) width / (GLfloat) height;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef GL_VERSION_ES_CM_1_0
glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
#else
glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
#endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
}
static void
draw(int win)
{
static const GLfloat verts[3][2] = {
{ -1, -1 },
{ 1, -1 },
{ 0, 1 }
};
static const GLfloat colors[3][4] = {
{ 1, 0, 0, 1 },
{ 0, 1, 0, 1 },
{ 0, 0, 1, 1 }
};
assert(win == 0 || win == 1);
reshape(WinWidth[win], WinHeight[win]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(view_rotx, 1, 0, 0);
glRotatef(view_roty, 0, 1, 0);
glRotatef(view_rotz, 0, 0, 1);
/* draw triangle */
{
glVertexPointer(2, GL_FLOAT, 0, verts);
glColorPointer(4, GL_FLOAT, 0, colors);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
glPopMatrix();
}
static void
init(void)
{
glClearColor(0.4, 0.4, 0.4, 0.0);
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, x, y, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
#if USE_FULL_GL
eglBindAPI(EGL_OPENGL_API);
#else
eglBindAPI(EGL_OPENGL_ES_API);
#endif
if (ctxRet) {
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
*ctxRet = ctx;
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
XFree(visInfo);
*winRet = win;
}
static void
event_loop(Display *dpy, Window win1, Window win2,
EGLDisplay egl_dpy, EGLSurface egl_surf1, EGLSurface egl_surf2,
EGLContext egl_ctx)
{
while (1) {
int redraw = 0;
int win;
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw = 1;
break;
case ConfigureNotify:
if (event.xconfigure.window == win1)
win = 0;
else
win = 1;
WinWidth[win] = event.xconfigure.width;
WinHeight[win] = event.xconfigure.height;
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
view_roty += 5.0;
}
else if (code == XK_Right) {
view_roty -= 5.0;
}
else if (code == XK_Up) {
view_rotx += 5.0;
}
else if (code == XK_Down) {
view_rotx -= 5.0;
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == 27) {
/* escape */
return;
}
}
}
redraw = 1;
break;
default:
; /*no-op*/
}
if (redraw) {
/* win 1 */
if (!eglMakeCurrent(egl_dpy, egl_surf1, egl_surf1, egl_ctx)) {
printf("Error: eglMakeCurrent(1) failed\n");
return;
}
draw(0);
eglSwapBuffers(egl_dpy, egl_surf1);
/* win 2 */
if (!eglMakeCurrent(egl_dpy, egl_surf2, egl_surf2, egl_ctx)) {
printf("Error: eglMakeCurrent(2) failed\n");
return;
}
draw(1);
eglSwapBuffers(egl_dpy, egl_surf2);
}
}
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
printf(" -info display OpenGL renderer info\n");
}
int
main(int argc, char *argv[])
{
Display *x_dpy;
Window win1, win2;
EGLSurface egl_surf1, egl_surf2;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
EGLint egl_major, egl_minor;
int i;
const char *s;
static struct {
char *name;
GLenum value;
enum {GetString, GetInteger} type;
} info_items[] = {
{"GL_RENDERER", GL_RENDERER, GetString},
{"GL_VERSION", GL_VERSION, GetString},
{"GL_VENDOR", GL_VENDOR, GetString},
{"GL_EXTENSIONS", GL_EXTENSIONS, GetString},
{"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger},
{"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger},
};
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
make_x_window(x_dpy, egl_dpy,
"xegl_two_win #1", 0, 0, WinWidth[0], WinHeight[0],
&win1, &egl_ctx, &egl_surf1);
make_x_window(x_dpy, egl_dpy,
"xegl_two_win #2", WinWidth[0] + 50, 0,
WinWidth[1], WinHeight[1],
&win2, NULL, &egl_surf2);
XMapWindow(x_dpy, win1);
XMapWindow(x_dpy, win2);
if (!eglMakeCurrent(egl_dpy, egl_surf1, egl_surf1, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
if (printInfo) {
for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) {
switch (info_items[i].type) {
case GetString:
printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value));
break;
case GetInteger: {
GLint rv = -1;
glGetIntegerv(info_items[i].value, &rv);
printf("%s = %d\n", info_items[i].name, rv);
break;
}
}
}
};
init();
event_loop(x_dpy, win1, win2, egl_dpy, egl_surf1, egl_surf2, egl_ctx);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf1);
eglDestroySurface(egl_dpy, egl_surf2);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win1);
XDestroyWindow(x_dpy, win2);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -1,51 +0,0 @@
# progs/es2/xegl/Makefile
TOP = ../../..
include $(TOP)/configs/current
INCLUDE_DIRS = \
-I$(TOP)/include \
HEADERS = $(TOP)/include/GLES/egl.h
ES2_LIB_DEPS = \
$(TOP)/$(LIB_DIR)/libEGL.so \
$(TOP)/$(LIB_DIR)/libGLESv2.so
ES2_LIBS = \
-L$(TOP)/$(LIB_DIR) -lEGL \
-L$(TOP)/$(LIB_DIR) -lGLESv2 $(LIBDRM_LIB) -lX11
PROGRAMS = \
es2_info \
tri
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: $(PROGRAMS)
es2_info.c:
cp ../../es1/xegl/es1_info.c es2_info.c
es2_info: es2_info.o $(ES2_LIB_DEPS)
$(CC) $(CFLAGS) es2_info.o $(ES2_LIBS) -o $@
tri: tri.o $(ES2_LIB_DEPS)
$(CC) $(CFLAGS) tri.o $(ES2_LIBS) -o $@
clean:
rm -f *.o *~
rm -f $(PROGRAMS)
rm -f es2_info.c

View File

@@ -1,516 +0,0 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
**************************************************************************/
/*
* Draw a triangle with X/EGL and OpenGL ES 2.x
*/
#define USE_FULL_GL 0
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#if USE_FULL_GL
#include <GL/gl.h> /* use full OpenGL */
#else
#include <GLES2/gl2.h> /* use OpenGL ES 2.x */
#endif
#include <EGL/egl.h>
#define FLOAT_TO_FIXED(X) ((X) * 65535.0)
static GLfloat view_rotx = 0.0, view_roty = 0.0;
static GLint u_matrix = -1;
static GLint attr_pos = 0, attr_color = 1;
static void
make_z_rot_matrix(GLfloat angle, GLfloat *m)
{
float c = cos(angle * M_PI / 180.0);
float s = sin(angle * M_PI / 180.0);
int i;
for (i = 0; i < 16; i++)
m[i] = 0.0;
m[0] = m[5] = m[10] = m[15] = 1.0;
m[0] = c;
m[1] = s;
m[4] = -s;
m[5] = c;
}
static void
make_scale_matrix(GLfloat xs, GLfloat ys, GLfloat zs, GLfloat *m)
{
int i;
for (i = 0; i < 16; i++)
m[i] = 0.0;
m[0] = xs;
m[5] = ys;
m[10] = zs;
m[15] = 1.0;
}
static void
mul_matrix(GLfloat *prod, const GLfloat *a, const GLfloat *b)
{
#define A(row,col) a[(col<<2)+row]
#define B(row,col) b[(col<<2)+row]
#define P(row,col) p[(col<<2)+row]
GLfloat p[16];
GLint i;
for (i = 0; i < 4; i++) {
const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
}
memcpy(prod, p, sizeof(p));
#undef A
#undef B
#undef PROD
}
static void
draw(void)
{
static const GLfloat verts[3][2] = {
{ -1, -1 },
{ 1, -1 },
{ 0, 1 }
};
static const GLfloat colors[3][3] = {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
GLfloat mat[16], rot[16], scale[16];
/* Set modelview/projection matrix */
make_z_rot_matrix(view_rotx, rot);
make_scale_matrix(0.5, 0.5, 0.5, scale);
mul_matrix(mat, rot, scale);
glUniformMatrix4fv(u_matrix, 1, GL_FALSE, mat);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
{
glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
glVertexAttribPointer(attr_color, 3, GL_FLOAT, GL_FALSE, 0, colors);
glEnableVertexAttribArray(attr_pos);
glEnableVertexAttribArray(attr_color);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(attr_pos);
glDisableVertexAttribArray(attr_color);
}
}
/* new window size or exposure */
static void
reshape(int width, int height)
{
glViewport(0, 0, (GLint) width, (GLint) height);
}
static void
create_shaders(void)
{
static const char *fragShaderText =
"varying vec4 v_color;\n"
"void main() {\n"
" gl_FragColor = v_color;\n"
"}\n";
static const char *vertShaderText =
"uniform mat4 modelviewProjection;\n"
"attribute vec4 pos;\n"
"attribute vec4 color;\n"
"varying vec4 v_color;\n"
"void main() {\n"
" gl_Position = modelviewProjection * pos;\n"
" v_color = color;\n"
"}\n";
GLuint fragShader, vertShader, program;
GLint stat;
fragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragShader, 1, (const char **) &fragShaderText, NULL);
glCompileShader(fragShader);
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &stat);
if (!stat) {
printf("Error: fragment shader did not compile!\n");
exit(1);
}
vertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertShader, 1, (const char **) &vertShaderText, NULL);
glCompileShader(vertShader);
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &stat);
if (!stat) {
printf("Error: vertex shader did not compile!\n");
exit(1);
}
program = glCreateProgram();
glAttachShader(program, fragShader);
glAttachShader(program, vertShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &stat);
if (!stat) {
char log[1000];
GLsizei len;
glGetProgramInfoLog(program, 1000, &len, log);
printf("Error: linking:\n%s\n", log);
exit(1);
}
glUseProgram(program);
if (1) {
/* test setting attrib locations */
glBindAttribLocation(program, attr_pos, "pos");
glBindAttribLocation(program, attr_color, "color");
glLinkProgram(program); /* needed to put attribs into effect */
}
else {
/* test automatic attrib locations */
attr_pos = glGetAttribLocation(program, "pos");
attr_color = glGetAttribLocation(program, "color");
}
u_matrix = glGetUniformLocation(program, "modelviewProjection");
printf("Uniform modelviewProjection at %d\n", u_matrix);
printf("Attrib pos at %d\n", attr_pos);
printf("Attrib color at %d\n", attr_color);
}
static void
init(void)
{
typedef void (*proc)();
#if 1 /* test code */
proc p = eglGetProcAddress("eglCreateContext");
assert(p);
p = eglGetProcAddress("glMapBufferOES");
assert(p);
#endif
glClearColor(0.4, 0.4, 0.4, 0.0);
create_shaders();
}
/*
* Create an RGB, double-buffered X window.
* Return the window and context handles.
*/
static void
make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
const char *name,
int x, int y, int width, int height,
Window *winRet,
EGLContext *ctxRet,
EGLSurface *surfRet)
{
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
static const EGLint ctx_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
XVisualInfo *visInfo, visTemplate;
int num_visuals;
EGLContext ctx;
EGLConfig config;
EGLint num_configs;
EGLint vid;
scrnum = DefaultScreen( x_dpy );
root = RootWindow( x_dpy, scrnum );
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
printf("Error: couldn't get an EGL visual config\n");
exit(1);
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("Error: eglGetConfigAttrib() failed\n");
exit(1);
}
/* The X window visual must match the EGL config */
visTemplate.visualid = vid;
visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
if (!visInfo) {
printf("Error: couldn't get X visual\n");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( x_dpy, root, 0, 0, width, height,
0, visInfo->depth, InputOutput,
visInfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(x_dpy, win, &sizehints);
XSetStandardProperties(x_dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
#if USE_FULL_GL /* XXX fix this when eglBindAPI() works */
eglBindAPI(EGL_OPENGL_API);
#else
eglBindAPI(EGL_OPENGL_ES_API);
#endif
ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
if (!ctx) {
printf("Error: eglCreateContext failed\n");
exit(1);
}
/* test eglQueryContext() */
{
EGLint val;
eglQueryContext(egl_dpy, ctx, EGL_CONTEXT_CLIENT_VERSION, &val);
assert(val == 2);
}
*surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
if (!*surfRet) {
printf("Error: eglCreateWindowSurface failed\n");
exit(1);
}
{
EGLint val;
eglQuerySurface(egl_dpy, *surfRet, EGL_WIDTH, &val);
assert(val == width);
eglQuerySurface(egl_dpy, *surfRet, EGL_HEIGHT, &val);
assert(val == height);
eglQuerySurface(egl_dpy, *surfRet, EGL_SURFACE_TYPE, &val);
assert(val == EGL_WINDOW_BIT);
}
XFree(visInfo);
*winRet = win;
*ctxRet = ctx;
}
static void
event_loop(Display *dpy, Window win,
EGLDisplay egl_dpy, EGLSurface egl_surf)
{
while (1) {
int redraw = 0;
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw = 1;
break;
case ConfigureNotify:
reshape(event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
view_roty += 5.0;
}
else if (code == XK_Right) {
view_roty -= 5.0;
}
else if (code == XK_Up) {
view_rotx += 5.0;
}
else if (code == XK_Down) {
view_rotx -= 5.0;
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == 27) {
/* escape */
return;
}
}
}
redraw = 1;
break;
default:
; /*no-op*/
}
if (redraw) {
draw();
eglSwapBuffers(egl_dpy, egl_surf);
}
}
}
static void
usage(void)
{
printf("Usage:\n");
printf(" -display <displayname> set the display to run on\n");
printf(" -info display OpenGL renderer info\n");
}
int
main(int argc, char *argv[])
{
const int winWidth = 300, winHeight = 300;
Display *x_dpy;
Window win;
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
char *dpyName = NULL;
GLboolean printInfo = GL_FALSE;
EGLint egl_major, egl_minor;
int i;
const char *s;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0) {
dpyName = argv[i+1];
i++;
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else {
usage();
return -1;
}
}
x_dpy = XOpenDisplay(dpyName);
if (!x_dpy) {
printf("Error: couldn't open display %s\n",
dpyName ? dpyName : getenv("DISPLAY"));
return -1;
}
egl_dpy = eglGetDisplay(x_dpy);
if (!egl_dpy) {
printf("Error: eglGetDisplay() failed\n");
return -1;
}
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
printf("Error: eglInitialize() failed\n");
return -1;
}
s = eglQueryString(egl_dpy, EGL_VERSION);
printf("EGL_VERSION = %s\n", s);
s = eglQueryString(egl_dpy, EGL_VENDOR);
printf("EGL_VENDOR = %s\n", s);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
printf("EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
printf("EGL_CLIENT_APIS = %s\n", s);
make_x_window(x_dpy, egl_dpy,
"OpenGL ES 2.x tri", 0, 0, winWidth, winHeight,
&win, &egl_ctx, &egl_surf);
XMapWindow(x_dpy, win);
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
printf("Error: eglMakeCurrent() failed\n");
return -1;
}
if (printInfo) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
init();
/* Set initial projection/viewing transformation.
* We can't be sure we'll get a ConfigureNotify event when the window
* first appears.
*/
reshape(winWidth, winHeight);
event_loop(x_dpy, win, egl_dpy, egl_surf);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
XDestroyWindow(x_dpy, win);
XCloseDisplay(x_dpy);
return 0;
}

View File

@@ -12,7 +12,6 @@
#include <GL/glut.h>
static GLint WinWidth = 500, WinHeight = 500;
static GLboolean Invert = GL_FALSE;
static void Display(void)
@@ -51,15 +50,7 @@ static void Display(void)
glPixelZoom(4.0, 4.0);
glColor4f(1, 0, 0, 0);
glWindowPos2i(100, 0);
if (Invert) {
glPixelTransferf(GL_DEPTH_SCALE, -1.0);
glPixelTransferf(GL_DEPTH_BIAS, 1.0);
}
glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
if (Invert) {
glPixelTransferf(GL_DEPTH_SCALE, 1.0);
glPixelTransferf(GL_DEPTH_BIAS, 0.0);
}
glDisable(GL_DEPTH_TEST);
@@ -86,9 +77,6 @@ static void Key(unsigned char key, int x, int y)
(void) x;
(void) y;
switch (key) {
case 'i':
Invert = !Invert;
break;
case 27:
exit(0);
break;

View File

@@ -119,6 +119,12 @@ static void Init( void )
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
sz, (const GLubyte *) buf);
if (glGetError()) {
printf("Program failed to compile:\n%s\n", buf);
printf("Error: %s\n",
(char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
exit(1);
}
assert(glIsProgramARB(prognum));
}

View File

@@ -340,7 +340,6 @@ def generate(env):
'-m32',
#'-march=pentium4',
'-mmmx', '-msse', '-msse2', # enable SIMD intrinsics
'-mstackrealign', # ensure stack is aligned -- do not enabled -msse without it!
#'-mfpmath=sse',
]
if env['machine'] == 'x86_64':

View File

@@ -56,17 +56,15 @@ def generate(env):
env.PrependENVPath('PATH', llvm_bin_dir)
if env.Detect('llvm-config'):
version = env.backtick('llvm-config --version').rstrip()
try:
env.ParseConfig('llvm-config --cppflags')
env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter')
env.ParseConfig('llvm-config --ldflags')
except OSError:
print 'llvm-config version %s failed' % version
else:
env['LINK'] = env['CXX']
env['LLVM_VERSION'] = version
env['LLVM_VERSION'] = env.backtick('llvm-config --version')
except AttributeError:
env['LLVM_VERSION'] = 'X.X'
env.ParseConfig('llvm-config --cppflags')
env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter')
env.ParseConfig('llvm-config --ldflags')
env['LINK'] = env['CXX']
def exists(env):
return True

View File

@@ -1 +0,0 @@
include $(call all-subdir-makefiles)

View File

@@ -1,41 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
main/eglapi.c \
main/eglclient.c \
main/eglconfig.c \
main/eglconfigutil.c \
main/eglcontext.c \
main/eglcurrent.c \
main/egldisplay.c \
main/egldriver.c \
main/eglglobals.c \
main/eglimage.c \
main/egllog.c \
main/eglmisc.c \
main/eglmode.c \
main/eglscreen.c \
main/eglstring.c \
main/eglsurface.c
LOCAL_SRC_FILES += \
drivers/android/egl_android.c \
drivers/android/droid_loader.c \
drivers/android/droid_ui.cpp \
drivers/android/droid_intel.c
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/main \
external/mesa/include \
external/mesa/src/mesa \
external/drm/shared-core
LOCAL_CFLAGS += -DPTHREADS
LOCAL_SHARED_LIBRARIES := libdl libui libutils
LOCAL_STATIC_LIBRARIES := libes1api
LOCAL_MODULE := libhgl
include $(BUILD_SHARED_LIBRARY)

View File

@@ -1,136 +0,0 @@
/*
* Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
*
* This is based on the work of eagle, by
* Copyright © 2008, 2009 Kristian Høgsberg
*
* 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.
*/
#ifndef _DROID_H_
#define _DROID_H_
#include "GL/gl.h"
#include "GL/internal/dri_interface.h"
#include "eglcurrent.h"
#include "egldisplay.h"
#include "eglcontext.h"
#include "eglsurface.h"
#include "eglconfig.h"
/* opaque types */
struct droid_loader;
struct droid_context;
struct droid_drawable;
struct droid_image;
struct droid_surface;
struct droid_backend {
/* these are usually used by a loader */
const char *driver_name;
int (*initialize)(struct droid_backend *backend, int *fd, int *screen_number);
int (*process_config)(struct droid_backend *backend, _EGLConfig *conf);
void (*destroy)(struct droid_backend *backend);
__DRIbuffer *(*get_native_buffer)(struct droid_backend *backend,
struct droid_surface *surf,
int *width, int *height);
__DRIbuffer *(*get_surface_buffers)(struct droid_backend *backend,
struct droid_surface *surf,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, int has_format);
/* public methods */
struct droid_surface *(*create_window_surface)(struct droid_backend *backend,
_EGLSurface *surf,
NativeWindowType win);
struct droid_surface *(*create_image_surface)(struct droid_backend *backend,
NativePixmapType pix);
void (*destroy_surface)(struct droid_backend *backend, struct droid_surface *surf);
void (*swap_native_buffers)(struct droid_backend *backend,
struct droid_surface *surf);
int (*match_pixmap)(struct droid_backend *backend, _EGLConfig *conf,
NativePixmapType pix);
};
struct droid_screen {
struct droid_loader *loader;
__DRIscreen *dri_screen;
__DRItexBufferExtension *tex_buffer;
__DRIcopyBufferExtension *copy_buffer;
const __DRIconfig **dri_configs;
int num_dri_configs;
};
struct droid_backend *
droid_backend_create_intel(const char *dev);
void
droid_backend_destroy(struct droid_backend *backend);
struct droid_screen *
droid_screen_create(struct droid_backend *backend);
void
droid_screen_destroy(struct droid_screen *screen);
int
droid_screen_convert_config(struct droid_screen *screen,
const __DRIconfig *conf, _EGLConfig *egl_conf);
struct droid_context *
droid_screen_create_context(struct droid_screen *screen,
const __DRIconfig *conf,
struct droid_context *shared);
void
droid_screen_destroy_context(struct droid_screen *screen,
struct droid_context *ctx);
struct droid_drawable *
droid_screen_create_drawable(struct droid_screen *screen,
const __DRIconfig *conf,
struct droid_surface *surf);
void *
droid_screen_get_drawable_data(struct droid_screen *screen,
struct droid_drawable *drawable);
void
droid_screen_destroy_drawable(struct droid_screen *screen,
struct droid_drawable *drawable);
int
droid_screen_bind_context(struct droid_screen *screen,
struct droid_drawable *draw,
struct droid_drawable *read,
struct droid_context *ctx);
int
droid_screen_swap_buffers(struct droid_screen *screen,
struct droid_context *ctx,
struct droid_drawable *drawable);
#endif /* _DROID_H_ */

View File

@@ -1,648 +0,0 @@
/*
* Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
*
* This is based on the work of eagle, by
* Copyright © 2008, 2009 Kristian Høgsberg
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#define LOG_TAG "DROID-INTEL"
#include <utils/Log.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <i915_drm.h>
#include <GL/gl.h> /* dri_interface.h uses some GL integer types... */
#include <GL/internal/dri_interface.h>
#include <EGL/egl.h>
#include "droid.h"
#include "droid_ui.h"
#define INTEL_IS_I965(x) ((x) & INTEL_GEN_4)
#define INTEL_IS_I915(x) ((x) & INTEL_GEN_3)
#define INTEL_IS_I9xx(x) ((x) & (INTEL_GEN_3 | INTEL_GEN_4))
#define INTEL_IS_I8xx(x) ((x) & (INTEL_GEN_1 | INTEL_GEN_2))
#define INTEL_HAS_128_BYTE_Y_TILING(x) \
(((x) & (INTEL_GEN_3 | INTEL_GEN_4 | INTEL_GEN_MINOR_MASK)) > INTEL_GEN_3)
enum {
INTEL_SURFACE_TYPE_WINDOW,
INTEL_SURFACE_TYPE_IMAGE,
};
/* Look at xf86-video-intel/src/common.h for the full horror of device
* identification.
*/
enum {
INTEL_GEN_1 = 0x10,
INTEL_GEN_2 = 0x20,
INTEL_GEN_3 = 0x40,
INTEL_GEN_31 = 0x41,
INTEL_GEN_4 = 0x80,
INTEL_GEN_MAJOR_MASK = 0xf0,
INTEL_GEN_MINOR_MASK = 0x0f,
};
struct droid_backend_intel {
struct droid_backend base;
int fd;
int screen_number;
uint32_t generation;
int pitch_align;
int enable_tiling;
};
struct droid_surface_intel {
int type;
union {
NativeWindowType win;
NativePixmapType pix;
} native;
__DRIbuffer native_buffer;
unsigned int native_width, native_height;
int native_changed;
unsigned int attachments[20];
__DRIbuffer buffers[10];
uint32_t handles[10];
int num_buffers;
int depth_idx;
_EGLSurface *surf;
};
static INLINE struct droid_backend_intel *
lookup_backend(struct droid_backend *backend)
{
return (struct droid_backend_intel *) backend;
}
static INLINE struct droid_surface_intel *
lookup_surface(struct droid_surface *surface)
{
return (struct droid_surface_intel *) surface;
}
static __DRIbuffer *
intel_get_native_buffer(struct droid_backend *backend,
struct droid_surface *surf,
int *width, int *height)
{
struct droid_surface_intel *isurf = lookup_surface(surf);
/* non-window surface is single-buffered */
if (isurf->type != INTEL_SURFACE_TYPE_WINDOW)
return NULL;
if (!isurf->native_buffer.name)
return NULL;
if (width)
*width = isurf->native_width;
if (height)
*height = isurf->native_height;
return &isurf->native_buffer;
}
static INLINE uint32_t
align_to(uint32_t value, uint32_t align)
{
return (value + align - 1) & ~(align - 1);
}
static INLINE int
fence_pitch(struct droid_backend *backend, int pitch, int tiling)
{
struct droid_backend_intel *intel = lookup_backend(backend);
int pitch_align, tile_width;
switch (tiling) {
case I915_TILING_NONE:
default:
pitch_align = intel->pitch_align;
tile_width = 1; /* not used */
break;
case I915_TILING_X:
pitch_align = 512;
tile_width = 512;
break;
case I915_TILING_Y:
pitch_align = 512;
tile_width =
(INTEL_HAS_128_BYTE_Y_TILING(intel->generation)) ? 128 : 512;
break;
}
pitch = align_to(pitch, pitch_align);
if (tiling == I915_TILING_NONE)
return pitch;
/* 965+ just needs multiples of tile width */
if (INTEL_IS_I965(intel->generation)) {
pitch = align_to(pitch, tile_width);
}
else {
/* Pre-965 needs power of two tile widths */
while (tile_width < pitch)
tile_width <<= 1;
pitch = tile_width;
}
return pitch;
}
static INLINE uint32_t
fence_size(struct droid_backend *backend, int height, int pitch, int tiling)
{
struct droid_backend_intel *intel = lookup_backend(backend);
int height_align;
uint32_t size;
switch (tiling) {
case I915_TILING_NONE:
default:
/* Round the height up so that the GPU's access to a 2x2 aligned
* subspan doesn't address an invalid page offset beyond the
* end of the GTT.
*/
height_align = 2;
break;
case I915_TILING_X:
height_align = 8;
break;
case I915_TILING_Y:
height_align = 32;
break;
}
height = align_to(height, height_align);
size = pitch * height;
if (tiling == I915_TILING_NONE)
return size;
/* The 965 can have fences at any page boundary. */
if (INTEL_IS_I965(intel->generation)) {
size = align_to(size, 4096);
}
else {
uint32_t fence;
/* Align the size to a power of two greater than the smallest fence. */
if (INTEL_IS_I9xx(intel->generation))
fence = 1 << 20; /* 1 MiB */
else
fence = 1 << 19; /* 512 KiB */
while (fence < size)
fence <<= 1;
size = fence;
}
return size;
}
static int
create_buffer(struct droid_backend *backend, __DRIbuffer *buffer,
int width, int height, int cpp, int tiling)
{
struct droid_backend_intel *intel = lookup_backend(backend);
struct drm_i915_gem_create create;
struct drm_gem_flink flink;
buffer->pitch = fence_pitch(backend, width * cpp, tiling);
create.size = fence_size(backend, height, buffer->pitch, tiling);
if (ioctl(intel->fd, DRM_IOCTL_I915_GEM_CREATE, &create)) {
LOGE("failed to create buffer");
return 0;
}
if (tiling != I915_TILING_NONE) {
struct drm_i915_gem_set_tiling set_tiling;
memset(&set_tiling, 0, sizeof(set_tiling));
set_tiling.handle = create.handle;
set_tiling.tiling_mode = tiling;
set_tiling.stride = buffer->pitch;
if (ioctl(intel->fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling))
LOGW("failed to enable tiling");
}
flink.handle = create.handle;
if (ioctl(intel->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
LOGE("failed to flink buffer");
return 0;
}
buffer->name = flink.name;
buffer->cpp = cpp;
buffer->flags = 0;
return create.handle;
}
static void
delete_buffers(struct droid_backend *backend, struct droid_surface *surf)
{
struct droid_backend_intel *intel = lookup_backend(backend);
struct droid_surface_intel *isurf = lookup_surface(surf);
int i;
for (i = 0; i < isurf->num_buffers; i++) {
if (isurf->handles[i]) {
struct drm_gem_close close;
close.handle = isurf->handles[i];
if (ioctl(intel->fd, DRM_IOCTL_GEM_CLOSE, &close) < 0)
LOGE("failed to close bo %d", close.handle);
isurf->handles[i] = 0;
}
}
isurf->num_buffers = 0;
}
static __DRIbuffer *
intel_get_surface_buffers(struct droid_backend *backend,
struct droid_surface *surf,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, int has_format)
{
struct droid_backend_intel *intel = lookup_backend(backend);
struct droid_surface_intel *isurf = lookup_surface(surf);
unsigned int att_size;
__DRIbuffer buffers[10];
uint32_t handles[10];
int num = 0;
if (count > 10) {
LOGW("too many buffers requested");
count = 10;
}
att_size = sizeof(attachments[0]) * count * ((has_format) ? 2 : 1);
if (isurf->native_changed) {
delete_buffers(backend, surf);
isurf->native_changed = 0;
}
/* same buffers requested */
if (isurf->num_buffers == count &&
memcmp(isurf->attachments, attachments, att_size) == 0) {
num = isurf->num_buffers;
goto end;
}
memcpy(isurf->attachments, attachments, att_size);
while (count-- > 0) {
unsigned int att = *attachments++;
unsigned int format = (has_format) ? *attachments++ : 0;
unsigned int cpp = (format) ? format / 8 : isurf->native_buffer.cpp;
__DRIbuffer *buf = NULL;
int reuse;
/* re-use buffer */
for (reuse = 0; reuse < isurf->num_buffers; reuse++) {
if (isurf->buffers[reuse].attachment == att) {
if (isurf->buffers[reuse].cpp == cpp &&
isurf->handles[reuse])
buf = &isurf->buffers[reuse];
break;
}
}
if (0)
LOGD("%s buffer %d: att %d cpp %d",
(buf) ? "reuse" : "create", num, att, cpp);
if (buf) {
buffers[num] = isurf->buffers[reuse];
handles[num] = isurf->handles[reuse];
isurf->handles[reuse] = 0;
}
else {
int tiling =
(intel->enable_tiling) ? I915_TILING_X : I915_TILING_NONE;
buffers[num].attachment = att;
if (isurf->type == INTEL_SURFACE_TYPE_IMAGE &&
att == __DRI_BUFFER_FRONT_LEFT) {
/* return native buffer */
buffers[num] = isurf->native_buffer;
buffers[num].attachment = att;
handles[num] = 0;
} else {
buffers[num].attachment = att;
handles[num] = create_buffer(backend, &buffers[num],
isurf->native_width,
isurf->native_height,
cpp,
tiling);
}
}
num++;
}
/* delete old buffers that are not re-used */
delete_buffers(backend, surf);
memcpy(isurf->buffers, buffers, sizeof(buffers[0]) * num);
memcpy(isurf->handles, handles, sizeof(handles[0]) * num);
isurf->num_buffers = num;
end:
*out_count = num;
*width = isurf->native_width;
*height = isurf->native_height;
return isurf->buffers;
}
static void
update_native_buffer(struct droid_surface *surf)
{
struct droid_surface_intel *isurf = lookup_surface(surf);
__DRIbuffer *buf = &isurf->native_buffer;
unsigned int name, cpp, pitch, width, height;
switch (isurf->type) {
case INTEL_SURFACE_TYPE_WINDOW:
/* oem[0] always point to the buffer that a client is drawing to */
name = isurf->native.win->oem[0];
cpp = ui_bytes_per_pixel(isurf->native.win->format);
pitch = isurf->native.win->stride * cpp;
width = isurf->native.win->width;
height = isurf->native.win->height;
break;
case INTEL_SURFACE_TYPE_IMAGE:
name = isurf->native.pix->reserved;
cpp = ui_bytes_per_pixel(isurf->native.pix->format);
pitch = isurf->native.pix->stride * cpp;
width = isurf->native.pix->width;
height = isurf->native.pix->height;
break;
default:
name = cpp = pitch = width = height = 0;
break;
}
if (buf->name != name || buf->cpp != cpp || buf->pitch != pitch ||
isurf->native_width != width || isurf->native_height != height) {
buf->attachment = __DRI_BUFFER_FRONT_LEFT;
buf->name = name;
buf->cpp = cpp;
buf->pitch = pitch;
buf->flags = 0;
isurf->native_width = width;
isurf->native_height = height;
isurf->native_changed = 1;
}
}
static struct droid_surface *
intel_create_window_surface(struct droid_backend *backend,
_EGLSurface *surf,
NativeWindowType win)
{
struct droid_surface_intel *isurf;
if (!win) {
LOGE("invalid native window");
_eglError(EGL_BAD_NATIVE_WINDOW, "eglCreateWindowSurface");
return NULL;
}
/* TODO lift this limitation */
if (!win->oem[0]) {
LOGE("TODO support for non-gem based window");
_eglError(EGL_BAD_NATIVE_WINDOW, "eglCreateWindowSurface");
return NULL;
}
isurf = calloc(1, sizeof(*isurf));
if (!isurf) {
_eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
return NULL;
}
isurf->type = INTEL_SURFACE_TYPE_WINDOW;
isurf->native.win = win;
surf->Width = win->width;
surf->Height = win->height;
/* always back buffer */
surf->RenderBuffer = EGL_BACK_BUFFER;
isurf->surf = surf;
update_native_buffer((struct droid_surface *) isurf);
return (struct droid_surface *) isurf;
}
static struct droid_surface *
intel_create_image_surface(struct droid_backend *backend,
NativePixmapType pix)
{
struct droid_surface_intel *isurf;
int cpp;
if (!pix) {
LOGE("invalid native pixmap");
_eglError(EGL_BAD_NATIVE_PIXMAP, "eglCreateImage");
return NULL;
}
/* TODO lift this limitation */
if (!pix->reserved) {
LOGE("TODO support for non-gem based pixmap");
_eglError(EGL_BAD_NATIVE_PIXMAP, "eglCreateImage");
return NULL;
}
isurf = calloc(1, sizeof(*isurf));
if (!isurf) {
_eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
return NULL;
}
isurf->type = INTEL_SURFACE_TYPE_IMAGE;
isurf->native.pix = pix;
update_native_buffer((struct droid_surface *) isurf);
return (struct droid_surface *) isurf;
}
static void
intel_destroy_surface(struct droid_backend *backend, struct droid_surface *surf)
{
struct droid_surface_intel *isurf = lookup_surface(surf);
delete_buffers(backend, surf);
free(isurf);
}
static void
intel_swap_native_buffers(struct droid_backend *backend,
struct droid_surface *surf)
{
struct droid_surface_intel *isurf = lookup_surface(surf);
if (isurf->type == INTEL_SURFACE_TYPE_WINDOW) {
uint32_t flags;
flags = isurf->native.win->swapBuffers(isurf->native.win);
if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) {
update_native_buffer(surf);
} else {
/* oem[0] is changed after buffer swap */
isurf->native_buffer.name = isurf->native.win->oem[0];
}
}
}
static int
intel_match_pixmap(struct droid_backend *backend, _EGLConfig *conf,
NativePixmapType pix)
{
int val;
val = GET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE);
/* match the visual type */
return (pix->format == val);
}
static int
intel_initialize(struct droid_backend *backend, int *fd, int *screen_number)
{
struct droid_backend_intel *intel = lookup_backend(backend);
drm_auth_t auth;
int err;
err = ioctl(intel->fd, DRM_IOCTL_GET_MAGIC, &auth);
if (!err)
err = ui_auth_gpu(auth.magic);
if (err) {
LOGE("failed to authenticate");
return 0;
}
if (fd)
*fd = intel->fd;
if (screen_number)
*screen_number = intel->screen_number;
return 1;
}
#include <assert.h>
static int
intel_process_config(struct droid_backend *backend, _EGLConfig *conf)
{
int r, g, b, a;
int surface_type;
int format;
r = GET_CONFIG_ATTRIB(conf, EGL_RED_SIZE);
g = GET_CONFIG_ATTRIB(conf, EGL_GREEN_SIZE);
b = GET_CONFIG_ATTRIB(conf, EGL_BLUE_SIZE);
a = GET_CONFIG_ATTRIB(conf, EGL_ALPHA_SIZE);
format = ui_get_rgb_format(r, g, b, a);
if (format) {
SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE, format);
SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE,
EGL_WINDOW_BIT |
EGL_PIXMAP_BIT |
EGL_PBUFFER_BIT);
}
else {
SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
}
return 1;
}
static void
intel_destroy(struct droid_backend *backend)
{
struct droid_backend_intel *intel = lookup_backend(backend);
close(intel->fd);
free(intel);
}
struct droid_backend *
droid_backend_create_intel(const char *dev)
{
struct droid_backend_intel *intel;
intel = calloc(1, sizeof(*intel));
if (!intel)
return NULL;
intel->fd = open(dev, O_RDWR);
if (intel->fd < 0) {
LOGE("failed to open %s", dev);
free(intel);
return NULL;
}
intel->screen_number = 0;
/* XXX query using I915_GETPARAM + PARAM_CHIPSET_ID */
intel->generation = INTEL_GEN_3;
intel->pitch_align = 64;
intel->enable_tiling = 1;
intel->base.driver_name = "i915";
intel->base.initialize = intel_initialize;
intel->base.process_config = intel_process_config;
intel->base.destroy = intel_destroy;
intel->base.get_native_buffer = intel_get_native_buffer;
intel->base.get_surface_buffers = intel_get_surface_buffers;
intel->base.create_window_surface = intel_create_window_surface;
intel->base.create_image_surface = intel_create_image_surface;
intel->base.destroy_surface = intel_destroy_surface;
intel->base.swap_native_buffers = intel_swap_native_buffers;
intel->base.match_pixmap = intel_match_pixmap;
return &intel->base;
}

View File

@@ -1,509 +0,0 @@
/*
* Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
*
* This is based on the work of eagle, by
* Copyright © 2008, 2009 Kristian Høgsberg
*
* 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.
*/
#define LOG_TAG "DROID-LOADER"
#include <utils/Log.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>
#include <assert.h>
#include "droid.h"
#include "EGL/internal/eglimage_dri.h"
#ifndef DROID_DRIVER_PATH
#define DROID_DRIVER_PATH "/system/lib"
#endif
struct droid_loader {
struct droid_backend *backend;
char *filename;
void *handle;
__DRIcoreExtension *core;
__DRIdri2Extension *dri2;
};
struct droid_context {
__DRIcontext *dri_context;
};
struct droid_drawable {
struct droid_loader *loader;
struct droid_surface *surface;
__DRIdrawable *dri_drawable;
const __DRIconfig *dri_config;
__DRIEGLImage *dri_image;
};
static __DRIbuffer *
loader_ext_get_buffers_with_format(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate)
{
struct droid_drawable *drawable = (struct droid_drawable *) loaderPrivate;
struct droid_loader *loader = drawable->loader;
__DRIbuffer *buffers;
buffers = loader->backend->get_surface_buffers(loader->backend,
drawable->surface,
width, height,
attachments, count,
out_count, 1);
return buffers;
}
static const __DRIdri2LoaderExtension loader_ext_dri2_loader = {
{ __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
NULL,
NULL,
loader_ext_get_buffers_with_format,
};
static int
loader_ext_get_ust(int64_t *ust)
{
struct timeval tv;
if (ust == NULL)
return -EFAULT;
if (gettimeofday(&tv, NULL) == 0) {
ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
return 0;
} else {
return -errno;
}
}
static const __DRIsystemTimeExtension loader_ext_system_time = {
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
loader_ext_get_ust,
NULL,
};
static const __DRIextension *loader_extensions[] = {
&loader_ext_dri2_loader.base,
&loader_ext_system_time.base,
NULL
};
static struct droid_loader *
loader_create(struct droid_backend *backend)
{
struct droid_loader *loader;
loader = calloc(1, sizeof(*loader));
if (!loader)
return NULL;
loader->backend = backend;
return loader;
}
static void
loader_destroy(struct droid_loader *loader)
{
if (loader->filename)
free(loader->filename);
if (loader->handle)
dlclose(loader->handle);
free(loader);
}
static int
loader_load(struct droid_loader *loader, const char *filename)
{
const __DRIextension **extensions;
const char *path = NULL;
int i;
LOGD("Loading DRI driver %s", filename);
loader->handle = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
if (loader->handle == NULL) {
LOGE("dlopen: %s", dlerror());
return 0;
}
extensions = dlsym(loader->handle, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
LOGE("dlsym: %s", dlerror());
dlclose(loader->handle);
loader->handle = NULL;
return 0;
}
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
extensions[i]->version >= __DRI_CORE_VERSION) {
loader->core = (__DRIcoreExtension *) extensions[i];
}
if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
extensions[i]->version >= __DRI_DRI2_VERSION) {
loader->dri2 = (__DRIdri2Extension *) extensions[i];
}
}
if (loader->core == NULL || loader->dri2 == NULL) {
LOGE("missing required DRI extensions");
dlclose(loader->handle);
loader->handle = NULL;
return 0;
}
return 1;
}
static int
loader_init(struct droid_loader *loader)
{
char filename[1024];
const char *path;
path = DROID_DRIVER_PATH;
snprintf(filename, sizeof(filename), "%s/%s_dri.so",
path, loader->backend->driver_name);
if (!loader_load(loader, filename))
return 0;
loader->filename = strdup(filename);
return 1;
}
void
droid_backend_destroy(struct droid_backend *backend)
{
backend->destroy(backend);
}
struct droid_screen *
droid_screen_create(struct droid_backend *backend)
{
struct droid_screen *screen = NULL;
struct droid_loader *loader;
const __DRIextension **extensions;
int fd, screen_number;
int i;
loader = loader_create(backend);
if (!loader || !loader_init(loader)) {
LOGE("failed to initialize loader");
goto fail;
}
screen = calloc(1, sizeof(*screen));
if (!screen) {
LOGE("failed to allocate new screen");
goto fail;
}
if (!loader->backend->initialize(loader->backend, &fd, &screen_number)) {
LOGE("failed to initialize backend");
goto fail;
}
screen->loader = loader;
screen->dri_screen =
loader->dri2->createNewScreen(screen_number, fd,
loader_extensions,
&screen->dri_configs, NULL);
if (!screen->dri_screen) {
LOGE("failed to create DRI screen");
goto fail;
}
extensions = loader->core->getExtensions(screen->dri_screen);
for (i = 0; extensions && extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0 &&
extensions[i]->version >= __DRI_TEX_BUFFER_VERSION)
screen->tex_buffer = (__DRItexBufferExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_COPY_BUFFER) == 0 &&
extensions[i]->version >= __DRI_COPY_BUFFER_VERSION)
screen->copy_buffer = (__DRIcopyBufferExtension *) extensions[i];
}
if (!screen->tex_buffer) {
LOGE("DRI driver has no TexBuffer extension");
goto fail;
}
if (!screen->tex_buffer) {
LOGE("DRI driver has no CopyBuffer extension");
goto fail;
}
for (i = 0; screen->dri_configs[i]; i++)
;
screen->num_dri_configs = i;
return screen;
fail:
if (screen)
droid_screen_destroy(screen);
if (loader)
loader_destroy(loader);
return NULL;
}
void
droid_screen_destroy(struct droid_screen *screen)
{
struct droid_loader *loader = screen->loader;
if (screen->dri_screen)
loader->core->destroyScreen(screen->dri_screen);
free(screen);
}
static const struct {
EGLenum egl_attrib;
unsigned int dri_attrib;
} droid_attrib_map[] = {
{ EGL_BUFFER_SIZE, __DRI_ATTRIB_BUFFER_SIZE },
{ EGL_RED_SIZE, __DRI_ATTRIB_RED_SIZE },
{ EGL_GREEN_SIZE, __DRI_ATTRIB_GREEN_SIZE },
{ EGL_BLUE_SIZE, __DRI_ATTRIB_BLUE_SIZE },
{ EGL_ALPHA_SIZE, __DRI_ATTRIB_ALPHA_SIZE },
{ EGL_BIND_TO_TEXTURE_RGB, __DRI_ATTRIB_BIND_TO_TEXTURE_RGB },
{ EGL_BIND_TO_TEXTURE_RGBA, __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA },
{ EGL_CONFIG_CAVEAT, __DRI_ATTRIB_CONFIG_CAVEAT },
{ EGL_DEPTH_SIZE, __DRI_ATTRIB_DEPTH_SIZE },
{ EGL_LEVEL, __DRI_ATTRIB_LEVEL },
{ EGL_MAX_PBUFFER_WIDTH, __DRI_ATTRIB_MAX_PBUFFER_WIDTH },
{ EGL_MAX_PBUFFER_HEIGHT, __DRI_ATTRIB_MAX_PBUFFER_HEIGHT },
{ EGL_MAX_PBUFFER_PIXELS, __DRI_ATTRIB_MAX_PBUFFER_PIXELS },
{ EGL_SAMPLE_BUFFERS, __DRI_ATTRIB_SAMPLE_BUFFERS },
{ EGL_SAMPLES, __DRI_ATTRIB_SAMPLES },
{ EGL_STENCIL_SIZE, __DRI_ATTRIB_STENCIL_SIZE },
};
int
droid_screen_convert_config(struct droid_screen *screen,
const __DRIconfig *conf, _EGLConfig *egl_conf)
{
struct droid_loader *loader = screen->loader;
const int num_attrs =
sizeof(droid_attrib_map) / sizeof(droid_attrib_map[0]);
int i;
for (i = 0; i < num_attrs; i++) {
unsigned int dri_attrib = droid_attrib_map[i].dri_attrib;
unsigned int dri_value;
EGLenum egl_attrib = droid_attrib_map[i].egl_attrib;
EGLint egl_value;
if (!loader->core->getConfigAttrib(conf, dri_attrib, &dri_value)) {
LOGE("failed to get attribute %02d for %p", dri_attrib, conf);
return 0;
}
switch (egl_attrib) {
case EGL_CONFIG_CAVEAT:
if (dri_value & __DRI_ATTRIB_SLOW_BIT)
egl_value = EGL_SLOW_CONFIG;
else if (dri_value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
egl_value = EGL_NON_CONFORMANT_CONFIG;
else
egl_value = EGL_NONE;
break;
default:
egl_value = (EGLint) dri_value;
break;
}
SET_CONFIG_ATTRIB(egl_conf, egl_attrib, egl_value);
}
return loader->backend->process_config(loader->backend, egl_conf);
}
struct droid_context *
droid_screen_create_context(struct droid_screen *screen,
const __DRIconfig *conf,
struct droid_context *shared)
{
struct droid_loader *loader = screen->loader;
struct droid_context *ctx;
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
LOGE("failed to allocate context");
return NULL;
}
ctx->dri_context =
loader->dri2->createNewContext(screen->dri_screen, conf,
(shared) ? shared->dri_context : NULL,
NULL);
if (!ctx->dri_context) {
LOGE("failed to create DRI context");
free(ctx);
return NULL;
}
return ctx;
}
void
droid_screen_destroy_context(struct droid_screen *screen,
struct droid_context *ctx)
{
struct droid_loader *loader = screen->loader;
loader->core->destroyContext(ctx->dri_context);
free(ctx);
}
struct droid_drawable *
droid_screen_create_drawable(struct droid_screen *screen,
const __DRIconfig *conf,
struct droid_surface *surf)
{
struct droid_loader *loader = screen->loader;
struct droid_drawable *drawable;
drawable = calloc(1, sizeof(*drawable));
if (!drawable) {
LOGE("failed to allocate drawable");
return NULL;
}
/* needed in GetBuffers */
drawable->loader = loader;
drawable->surface = surf;
drawable->dri_config = conf;
drawable->dri_drawable =
loader->dri2->createNewDrawable(screen->dri_screen,
conf, (void *) drawable);
if (!drawable->dri_drawable) {
LOGE("failed to create DRI drawable");
free(drawable);
return NULL;
}
return drawable;
}
void *
droid_screen_get_drawable_data(struct droid_screen *screen,
struct droid_drawable *drawable)
{
struct droid_loader *loader = screen->loader;
__DRIEGLImage *img = drawable->dri_image;
if (!img) {
unsigned int val;
img = calloc(1, sizeof(__DRIEGLImage));
if (!img)
return NULL;
img->magic = __DRI_EGL_IMAGE_MAGIC;
img->drawable = drawable->dri_drawable;
img->level = 0;
if (loader->core->getConfigAttrib(drawable->dri_config,
__DRI_ATTRIB_ALPHA_SIZE, &val))
img->texture_format_rgba = (val > 0);
drawable->dri_image = img;
}
return (void *) img;
}
void
droid_screen_destroy_drawable(struct droid_screen *screen,
struct droid_drawable *drawable)
{
struct droid_loader *loader = screen->loader;
if (drawable->dri_image)
free(drawable->dri_image);
loader->core->destroyDrawable(drawable->dri_drawable);
free(drawable);
}
int
droid_screen_bind_context(struct droid_screen *screen,
struct droid_drawable *draw,
struct droid_drawable *read,
struct droid_context *ctx)
{
struct droid_loader *loader = screen->loader;
int ret = 0;
if (ctx) {
if (draw && read)
ret = loader->core->bindContext(ctx->dri_context,
draw->dri_drawable,
read->dri_drawable);
else if (!draw && !read)
ret = loader->core->unbindContext(ctx->dri_context);
}
if (!ret)
LOGE("failed to bind context %p", ctx);
return ret;
}
int
droid_screen_swap_buffers(struct droid_screen *screen,
struct droid_context *ctx,
struct droid_drawable *drawable)
{
struct droid_loader *loader = screen->loader;
__DRIbuffer *native;
int width, height;
int err = 0;
native = loader->backend->get_native_buffer(loader->backend,
drawable->surface,
&width, &height);
/* copy from front buffer to native buffer */
if (native)
err = screen->copy_buffer->copyBuffer(ctx->dri_context, native, 0, 0,
drawable->dri_drawable,
__DRI_BUFFER_FRONT_LEFT, 0, 0,
width, height);
if (!err)
loader->backend->swap_native_buffers(loader->backend, drawable->surface);
return (!err);
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
*
* 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.
*/
#include <ui/PixelFormat.h>
#include <ui/ISurfaceComposer.h>
#include "droid_ui.h"
using namespace android;
namespace android {
const sp<ISurfaceComposer>& _get_surface_manager();
};
int
ui_auth_gpu(drm_magic_t magic)
{
/*
* surface flinger itself or root; we might want something like
* getSurfaceFlinger() from libEGL
*/
if (getuid() == 1000 || getuid() == 0)
return 0;
sp<ISurfaceComposer> sm(_get_surface_manager());
if (sm == NULL)
return -ENODEV;
return sm->authGPU(magic);
}
int ui_bytes_per_pixel(int format)
{
return bytesPerPixel(format);
}
int ui_get_rgb_format(int red, int green, int blue, int alpha)
{
PixelFormatInfo info;
PixelFormat fmt;
/* look in the RGB range */
for (fmt = 1; fmt < PIXEL_FORMAT_YCbCr_422_SP; fmt++) {
status_t err = getPixelFormatInfo(fmt, &info);
if (err)
return -1;
/* bpp must be equal to depth */
if (info.bytesPerPixel * 8 != info.bitsPerPixel)
continue;
if ((info.h_red - info.l_red != red) ||
(info.h_green - info.l_green != green) ||
(info.h_blue - info.l_blue != blue) ||
(info.h_alpha - info.l_alpha != alpha))
continue;
/* mask? */
return fmt;
}
return -1;
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
*
* 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.
*/
#ifndef _DROID_UI_H
#define _DROID_UI_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus */
#include <drm.h>
int ui_auth_gpu(drm_magic_t magic);
int ui_bytes_per_pixel(int format);
int ui_get_rgb_format(int red, int green, int blue, int alpha);
#ifdef __cplusplus
}
#endif /*__cplusplus */
#endif /* _DROID_UI_H */

View File

@@ -1,596 +0,0 @@
/*
* Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
*
* 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.
*/
#define LOG_TAG "DROID-EGL"
#include <utils/Log.h>
#include "glapi/glapi.h"
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "egllog.h"
#include "eglsurface.h"
#include "eglimage.h"
#include "droid.h"
#ifndef DROID_DEVICE_PATH
#define DROID_DEVICE_PATH "/dev/dri/card0"
#endif
struct droid_egl_driver
{
_EGLDriver base;
/* EGL_DEFAULT_DISPLAY */
struct droid_egl_display *default_display;
void (*flush_current)(void);
void (*finish_current)(void);
};
struct droid_egl_display
{
EGLint refcnt;
EGLint apis;
EGLint major;
EGLint minor;
struct droid_backend *backend;
struct droid_screen *screen;
};
struct droid_egl_context {
_EGLContext base;
struct droid_context *context;
};
struct droid_egl_surface {
_EGLSurface base;
struct droid_drawable *drawable;
struct droid_surface *surface;
};
struct droid_egl_image {
_EGLImage base;
struct droid_drawable *drawable;
struct droid_surface *surface;
};
struct droid_egl_config {
_EGLConfig base;
const __DRIconfig *config;
};
static INLINE struct droid_egl_driver *
lookup_driver(_EGLDriver *drv)
{
return (struct droid_egl_driver *) drv;
}
static INLINE struct droid_egl_display *
lookup_display(_EGLDisplay *dpy)
{
return (struct droid_egl_display *) dpy->DriverData;
}
static INLINE struct droid_egl_context *
lookup_context(_EGLContext *context)
{
return (struct droid_egl_context *) context;
}
static INLINE struct droid_egl_surface *
lookup_surface(_EGLSurface *surface)
{
return (struct droid_egl_surface *) surface;
}
static INLINE struct droid_egl_image *
lookup_image(_EGLImage *image)
{
return (struct droid_egl_image *) image;
}
static INLINE struct droid_egl_config *
lookup_config(_EGLConfig *conf)
{
return (struct droid_egl_config *) conf;
}
static void
droid_create_configs(_EGLDisplay *dpy, struct droid_egl_display *droid_dpy,
const __DRIconfig **configs, EGLint num_configs)
{
EGLint i;
EGLint id = 1;
for (i = 0; i < num_configs; i++) {
struct droid_egl_config *droid_conf = calloc(1, sizeof(*droid_conf));
EGLint val;
if (!droid_conf)
break;
_eglInitConfig(&droid_conf->base, id);
droid_conf->config = configs[i];
if (!droid_screen_convert_config(droid_dpy->screen, droid_conf->config,
&droid_conf->base)) {
free(droid_conf);
continue;
}
val = GET_CONFIG_ATTRIB(&droid_conf->base, EGL_CONFIG_CAVEAT);
/* we do not want slow configs */
if (val == EGL_SLOW_CONFIG) {
free(droid_conf);
} else {
_eglAddConfig(dpy, &droid_conf->base);
id++;
}
}
}
static EGLBoolean
droid_initialize_display(struct droid_egl_display *droid_dpy)
{
const char *path = DROID_DEVICE_PATH;
droid_dpy->backend = droid_backend_create_intel(path);
if (!droid_dpy->backend)
return EGL_FALSE;
droid_dpy->screen = droid_screen_create(droid_dpy->backend);
if (!droid_dpy->screen) {
free(droid_dpy->backend);
droid_dpy->backend = NULL;
return EGL_FALSE;
}
droid_dpy->apis = EGL_OPENGL_ES_BIT;
droid_dpy->major = 1;
droid_dpy->major = 4;
return EGL_TRUE;
}
static EGLBoolean
droid_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
EGLint *major, EGLint *minor)
{
struct droid_egl_driver *droid_drv = lookup_driver(drv);
struct droid_egl_display *droid_dpy;
if (dpy->NativeDisplay != EGL_DEFAULT_DISPLAY)
return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
/* the default display */
droid_dpy = droid_drv->default_display;
if (!droid_dpy) {
droid_dpy = calloc(1, sizeof(*droid_dpy));
if (!droid_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
if (!droid_initialize_display(droid_dpy))
return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
droid_create_configs(dpy, droid_dpy, droid_dpy->screen->dri_configs,
droid_dpy->screen->num_dri_configs);
#if EGL_KHR_image_base
if (droid_dpy->backend->create_image_surface) {
dpy->Extensions.KHR_image = EGL_TRUE;
dpy->Extensions.KHR_image_base = EGL_TRUE;
dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
}
#endif
droid_drv->default_display = droid_dpy;
}
dpy->DriverData = (void *) droid_dpy;
droid_dpy->refcnt++;
*major = droid_dpy->major;
*minor = droid_dpy->minor;
return EGL_TRUE;
}
static EGLBoolean
droid_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
struct droid_egl_driver *droid_drv = lookup_driver(drv);
struct droid_egl_display *droid_dpy = lookup_display(dpy);
dpy->DriverData = NULL;
droid_dpy->refcnt--;
if (!droid_dpy->refcnt) {
_eglReleaseDisplayResources(drv, dpy);
_eglCleanupDisplay(dpy);
free(droid_dpy);
droid_drv->default_display = NULL;
}
return EGL_TRUE;
}
static _EGLProc
droid_eglGetProcAddress(const char *procname)
{
return (_EGLProc) _glapi_get_proc_address(procname);
}
static _EGLContext *
droid_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
_EGLContext *share_list, const EGLint *attrib_list)
{
struct droid_egl_display *droid_dpy = lookup_display(dpy);
struct droid_egl_config *droid_conf = lookup_config(conf);
struct droid_egl_context *shared = lookup_context(share_list);
struct droid_egl_context *ctx;
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
_eglError(EGL_BAD_ALLOC, "eglCreateContext");
return NULL;
}
if (!_eglInitContext(drv, &ctx->base, &droid_conf->base, attrib_list)) {
free(ctx);
return NULL;
}
ctx->context =
droid_screen_create_context(droid_dpy->screen, droid_conf->config,
(shared) ? shared->context : NULL);
if (!ctx->context) {
free(ctx);
return NULL;
}
return &ctx->base;
}
static EGLBoolean
droid_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
struct droid_egl_display *droid_dpy = lookup_display(dpy);
struct droid_egl_context *droid_ctx = lookup_context(ctx);
if (!_eglIsContextBound(ctx))
droid_screen_destroy_context(droid_dpy->screen, droid_ctx->context);
return EGL_TRUE;
}
static EGLBoolean
droid_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
_EGLSurface *r, _EGLContext *ctx)
{
struct droid_egl_driver *droid_drv = lookup_driver(drv);
struct droid_egl_display *droid_dpy = lookup_display(dpy);
struct droid_egl_surface *draw = lookup_surface(d);
struct droid_egl_surface *read = lookup_surface(r);
struct droid_egl_context *droid_ctx = lookup_context(ctx);
_EGLContext *old;
struct droid_egl_context *droid_old;
old = _eglGetCurrentContext();
/* an unlinked context will be invalid after context switch */
if (!_eglIsContextLinked(old))
old = NULL;
droid_old = lookup_context(old);
if (!_eglMakeCurrent(drv, dpy, d, r, ctx))
return EGL_FALSE;
if (droid_old && droid_old != droid_ctx && droid_drv->flush_current)
droid_drv->flush_current();
_glapi_check_multithread();
/* bind new context or unbind old one */
if (droid_ctx)
droid_screen_bind_context(droid_dpy->screen,
draw->drawable, read->drawable,
droid_ctx->context);
else if (droid_old)
droid_screen_bind_context(droid_dpy->screen,
NULL, NULL,
droid_old->context);
return EGL_TRUE;
}
static _EGLSurface *
droid_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
NativeWindowType window, const EGLint *attrib_list)
{
struct droid_egl_display *droid_dpy = lookup_display(dpy);
struct droid_egl_config *droid_conf = lookup_config(conf);
struct droid_egl_surface *surf;
surf = calloc(1, sizeof(*surf));
if (!surf) {
_eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
return NULL;
}
if (!_eglInitSurface(drv, &surf->base, EGL_WINDOW_BIT, &droid_conf->base, attrib_list)) {
free(surf);
return NULL;
}
surf->surface =
droid_dpy->backend->create_window_surface(droid_dpy->backend,
&surf->base, window);
if (!surf->surface) {
free(surf);
return NULL;
}
surf->drawable = droid_screen_create_drawable(droid_dpy->screen,
droid_conf->config,
surf->surface);
if (!surf->drawable) {
droid_dpy->backend->destroy_surface(droid_dpy->backend, surf->surface);
free(surf);
return NULL;
}
return &surf->base;
}
static EGLBoolean
droid_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
struct droid_egl_display *droid_dpy = lookup_display(dpy);
struct droid_egl_surface *droid_surf = lookup_surface(surf);
if (_eglIsSurfaceBound(&droid_surf->base))
return EGL_TRUE;
droid_screen_destroy_drawable(droid_dpy->screen, droid_surf->drawable);
droid_dpy->backend->destroy_surface(droid_dpy->backend, droid_surf->surface);
free(droid_surf);
return EGL_TRUE;
}
static EGLBoolean
droid_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
struct droid_egl_driver *droid_drv = lookup_driver(drv);
struct droid_egl_display *droid_dpy = lookup_display(dpy);
struct droid_egl_surface *droid_surf = lookup_surface(surf);
_EGLContext *ctx = _eglGetCurrentContext();
struct droid_egl_context *droid_ctx = lookup_context(ctx);
if (droid_ctx) {
if (droid_drv->flush_current)
droid_drv->flush_current();
droid_screen_swap_buffers(droid_dpy->screen,
droid_ctx->context,
droid_surf->drawable);
}
return EGL_TRUE;
}
#if EGL_KHR_image_base
static _EGLImage *
droid_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list)
{
struct droid_egl_display *droid_dpy = lookup_display(dpy);
struct droid_egl_image *droid_img;
struct droid_egl_config *droid_conf;
_EGLConfig *conf;
EGLint val, i;
/* only EGL_KHR_image_pixmap is supported */
if (target != EGL_NATIVE_PIXMAP_KHR || ctx) {
_eglError(EGL_BAD_PARAMETER, "eglCreateImageKHR");
return NULL;
}
for (i = 0; i < dpy->NumConfigs; i++) {
conf = dpy->Configs[i];
if (droid_dpy->backend->match_pixmap(droid_dpy->backend, conf,
(NativePixmapType) buffer)) {
EGLint val;
val = GET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB);
val |= GET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA);
if (val)
break;
}
}
if (i >= dpy->NumConfigs)
return NULL;
droid_img = calloc(1, sizeof(*droid_img));
if (!droid_img) {
_eglError(EGL_BAD_ALLOC, "eglCreateImageKHR");
return NULL;
}
if (!_eglInitImage(drv, &droid_img->base, attr_list)) {
free(droid_img);
return NULL;
}
droid_img->surface =
droid_dpy->backend->create_image_surface(droid_dpy->backend,
(NativePixmapType) buffer);
if (!droid_img->surface) {
free(droid_img);
return NULL;
}
droid_conf = lookup_config(conf);
droid_img->drawable =
droid_screen_create_drawable(droid_dpy->screen, droid_conf->config,
droid_img->surface);
if (!droid_img->drawable) {
droid_dpy->backend->destroy_surface(droid_dpy->backend,
droid_img->surface);
free(droid_img);
return NULL;
}
droid_img->base.ClientData =
droid_screen_get_drawable_data(droid_dpy->screen, droid_img->drawable);
return &droid_img->base;
}
static EGLBoolean
droid_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img)
{
struct droid_egl_display *droid_dpy = lookup_display(dpy);
struct droid_egl_image *droid_img = lookup_image(img);
droid_screen_destroy_drawable(droid_dpy->screen, droid_img->drawable);
droid_dpy->backend->destroy_surface(droid_dpy->backend, droid_img->surface);
free(droid_img);
return EGL_TRUE;
}
#endif /* EGL_KHR_image_base */
static EGLBoolean
droid_eglWaitClient(_EGLDriver *drv, _EGLDisplay *dpy)
{
struct droid_egl_driver *droid_drv = lookup_driver(drv);
_EGLContext *ctx = _eglGetCurrentContext();
if (!ctx || !droid_drv->finish_current)
return EGL_TRUE;
if (!_eglIsSurfaceLinked(ctx->DrawSurface))
return _eglError(EGL_BAD_CURRENT_SURFACE, "eglWaitClient");
droid_drv->finish_current();
return EGL_TRUE;
}
static EGLBoolean
droid_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
{
struct droid_egl_display *droid_dpy = lookup_display(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
struct droid_egl_surface *droid_surf;
if (engine != EGL_CORE_NATIVE_ENGINE)
return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
if (!ctx)
return EGL_TRUE;
if (!_eglIsSurfaceLinked(ctx->DrawSurface))
return _eglError(EGL_BAD_CURRENT_SURFACE, "eglWaitNative");
droid_surf = lookup_surface(ctx->DrawSurface);
droid_dpy->backend->swap_native_buffers(droid_dpy->backend,
droid_surf->surface);
return EGL_TRUE;
}
static void
droid_Unload(_EGLDriver *drv)
{
struct droid_egl_driver *droid_drv = lookup_driver(drv);
free(droid_drv);
}
static void
droid_Log(EGLint level, const char *msg)
{
switch (level) {
case _EGL_DEBUG:
LOGD(msg);
break;
case _EGL_INFO:
LOGI(msg);
break;
case _EGL_WARNING:
LOGW(msg);
break;
case _EGL_FATAL:
LOGE(msg);
break;
}
}
_EGLDriver *
_eglMain(const char *args)
{
struct droid_egl_driver *droid_drv = calloc(1, sizeof(*droid_drv));
if (!droid_drv)
return NULL;
_eglInitDriverFallbacks(&droid_drv->base);
droid_drv->base.API.Initialize = droid_eglInitialize;
droid_drv->base.API.Terminate = droid_eglTerminate;
droid_drv->base.API.GetProcAddress = droid_eglGetProcAddress;
droid_drv->base.API.CreateContext = droid_eglCreateContext;
droid_drv->base.API.DestroyContext = droid_eglDestroyContext;
droid_drv->base.API.MakeCurrent = droid_eglMakeCurrent;
droid_drv->base.API.CreateWindowSurface = droid_eglCreateWindowSurface;
droid_drv->base.API.DestroySurface = droid_eglDestroySurface;
droid_drv->base.API.SwapBuffers = droid_eglSwapBuffers;
#if EGL_KHR_image_base
droid_drv->base.API.CreateImageKHR = droid_eglCreateImageKHR;
droid_drv->base.API.DestroyImageKHR = droid_eglDestroyImageKHR;
#endif /* EGL_KHR_image_base */
droid_drv->base.API.WaitClient = droid_eglWaitClient;
droid_drv->base.API.WaitNative = droid_eglWaitNative;
droid_drv->base.Name = "Android/i915";
droid_drv->base.Unload = droid_Unload;
/* we need a way to flush commands */
droid_drv->flush_current =
(void (*)(void)) droid_eglGetProcAddress("glFlush");
droid_drv->finish_current =
(void (*)(void)) droid_eglGetProcAddress("glFinish");
_eglSetLogProc(droid_Log);
return &droid_drv->base;
}

View File

@@ -54,18 +54,13 @@
#include "eglglobals.h"
#include "egllog.h"
#include "eglsurface.h"
#include "eglimage.h"
#include "EGL/internal/eglimage_dri.h"
#define MAX_DEPTH 32
#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
/** subclass of _EGLDriver */
struct xdri_egl_driver
{
_EGLDriver Base; /**< base class */
void (*FlushCurrentContext)(void);
};
@@ -78,8 +73,6 @@ struct xdri_egl_display
__GLXscreenConfigs *psc;
EGLint scr;
const __GLcontextModes *imageConfigs[MAX_DEPTH + 1];
};
@@ -105,16 +98,6 @@ struct xdri_egl_surface
};
/** subclass of _EGLImage */
struct xdri_egl_image
{
_EGLImage Base; /**< base class */
Drawable pixmap;
__GLXDRIdrawable *driDrawable;
};
/** subclass of _EGLConfig */
struct xdri_egl_config
{
@@ -164,14 +147,6 @@ lookup_config(_EGLConfig *conf)
}
/** Map EGLImage handle to xdri_egl_image object */
static INLINE struct xdri_egl_image *
lookup_image(_EGLImage *img)
{
return (struct xdri_egl_image *) img;
}
/** Get size of given window */
static Status
get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
@@ -187,62 +162,6 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
}
#if EGL_KHR_image_base
/** Get depth of given window */
static Status
get_drawable_depth(Display *dpy, Drawable d, uint *depth_ret)
{
Window root;
Status stat;
int xpos, ypos;
unsigned int w, h, bw, depth;
stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
*depth_ret = depth;
return stat;
}
/**
* The config of a pixmap must be guessed from its depth. Do the guess once
* for all depths.
*/
static void
find_image_configs(_EGLDisplay *dpy, const __GLcontextModes *modes)
{
struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
EGLint depth;
for (depth = 0; depth < MAX_DEPTH + 1; depth++) {
const __GLcontextModes *m;
for (m = modes; m; m = m->next) {
/* the depth of a pixmap might not include alpha */
if (m->rgbBits != depth && (m->rgbBits - m->alphaBits) != depth)
continue;
if (!m->visualID)
continue;
if (depth == 32) {
if (m->bindToTextureRgba) {
xdri_dpy->imageConfigs[depth] = m;
break;
}
}
if (m->bindToTextureRgb) {
xdri_dpy->imageConfigs[depth] = m;
break;
}
}
if (m)
_eglLog(_EGL_DEBUG, "Use mode 0x%02x for depth %d",
m->visualID, depth);
}
}
#endif /* EGL_KHR_image_base */
/**
* Produce a set of EGL configs.
*/
@@ -356,15 +275,6 @@ xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
EGL_OPENGL_ES2_BIT |
EGL_OPENVG_BIT);
#if EGL_KHR_image_base
/* must be called after DriverData is set */
find_image_configs(dpy, psc->configs);
dpy->Extensions.KHR_image = EGL_TRUE;
dpy->Extensions.KHR_image_base = EGL_TRUE;
dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
#endif
/* we're supporting EGL 1.4 */
*minor = 1;
*major = 4;
@@ -496,23 +406,13 @@ static EGLBoolean
xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
_EGLSurface *r, _EGLContext *context)
{
struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv);
struct xdri_egl_context *xdri_ctx = lookup_context(context);
struct xdri_egl_surface *draw = lookup_surface(d);
struct xdri_egl_surface *read = lookup_surface(r);
_EGLContext *old = _eglGetCurrentContext();
/* an unlinked context will be invalid after context switch */
if (!_eglIsContextLinked(old))
old = NULL;
if (!_eglMakeCurrent(drv, dpy, d, r, context))
return EGL_FALSE;
/* flush before context switch */
if (old && old != context && xdri_driver->FlushCurrentContext)
xdri_driver->FlushCurrentContext();
/* the symbol is defined in libGL.so */
_glapi_check_multithread();
@@ -523,9 +423,12 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
return EGL_FALSE;
}
}
else if (old) {
xdri_ctx = lookup_context(old);
xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
else {
_EGLContext *old = _eglGetCurrentContext();
if (old) {
xdri_ctx = lookup_context(old);
xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
}
}
return EGL_TRUE;
@@ -621,119 +524,15 @@ xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
static EGLBoolean
xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
{
struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv);
struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
/* swapBuffers does not flush commands */
if (draw == _eglGetCurrentSurface(EGL_DRAW) &&
xdri_driver->FlushCurrentContext)
xdri_driver->FlushCurrentContext();
xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable);
return EGL_TRUE;
}
#if EGL_KHR_image_base
static _EGLImage *
xdri_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list)
{
struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
struct xdri_egl_image *xdri_img;
__DRIEGLImage *driImage;
EGLint err = EGL_SUCCESS;
const __GLcontextModes *mode;
uint depth;
xdri_img = CALLOC_STRUCT(xdri_egl_image);
if (!xdri_img) {
_eglError(EGL_BAD_ALLOC, "eglCreateImageKHR");
return NULL;
}
switch (target) {
case EGL_NATIVE_PIXMAP_KHR:
if (ctx) {
err = EGL_BAD_PARAMETER;
break;
}
xdri_img->pixmap = (Pixmap) buffer;
break;
default:
err = EGL_BAD_PARAMETER;
break;
}
if (err != EGL_SUCCESS) {
_eglError(EGL_BAD_PARAMETER, "eglCreateImageKHR");
free(xdri_img);
return NULL;
}
if (!_eglInitImage(drv, &xdri_img->Base, attr_list)) {
free(xdri_img);
return NULL;
}
if (!get_drawable_depth(xdri_dpy->dpy, xdri_img->pixmap, &depth) ||
depth > MAX_DEPTH) {
free(xdri_img);
return NULL;
}
mode = xdri_dpy->imageConfigs[depth];
if (!mode) {
free(xdri_img);
return NULL;
}
driImage = CALLOC_STRUCT(__DRIEGLImageRec);
if (!driImage) {
_eglError(EGL_BAD_ALLOC, "eglCreateImageKHR");
free(xdri_img);
return NULL;
}
xdri_img->driDrawable =
xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc,
(XID) xdri_img->pixmap,
(GLXDrawable) xdri_img->pixmap,
mode);
if (!xdri_img->driDrawable) {
free(driImage);
free(xdri_img);
return NULL;
}
driImage->magic = __DRI_EGL_IMAGE_MAGIC;
driImage->drawable = xdri_img->driDrawable->driDrawable;
driImage->texture_format_rgba = (depth == 32 && mode->bindToTextureRgba);
driImage->level = 0;
xdri_img->Base.ClientData = (void *) driImage;
return &xdri_img->Base;
}
static EGLBoolean
xdri_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img)
{
struct xdri_egl_image *xdri_img = lookup_image(img);
free(xdri_img->Base.ClientData);
xdri_img->driDrawable->destroyDrawable(xdri_img->driDrawable);
free(xdri_img);
return EGL_TRUE;
}
#endif /* EGL_KHR_image_base */
static void
xdri_Unload(_EGLDriver *drv)
{
@@ -768,17 +567,9 @@ _eglMain(const char *args)
xdri_drv->Base.API.BindTexImage = xdri_eglBindTexImage;
xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage;
xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers;
#if EGL_KHR_image_base
xdri_drv->Base.API.CreateImageKHR = xdri_eglCreateImageKHR;
xdri_drv->Base.API.DestroyImageKHR = xdri_eglDestroyImageKHR;
#endif /* EGL_KHR_image_base */
xdri_drv->Base.Name = "X/DRI";
xdri_drv->Base.Unload = xdri_Unload;
/* we need a way to flush commands */
xdri_drv->FlushCurrentContext =
(void (*)(void)) xdri_eglGetProcAddress("glFlush");
return &xdri_drv->Base;
}

View File

@@ -7,7 +7,6 @@ include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi $(X11_INCLUDES)
HEADERS = \
eglclient.h \
eglcompiler.h \
eglconfig.h \
eglconfigutil.h \
@@ -17,7 +16,6 @@ HEADERS = \
egldisplay.h \
egldriver.h \
eglglobals.h \
eglimage.h \
egllog.h \
eglmisc.h \
eglmode.h \
@@ -28,7 +26,6 @@ HEADERS = \
SOURCES = \
eglapi.c \
eglclient.c \
eglconfig.c \
eglconfigutil.c \
eglcontext.c \
@@ -36,7 +33,6 @@ SOURCES = \
egldisplay.c \
egldriver.c \
eglglobals.c \
eglimage.c \
egllog.c \
eglmisc.c \
eglmode.c \

View File

@@ -41,7 +41,6 @@
#include "eglconfig.h"
#include "eglscreen.h"
#include "eglmode.h"
#include "eglimage.h"
/**
@@ -93,8 +92,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
snprintf(disp->Version, sizeof(disp->Version),
"%d.%d (%s)", major_int, minor_int, drv->Name);
/* limit to APIs supported by core */
disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
/* update the global notion of supported APIs */
_eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask;
disp->Driver = drv;
} else {
@@ -645,10 +644,6 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
{ "eglReleaseThread", (_EGLProc) eglReleaseThread },
{ "eglWaitClient", (_EGLProc) eglWaitClient },
#endif /* EGL_VERSION_1_2 */
#ifdef EGL_KHR_image_base
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
#endif /* EGL_KHR_image_base */
{ NULL, NULL }
};
EGLint i;
@@ -658,10 +653,6 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
}
}
/* preload a driver if there isn't one */
if (!_eglGlobal.NumDrivers)
_eglPreloadDriver(NULL);
/* now loop over drivers to query their procs */
for (i = 0; i < _eglGlobal.NumDrivers; i++) {
_EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname);
@@ -876,7 +867,33 @@ eglBindAPI(EGLenum api)
if (!_eglIsApiValid(api))
return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
t->CurrentAPIIndex = _eglConvertApiToIndex(api);
switch (api) {
#ifdef EGL_VERSION_1_4
case EGL_OPENGL_API:
if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) {
t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
return EGL_FALSE;
#endif
case EGL_OPENGL_ES_API:
if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) {
t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
return EGL_FALSE;
case EGL_OPENVG_API:
if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) {
t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
return EGL_FALSE;
default:
return EGL_FALSE;
}
return EGL_TRUE;
}
@@ -951,50 +968,3 @@ eglWaitClient(void)
#endif /* EGL_VERSION_1_2 */
#ifdef EGL_KHR_image_base
EGLImageKHR
eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLContext *context = _eglLookupContext(ctx, disp);
_EGLDriver *drv;
_EGLImage *img;
drv = _eglCheckDisplay(disp, __FUNCTION__);
if (!drv)
return EGL_NO_IMAGE_KHR;
if (!context && ctx != EGL_NO_CONTEXT) {
_eglError(EGL_BAD_CONTEXT, __FUNCTION__);
return EGL_NO_IMAGE_KHR;
}
img = drv->API.CreateImageKHR(drv, disp, context, target, buffer, attr_list);
if (img)
return _eglLinkImage(img, disp);
else
return EGL_NO_IMAGE_KHR;
}
EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLImage *img = _eglLookupImage(image, disp);
_EGLDriver *drv;
drv = _eglCheckDisplay(disp, __FUNCTION__);
if (!drv)
return EGL_FALSE;
if (!img)
return _eglError(EGL_BAD_PARAMETER, __FUNCTION__);
_eglUnlinkImage(img);
return drv->API.DestroyImageKHR(drv, disp, img);
}
#endif /* EGL_KHR_image_base */

View File

@@ -70,11 +70,6 @@ typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDis
#endif /* EGL_VERSION_1_2 */
#ifdef EGL_KHR_image_base
typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list);
typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
#endif /* EGL_KHR_image_base */
/**
* The API dispatcher jumps through these functions
@@ -110,7 +105,7 @@ struct _egl_api
WaitNative_t WaitNative;
GetProcAddress_t GetProcAddress;
#ifdef EGL_MESA_screen_surface
/* EGL_MESA_screen extension */
ChooseModeMESA_t ChooseModeMESA;
GetModesMESA_t GetModesMESA;
GetModeAttribMESA_t GetModeAttribMESA;
@@ -123,17 +118,11 @@ struct _egl_api
QueryScreenSurfaceMESA_t QueryScreenSurfaceMESA;
QueryScreenModeMESA_t QueryScreenModeMESA;
QueryModeStringMESA_t QueryModeStringMESA;
#endif /* EGL_MESA_screen_surface */
#ifdef EGL_VERSION_1_2
WaitClient_t WaitClient;
CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer;
#endif
#ifdef EGL_KHR_image_base
CreateImageKHR_t CreateImageKHR;
DestroyImageKHR_t DestroyImageKHR;
#endif /* EGL_KHR_image_base */
};
#endif /* EGLAPI_INCLUDED */

View File

@@ -1,21 +0,0 @@
/**
* Functions that client APIs can call.
*/
#include "eglcurrent.h"
#include "egldisplay.h"
#include "eglimage.h"
#include "eglclient.h"
/**
* Return the opaque client data of an image.
*/
void *
_eglClientGetImageData(EGLImageKHR image)
{
_EGLDisplay *dpy = _eglGetCurrentDisplay();
_EGLImage *img = _eglLookupImage(image, dpy);
return (img) ? img->ClientData : NULL;
}

View File

@@ -1,12 +0,0 @@
#ifndef EGLCLIENT_INCLUDED
#define EGLCLIENT_INCLUDED
#include "egltypedefs.h"
extern void *
_eglClientGetImageData(EGLImageKHR image);
#endif /* EGLCLIENT_INCLUDED */

View File

@@ -9,7 +9,7 @@
/* This should be kept in sync with _eglInitThreadInfo() */
#define _EGL_THREAD_INFO_INITIALIZER \
{ EGL_SUCCESS, { NULL }, 0 }
{ EGL_SUCCESS, { NULL }, 1 }
/* a fallback thread info to guarantee that every thread always has one */
static _EGLThreadInfo dummy_thread = _EGL_THREAD_INFO_INITIALIZER;

View File

@@ -4,16 +4,8 @@
#include "egltypedefs.h"
#define _EGL_API_ALL_BITS \
(EGL_OPENGL_ES_BIT | \
EGL_OPENVG_BIT | \
EGL_OPENGL_ES2_BIT | \
EGL_OPENGL_BIT)
#define _EGL_API_FIRST_API EGL_OPENGL_ES_API
#define _EGL_API_LAST_API EGL_OPENGL_API
#define _EGL_API_NUM_APIS (_EGL_API_LAST_API - _EGL_API_FIRST_API + 1)
#define _EGL_API_NUM_INDICES \
(EGL_OPENGL_API - EGL_OPENGL_ES_API + 2) /* idx 0 is for EGL_NONE */
/**
@@ -22,19 +14,20 @@
struct _egl_thread_info
{
EGLint LastError;
_EGLContext *CurrentContexts[_EGL_API_NUM_APIS];
_EGLContext *CurrentContexts[_EGL_API_NUM_INDICES];
/* use index for fast access to current context */
EGLint CurrentAPIIndex;
};
/**
* Return true if a client API enum is recognized.
* Return true if a client API enum can be converted to an index.
*/
static INLINE EGLBoolean
_eglIsApiValid(EGLenum api)
{
return (api >= _EGL_API_FIRST_API && api <= _EGL_API_LAST_API);
return ((api >= EGL_OPENGL_ES_API && api <= EGL_OPENGL_API) ||
api == EGL_NONE);
}
@@ -45,7 +38,7 @@ _eglIsApiValid(EGLenum api)
static INLINE EGLint
_eglConvertApiToIndex(EGLenum api)
{
return api - _EGL_API_FIRST_API;
return (api != EGL_NONE) ? api - EGL_OPENGL_ES_API + 1 : 0;
}
@@ -56,7 +49,7 @@ _eglConvertApiToIndex(EGLenum api)
static INLINE EGLenum
_eglConvertApiFromIndex(EGLint idx)
{
return _EGL_API_FIRST_API + idx;
return (idx) ? EGL_OPENGL_ES_API + idx - 1 : EGL_NONE;
}

View File

@@ -14,9 +14,6 @@ struct _egl_extensions
{
EGLBoolean MESA_screen_surface;
EGLBoolean MESA_copy_context;
EGLBoolean KHR_image;
EGLBoolean KHR_image_base;
EGLBoolean KHR_image_pixmap;
char String[_EGL_MAX_EXTENSIONS_LEN];
};
@@ -53,8 +50,6 @@ struct _egl_display
/* lists of linked contexts and surface */
_EGLContext *ContextList;
_EGLSurface *SurfaceList;
_EGLImage *ImageList;
};

View File

@@ -19,74 +19,62 @@
#include "eglscreen.h"
#include "eglstring.h"
#include "eglsurface.h"
#include "eglimage.h"
#if defined(_EGL_PLATFORM_X)
#include <dlfcn.h>
#elif defined(_EGL_PLATFORM_WINDOWS)
/* Use static linking on Windows for now */
#define WINDOWS_STATIC_LINK
#endif
/**
* Wrappers for dlopen/dlclose()
*/
#if defined(_EGL_PLATFORM_WINDOWS)
#ifdef WINDOWS_STATIC_LINK
static const char *DefaultDriverName = "Windows EGL Static Library";
#else
/* XXX Need to decide how to do dynamic name lookup on Windows */
static const char *DefaultDriverName = "TBD";
#endif
typedef HMODULE lib_handle;
static HMODULE
open_library(const char *filename)
{
#ifdef WINDOWS_STATIC_LINK
return 0;
#else
return LoadLibrary(filename);
#endif
}
/* XXX Need to decide how to do dynamic name lookup on Windows */
static const char DefaultDriverName[] = "TBD";
typedef HMODULE lib_handle;
static HMODULE
open_library(const char *filename)
{
return LoadLibrary(filename);
}
static void
close_library(HMODULE lib)
{
FreeLibrary(lib);
}
static void
close_library(HMODULE lib)
{
#ifdef WINDOWS_STATIC_LINK
#else
FreeLibrary(lib);
#endif
}
#elif defined(_EGL_PLATFORM_X)
static const char *DefaultDriverName = "egl_softpipe";
typedef void * lib_handle;
static const char DefaultDriverName[] = "egl_softpipe";
typedef void * lib_handle;
static void *
open_library(const char *filename)
{
return dlopen(filename, RTLD_LAZY);
}
static void
close_library(void *lib)
{
dlclose(lib);
}
#else /* _EGL_PLATFORM_NO_OS */
static const char DefaultDriverName[] = "builtin";
typedef void *lib_handle;
static INLINE void *
open_library(const char *filename)
{
return (void *) filename;
}
static INLINE void
close_library(void *lib)
{
}
static void *
open_library(const char *filename)
{
return dlopen(filename, RTLD_LAZY);
}
static void
close_library(void *lib)
{
dlclose(lib);
}
#endif
@@ -107,22 +95,14 @@ _eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
path = _eglstrdup(path);
#if defined(_EGL_PLATFORM_X)
if (!path && dpy && dpy->NativeDisplay) {
if (!path && dpy->NativeDisplay) {
/* assume (wrongly!) that the native display is a display string */
path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args);
}
suffix = "so";
#elif defined(_EGL_PLATFORM_WINDOWS)
suffix = "dll";
#else /* _EGL_PLATFORM_NO_OS */
if (path) {
/* force the use of the default driver */
_eglLog(_EGL_DEBUG, "ignore EGL_DRIVER");
free(path);
path = NULL;
}
suffix = NULL;
#endif
#endif /* _EGL_PLATFORM_X */
if (!path)
path = _eglstrdup(DefaultDriverName);
@@ -156,48 +136,43 @@ _eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
static _EGLMain_t
_eglOpenLibrary(const char *driverPath, lib_handle *handle)
{
_EGLMain_t mainFunc;
lib_handle lib;
_EGLMain_t mainFunc = NULL;
const char *error = "unknown error";
assert(driverPath);
#if defined(_EGL_PLATFORM_WINDOWS)
/* Use static linking on Windows for now */
#ifdef WINDOWS_STATIC_LINK
lib = 0;
mainFunc = (_EGLMain_t)_eglMain;
#else
/* XXX untested */
_eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
lib = open_library(driverPath);
#if defined(_EGL_PLATFORM_WINDOWS)
/* XXX untested */
if (lib)
mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
#elif defined(_EGL_PLATFORM_X)
if (lib) {
mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
if (!mainFunc)
error = dlerror();
}
else {
error = dlerror();
}
#else /* _EGL_PLATFORM_NO_OS */
/* must be the default driver name */
if (strcmp(driverPath, DefaultDriverName) == 0)
mainFunc = (_EGLMain_t) _eglMain;
else
error = "not builtin driver";
#endif
if (!lib) {
_eglLog(_EGL_WARNING, "Could not open driver %s (%s)",
driverPath, error);
_eglLog(_EGL_WARNING, "Could not open %s",
driverPath);
return NULL;
}
mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
#endif
#elif defined(_EGL_PLATFORM_X)
_eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
lib = open_library(driverPath);
if (!lib) {
_eglLog(_EGL_WARNING, "Could not open %s (%s)",
driverPath, dlerror());
if (!getenv("EGL_DRIVER"))
_eglLog(_EGL_WARNING,
"The driver can be overridden by setting EGL_DRIVER");
return NULL;
}
mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
#endif
if (!mainFunc) {
_eglLog(_EGL_WARNING, "_eglMain not found in %s (%s)",
driverPath, error);
_eglLog(_EGL_WARNING, "_eglMain not found in %s", driverPath);
if (lib)
close_library(lib);
return NULL;
@@ -429,11 +404,6 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
#ifdef EGL_VERSION_1_2
drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
#endif /* EGL_VERSION_1_2 */
#ifdef EGL_KHR_image_base
drv->API.CreateImageKHR = _eglCreateImageKHR;
drv->API.DestroyImageKHR = _eglDestroyImageKHR;
#endif /* EGL_KHR_image_base */
}
@@ -458,11 +428,6 @@ _eglFindAPIs(void)
const char *es2_libname = "libGLESv2.so";
const char *gl_libname = "libGL.so";
const char *vg_libname = "libOpenVG.so";
#else /* _EGL_PLATFORM_NO_OS */
const char *es1_libname = NULL;
const char *es2_libname = NULL;
const char *gl_libname = NULL;
const char *vg_libname = NULL;
#endif
if ((lib = open_library(es1_libname))) {

View File

@@ -15,13 +15,13 @@ struct _egl_global _eglGlobal =
&_eglGlobalMutex, /* Mutex */
NULL, /* DisplayList */
1, /* FreeScreenHandle */
0x0, /* ClientAPIsMask */
0, /* NumDrivers */
{ NULL }, /* Drivers */
2, /* NumAtExitCalls */
{
/* default AtExitCalls, called in reverse order */
_eglUnloadDrivers, /* always called last */
_eglFiniDisplay
{ /* AtExitCalls */
_eglFiniDisplay,
_eglUnloadDrivers
},
};

View File

@@ -19,6 +19,9 @@ struct _egl_global
EGLScreenMESA FreeScreenHandle;
/* bitmaks of supported APIs (supported by _some_ driver) */
EGLint ClientAPIsMask;
EGLint NumDrivers;
_EGLDriver *Drivers[10];

View File

@@ -1,104 +0,0 @@
#include <assert.h>
#include "eglimage.h"
#include "egldisplay.h"
EGLBoolean
_eglInitImage(_EGLDriver *drv, _EGLImage *img, const EGLint *attrib_list)
{
EGLint i;
img->Preserved = EGL_FALSE;
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_IMAGE_PRESERVED_KHR:
i++;
img->Preserved = attrib_list[i];
break;
default:
/* not an error */
break;
}
}
return EGL_TRUE;
}
_EGLImage *
_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list)
{
/* driver should override this function */
return NULL;
}
EGLBoolean
_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image)
{
/* driver should override this function */
return EGL_FALSE;
}
EGLImageKHR
_eglLinkImage(_EGLImage *img, _EGLDisplay *dpy)
{
img->Display = dpy;
img->Next = dpy->ImageList;
dpy->ImageList = img;
return (EGLImageKHR) img;
}
void
_eglUnlinkImage(_EGLImage *img)
{
_EGLImage *prev;
prev = img->Display->ImageList;
if (prev != img) {
while (prev) {
if (prev->Next == img)
break;
prev = prev->Next;
}
assert(prev);
prev->Next = img->Next;
}
else {
img->Display->ImageList = img->Next;
}
img->Next = NULL;
img->Display = NULL;
}
#ifndef _EGL_SKIP_HANDLE_CHECK
/**
* Return EGL_TRUE if the given handle is a valid handle to an image.
*/
EGLBoolean
_eglCheckImageHandle(EGLImageKHR img, _EGLDisplay *dpy)
{
_EGLImage *cur = NULL;
if (dpy)
cur = dpy->ImageList;
while (cur) {
if (cur == (_EGLImage *) img) {
assert(cur->Display == dpy);
break;
}
cur = cur->Next;
}
return (cur != NULL);
}
#endif /* _EGL_SKIP_HANDLE_CHECK */

View File

@@ -1,93 +0,0 @@
#ifndef EGLIMAGE_INCLUDED
#define EGLIMAGE_INCLUDED
#include "egltypedefs.h"
/**
* "Base" class for device driver images.
*/
struct _egl_image
{
/* Client data that client APIs and the driver agree on */
void *ClientData;
/* Managed by EGLDisplay for linking */
_EGLDisplay *Display;
_EGLImage *Next;
EGLBoolean Preserved;
};
extern EGLBoolean
_eglInitImage(_EGLDriver *drv, _EGLImage *img, const EGLint *attrib_list);
extern _EGLImage *
_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list);
extern EGLBoolean
_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
extern EGLImageKHR
_eglLinkImage(_EGLImage *img, _EGLDisplay *dpy);
extern void
_eglUnlinkImage(_EGLImage *img);
#ifndef _EGL_SKIP_HANDLE_CHECK
extern EGLBoolean
_eglCheckImageHandle(EGLImageKHR img, _EGLDisplay *dpy);
#else
/**
* Perform a quick check on the handle.
*/
static INLINE EGLBoolean
_eglCheckImageHandle(EGLImageKHR img, _EGLDisplay *dpy)
{
_EGLImage *i = (_EGLImage *) img;
return (dpy && i && i->Display == dpy);
}
#endif
/**
* Lookup a handle to find the linked image.
* Return NULL if the handle has no corresponding linked image.
*/
static INLINE _EGLImage *
_eglLookupImage(EGLImageKHR image, _EGLDisplay *dpy)
{
_EGLImage *img = (_EGLImage *) image;
if (!_eglCheckImageHandle(img, dpy))
img = NULL;
return img;
}
/**
* Return the handle of a linked image.
*/
static INLINE EGLImageKHR
_eglGetImageHandle(_EGLImage *img)
{
return (EGLImageKHR) ((img && img->Display) ? img : EGL_NO_IMAGE_KHR);
}
#endif /* EGLIMAGE_INCLUDED */

View File

@@ -9,140 +9,51 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "egllog.h"
#include "eglmutex.h"
#define MAXSTRING 1000
#define FALLBACK_LOG_LEVEL _EGL_WARNING
#define FALLBACK_LOG_LEVEL _EGL_WARNING
#define FALLBACK_LOG_LEVEL_STR "warning"
static EGLint ReportingLevel = -1;
static struct {
_EGLMutex mutex;
EGLBoolean initialized;
EGLint level;
_EGLLogProc logger;
EGLint num_messages;
} logging = {
_EGL_MUTEX_INITIALIZER,
EGL_FALSE,
FALLBACK_LOG_LEVEL,
NULL,
0
};
static const char *level_strings[] = {
/* the order is important */
"fatal",
"warning",
"info",
"debug",
NULL
};
/**
* Set the function to be called when there is a message to log.
* Note that the function will be called with an internal lock held.
* Recursive logging is not allowed.
*/
void
_eglSetLogProc(_EGLLogProc logger)
{
EGLint num_messages = 0;
_eglLockMutex(&logging.mutex);
if (logging.logger != logger) {
logging.logger = logger;
num_messages = logging.num_messages;
logging.num_messages = 0;
}
_eglUnlockMutex(&logging.mutex);
if (num_messages)
_eglLog(_EGL_DEBUG,
"New logger installed. "
"Messages before the new logger might not be available.");
}
/**
* Set the log reporting level.
*/
void
_eglSetLogLevel(EGLint level)
{
switch (level) {
case _EGL_FATAL:
case _EGL_WARNING:
case _EGL_INFO:
case _EGL_DEBUG:
_eglLockMutex(&logging.mutex);
logging.level = level;
_eglUnlockMutex(&logging.mutex);
break;
default:
break;
}
}
/**
* The default logger. It prints the message to stderr.
*/
static void
_eglDefaultLogger(EGLint level, const char *msg)
log_level_initialize(void)
{
fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg);
}
#if defined(_EGL_PLATFORM_X)
char *log_env = getenv("EGL_LOG_LEVEL");
#else
char *log_env = NULL;
#endif
/**
* Initialize the logging facility.
*/
static void
_eglInitLogger(void)
{
const char *log_env;
EGLint i, level = -1;
if (logging.initialized)
return;
log_env = getenv("EGL_LOG_LEVEL");
if (log_env) {
for (i = 0; level_strings[i]; i++) {
if (strcasecmp(log_env, level_strings[i]) == 0) {
level = i;
break;
}
}
if (log_env == NULL) {
ReportingLevel = FALLBACK_LOG_LEVEL;
}
else if (strcasecmp(log_env, "fatal") == 0) {
ReportingLevel = _EGL_FATAL;
}
else if (strcasecmp(log_env, "warning") == 0) {
ReportingLevel = _EGL_WARNING;
}
else if (strcasecmp(log_env, "info") == 0) {
ReportingLevel = _EGL_INFO;
}
else if (strcasecmp(log_env, "debug") == 0) {
ReportingLevel = _EGL_DEBUG;
}
else {
level = FALLBACK_LOG_LEVEL;
}
logging.logger = _eglDefaultLogger;
logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL;
logging.initialized = EGL_TRUE;
/* it is fine to call _eglLog now */
if (log_env && level < 0) {
_eglLog(_EGL_WARNING,
"Unrecognized EGL_LOG_LEVEL environment variable value. "
fprintf(stderr, "Unrecognized EGL_LOG_LEVEL environment variable value. "
"Expected one of \"fatal\", \"warning\", \"info\", \"debug\". "
"Got \"%s\". Falling back to \"%s\".",
log_env, level_strings[FALLBACK_LOG_LEVEL]);
"Got \"%s\". Falling back to \"%s\".\n",
log_env, FALLBACK_LOG_LEVEL_STR);
ReportingLevel = FALLBACK_LOG_LEVEL;
}
}
/**
* Log a message with message logger.
* Log a message to stderr.
* \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG.
*/
void
@@ -150,26 +61,40 @@ _eglLog(EGLint level, const char *fmtStr, ...)
{
va_list args;
char msg[MAXSTRING];
const char *levelStr;
static int log_level_initialized = 0;
/* one-time initialization; a little race here is fine */
if (!logging.initialized)
_eglInitLogger();
if (level > logging.level || level < 0)
return;
if (!log_level_initialized) {
log_level_initialize();
log_level_initialized = 1;
}
_eglLockMutex(&logging.mutex);
if (level <= ReportingLevel) {
switch (level) {
case _EGL_FATAL:
levelStr = "Fatal";
break;
case _EGL_WARNING:
levelStr = "Warning";
break;
case _EGL_INFO:
levelStr = "Info";
break;
case _EGL_DEBUG:
levelStr = "Debug";
break;
default:
levelStr = "";
}
if (logging.logger) {
va_start(args, fmtStr);
vsnprintf(msg, MAXSTRING, fmtStr, args);
va_end(args);
logging.logger(level, msg);
logging.num_messages++;
fprintf(stderr, "libEGL %s: %s\n", levelStr, msg);
if (level == _EGL_FATAL) {
exit(1); /* or abort()? */
}
}
_eglUnlockMutex(&logging.mutex);
if (level == _EGL_FATAL)
exit(1); /* or abort()? */
}

View File

@@ -9,17 +9,6 @@
#define _EGL_DEBUG 3 /* useful info for debugging */
typedef void (*_EGLLogProc)(EGLint level, const char *msg);
extern void
_eglSetLogProc(_EGLLogProc logger);
extern void
_eglSetLogLevel(EGLint level);
extern void
_eglLog(EGLint level, const char *fmtStr, ...);

View File

@@ -54,12 +54,6 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
strcat(exts, "EGL_MESA_screen_surface ");
if (dpy->Extensions.MESA_copy_context)
strcat(exts, "EGL_MESA_copy_context ");
if (dpy->Extensions.KHR_image)
strcat(exts, "EGL_KHR_image ");
if (dpy->Extensions.KHR_image_base)
strcat(exts, "EGL_KHR_image_base ");
if (dpy->Extensions.KHR_image_pixmap)
strcat(exts, "EGL_KHR_image_pixmap ");
assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN);
}

View File

@@ -6,62 +6,6 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#ifndef EGL_MESA_screen_surface
#define EGL_MESA_screen_surface 1
#define EGL_BAD_SCREEN_MESA 0x4000
#define EGL_BAD_MODE_MESA 0x4001
#define EGL_SCREEN_COUNT_MESA 0x4002
#define EGL_SCREEN_POSITION_MESA 0x4003
#define EGL_SCREEN_POSITION_GRANULARITY_MESA 0x4004
#define EGL_MODE_ID_MESA 0x4005
#define EGL_REFRESH_RATE_MESA 0x4006
#define EGL_OPTIMAL_MESA 0x4007
#define EGL_INTERLACED_MESA 0x4008
#define EGL_SCREEN_BIT_MESA 0x08
typedef uint32_t EGLScreenMESA;
typedef uint32_t EGLModeMESA;
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
EGLAPI EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
EGLAPI EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
EGLAPI EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
EGLAPI EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
EGLAPI const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSEMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMODESMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGetModeATTRIBMESA) (EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSCRREENSMESA) (EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESCREENSURFACEMESA) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSHOWSCREENSURFACEMESA) (EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSCREENPOSIITONMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENSURFACEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
typedef const char * (EGLAPIENTRYP PFNEGLQUERYMODESTRINGMESA) (EGLDisplay dpy, EGLModeMESA mode);
#endif /* EGL_MESA_screen_surface */
#ifndef EGL_MESA_copy_context
#define EGL_MESA_copy_context 1
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
#endif /* EGL_MESA_copy_context */
#include "eglcompiler.h"
typedef struct _egl_api _EGLAPI;
@@ -84,8 +28,6 @@ typedef struct _egl_surface _EGLSurface;
typedef struct _egl_thread_info _EGLThreadInfo;
typedef struct _egl_image _EGLImage;
typedef _EGLDriver *(*_EGLMain_t)(const char *args);

View File

@@ -1431,11 +1431,11 @@ fetch_texel( struct tgsi_sampler **sampler,
{
float rgba[NUM_CHANNELS][QUAD_SIZE];
(*sampler)->get_samples(*sampler,
&store[0],
&store[4],
&store[8],
0.0f, /*store[12], lodbias */
rgba);
&store[0], /* s */
&store[4], /* t */
&store[8], /* r */
store[12], /* lodbias */
rgba); /* results */
memcpy( store, rgba, 16 * sizeof(float));
}

View File

@@ -1,94 +0,0 @@
/**************************************************************************
*
* Copyright © 2009 Jakob Bornecrantz
*
* 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.
*
**************************************************************************/
#ifndef U_FIFO_H
#define U_FIFO_H
#include "util/u_memory.h"
struct util_fifo
{
size_t head;
size_t tail;
size_t num;
size_t size;
};
static INLINE struct util_fifo *
u_fifo_create(size_t size)
{
struct util_fifo *fifo;
fifo = MALLOC(sizeof(*fifo) + size * sizeof(void*));
fifo->head = 0;
fifo->tail = 0;
fifo->num = 0;
fifo->size = size;
return fifo;
}
static INLINE boolean
u_fifo_add(struct util_fifo *fifo, void *ptr)
{
void **array = (void**)&fifo[1];
if (fifo->num >= fifo->size)
return FALSE;
if (++fifo->head >= fifo->size)
fifo->head = 0;
array[fifo->head] = ptr;
++fifo->num;
return TRUE;
}
static INLINE boolean
u_fifo_pop(struct util_fifo *fifo, void **ptr)
{
void **array = (void**)&fifo[1];
if (!fifo->num)
return FALSE;
if (++fifo->tail >= fifo->size)
fifo->tail = 0;
*ptr = array[fifo->tail];
++fifo->num;
return TRUE;
}
static INLINE void
u_fifo_destroy(struct util_fifo *fifo)
{
FREE(fifo);
}
#endif

View File

@@ -14,10 +14,10 @@ PIPE_FORMAT_L16_UNORM , arith , 1, 1, un16, , , , xxx1,
PIPE_FORMAT_Z16_UNORM , array , 1, 1, un16, , , , x___, zs
PIPE_FORMAT_Z32_UNORM , array , 1, 1, un32, , , , x___, zs
PIPE_FORMAT_Z32_FLOAT , array , 1, 1, f32 , , , , x___, zs
PIPE_FORMAT_S8Z24_UNORM , arith , 1, 1, un24, un8 , , , xy__, zs
PIPE_FORMAT_Z24S8_UNORM , arith , 1, 1, un8 , un24, , , yx__, zs
PIPE_FORMAT_X8Z24_UNORM , arith , 1, 1, un24, un8 , , , x___, zs
PIPE_FORMAT_Z24X8_UNORM , arith , 1, 1, un8 , un24, , , y___, zs
PIPE_FORMAT_S8Z24_UNORM , arith , 1, 1, un8 , un24, , , yx__, zs
PIPE_FORMAT_Z24S8_UNORM , arith , 1, 1, un24, un8 , , , xy__, zs
PIPE_FORMAT_X8Z24_UNORM , arith , 1, 1, un8 , un24, , , y___, zs
PIPE_FORMAT_Z24X8_UNORM , arith , 1, 1, un24, un8 , , , x___, zs
PIPE_FORMAT_S8_UNORM , array , 1, 1, un8 , , , , _x__, zs
PIPE_FORMAT_R64_FLOAT , array , 1, 1, f64 , , , , x001, rgb
PIPE_FORMAT_R64G64_FLOAT , array , 1, 1, f64 , f64 , , , xy01, rgb
1 PIPE_FORMAT_A8R8G8B8_UNORM arith 1 1 un8 un8 un8 un8 zyxw rgb
14 PIPE_FORMAT_Z16_UNORM array 1 1 un16 x___ zs
15 PIPE_FORMAT_Z32_UNORM array 1 1 un32 x___ zs
16 PIPE_FORMAT_Z32_FLOAT array 1 1 f32 x___ zs
17 PIPE_FORMAT_S8Z24_UNORM arith 1 1 un24 un8 un8 un24 xy__ yx__ zs
18 PIPE_FORMAT_Z24S8_UNORM arith 1 1 un8 un24 un24 un8 yx__ xy__ zs
19 PIPE_FORMAT_X8Z24_UNORM arith 1 1 un24 un8 un8 un24 x___ y___ zs
20 PIPE_FORMAT_Z24X8_UNORM arith 1 1 un8 un24 un24 un8 y___ x___ zs
21 PIPE_FORMAT_S8_UNORM array 1 1 un8 _x__ zs
22 PIPE_FORMAT_R64_FLOAT array 1 1 f64 x001 rgb
23 PIPE_FORMAT_R64G64_FLOAT array 1 1 f64 f64 xy01 rgb

View File

@@ -340,16 +340,6 @@ util_is_inf_or_nan(float x)
}
/**
* Test whether x is a power of two.
*/
static INLINE boolean
util_is_pot(unsigned x)
{
return (x & (x - 1)) == 0;
}
/**
* Find first bit set in word. Least significant bit is 1.
* Return 0 if no bits set.

View File

@@ -52,7 +52,8 @@ pass_user_buffer_create(struct pipe_screen *screen,
unsigned bytes)
{
struct pipe_buffer *buffer =
screen->winsys->user_buffer_create(screen->winsys, ptr, bytes);
screen->winsys->user_buffer_create(screen->winsys,
ptr, bytes);
buffer->screen = screen;
@@ -68,8 +69,9 @@ pass_surface_buffer_create(struct pipe_screen *screen,
unsigned *stride)
{
struct pipe_buffer *buffer =
screen->winsys->surface_buffer_create(screen->winsys, width, height,
format, usage, tex_usage, stride);
screen->winsys->surface_buffer_create(screen->winsys,
width, height,
format, usage, tex_usage, stride);
buffer->screen = screen;
@@ -81,7 +83,8 @@ pass_buffer_map(struct pipe_screen *screen,
struct pipe_buffer *buf,
unsigned usage)
{
return screen->winsys->buffer_map(screen->winsys, buf, usage);
return screen->winsys->buffer_map(screen->winsys,
buf, usage);
}
static void
@@ -103,7 +106,8 @@ pass_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surf,
void *context_private)
{
screen->winsys->flush_frontbuffer(screen->winsys, surf, context_private);
screen->winsys->flush_frontbuffer(screen->winsys,
surf, context_private);
}
static void
@@ -111,7 +115,8 @@ pass_fence_reference(struct pipe_screen *screen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
screen->winsys->fence_reference(screen->winsys, ptr, fence);
screen->winsys->fence_reference(screen->winsys,
ptr, fence);
}
static int
@@ -119,7 +124,8 @@ pass_fence_signalled(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
unsigned flag)
{
return screen->winsys->fence_signalled(screen->winsys, fence, flag);
return screen->winsys->fence_signalled(screen->winsys,
fence, flag);
}
static int
@@ -127,11 +133,11 @@ pass_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
unsigned flag)
{
return screen->winsys->fence_finish(screen->winsys, fence, flag);
return screen->winsys->fence_finish(screen->winsys,
fence, flag);
}
void
u_simple_screen_init(struct pipe_screen *screen)
void u_simple_screen_init(struct pipe_screen *screen)
{
screen->buffer_create = pass_buffer_create;
screen->user_buffer_create = pass_user_buffer_create;
@@ -146,8 +152,7 @@ u_simple_screen_init(struct pipe_screen *screen)
screen->fence_finish = pass_fence_finish;
}
const char *
u_simple_screen_winsys_name(struct pipe_screen *screen)
const char* u_simple_screen_winsys_name(struct pipe_screen *screen)
{
return screen->winsys->get_name(screen->winsys);
}

View File

@@ -34,8 +34,14 @@
#include "pipe/p_context.h"
#include "util/u_debug.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
#include "tgsi/tgsi_ureg.h"

View File

@@ -170,7 +170,7 @@ x8r8g8b8_get_tile_rgba(const unsigned *src,
pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
pRow[1] = ubyte_to_float((pixel >> 8) & 0xff);
pRow[2] = ubyte_to_float((pixel >> 0) & 0xff);
pRow[3] = 1.0F;
pRow[3] = ubyte_to_float(0xff);
}
p += dst_stride;
}
@@ -394,52 +394,6 @@ r5g6b5_put_tile_rgba(ushort *dst,
/*** PIPE_FORMAT_R8G8B8_UNORM ***/
static void
r8g8b8_get_tile_rgba(const ubyte *src,
unsigned w, unsigned h,
float *p,
unsigned dst_stride)
{
unsigned i, j;
for (i = 0; i < h; i++) {
float *pRow = p;
for (j = 0; j < w; j++, pRow += 4) {
pRow[0] = ubyte_to_float(src[0]);
pRow[1] = ubyte_to_float(src[1]);
pRow[2] = ubyte_to_float(src[2]);
pRow[3] = 1.0f;
src += 3;
}
p += dst_stride;
}
}
static void
r8g8b8_put_tile_rgba(ubyte *dst,
unsigned w, unsigned h,
const float *p,
unsigned src_stride)
{
unsigned i, j;
for (i = 0; i < h; i++) {
const float *pRow = p;
for (j = 0; j < w; j++, pRow += 4) {
dst[0] = float_to_ubyte(pRow[0]);
dst[1] = float_to_ubyte(pRow[1]);
dst[2] = float_to_ubyte(pRow[2]);
dst += 3;
}
p += src_stride;
}
}
/*** PIPE_FORMAT_Z16_UNORM ***/
/**
@@ -1152,9 +1106,6 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
case PIPE_FORMAT_R5G6B5_UNORM:
r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_R8G8B8_UNORM:
r8g8b8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_L8_UNORM:
l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
@@ -1271,9 +1222,6 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
case PIPE_FORMAT_R5G6B5_UNORM:
r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
break;
case PIPE_FORMAT_R8G8B8_UNORM:
r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
break;
case PIPE_FORMAT_R8G8B8A8_UNORM:
assert(0);
break;

View File

@@ -44,7 +44,6 @@
#include "pipe/p_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_fifo.h"
#include "i915_context.h"
#include "i915_reg.h"
@@ -77,13 +76,8 @@ struct i915_vbuf_render {
size_t vbo_size;
size_t vbo_offset;
void *vbo_ptr;
size_t vbo_alloc_size;
size_t vbo_max_used;
/* stuff for the pool */
struct util_fifo *pool_fifo;
unsigned pool_used;
unsigned pool_buffer_size;
boolean pool_not_used;
};
@@ -111,55 +105,6 @@ i915_vbuf_render_get_vertex_info(struct vbuf_render *render)
return &i915->current.vertex_info;
}
static boolean
i915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size)
{
struct i915_context *i915 = i915_render->i915;
if (i915_render->vbo_size < size + i915_render->vbo_offset)
return FALSE;
if (i915->vbo_flushed)
return FALSE;
return TRUE;
}
static void
i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
{
struct i915_context *i915 = i915_render->i915;
struct intel_winsys *iws = i915->iws;
if (i915_render->vbo) {
if (i915_render->pool_not_used)
iws->buffer_destroy(iws, i915_render->vbo);
else
u_fifo_add(i915_render->pool_fifo, i915_render->vbo);
i915_render->vbo = NULL;
}
i915->vbo_flushed = 0;
i915_render->vbo_size = MAX2(size, i915_render->pool_buffer_size);
i915_render->vbo_offset = 0;
if (i915_render->vbo_size != i915_render->pool_buffer_size) {
i915_render->pool_not_used = TRUE;
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
INTEL_NEW_VERTEX);
} else {
i915_render->pool_not_used = FALSE;
if (i915_render->pool_used >= 2) {
FLUSH_BATCH(NULL);
i915->vbo_flushed = 0;
i915_render->pool_used = 0;
}
u_fifo_pop(i915_render->pool_fifo, (void**)&i915_render->vbo);
}
}
static boolean
i915_vbuf_render_allocate_vertices(struct vbuf_render *render,
ushort vertex_size,
@@ -167,17 +112,27 @@ i915_vbuf_render_allocate_vertices(struct vbuf_render *render,
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
struct intel_winsys *iws = i915->iws;
size_t size = (size_t)vertex_size * (size_t)nr_vertices;
/* FIXME: handle failure */
assert(!i915->vbo);
if (!i915_vbuf_render_reserve(i915_render, size)) {
if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
} else {
i915->vbo_flushed = 0;
if (i915_render->vbo) {
iws->buffer_destroy(iws, i915_render->vbo);
i915_render->vbo = NULL;
}
}
if (i915->vbo_flushed)
i915_render->pool_used = 0;
if (!i915_render->vbo) {
i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
i915_render->vbo_offset = 0;
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
INTEL_NEW_VERTEX);
i915_vbuf_render_new_buf(i915_render, size);
}
i915_render->vertex_size = vertex_size;
@@ -549,7 +504,6 @@ i915_vbuf_render_create(struct i915_context *i915)
{
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
struct intel_winsys *iws = i915->iws;
int i;
i915_render->i915 = i915;
@@ -570,24 +524,14 @@ i915_vbuf_render_create(struct i915_context *i915)
i915_render->base.release_vertices = i915_vbuf_render_release_vertices;
i915_render->base.destroy = i915_vbuf_render_destroy;
i915_render->vbo = NULL;
i915_render->vbo_size = 0;
i915_render->vbo_alloc_size = 128 * 4096;
i915_render->vbo_size = i915_render->vbo_alloc_size;
i915_render->vbo_offset = 0;
i915_render->pool_used = FALSE;
i915_render->pool_buffer_size = 128 * 4096;
i915_render->pool_fifo = u_fifo_create(6);
for (i = 0; i < 6; i++)
u_fifo_add(i915_render->pool_fifo,
iws->buffer_create(iws, i915_render->pool_buffer_size, 64,
INTEL_NEW_VERTEX));
#if 0
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
INTEL_NEW_VERTEX);
/* TODO JB: is this realy needed? */
i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
iws->buffer_unmap(iws, i915_render->vbo);
#endif
return &i915_render->base;
}

View File

@@ -150,17 +150,6 @@ struct intel_winsys {
void (*buffer_unmap)(struct intel_winsys *iws,
struct intel_buffer *buffer);
/**
* Write to a buffer.
*
* Arguments follows pwrite(2)
*/
int (*buffer_write)(struct intel_winsys *iws,
struct intel_buffer *dst,
const void *src,
size_t size,
size_t offset);
void (*buffer_destroy)(struct intel_winsys *iws,
struct intel_buffer *buffer);
/*@}*/

View File

@@ -3,6 +3,8 @@ include $(TOP)/configs/current
LIBNAME = llvmpipe
CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
C_SOURCES = \
lp_bld_alpha.c \
lp_bld_arit.c \
@@ -15,11 +17,9 @@ C_SOURCES = \
lp_bld_depth.c \
lp_bld_flow.c \
lp_bld_format_aos.c \
lp_bld_format_soa.c \
lp_bld_interp.c \
lp_bld_intr.c \
lp_bld_logic.c \
lp_bld_sample_soa.c \
lp_bld_swizzle.c \
lp_bld_struct.c \
lp_bld_tgsi_soa.c \
@@ -46,8 +46,7 @@ C_SOURCES = \
lp_state_vs.c \
lp_surface.c \
lp_tex_cache.c \
lp_tex_sample_c.c \
lp_tex_sample_llvm.c \
lp_tex_sample.c \
lp_texture.c \
lp_tile_cache.c \
lp_tile_soa.c

View File

@@ -8,16 +8,13 @@ Done so far is:
- the whole fragment pipeline is code generated in a single function
- input interpolation
- depth testing
- texture sampling (not all state/formats are supported)
- fragment shader TGSI translation
- same level of support as the TGSI SSE2 exec machine, with the exception
we don't fallback to TGSI interpretation when an unsupported opcode is
found, but just ignore it
- texture sampling via an intrinsic call
- done in SoA layout
- input interpolation also code generated
@@ -31,17 +28,16 @@ Done so far is:
any width and length
- not all operations are implemented for these types yet though
Most mesa/progs/demos/* work.
Most mesa/progs/demos/* work. Speed is on par with Keith's softpipe-opt branch,
which includes hand written fast implementations for common cases.
To do (probably by this order):
- code generate stipple and stencil testing
- translate the remaining bits of texture sampling state
- code generate texture sampling
- translate TGSI control flow instructions, and all other remaining opcodes
- integrate with the draw module for VS code generation
- code generate the triangle setup and rasterization
@@ -97,7 +93,7 @@ Alternatively, you can build it with GNU make, if you prefer, by invoking it as
make linux-llvm
but the rest of these instructions assume that scons is used.
but the rest of these instructions assume scons is used.
Using
@@ -112,9 +108,6 @@ or
export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib:$LD_LIBRARY_PATH
For performance evaluation pass debug=no to scons, and use the corresponding
lib directory without the "-debug" suffix.
Unit testing
============
@@ -126,7 +119,7 @@ build/linux-???-debug/gallium/drivers/llvmpipe:
- lp_test_conv: SIMD vector conversion
- lp_test_format: pixel unpacking/packing
Some of this tests can output results and benchmarks to a tab-separated-file
Some of this tests can output results and benchmarks to a tab-seperated-file
for posterior analysis, e.g.:
build/linux-x86_64-debug/gallium/drivers/llvmpipe/lp_test_blend -o blend.tsv
@@ -140,10 +133,10 @@ Development Notes
at the top of the lp_bld_*.c functions.
- All lp_bld_*.[ch] are isolated from the rest of the driver, and could/may be
put in a stand-alone Gallium state -> LLVM IR translation module.
put in a standalone Gallium state -> LLVM IR translation module.
- We use LLVM-C bindings for now. They are not documented, but follow the C++
interfaces very closely, and appear to be complete enough for code
generation. See
http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html
for a stand-alone example.
for a standalone example.

View File

@@ -3,7 +3,7 @@ Import('*')
env = env.Clone()
env.Tool('llvm')
if env.has_key('LLVM_VERSION') is False:
if 'LLVM_VERSION' not in env:
print 'warning: LLVM not found: not building llvmpipe'
Return()
@@ -23,10 +23,8 @@ llvmpipe = env.ConvenienceLibrary(
'lp_bld_depth.c',
'lp_bld_flow.c',
'lp_bld_format_aos.c',
'lp_bld_format_soa.c',
'lp_bld_interp.c',
'lp_bld_intr.c',
'lp_bld_sample_soa.c',
'lp_bld_struct.c',
'lp_bld_logic.c',
'lp_bld_swizzle.c',
@@ -54,8 +52,7 @@ llvmpipe = env.ConvenienceLibrary(
'lp_state_vs.c',
'lp_surface.c',
'lp_tex_cache.c',
'lp_tex_sample_c.c',
'lp_tex_sample_llvm.c',
'lp_tex_sample.c',
'lp_texture.c',
'lp_tile_cache.c',
'lp_tile_soa.c',

View File

@@ -502,31 +502,6 @@ lp_build_div(struct lp_build_context *bld,
}
LLVMValueRef
lp_build_lerp(struct lp_build_context *bld,
LLVMValueRef x,
LLVMValueRef v0,
LLVMValueRef v1)
{
return lp_build_add(bld, v0, lp_build_mul(bld, x, lp_build_sub(bld, v1, v0)));
}
LLVMValueRef
lp_build_lerp_2d(struct lp_build_context *bld,
LLVMValueRef x,
LLVMValueRef y,
LLVMValueRef v00,
LLVMValueRef v01,
LLVMValueRef v10,
LLVMValueRef v11)
{
LLVMValueRef v0 = lp_build_lerp(bld, x, v00, v01);
LLVMValueRef v1 = lp_build_lerp(bld, x, v10, v11);
return lp_build_lerp(bld, y, v0, v1);
}
/**
* Generate min(a, b)
* Do checks for special cases.
@@ -591,31 +566,20 @@ lp_build_abs(struct lp_build_context *bld,
LLVMValueRef a)
{
const union lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
if(!type.sign)
return a;
if(type.floating) {
/* Mask out the sign bit */
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long)1 << type.width) - 1);
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
a = LLVMBuildAnd(bld->builder, a, mask, "");
a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
return a;
}
/* XXX: is this really necessary? */
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
if(type.width*type.length == 128) {
switch(type.width) {
case 8:
if(!type.floating && type.width*type.length == 128) {
LLVMTypeRef vec_type = lp_build_vec_type(type);
if(type.width == 8)
return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.b.128", vec_type, a);
case 16:
if(type.width == 16)
return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.w.128", vec_type, a);
case 32:
if(type.width == 32)
return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.d.128", vec_type, a);
}
}
#endif
@@ -623,89 +587,6 @@ lp_build_abs(struct lp_build_context *bld,
}
enum lp_build_round_sse41_mode
{
LP_BUILD_ROUND_SSE41_NEAREST = 0,
LP_BUILD_ROUND_SSE41_FLOOR = 1,
LP_BUILD_ROUND_SSE41_CEIL = 2,
LP_BUILD_ROUND_SSE41_TRUNCATE = 3
};
static INLINE LLVMValueRef
lp_build_round_sse41(struct lp_build_context *bld,
LLVMValueRef a,
enum lp_build_round_sse41_mode mode)
{
const union lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
const char *intrinsic;
assert(type.floating);
assert(type.width*type.length == 128);
switch(type.width) {
case 32:
intrinsic = "llvm.x86.sse41.round.ps";
break;
case 64:
intrinsic = "llvm.x86.sse41.round.pd";
break;
default:
assert(0);
return bld->undef;
}
return lp_build_intrinsic_binary(bld->builder, intrinsic, vec_type, a,
LLVMConstInt(LLVMInt32Type(), mode, 0));
}
LLVMValueRef
lp_build_floor(struct lp_build_context *bld,
LLVMValueRef a)
{
const union lp_type type = bld->type;
assert(type.floating);
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR);
#endif
/* FIXME */
assert(0);
return bld->undef;
}
/**
* Convert to integer, through whichever rounding method that's fastest,
* typically truncating to zero.
*/
LLVMValueRef
lp_build_int(struct lp_build_context *bld,
LLVMValueRef a)
{
const union lp_type type = bld->type;
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
assert(type.floating);
return LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
}
LLVMValueRef
lp_build_ifloor(struct lp_build_context *bld,
LLVMValueRef a)
{
a = lp_build_floor(bld, a);
a = lp_build_int(bld, a);
return a;
}
LLVMValueRef
lp_build_sqrt(struct lp_build_context *bld,
LLVMValueRef a)

View File

@@ -71,26 +71,6 @@ lp_build_div(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b);
LLVMValueRef
lp_build_lerp(struct lp_build_context *bld,
LLVMValueRef x,
LLVMValueRef v0,
LLVMValueRef v1);
/**
* Bilinear interpolation.
*
* Values indices are in v_{yx}.
*/
LLVMValueRef
lp_build_lerp_2d(struct lp_build_context *bld,
LLVMValueRef x,
LLVMValueRef y,
LLVMValueRef v00,
LLVMValueRef v01,
LLVMValueRef v10,
LLVMValueRef v11);
LLVMValueRef
lp_build_min(struct lp_build_context *bld,
LLVMValueRef a,
@@ -105,18 +85,6 @@ LLVMValueRef
lp_build_abs(struct lp_build_context *bld,
LLVMValueRef a);
LLVMValueRef
lp_build_floor(struct lp_build_context *bld,
LLVMValueRef a);
LLVMValueRef
lp_build_int(struct lp_build_context *bld,
LLVMValueRef a);
LLVMValueRef
lp_build_ifloor(struct lp_build_context *bld,
LLVMValueRef a);
LLVMValueRef
lp_build_sqrt(struct lp_build_context *bld,
LLVMValueRef a);

View File

@@ -122,7 +122,7 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
int shift = dst_width - n;
res = LLVMBuildShl(builder, res, lp_build_int_const_scalar(src_type, shift), "");
/* TODO: Fill in the empty lower bits for additional precision? */
/* Fill in the empty lower bits for added precision? */
#if 0
{
LLVMValueRef msb;
@@ -244,7 +244,7 @@ lp_build_const_pack_shuffle(unsigned n)
* Expand the bit width.
*
* This will only change the number of bits the values are represented, not the
* values themselves.
* values themselved.
*/
static void
lp_build_expand(LLVMBuilderRef builder,

View File

@@ -30,27 +30,10 @@
#include <udis86.h>
#endif
#include "util/u_math.h"
#include "util/u_debug.h"
#include "lp_bld_debug.h"
/**
* Check alignment.
*
* It is important that this check is not implemented as a macro or inlined
* function, as the compiler assumptions in respect to alignment of global
* and stack variables would often make the check a no op, defeating the
* whole purpose of the exercise.
*/
boolean
lp_check_alignment(const void *ptr, unsigned alignment)
{
assert(util_is_pot(alignment));
return ((uintptr_t)ptr & (alignment - 1)) == 0;
}
void
lp_disassemble(const void* func)
{

View File

@@ -53,10 +53,6 @@ lp_build_name(LLVMValueRef val, const char *format, ...)
}
boolean
lp_check_alignment(const void *ptr, unsigned alignment);
void
lp_disassemble(const void* func);

View File

@@ -179,13 +179,12 @@ lp_build_depth_test(LLVMBuilderRef builder,
padding_right = 0;
for(chan = 0; chan < z_swizzle; ++chan)
padding_right += format_desc->channel[chan].size;
padding_left = format_desc->block.bits -
(padding_right + format_desc->channel[z_swizzle].size);
padding_left = format_desc->block.bits - format_desc->channel[z_swizzle].size;
if(padding_left || padding_right) {
const unsigned long long mask_left = ((unsigned long long)1 << (format_desc->block.bits - padding_left)) - 1;
const unsigned long long mask_right = ((unsigned long long)1 << (padding_right)) - 1;
z_bitmask = lp_build_int_const_scalar(type, mask_left ^ mask_right);
const long long mask_left = ((long long)1 << (format_desc->block.bits - padding_left)) - 1;
const long long mask_right = ((long long)1 << (padding_right)) - 1;
z_bitmask = lp_build_int_const_scalar(type, mask_left & mask_right);
}
if(padding_left)
@@ -211,6 +210,5 @@ lp_build_depth_test(LLVMBuilderRef builder,
LLVMBuildStore(builder, dst, dst_ptr);
}
/* FIXME */
assert(!state->occlusion_count);
}

View File

@@ -32,261 +32,59 @@
*/
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "lp_bld_type.h"
#include "lp_bld_flow.h"
#define LP_BUILD_FLOW_MAX_VARIABLES 32
#define LP_BUILD_FLOW_MAX_DEPTH 32
/**
* Enumeration of all possible flow constructs.
*/
enum lp_build_flow_construct_kind {
lP_BUILD_FLOW_SCOPE,
LP_BUILD_FLOW_SKIP,
};
/**
* Variable declaration scope.
*/
struct lp_build_flow_scope
void
lp_build_mask_begin(struct lp_build_mask_context *mask,
LLVMBuilderRef builder,
union lp_type type,
LLVMValueRef value)
{
/** Number of variables declared in this scope */
unsigned num_variables;
};
memset(mask, 0, sizeof *mask);
/**
* Early exit. Useful to skip to the end of a function or block when
* the execution mask becomes zero or when there is an error condition.
*/
struct lp_build_flow_skip
{
/** Block to skip to */
LLVMBasicBlockRef block;
/** Number of variables declared at the beginning */
unsigned num_variables;
LLVMValueRef *phi;
};
/**
* Union of all possible flow constructs' data
*/
union lp_build_flow_construct_data
{
struct lp_build_flow_scope scope;
struct lp_build_flow_skip skip;
};
/**
* Element of the flow construct stack.
*/
struct lp_build_flow_construct
{
enum lp_build_flow_construct_kind kind;
union lp_build_flow_construct_data data;
};
/**
* All necessary data to generate LLVM control flow constructs.
*
* Besides keeping track of the control flow construct themselves we also
* need to keep track of variables in order to generate SSA Phi values.
*/
struct lp_build_flow_context
{
LLVMBuilderRef builder;
/**
* Control flow stack.
*/
struct lp_build_flow_construct constructs[LP_BUILD_FLOW_MAX_DEPTH];
unsigned num_constructs;
/**
* Variable stack
*/
LLVMValueRef *variables[LP_BUILD_FLOW_MAX_VARIABLES];
unsigned num_variables;
};
struct lp_build_flow_context *
lp_build_flow_create(LLVMBuilderRef builder)
{
struct lp_build_flow_context *flow;
flow = CALLOC_STRUCT(lp_build_flow_context);
if(!flow)
return NULL;
flow->builder = builder;
return flow;
mask->builder = builder;
mask->reg_type = LLVMIntType(type.width * type.length);
mask->value = value;
}
void
lp_build_flow_destroy(struct lp_build_flow_context *flow)
lp_build_mask_update(struct lp_build_mask_context *mask,
LLVMValueRef value)
{
assert(flow->num_constructs == 0);
assert(flow->num_variables == 0);
FREE(flow);
}
static union lp_build_flow_construct_data *
lp_build_flow_push(struct lp_build_flow_context *flow,
enum lp_build_flow_construct_kind kind)
{
assert(flow->num_constructs < LP_BUILD_FLOW_MAX_DEPTH);
if(flow->num_constructs >= LP_BUILD_FLOW_MAX_DEPTH)
return NULL;
flow->constructs[flow->num_constructs].kind = kind;
return &flow->constructs[flow->num_constructs++].data;
}
static union lp_build_flow_construct_data *
lp_build_flow_peek(struct lp_build_flow_context *flow,
enum lp_build_flow_construct_kind kind)
{
assert(flow->num_constructs);
if(!flow->num_constructs)
return NULL;
assert(flow->constructs[flow->num_constructs - 1].kind == kind);
if(flow->constructs[flow->num_constructs - 1].kind != kind)
return NULL;
return &flow->constructs[flow->num_constructs - 1].data;
}
static union lp_build_flow_construct_data *
lp_build_flow_pop(struct lp_build_flow_context *flow,
enum lp_build_flow_construct_kind kind)
{
assert(flow->num_constructs);
if(!flow->num_constructs)
return NULL;
assert(flow->constructs[flow->num_constructs - 1].kind == kind);
if(flow->constructs[flow->num_constructs - 1].kind != kind)
return NULL;
return &flow->constructs[--flow->num_constructs].data;
}
/**
* Begin a variable scope.
*
*
*/
void
lp_build_flow_scope_begin(struct lp_build_flow_context *flow)
{
struct lp_build_flow_scope *scope;
scope = &lp_build_flow_push(flow, lP_BUILD_FLOW_SCOPE)->scope;
if(!scope)
return;
scope->num_variables = 0;
}
/**
* Declare a variable.
*
* A variable is a named entity which can have different LLVMValueRef's at
* different points of the program. This is relevant for control flow because
* when there are mutiple branches to a same location we need to replace
* the variable's value with a Phi function as explained in
* http://en.wikipedia.org/wiki/Static_single_assignment_form .
*
* We keep track of variables by keeping around a pointer to where their
* current.
*
* There are a few cautions to observe:
*
* - Variable's value must not be NULL. If there is no initial value then
* LLVMGetUndef() should be used.
*
* - Variable's value must be kept up-to-date. If the variable is going to be
* modified by a function then a pointer should be passed so that its value
* is accurate. Failure to do this will cause some of the variables'
* transient values to be lost, leading to wrong results.
*
* - A program should be written from top to bottom, by always appending
* instructions to the bottom with a single LLVMBuilderRef. Inserting and/or
* modifying existing statements will most likely lead to wrong results.
*
*/
void
lp_build_flow_scope_declare(struct lp_build_flow_context *flow,
LLVMValueRef *variable)
{
struct lp_build_flow_scope *scope;
scope = &lp_build_flow_peek(flow, lP_BUILD_FLOW_SCOPE)->scope;
if(!scope)
return;
assert(*variable);
if(!*variable)
return;
assert(flow->num_variables < LP_BUILD_FLOW_MAX_VARIABLES);
if(flow->num_variables >= LP_BUILD_FLOW_MAX_VARIABLES)
return;
flow->variables[flow->num_variables++] = variable;
++scope->num_variables;
}
void
lp_build_flow_scope_end(struct lp_build_flow_context *flow)
{
struct lp_build_flow_scope *scope;
scope = &lp_build_flow_pop(flow, lP_BUILD_FLOW_SCOPE)->scope;
if(!scope)
return;
assert(flow->num_variables >= scope->num_variables);
if(flow->num_variables < scope->num_variables) {
flow->num_variables = 0;
return;
}
flow->num_variables -= scope->num_variables;
}
static LLVMBasicBlockRef
lp_build_flow_insert_block(struct lp_build_flow_context *flow)
{
LLVMValueRef cond;
LLVMBasicBlockRef current_block;
LLVMBasicBlockRef next_block;
LLVMBasicBlockRef new_block;
current_block = LLVMGetInsertBlock(flow->builder);
if(mask->value)
mask->value = LLVMBuildAnd(mask->builder, mask->value, value, "");
else
mask->value = value;
/* FIXME: disabled until we have proper control flow helpers */
#if 0
cond = LLVMBuildICmp(mask->builder,
LLVMIntEQ,
LLVMBuildBitCast(mask->builder, mask->value, mask->reg_type, ""),
LLVMConstNull(mask->reg_type),
"");
current_block = LLVMGetInsertBlock(mask->builder);
if(!mask->skip_block) {
LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
mask->skip_block = LLVMAppendBasicBlock(function, "skip");
mask->phi = LLVMBuildPhi(mask->builder, LLVMTypeOf(mask->value), "");
}
next_block = LLVMGetNextBasicBlock(current_block);
assert(next_block);
if(next_block) {
new_block = LLVMInsertBasicBlock(next_block, "");
}
@@ -295,148 +93,30 @@ lp_build_flow_insert_block(struct lp_build_flow_context *flow)
new_block = LLVMAppendBasicBlock(function, "");
}
return new_block;
}
LLVMAddIncoming(mask->phi, &mask->value, &current_block, 1);
LLVMBuildCondBr(mask->builder, cond, mask->skip_block, new_block);
void
lp_build_flow_skip_begin(struct lp_build_flow_context *flow)
{
struct lp_build_flow_skip *skip;
LLVMBuilderRef builder;
unsigned i;
skip = &lp_build_flow_push(flow, LP_BUILD_FLOW_SKIP)->skip;
if(!skip)
return;
skip->block = lp_build_flow_insert_block(flow);
skip->num_variables = flow->num_variables;
if(!skip->num_variables) {
skip->phi = NULL;
return;
}
skip->phi = MALLOC(skip->num_variables * sizeof *skip->phi);
if(!skip->phi) {
skip->num_variables = 0;
return;
}
builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, skip->block);
for(i = 0; i < skip->num_variables; ++i)
skip->phi[i] = LLVMBuildPhi(builder, LLVMTypeOf(*flow->variables[i]), "");
LLVMDisposeBuilder(builder);
}
void
lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow,
LLVMValueRef cond)
{
struct lp_build_flow_skip *skip;
LLVMBasicBlockRef current_block;
LLVMBasicBlockRef new_block;
unsigned i;
skip = &lp_build_flow_peek(flow, LP_BUILD_FLOW_SKIP)->skip;
if(!skip)
return;
current_block = LLVMGetInsertBlock(flow->builder);
new_block = lp_build_flow_insert_block(flow);
for(i = 0; i < skip->num_variables; ++i) {
assert(*flow->variables[i]);
LLVMAddIncoming(skip->phi[i], flow->variables[i], &current_block, 1);
}
LLVMBuildCondBr(flow->builder, cond, skip->block, new_block);
LLVMPositionBuilderAtEnd(flow->builder, new_block);
}
void
lp_build_flow_skip_end(struct lp_build_flow_context *flow)
{
struct lp_build_flow_skip *skip;
LLVMBasicBlockRef current_block;
unsigned i;
skip = &lp_build_flow_pop(flow, LP_BUILD_FLOW_SKIP)->skip;
if(!skip)
return;
current_block = LLVMGetInsertBlock(flow->builder);
for(i = 0; i < skip->num_variables; ++i) {
assert(*flow->variables[i]);
LLVMAddIncoming(skip->phi[i], flow->variables[i], &current_block, 1);
*flow->variables[i] = skip->phi[i];
}
LLVMBuildBr(flow->builder, skip->block);
LLVMPositionBuilderAtEnd(flow->builder, skip->block);
FREE(skip->phi);
}
static void
lp_build_mask_check(struct lp_build_mask_context *mask)
{
LLVMBuilderRef builder = mask->flow->builder;
LLVMValueRef cond;
cond = LLVMBuildICmp(builder,
LLVMIntEQ,
LLVMBuildBitCast(builder, mask->value, mask->reg_type, ""),
LLVMConstNull(mask->reg_type),
"");
lp_build_flow_skip_cond_break(mask->flow, cond);
}
void
lp_build_mask_begin(struct lp_build_mask_context *mask,
struct lp_build_flow_context *flow,
union lp_type type,
LLVMValueRef value)
{
memset(mask, 0, sizeof *mask);
mask->flow = flow;
mask->reg_type = LLVMIntType(type.width * type.length);
mask->value = value;
lp_build_flow_scope_begin(flow);
lp_build_flow_scope_declare(flow, &mask->value);
lp_build_flow_skip_begin(flow);
lp_build_mask_check(mask);
}
void
lp_build_mask_update(struct lp_build_mask_context *mask,
LLVMValueRef value)
{
mask->value = LLVMBuildAnd( mask->flow->builder, mask->value, value, "");
lp_build_mask_check(mask);
LLVMPositionBuilderAtEnd(mask->builder, new_block);
#endif
}
LLVMValueRef
lp_build_mask_end(struct lp_build_mask_context *mask)
{
lp_build_flow_skip_end(mask->flow);
lp_build_flow_scope_end(mask->flow);
if(mask->skip_block) {
LLVMBasicBlockRef current_block = LLVMGetInsertBlock(mask->builder);
LLVMAddIncoming(mask->phi, &mask->value, &current_block, 1);
LLVMBuildBr(mask->builder, mask->skip_block);
LLVMPositionBuilderAtEnd(mask->builder, mask->skip_block);
mask->value = mask->phi;
mask->phi = NULL;
mask->skip_block = NULL;
}
return mask->value;
}

View File

@@ -41,49 +41,23 @@
union lp_type;
struct lp_build_flow_context;
struct lp_build_flow_context *
lp_build_flow_create(LLVMBuilderRef builder);
void
lp_build_flow_destroy(struct lp_build_flow_context *flow);
void
lp_build_flow_scope_begin(struct lp_build_flow_context *flow);
void
lp_build_flow_scope_declare(struct lp_build_flow_context *flow,
LLVMValueRef *variable);
void
lp_build_flow_scope_end(struct lp_build_flow_context *flow);
void
lp_build_flow_skip_begin(struct lp_build_flow_context *flow);
void
lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow,
LLVMValueRef cond);
void
lp_build_flow_skip_end(struct lp_build_flow_context *flow);
struct lp_build_mask_context
{
struct lp_build_flow_context *flow;
LLVMBuilderRef builder;
LLVMTypeRef reg_type;
LLVMValueRef value;
LLVMValueRef phi;
LLVMBasicBlockRef skip_block;
};
void
lp_build_mask_begin(struct lp_build_mask_context *mask,
struct lp_build_flow_context *flow,
LLVMBuilderRef builder,
union lp_type type,
LLVMValueRef value);

View File

@@ -31,14 +31,20 @@
/**
* @file
* Pixel format helpers.
* LLVM IR building helpers interfaces.
*
* We use LLVM-C bindings for now. They are not documented, but follow the C++
* interfaces very closely, and appear to be complete enough for code
* genration. See
* http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html
* for a standalone example.
*/
#include <llvm-c/Core.h>
#include "pipe/p_format.h"
struct util_format_description;
union lp_type;
@@ -50,9 +56,9 @@ union lp_type;
* @return RGBA in a 4 floats vector.
*/
LLVMValueRef
lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef packed);
lp_build_unpack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef packed);
/**
@@ -61,9 +67,9 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
* @param rgba 4 float vector with the unpacked components.
*/
LLVMValueRef
lp_build_pack_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef rgba);
lp_build_pack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef rgba);
/**
@@ -75,9 +81,9 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
* @return RGBA in a 4 floats vector.
*/
LLVMValueRef
lp_build_load_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr);
lp_build_load_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr);
/**
@@ -86,34 +92,10 @@ lp_build_load_rgba_aos(LLVMBuilderRef builder,
* @param rgba 4 float vector with the unpacked components.
*/
void
lp_build_store_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba);
lp_build_store_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba);
LLVMValueRef
lp_build_gather(LLVMBuilderRef builder,
unsigned length,
unsigned src_width,
unsigned dst_width,
LLVMValueRef base_ptr,
LLVMValueRef offsets);
void
lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
union lp_type type,
LLVMValueRef packed,
LLVMValueRef *rgba);
void
lp_build_load_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
union lp_type type,
LLVMValueRef base_ptr,
LLVMValueRef offsets,
LLVMValueRef *rgba);
#endif /* !LP_BLD_H */

View File

@@ -32,9 +32,9 @@
LLVMValueRef
lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef packed)
lp_build_unpack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef packed)
{
const struct util_format_description *desc;
LLVMTypeRef type;
@@ -152,9 +152,9 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
LLVMValueRef
lp_build_pack_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef rgba)
lp_build_pack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef rgba)
{
const struct util_format_description *desc;
LLVMTypeRef type;
@@ -250,9 +250,9 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
LLVMValueRef
lp_build_load_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr)
lp_build_load_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr)
{
const struct util_format_description *desc;
LLVMTypeRef type;
@@ -272,15 +272,15 @@ lp_build_load_rgba_aos(LLVMBuilderRef builder,
packed = LLVMBuildLoad(builder, ptr, "");
return lp_build_unpack_rgba_aos(builder, format, packed);
return lp_build_unpack_rgba(builder, format, packed);
}
void
lp_build_store_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba)
lp_build_store_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba)
{
const struct util_format_description *desc;
LLVMTypeRef type;
@@ -294,7 +294,7 @@ lp_build_store_rgba_aos(LLVMBuilderRef builder,
type = LLVMIntType(desc->block.bits);
packed = lp_build_pack_rgba_aos(builder, format, rgba);
packed = lp_build_pack_rgba(builder, format, rgba);
ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");

View File

@@ -1,208 +0,0 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* 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, sub license, 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 NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
*
**************************************************************************/
#include "util/u_format.h"
#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_conv.h"
#include "lp_bld_format.h"
/**
* Gather elements from scatter positions in memory into a single vector.
*
* @param src_width src element width
* @param dst_width result element width (source will be expanded to fit)
* @param length length of the offsets,
* @param base_ptr base pointer, should be a i8 pointer type.
* @param offsets vector with offsets
*/
LLVMValueRef
lp_build_gather(LLVMBuilderRef builder,
unsigned length,
unsigned src_width,
unsigned dst_width,
LLVMValueRef base_ptr,
LLVMValueRef offsets)
{
LLVMTypeRef src_type = LLVMIntType(src_width);
LLVMTypeRef src_ptr_type = LLVMPointerType(src_type, 0);
LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
LLVMTypeRef dst_vec_type = LLVMVectorType(dst_elem_type, length);
LLVMValueRef res;
unsigned i;
res = LLVMGetUndef(dst_vec_type);
for(i = 0; i < length; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMValueRef elem_offset;
LLVMValueRef elem_ptr;
LLVMValueRef elem;
elem_offset = LLVMBuildExtractElement(builder, offsets, index, "");
elem_ptr = LLVMBuildGEP(builder, base_ptr, &elem_offset, 1, "");
elem_ptr = LLVMBuildBitCast(builder, elem_ptr, src_ptr_type, "");
elem = LLVMBuildLoad(builder, elem_ptr, "");
assert(src_width <= dst_width);
if(src_width > dst_width)
elem = LLVMBuildTrunc(builder, elem, dst_elem_type, "");
if(src_width < dst_width)
elem = LLVMBuildZExt(builder, elem, dst_elem_type, "");
res = LLVMBuildInsertElement(builder, res, elem, index, "");
}
return res;
}
static LLVMValueRef
lp_build_format_swizzle(union lp_type type,
const LLVMValueRef *inputs,
enum util_format_swizzle swizzle)
{
switch (swizzle) {
case UTIL_FORMAT_SWIZZLE_X:
case UTIL_FORMAT_SWIZZLE_Y:
case UTIL_FORMAT_SWIZZLE_Z:
case UTIL_FORMAT_SWIZZLE_W:
return inputs[swizzle];
case UTIL_FORMAT_SWIZZLE_0:
return lp_build_zero(type);
case UTIL_FORMAT_SWIZZLE_1:
return lp_build_one(type);
case UTIL_FORMAT_SWIZZLE_NONE:
return lp_build_undef(type);
default:
assert(0);
return lp_build_undef(type);
}
}
void
lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
union lp_type type,
LLVMValueRef packed,
LLVMValueRef *rgba)
{
LLVMValueRef inputs[4];
unsigned start;
unsigned chan;
/* FIXME: Support more formats */
assert(format_desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
assert(format_desc->block.width == 1);
assert(format_desc->block.height == 1);
assert(format_desc->block.bits <= 32);
/* Decode the input vector components */
start = 0;
for (chan = 0; chan < 4; ++chan) {
unsigned width = format_desc->channel[chan].size;
unsigned stop = start + width;
LLVMValueRef input;
input = packed;
switch(format_desc->channel[chan].type) {
case UTIL_FORMAT_TYPE_VOID:
input = NULL;
break;
case UTIL_FORMAT_TYPE_UNSIGNED:
if(type.floating) {
if(start)
input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(type, start), "");
if(stop < format_desc->block.bits) {
unsigned mask = ((unsigned long long)1 << width) - 1;
input = LLVMBuildAnd(builder, input, lp_build_int_const_scalar(type, mask), "");
}
if(format_desc->channel[chan].normalized)
input = lp_build_unsigned_norm_to_float(builder, width, type, input);
else
input = LLVMBuildFPToSI(builder, input, lp_build_vec_type(type), "");
}
else {
/* FIXME */
assert(0);
input = lp_build_undef(type);
}
break;
default:
/* fall through */
input = lp_build_undef(type);
break;
}
inputs[chan] = input;
start = stop;
}
if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
enum util_format_swizzle swizzle = format_desc->swizzle[0];
LLVMValueRef depth = lp_build_format_swizzle(type, inputs, swizzle);
rgba[2] = rgba[1] = rgba[0] = depth;
rgba[3] = lp_build_one(type);
}
else {
for (chan = 0; chan < 4; ++chan) {
enum util_format_swizzle swizzle = format_desc->swizzle[chan];
rgba[chan] = lp_build_format_swizzle(type, inputs, swizzle);
}
}
}
void
lp_build_load_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
union lp_type type,
LLVMValueRef base_ptr,
LLVMValueRef offsets,
LLVMValueRef *rgba)
{
LLVMValueRef packed;
assert(format_desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
assert(format_desc->block.width == 1);
assert(format_desc->block.height == 1);
assert(format_desc->block.bits <= 32);
packed = lp_build_gather(builder,
type.length, format_desc->block.bits, type.width,
base_ptr, offsets);
lp_build_unpack_rgba_soa(builder, format_desc, type, packed, rgba);
}

View File

@@ -313,6 +313,8 @@ lp_build_select(struct lp_build_context *bld,
b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
}
/* TODO: On SSE4 we could do this with a single instruction -- PBLENDVB */
a = LLVMBuildAnd(bld->builder, a, mask, "");
/* This often gets translated to PANDN, but sometimes the NOT is
@@ -374,9 +376,9 @@ lp_build_select_aos(struct lp_build_context *bld,
return LLVMBuildShuffleVector(bld->builder, a, b, LLVMConstVector(shuffles, n), "");
}
else {
#if 0
/* XXX: Unfortunately select of vectors do not work */
else if(0) {
/* FIXME: Unfortunately select of vectors do not work */
/* Use a select */
LLVMTypeRef elem_type = LLVMInt1Type();
LLVMValueRef cond[LP_MAX_VECTOR_LENGTH];
@@ -386,9 +388,10 @@ lp_build_select_aos(struct lp_build_context *bld,
cond[j + i] = LLVMConstInt(elem_type, cond[i] ? 1 : 0, 0);
return LLVMBuildSelect(bld->builder, LLVMConstVector(cond, n), a, b, "");
#else
}
#endif
else {
LLVMValueRef mask = lp_build_const_mask_aos(type, cond);
return lp_build_select(bld, mask, a, b);
#endif
}
}

View File

@@ -1,135 +0,0 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* 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, sub license, 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 NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
*
**************************************************************************/
/**
* @file
* Texture sampling.
*
* @author Jose Fonseca <jfonseca@vmware.com>
*/
#ifndef LP_BLD_SAMPLE_H
#define LP_BLD_SAMPLE_H
#include <llvm-c/Core.h>
struct pipe_texture;
struct pipe_sampler_state;
union lp_type;
/**
* Sampler static state.
*
* These are the bits of state from pipe_texture and pipe_sampler_state that
* are embedded in the generated code.
*/
struct lp_sampler_static_state
{
/* pipe_texture's state */
enum pipe_format format;
unsigned target:2;
unsigned pot_width:1;
unsigned pot_height:1;
unsigned pot_depth:1;
/* pipe_sampler_state's state */
unsigned wrap_s:3;
unsigned wrap_t:3;
unsigned wrap_r:3;
unsigned min_img_filter:2;
unsigned min_mip_filter:2;
unsigned mag_img_filter:2;
unsigned compare_mode:1;
unsigned compare_func:3;
unsigned normalized_coords:1;
unsigned prefilter:4;
};
/**
* Sampler dynamic state.
*
* These are the bits of state from pipe_texture and pipe_sampler_state that
* are computed in runtime.
*
* There are obtained through callbacks, as we don't want to tie the texture
* sampling code generation logic to any particular texture layout or pipe
* driver.
*/
struct lp_sampler_dynamic_state
{
/** Obtain the base texture width. */
LLVMValueRef
(*width)( struct lp_sampler_dynamic_state *state,
LLVMBuilderRef builder,
unsigned unit);
/** Obtain the base texture height. */
LLVMValueRef
(*height)( struct lp_sampler_dynamic_state *state,
LLVMBuilderRef builder,
unsigned unit);
LLVMValueRef
(*stride)( struct lp_sampler_dynamic_state *state,
LLVMBuilderRef builder,
unsigned unit);
LLVMValueRef
(*data_ptr)( struct lp_sampler_dynamic_state *state,
LLVMBuilderRef builder,
unsigned unit);
};
/**
* Derive the sampler static state.
*/
void
lp_sampler_static_state(struct lp_sampler_static_state *state,
const struct pipe_texture *texture,
const struct pipe_sampler_state *sampler);
void
lp_build_sample_soa(LLVMBuilderRef builder,
const struct lp_sampler_static_state *static_state,
struct lp_sampler_dynamic_state *dynamic_state,
union lp_type fp_type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
LLVMValueRef lodbias,
LLVMValueRef *texel);
#endif /* LP_BLD_SAMPLE_H */

View File

@@ -1,411 +0,0 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* 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, sub license, 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 NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
*
**************************************************************************/
/**
* @file
* Texture sampling.
*
* @author Jose Fonseca <jfonseca@vmware.com>
*/
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "lp_bld_debug.h"
#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_arit.h"
#include "lp_bld_logic.h"
#include "lp_bld_swizzle.h"
#include "lp_bld_format.h"
#include "lp_bld_sample.h"
void
lp_sampler_static_state(struct lp_sampler_static_state *state,
const struct pipe_texture *texture,
const struct pipe_sampler_state *sampler)
{
memset(state, 0, sizeof *state);
if(!texture)
return;
if(!sampler)
return;
state->format = texture->format;
state->target = texture->target;
state->pot_width = util_is_pot(texture->width[0]);
state->pot_height = util_is_pot(texture->height[0]);
state->pot_depth = util_is_pot(texture->depth[0]);
state->wrap_s = sampler->wrap_s;
state->wrap_t = sampler->wrap_t;
state->wrap_r = sampler->wrap_r;
state->min_img_filter = sampler->min_img_filter;
state->min_mip_filter = sampler->min_mip_filter;
state->mag_img_filter = sampler->mag_img_filter;
if(sampler->compare_mode) {
state->compare_mode = sampler->compare_mode;
state->compare_func = sampler->compare_func;
}
state->normalized_coords = sampler->normalized_coords;
state->prefilter = sampler->prefilter;
}
/**
* Keep all information for sampling code generation in a single place.
*/
struct lp_build_sample_context
{
LLVMBuilderRef builder;
const struct lp_sampler_static_state *static_state;
struct lp_sampler_dynamic_state *dynamic_state;
const struct util_format_description *format_desc;
/** Incoming coordinates type and build context */
union lp_type coord_type;
struct lp_build_context coord_bld;
/** Integer coordinates */
union lp_type int_coord_type;
struct lp_build_context int_coord_bld;
/** Output texels type and build context */
union lp_type texel_type;
struct lp_build_context texel_bld;
};
static void
lp_build_sample_texel(struct lp_build_sample_context *bld,
LLVMValueRef x,
LLVMValueRef y,
LLVMValueRef y_stride,
LLVMValueRef data_ptr,
LLVMValueRef *texel)
{
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef x_stride;
LLVMValueRef offset;
x_stride = lp_build_const_scalar(bld->int_coord_type, bld->format_desc->block.bits/8);
if(bld->format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
LLVMValueRef x_lo, x_hi;
LLVMValueRef y_lo, y_hi;
LLVMValueRef x_stride_lo, x_stride_hi;
LLVMValueRef y_stride_lo, y_stride_hi;
LLVMValueRef x_offset_lo, x_offset_hi;
LLVMValueRef y_offset_lo, y_offset_hi;
LLVMValueRef offset_lo, offset_hi;
x_lo = LLVMBuildAnd(bld->builder, x, int_coord_bld->one, "");
y_lo = LLVMBuildAnd(bld->builder, y, int_coord_bld->one, "");
x_hi = LLVMBuildLShr(bld->builder, x, int_coord_bld->one, "");
y_hi = LLVMBuildLShr(bld->builder, y, int_coord_bld->one, "");
x_stride_lo = x_stride;
y_stride_lo = lp_build_const_scalar(bld->int_coord_type, 2*bld->format_desc->block.bits/8);
x_stride_hi = lp_build_const_scalar(bld->int_coord_type, 4*bld->format_desc->block.bits/8);
y_stride_hi = LLVMBuildShl(bld->builder, y_stride, int_coord_bld->one, "");
x_offset_lo = lp_build_mul(int_coord_bld, x_lo, x_stride_lo);
y_offset_lo = lp_build_mul(int_coord_bld, y_lo, y_stride_lo);
offset_lo = lp_build_add(int_coord_bld, x_offset_lo, y_offset_lo);
x_offset_hi = lp_build_mul(int_coord_bld, x_hi, x_stride_hi);
y_offset_hi = lp_build_mul(int_coord_bld, y_hi, y_stride_hi);
offset_hi = lp_build_add(int_coord_bld, x_offset_hi, y_offset_hi);
offset = lp_build_add(int_coord_bld, offset_hi, offset_lo);
}
else {
LLVMValueRef x_offset;
LLVMValueRef y_offset;
x_offset = lp_build_mul(int_coord_bld, x, x_stride);
y_offset = lp_build_mul(int_coord_bld, y, y_stride);
offset = lp_build_add(int_coord_bld, x_offset, y_offset);
}
lp_build_load_rgba_soa(bld->builder,
bld->format_desc,
bld->texel_type,
data_ptr,
offset,
texel);
}
static LLVMValueRef
lp_build_sample_wrap(struct lp_build_sample_context *bld,
LLVMValueRef coord,
LLVMValueRef length,
boolean is_pot,
unsigned wrap_mode)
{
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef length_minus_one;
length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
switch(wrap_mode) {
case PIPE_TEX_WRAP_REPEAT:
if(is_pot)
coord = LLVMBuildAnd(bld->builder, coord, length_minus_one, "");
else
/* Signed remainder won't give the right results for negative
* dividends but unsigned remainder does.*/
coord = LLVMBuildURem(bld->builder, coord, length, "");
break;
case PIPE_TEX_WRAP_CLAMP:
coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero);
coord = lp_build_min(int_coord_bld, coord, length_minus_one);
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
case PIPE_TEX_WRAP_MIRROR_REPEAT:
case PIPE_TEX_WRAP_MIRROR_CLAMP:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
/* FIXME */
default:
assert(0);
}
return coord;
}
static void
lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef stride,
LLVMValueRef data_ptr,
LLVMValueRef *texel)
{
LLVMValueRef x;
LLVMValueRef y;
x = lp_build_ifloor(&bld->coord_bld, s);
y = lp_build_ifloor(&bld->coord_bld, t);
x = lp_build_sample_wrap(bld, x, width, bld->static_state->pot_width, bld->static_state->wrap_s);
y = lp_build_sample_wrap(bld, y, height, bld->static_state->pot_height, bld->static_state->wrap_t);
lp_build_sample_texel(bld, x, y, stride, data_ptr, texel);
}
static void
lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef stride,
LLVMValueRef data_ptr,
LLVMValueRef *texel)
{
LLVMValueRef half;
LLVMValueRef s_ipart;
LLVMValueRef t_ipart;
LLVMValueRef s_fpart;
LLVMValueRef t_fpart;
LLVMValueRef x0, x1;
LLVMValueRef y0, y1;
LLVMValueRef neighbors[2][2][4];
unsigned chan;
half = lp_build_const_scalar(bld->coord_type, 0.5);
s = lp_build_sub(&bld->coord_bld, s, half);
t = lp_build_sub(&bld->coord_bld, t, half);
s_ipart = lp_build_floor(&bld->coord_bld, s);
t_ipart = lp_build_floor(&bld->coord_bld, t);
s_fpart = lp_build_sub(&bld->coord_bld, s, s_ipart);
t_fpart = lp_build_sub(&bld->coord_bld, t, t_ipart);
x0 = lp_build_int(&bld->coord_bld, s_ipart);
y0 = lp_build_int(&bld->coord_bld, t_ipart);
x0 = lp_build_sample_wrap(bld, x0, width, bld->static_state->pot_width, bld->static_state->wrap_s);
y0 = lp_build_sample_wrap(bld, y0, height, bld->static_state->pot_height, bld->static_state->wrap_t);
x1 = lp_build_add(&bld->int_coord_bld, x0, bld->int_coord_bld.one);
y1 = lp_build_add(&bld->int_coord_bld, y0, bld->int_coord_bld.one);
x1 = lp_build_sample_wrap(bld, x1, width, bld->static_state->pot_width, bld->static_state->wrap_s);
y1 = lp_build_sample_wrap(bld, y1, height, bld->static_state->pot_height, bld->static_state->wrap_t);
lp_build_sample_texel(bld, x0, y0, stride, data_ptr, neighbors[0][0]);
lp_build_sample_texel(bld, x1, y0, stride, data_ptr, neighbors[0][1]);
lp_build_sample_texel(bld, x0, y1, stride, data_ptr, neighbors[1][0]);
lp_build_sample_texel(bld, x1, y1, stride, data_ptr, neighbors[1][1]);
/* TODO: Don't interpolate missing channels */
for(chan = 0; chan < 4; ++chan) {
texel[chan] = lp_build_lerp_2d(&bld->texel_bld,
s_fpart, t_fpart,
neighbors[0][0][chan],
neighbors[0][1][chan],
neighbors[1][0][chan],
neighbors[1][1][chan]);
}
}
static void
lp_build_sample_compare(struct lp_build_sample_context *bld,
LLVMValueRef p,
LLVMValueRef *texel)
{
struct lp_build_context *texel_bld = &bld->texel_bld;
LLVMValueRef res;
unsigned chan;
if(!bld->static_state->compare_mode)
return;
/* TODO: Compare before swizzling, to avoid redundant computations */
res = NULL;
for(chan = 0; chan < 4; ++chan) {
LLVMValueRef cmp;
cmp = lp_build_cmp(texel_bld, bld->static_state->compare_func, p, texel[chan]);
cmp = lp_build_select(texel_bld, cmp, texel_bld->one, texel_bld->zero);
if(res)
res = lp_build_add(texel_bld, res, cmp);
else
res = cmp;
}
assert(res);
res = lp_build_mul(texel_bld, res, lp_build_const_scalar(texel_bld->type, 0.25));
/* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
for(chan = 0; chan < 3; ++chan)
texel[chan] = res;
texel[3] = texel_bld->one;
}
void
lp_build_sample_soa(LLVMBuilderRef builder,
const struct lp_sampler_static_state *static_state,
struct lp_sampler_dynamic_state *dynamic_state,
union lp_type type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
LLVMValueRef lodbias,
LLVMValueRef *texel)
{
struct lp_build_sample_context bld;
LLVMValueRef width;
LLVMValueRef height;
LLVMValueRef stride;
LLVMValueRef data_ptr;
LLVMValueRef s;
LLVMValueRef t;
LLVMValueRef p;
/* Setup our build context */
memset(&bld, 0, sizeof bld);
bld.builder = builder;
bld.static_state = static_state;
bld.dynamic_state = dynamic_state;
bld.format_desc = util_format_description(static_state->format);
bld.coord_type = type;
bld.int_coord_type = lp_int_type(type);
bld.texel_type = type;
lp_build_context_init(&bld.coord_bld, builder, bld.coord_type);
lp_build_context_init(&bld.int_coord_bld, builder, bld.int_coord_type);
lp_build_context_init(&bld.texel_bld, builder, bld.texel_type);
/* Get the dynamic state */
width = dynamic_state->width(dynamic_state, builder, unit);
height = dynamic_state->height(dynamic_state, builder, unit);
stride = dynamic_state->stride(dynamic_state, builder, unit);
data_ptr = dynamic_state->data_ptr(dynamic_state, builder, unit);
s = coords[0];
t = coords[1];
p = coords[2];
width = lp_build_broadcast_scalar(&bld.int_coord_bld, width);
height = lp_build_broadcast_scalar(&bld.int_coord_bld, height);
stride = lp_build_broadcast_scalar(&bld.int_coord_bld, stride);
if(static_state->target == PIPE_TEXTURE_1D)
t = bld.coord_bld.zero;
if(static_state->normalized_coords) {
LLVMTypeRef coord_vec_type = lp_build_vec_type(bld.coord_type);
LLVMValueRef fp_width = LLVMBuildSIToFP(builder, width, coord_vec_type, "");
LLVMValueRef fp_height = LLVMBuildSIToFP(builder, height, coord_vec_type, "");
s = lp_build_mul(&bld.coord_bld, s, fp_width);
t = lp_build_mul(&bld.coord_bld, t, fp_height);
}
switch (static_state->min_img_filter) {
case PIPE_TEX_FILTER_NEAREST:
lp_build_sample_2d_nearest_soa(&bld, s, t, width, height, stride, data_ptr, texel);
break;
case PIPE_TEX_FILTER_LINEAR:
case PIPE_TEX_FILTER_ANISO:
lp_build_sample_2d_linear_soa(&bld, s, t, width, height, stride, data_ptr, texel);
break;
default:
assert(0);
}
/* FIXME: respect static_state->min_mip_filter */;
/* FIXME: respect static_state->mag_img_filter */;
/* FIXME: respect static_state->prefilter */;
lp_build_sample_compare(&bld, p, texel);
}

View File

@@ -41,31 +41,18 @@
#include "lp_bld_struct.h"
LLVMValueRef
lp_build_struct_get_ptr(LLVMBuilderRef builder,
LLVMValueRef ptr,
unsigned member,
const char *name)
{
LLVMValueRef indices[2];
LLVMValueRef member_ptr;
indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
indices[1] = LLVMConstInt(LLVMInt32Type(), member, 0);
member_ptr = LLVMBuildGEP(builder, ptr, indices, Elements(indices), "");
lp_build_name(member_ptr, "%s.%s_ptr", LLVMGetValueName(ptr), name);
return member_ptr;
}
LLVMValueRef
lp_build_struct_get(LLVMBuilderRef builder,
LLVMValueRef ptr,
unsigned member,
const char *name)
{
LLVMValueRef indices[2];
LLVMValueRef member_ptr;
LLVMValueRef res;
member_ptr = lp_build_struct_get_ptr(builder, ptr, member, name);
indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
indices[1] = LLVMConstInt(LLVMInt32Type(), member, 0);
member_ptr = LLVMBuildGEP(builder, ptr, indices, Elements(indices), "");
res = LLVMBuildLoad(builder, member_ptr, "");
lp_build_name(res, "%s.%s", LLVMGetValueName(ptr), name);
return res;

View File

@@ -53,18 +53,6 @@
offsetof(_ctype, _cmember))
/**
* Get value pointer to a structure member.
*/
LLVMValueRef
lp_build_struct_get_ptr(LLVMBuilderRef builder,
LLVMValueRef ptr,
unsigned member,
const char *name);
/**
* Get the value of a structure member.
*/
LLVMValueRef
lp_build_struct_get(LLVMBuilderRef builder,
LLVMValueRef ptr,

View File

@@ -44,30 +44,14 @@ struct lp_build_context;
struct lp_build_mask_context;
/**
* Sampler code generation interface.
*
* Although texture sampling is a requirement for TGSI translation, it is
* a very different problem with several different approaches to it. This
* structure establishes an interface for texture sampling code generation, so
* that we can easily use different texture sampling strategies.
*/
struct lp_build_sampler_soa
{
void
(*destroy)( struct lp_build_sampler_soa *sampler );
void
(*emit_fetch_texel)( struct lp_build_sampler_soa *sampler,
LLVMBuilderRef builder,
union lp_type type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
LLVMValueRef lodbias,
LLVMValueRef *texel);
};
typedef void
(*lp_emit_fetch_texel_soa_callback)( LLVMBuilderRef builder,
void *context,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
LLVMValueRef lodbias,
LLVMValueRef *texel);
void
lp_build_tgsi_soa(LLVMBuilderRef builder,
@@ -78,7 +62,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
const LLVMValueRef *pos,
const LLVMValueRef (*inputs)[4],
LLVMValueRef (*outputs)[4],
struct lp_build_sampler_soa *sampler);
lp_emit_fetch_texel_soa_callback emit_fetch_texel,
void *emit_fetch_texel_context);
#endif /* LP_BLD_TGSI_H */

View File

@@ -88,7 +88,8 @@ struct lp_build_tgsi_soa_context
const LLVMValueRef (*inputs)[NUM_CHANNELS];
LLVMValueRef (*outputs)[NUM_CHANNELS];
struct lp_build_sampler_soa *sampler;
lp_emit_fetch_texel_soa_callback emit_fetch_texel;
void *emit_fetch_texel_context;
LLVMValueRef immediates[LP_MAX_IMMEDIATES][NUM_CHANNELS];
LLVMValueRef temps[LP_MAX_TEMPS][NUM_CHANNELS];
@@ -167,7 +168,6 @@ emit_fetch(
break;
case TGSI_UTIL_SIGN_SET:
/* TODO: Use bitwese OR for floating point */
res = lp_build_abs( &bld->base, res );
res = LLVMBuildNeg( bld->base.builder, res, "" );
break;
@@ -289,11 +289,8 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
coords[i] = lp_build_mul(&bld->base, coords[i], oow);
}
bld->sampler->emit_fetch_texel(bld->sampler,
bld->base.builder,
bld->base.type,
unit, num_coords, coords, lodbias,
texel);
bld->emit_fetch_texel(bld->base.builder, bld->emit_fetch_texel_context,
unit, num_coords, coords, lodbias, texel);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, i ) {
emit_store( bld, inst, 0, i, texel[i] );
@@ -350,6 +347,14 @@ emit_kil(
}
static void
emit_kilp(
struct lp_build_tgsi_soa_context *bld )
{
/* XXX todo / fix me */
}
/**
* Check if inst src/dest regs use indirect addressing into temporary
* register file.
@@ -391,7 +396,6 @@ emit_instruction(
switch (inst->Instruction.Opcode) {
#if 0
case TGSI_OPCODE_ARL:
/* FIXME */
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
emit_flr(bld, 0, 0);
@@ -680,7 +684,6 @@ emit_instruction(
break;
case TGSI_OPCODE_CND:
/* FIXME */
return 0;
break;
@@ -844,11 +847,13 @@ emit_instruction(
return 0;
break;
#if 0
case TGSI_OPCODE_KILP:
/* predicated kill */
/* FIXME */
return 0;
emit_kilp( bld );
return 0; /* XXX fix me */
break;
#endif
case TGSI_OPCODE_KIL:
/* conditional kill */
@@ -1278,7 +1283,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
const LLVMValueRef *pos,
const LLVMValueRef (*inputs)[NUM_CHANNELS],
LLVMValueRef (*outputs)[NUM_CHANNELS],
struct lp_build_sampler_soa *sampler)
lp_emit_fetch_texel_soa_callback emit_fetch_texel,
void *emit_fetch_texel_context)
{
struct lp_build_tgsi_soa_context bld;
struct tgsi_parse_context parse;
@@ -1293,7 +1299,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
bld.inputs = inputs;
bld.outputs = outputs;
bld.consts_ptr = consts_ptr;
bld.sampler = sampler;
bld.emit_fetch_texel = emit_fetch_texel;
bld.emit_fetch_texel_context = emit_fetch_texel_context;
tgsi_parse_init( &parse, tokens );
@@ -1302,7 +1309,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
/* Inputs already interpolated */
/* Input already interpolated */
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:

View File

@@ -157,17 +157,6 @@ lp_build_int_vec_type(union lp_type type)
}
union lp_type
lp_int_type(union lp_type type)
{
union lp_type int_type;
int_type.value = 0;
int_type.width = type.width;
int_type.length = type.length;
return int_type;
}
void
lp_build_context_init(struct lp_build_context *bld,
LLVMBuilderRef builder,

View File

@@ -165,10 +165,6 @@ LLVMTypeRef
lp_build_int_vec_type(union lp_type type);
union lp_type
lp_int_type(union lp_type type);
void
lp_build_context_init(struct lp_build_context *bld,
LLVMBuilderRef builder,

View File

@@ -67,7 +67,6 @@ llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
util_pack_color(rgba, ps->format, &cv);
lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, cv);
}
llvmpipe->dirty_render_cache = TRUE;
}
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {

View File

@@ -141,6 +141,8 @@ llvmpipe_is_texture_referenced( struct pipe_context *pipe,
return PIPE_REFERENCED_FOR_WRITE;
}
/* FIXME: we also need to do the same for the texture cache */
return PIPE_UNREFERENCED;
}

View File

@@ -44,47 +44,15 @@
static void
lp_jit_init_globals(struct llvmpipe_screen *screen)
{
LLVMTypeRef texture_type;
/* struct lp_jit_texture */
{
LLVMTypeRef elem_types[4];
elem_types[LP_JIT_TEXTURE_WIDTH] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0);
texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, width,
screen->target, texture_type,
LP_JIT_TEXTURE_WIDTH);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, height,
screen->target, texture_type,
LP_JIT_TEXTURE_HEIGHT);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, stride,
screen->target, texture_type,
LP_JIT_TEXTURE_STRIDE);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
screen->target, texture_type,
LP_JIT_TEXTURE_DATA);
LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
screen->target, texture_type);
LLVMAddTypeName(screen->module, "texture", texture_type);
}
/* struct lp_jit_context */
{
LLVMTypeRef elem_types[5];
LLVMTypeRef elem_types[4];
LLVMTypeRef context_type;
elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
elem_types[1] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */
elem_types[2] = LLVMFloatType(); /* alpha_ref_value */
elem_types[3] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */
elem_types[4] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
@@ -96,9 +64,6 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
screen->target, context_type, 2);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
screen->target, context_type, 3);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
screen->target, context_type,
LP_JIT_CONTEXT_TEXTURES_INDEX);
LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
screen->target, context_type);

View File

@@ -38,31 +38,11 @@
#include "lp_bld_struct.h"
#include "pipe/p_state.h"
struct tgsi_sampler;
struct llvmpipe_screen;
struct lp_jit_texture
{
uint32_t width;
uint32_t height;
uint32_t stride;
const void *data;
};
enum {
LP_JIT_TEXTURE_WIDTH = 0,
LP_JIT_TEXTURE_HEIGHT,
LP_JIT_TEXTURE_STRIDE,
LP_JIT_TEXTURE_DATA
};
/**
* This structure is passed directly to the generated fragment shader.
*
@@ -80,12 +60,11 @@ struct lp_jit_context
struct tgsi_sampler **samplers;
/* TODO: alpha reference value */
float alpha_ref_value;
/* FIXME: store (also?) in floats */
/* TODO: blend constant color */
uint8_t *blend_color;
struct lp_jit_texture textures[PIPE_MAX_SAMPLERS];
};
@@ -101,11 +80,6 @@ struct lp_jit_context
#define lp_jit_context_blend_color(_builder, _ptr) \
lp_build_struct_get(_builder, _ptr, 3, "blend_color")
#define LP_JIT_CONTEXT_TEXTURES_INDEX 4
#define lp_jit_context_textures(_builder, _ptr) \
lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures")
typedef void
(*lp_jit_frag_func)(struct lp_jit_context *context,

View File

@@ -44,7 +44,6 @@
#include "pipe/p_thread.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "lp_bld_debug.h"
#include "lp_tile_cache.h"
#include "lp_tile_soa.h"
@@ -163,12 +162,12 @@ shade_quads(struct llvmpipe_context *llvmpipe,
else
depth = NULL;
/* XXX: This will most likely fail on 32bit x86 without -mstackrealign */
assert(lp_check_alignment(mask, 16));
/* TODO: blend color */
assert(lp_check_alignment(depth, 16));
assert(lp_check_alignment(color, 16));
assert(lp_check_alignment(llvmpipe->jit_context.blend_color, 16));
assert((((uintptr_t)mask) & 0xf) == 0);
assert((((uintptr_t)depth) & 0xf) == 0);
assert((((uintptr_t)color) & 0xf) == 0);
assert((((uintptr_t)llvmpipe->jit_context.blend_color) & 0xf) == 0);
/* run shader */
fs->current->jit_function( &llvmpipe->jit_context,

View File

@@ -36,7 +36,6 @@
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
#include "lp_jit.h"
#include "lp_bld_sample.h" /* for struct lp_sampler_static_state */
#define LP_NEW_VIEWPORT 0x1
@@ -58,20 +57,16 @@
struct tgsi_sampler;
struct vertex_info;
struct pipe_context;
struct llvmpipe_context;
struct lp_fragment_shader;
struct lp_fragment_shader_variant_key
{
enum pipe_format zsbuf_format;
struct pipe_depth_state depth;
struct pipe_alpha_state alpha;
struct pipe_blend_state blend;
struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS];
};

View File

@@ -250,9 +250,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
if (llvmpipe->dirty & (LP_NEW_FS |
LP_NEW_BLEND |
LP_NEW_DEPTH_STENCIL_ALPHA |
LP_NEW_SAMPLER |
LP_NEW_TEXTURE))
LP_NEW_DEPTH_STENCIL_ALPHA))
llvmpipe_update_fs( llvmpipe );

View File

@@ -85,7 +85,6 @@
#include "lp_context.h"
#include "lp_state.h"
#include "lp_quad.h"
#include "lp_tex_sample.h"
static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
@@ -131,8 +130,9 @@ generate_pos0(LLVMBuilderRef builder,
* Generate the depth test.
*/
static void
generate_depth(LLVMBuilderRef builder,
const struct lp_fragment_shader_variant_key *key,
generate_depth(struct llvmpipe_context *lp,
LLVMBuilderRef builder,
const struct pipe_depth_state *state,
union lp_type src_type,
struct lp_build_mask_context *mask,
LLVMValueRef src,
@@ -141,10 +141,10 @@ generate_depth(LLVMBuilderRef builder,
const struct util_format_description *format_desc;
union lp_type dst_type;
if(!key->depth.enabled)
if(!lp->framebuffer.zsbuf)
return;
format_desc = util_format_description(key->zsbuf_format);
format_desc = util_format_description(lp->framebuffer.zsbuf->format);
assert(format_desc);
/* Pick the depth type. */
@@ -164,7 +164,7 @@ generate_depth(LLVMBuilderRef builder,
#endif
lp_build_depth_test(builder,
&key->depth,
state,
dst_type,
format_desc,
mask,
@@ -173,6 +173,107 @@ generate_depth(LLVMBuilderRef builder,
}
struct build_fetch_texel_context
{
LLVMValueRef context_ptr;
LLVMValueRef samplers_ptr;
/** Coords/texels store */
LLVMValueRef store_ptr;
};
void PIPE_CDECL
lp_fetch_texel_soa( struct tgsi_sampler **samplers,
uint32_t unit,
float *store )
{
struct tgsi_sampler *sampler = samplers[unit];
#if 0
uint j;
debug_printf("%s sampler: %p (%p) store: %p\n",
__FUNCTION__,
sampler, *sampler,
store );
debug_printf("lodbias %f\n", store[12]);
for (j = 0; j < 4; j++)
debug_printf("sample %d texcoord %f %f\n",
j,
store[0+j],
store[4+j]);
#endif
{
float rgba[NUM_CHANNELS][QUAD_SIZE];
sampler->get_samples(sampler,
&store[0],
&store[4],
&store[8],
0.0f, /*store[12], lodbias */
rgba);
memcpy(store, rgba, sizeof rgba);
}
#if 0
for (j = 0; j < 4; j++)
debug_printf("sample %d result %f %f %f %f\n",
j,
store[0+j],
store[4+j],
store[8+j],
store[12+j]);
#endif
}
static void
emit_fetch_texel( LLVMBuilderRef builder,
void *context,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
LLVMValueRef lodbias,
LLVMValueRef *texel)
{
struct build_fetch_texel_context *bld = context;
LLVMTypeRef vec_type = LLVMTypeOf(coords[0]);
LLVMValueRef args[3];
unsigned i;
if(!bld->samplers_ptr)
bld->samplers_ptr = lp_jit_context_samplers(builder, bld->context_ptr);
if(!bld->store_ptr)
bld->store_ptr = LLVMBuildArrayAlloca(builder,
vec_type,
LLVMConstInt(LLVMInt32Type(), 4, 0),
"texel_store");
for (i = 0; i < num_coords; i++) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMValueRef coord_ptr = LLVMBuildGEP(builder, bld->store_ptr, &index, 1, "");
LLVMBuildStore(builder, coords[i], coord_ptr);
}
args[0] = bld->samplers_ptr;
args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0);
args[2] = bld->store_ptr;
lp_build_intrinsic(builder, "fetch_texel", LLVMVoidType(), args, 3);
for (i = 0; i < NUM_CHANNELS; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMValueRef texel_ptr = LLVMBuildGEP(builder, bld->store_ptr, &index, 1, "");
texel[i] = LLVMBuildLoad(builder, texel_ptr, "");
}
}
/**
* Generate the fragment shader, depth/stencil test, and alpha tests.
*/
@@ -185,7 +286,7 @@ generate_fs(struct llvmpipe_context *lp,
LLVMValueRef context_ptr,
unsigned i,
const struct lp_build_interp_soa_context *interp,
struct lp_build_sampler_soa *sampler,
struct build_fetch_texel_context *sampler,
LLVMValueRef *pmask,
LLVMValueRef *color,
LLVMValueRef depth_ptr)
@@ -197,7 +298,6 @@ generate_fs(struct llvmpipe_context *lp,
LLVMValueRef consts_ptr;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
LLVMValueRef z = interp->pos[2];
struct lp_build_flow_context *flow;
struct lp_build_mask_context mask;
boolean early_depth_test;
unsigned attrib;
@@ -209,35 +309,25 @@ generate_fs(struct llvmpipe_context *lp,
consts_ptr = lp_jit_context_constants(builder, context_ptr);
flow = lp_build_flow_create(builder);
memset(outputs, 0, sizeof outputs);
lp_build_flow_scope_begin(flow);
/* Declare the color and z variables */
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
color[chan] = LLVMGetUndef(vec_type);
lp_build_flow_scope_declare(flow, &color[chan]);
}
lp_build_flow_scope_declare(flow, &z);
lp_build_mask_begin(&mask, flow, type, *pmask);
lp_build_mask_begin(&mask, builder, type, *pmask);
early_depth_test =
key->depth.enabled &&
!key->alpha.enabled &&
!shader->info.uses_kill &&
!shader->info.writes_z;
lp->depth_stencil->depth.enabled &&
lp->framebuffer.zsbuf &&
!lp->depth_stencil->alpha.enabled &&
!lp->fs->info.uses_kill &&
!lp->fs->info.writes_z;
if(early_depth_test)
generate_depth(builder, key,
generate_depth(lp, builder, &key->depth,
type, &mask,
z, depth_ptr);
memset(outputs, 0, sizeof outputs);
lp_build_tgsi_soa(builder, tokens, type, &mask,
consts_ptr, interp->pos, interp->inputs,
outputs, sampler);
outputs, emit_fetch_texel, sampler);
for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
@@ -278,16 +368,12 @@ generate_fs(struct llvmpipe_context *lp,
}
if(!early_depth_test)
generate_depth(builder, key,
generate_depth(lp, builder, &key->depth,
type, &mask,
z, depth_ptr);
lp_build_mask_end(&mask);
lp_build_flow_scope_end(flow);
lp_build_flow_destroy(flow);
*pmask = mask.value;
}
@@ -306,8 +392,6 @@ generate_blend(const struct pipe_blend_state *blend,
LLVMValueRef dst_ptr)
{
struct lp_build_context bld;
struct lp_build_flow_context *flow;
struct lp_build_mask_context mask_ctx;
LLVMTypeRef vec_type;
LLVMTypeRef int_vec_type;
LLVMValueRef const_ptr;
@@ -316,14 +400,11 @@ generate_blend(const struct pipe_blend_state *blend,
LLVMValueRef res[4];
unsigned chan;
lp_build_context_init(&bld, builder, type);
flow = lp_build_flow_create(builder);
lp_build_mask_begin(&mask_ctx, flow, type, mask);
vec_type = lp_build_vec_type(type);
int_vec_type = lp_build_int_vec_type(type);
lp_build_context_init(&bld, builder, type);
const_ptr = lp_jit_context_blend_color(builder, context_ptr);
const_ptr = LLVMBuildBitCast(builder, const_ptr,
LLVMPointerType(vec_type, 0), "");
@@ -341,16 +422,11 @@ generate_blend(const struct pipe_blend_state *blend,
lp_build_blend_soa(builder, blend, type, src, dst, con, res);
for(chan = 0; chan < 4; ++chan) {
if(blend->colormask & (1 << chan)) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
lp_build_name(res[chan], "res.%c", "rgba"[chan]);
res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]);
LLVMBuildStore(builder, res[chan], LLVMBuildGEP(builder, dst_ptr, &index, 1, ""));
}
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
lp_build_name(res[chan], "res.%c", "rgba"[chan]);
res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]);
LLVMBuildStore(builder, res[chan], LLVMBuildGEP(builder, dst_ptr, &index, 1, ""));
}
lp_build_mask_end(&mask_ctx);
lp_build_flow_destroy(flow);
}
@@ -386,7 +462,7 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMBuilderRef builder;
LLVMValueRef x0;
LLVMValueRef y0;
struct lp_build_sampler_soa *sampler;
struct build_fetch_texel_context sampler;
struct lp_build_interp_soa_context interp;
LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
LLVMValueRef fs_out_color[NUM_CHANNELS][LP_MAX_VECTOR_LENGTH];
@@ -510,13 +586,8 @@ generate_fragment(struct llvmpipe_context *lp,
a0_ptr, dadx_ptr, dady_ptr,
x0, y0, 2, 0);
#if 0
/* C texture sampling */
sampler = lp_c_sampler_soa_create(context_ptr);
#else
/* code generated texture sampling */
sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr);
#endif
memset(&sampler, 0, sizeof sampler);
sampler.context_ptr = context_ptr;
for(i = 0; i < num_fs; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
@@ -535,7 +606,7 @@ generate_fragment(struct llvmpipe_context *lp,
context_ptr,
i,
&interp,
sampler,
&sampler,
&fs_mask[i],
out_color,
depth_ptr_i);
@@ -544,8 +615,6 @@ generate_fragment(struct llvmpipe_context *lp,
fs_out_color[chan][i] = out_color[chan];
}
sampler->destroy(sampler);
/*
* Convert the fs's output color and mask to fit to the blending type.
*/
@@ -696,45 +765,18 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
*/
static void
make_variant_key(struct llvmpipe_context *lp,
struct lp_fragment_shader *shader,
struct lp_fragment_shader_variant_key *key)
{
unsigned i;
memset(key, 0, sizeof *key);
if(lp->framebuffer.zsbuf &&
lp->depth_stencil->depth.enabled) {
key->zsbuf_format = lp->framebuffer.zsbuf->format;
memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
}
memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
key->alpha.enabled = lp->depth_stencil->alpha.enabled;
if(key->alpha.enabled)
key->alpha.func = lp->depth_stencil->alpha.func;
/* alpha.ref_value is passed in jit_context */
if(lp->framebuffer.cbufs[0]) {
const struct util_format_description *format_desc;
unsigned chan;
memcpy(&key->blend, lp->blend, sizeof key->blend);
format_desc = util_format_description(lp->framebuffer.cbufs[0]->format);
assert(format_desc->layout == UTIL_FORMAT_COLORSPACE_RGB ||
format_desc->layout == UTIL_FORMAT_COLORSPACE_SRGB);
/* mask out color channels not present in the color buffer */
for(chan = 0; chan < 4; ++chan) {
enum util_format_swizzle swizzle = format_desc->swizzle[chan];
if(swizzle > 4)
key->blend.colormask &= ~(1 << chan);
}
}
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i))
lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]);
memcpy(&key->blend, lp->blend, sizeof key->blend);
}
@@ -745,7 +787,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
struct lp_fragment_shader_variant_key key;
struct lp_fragment_shader_variant *variant;
make_variant_key(lp, shader, &key);
make_variant_key(lp, &key);
variant = shader->variants;
while(variant) {

View File

@@ -98,16 +98,6 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe,
pipe_texture_reference(&llvmpipe->texture[i], tex);
lp_tex_tile_cache_set_texture(llvmpipe->tex_cache[i], tex);
if(tex) {
struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex);
struct lp_jit_texture *jit_tex = &llvmpipe->jit_context.textures[i];
jit_tex->width = tex->width[0];
jit_tex->height = tex->height[0];
jit_tex->stride = lp_tex->stride[0];
if(!lp_tex->dt)
jit_tex->data = lp_tex->data;
}
}
llvmpipe->num_textures = num;

View File

@@ -119,7 +119,7 @@ add_load_rgba_test(LLVMModuleRef module,
lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 1, 0), &loop);
rgba = lp_build_load_rgba_aos(builder, format, ptr);
rgba = lp_build_load_rgba(builder, format, ptr);
LLVMBuildStore(builder, rgba, rgba_ptr);
lp_build_loop_end(builder, LLVMConstInt(LLVMInt32Type(), 4, 0), NULL, &loop);
@@ -160,7 +160,7 @@ add_store_rgba_test(LLVMModuleRef module,
rgba = LLVMBuildLoad(builder, rgba_ptr, "");
lp_build_store_rgba_aos(builder, format, ptr, rgba);
lp_build_store_rgba(builder, format, ptr, rgba);
LLVMBuildRetVoid(builder);

View File

@@ -154,7 +154,7 @@ lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc)
if (lpt->timestamp != tc->timestamp) {
/* texture was modified, invalidate all cached tiles */
uint i;
debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp);
_debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp);
for (i = 0; i < NUM_ENTRIES; i++) {
tc->entries[i].addr.bits.invalid = 1;
}

Some files were not shown because too many files have changed in this diff Show More