Compare commits

...

197 Commits

Author SHA1 Message Date
Ian Romanick
0c88e34049 mesa: Add 7.7.1 release MD5 sums 2010-03-28 16:25:47 -07:00
Ian Romanick
663642b435 mesa: set version string to 7.7.1
Also set the correct release date.
2010-03-28 16:22:44 -07:00
Brian Paul
535742d75f mesa: move/update hash function comments 2010-03-27 08:58:02 -06:00
Török Edwin
8fe3b3f66a mesa: fix deadlock in _mesa_HashFindFreeKeyBlock()
Fixes fd.o bug 27340.
2010-03-27 08:55:47 -06:00
Michel Dänzer
4cf14fa80b dri/swrast: Fix frontbuffer rendering.
Was broken since the endianness fixes.
2010-03-26 18:29:18 +01:00
Michel Dänzer
6ec259eb17 dri/swrast: Fix missed conversion of one pixel pointer increment.
This probably broke the swrast DRI driver when running X in depth 16.
2010-03-26 16:29:59 +01:00
Brian Paul
ca1c8a183d docs: added news item for 7.7.1 release 2010-03-23 09:19:44 -06:00
Brian Paul
3f3b1094bf docs: insert expected 7.7.1 release date 2010-03-23 09:19:26 -06:00
Ian Romanick
e33121b2d8 mesa: set version string to 7.7.1-rc2 2010-03-22 18:15:53 -07:00
Pauli Nieminen
415d0326bb r200: Fix emit size prediction to account elt splitting.
Emit sizes prediction didn't account for render splitting in
hwtnl path.
2010-03-21 23:32:14 +02:00
Pauli Nieminen
7e24ce2d9b r200: Don't flush when closing elts in KMS.
Flush in middle of rendering in KMS is not allowed because
buffers are discarded in flush.

Fixes crash when emiting split indices with RADEON_DEBUG=all.
2010-03-21 23:30:23 +02:00
Pauli Nieminen
2ae754b7b9 r200: Fix swtnl fallback to flush pending rendering before transition.
Flush after transition would emit wrong state that could cause
wrong state emited for pending rendering operation.

Fixes wan once from extrement tuxracer that is using per vertex
materials.
2010-03-21 20:23:01 +02:00
Pauli Nieminen
501156b36b r200: Fix mixed indetion in r200TclFallback. 2010-03-21 20:22:56 +02:00
Pauli Nieminen
4ff3244457 vbo: Fix vbo_split_copy to pass correct max_index to draw.
vbo_split_copy was passing one past the max_index to draw function
which caused _tnl_draw_prims function to read uninitialized values
from copied array.

Bug was spoted in valgrind report of progs/tests/cva_huge.
2010-03-21 12:42:10 +02:00
Michel Dänzer
3889556d70 Revert "Revert "mesa/st: Make ST_SURFACE_DEPTH index consistent with mesa's BUFFER_DEPTH.""
This reverts commit 52d83efdbc.

The fix it reverted should be fine with the two previous fixes.
2010-03-19 17:32:54 +01:00
Brian Paul
6412046f65 st/mesa: s/BUFFER_FRONT_LEFT/surfIndex/
(cherry picked from commit 5d5c524cbe)
2010-03-19 17:20:26 +01:00
Brian Paul
6e96cea6e2 st/mesa: fix st_set_framebuffer_surface() state validation
Set the _NEW_BUFFERS flag and remove the code which updated the
parent framebuffer size.  Normal Mesa state validation will do that.

Fixes issues with Warsow on r300g and possibly other bugs.
(cherry picked from commit c472ce5302)
2010-03-19 17:20:19 +01:00
Ian Romanick
3a3ef3d6c9 intel: Use bit-wise not instead of logical not (i830 path)
The assertion is checking that the low-order bits of offset are not
set.  It does this by anding the inverted offset mask with the
offset.  This is clearly intended to be a bit-wise "invert".

Fixes bug #25984.
(cherry picked from commit 062a208814)
2010-03-18 18:23:21 -07:00
Ian Romanick
98aed6dc69 intel: Correct value of S0_VB_OFFSET_MASK to match hardware docs.
(cherry picked from commit 689e4b5541)
2010-03-18 17:31:22 -07:00
Ian Romanick
d3a607f889 Use bit-wise not instead of logical not.
The assertion is checking that the low-order bits of offset are not
set.  It does this by anding the inverted offset mask with the
offset.  This is clearly intended to be a bit-wise "invert".

Fixes bug #25984.
(cherry picked from commit fda5078324)
2010-03-18 15:39:00 -07:00
Thomas Hellstrom
00e41e007e st/xorg: Fix Xv cliprect scaling.
Due to a quantization error, different cliprects of scaled video windows may
not have identical x / y scale.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
2010-03-13 20:32:00 +01:00
Ian Romanick
6624845a5d mesa: set version string to 7.7.1-rc1 2010-03-16 10:26:52 -07:00
Matthew W. S. Bell
c9c54180e4 Correct GL_EQUIV code in r67/7xx.
From 247e121106e8d3e389f2e5a6edf13ea70ac18df7 Mon Sep 17 00:00:00 2001

These seem to be documented in
<http://www.svgopen.org/2003/papers/RasterOperationsUsingFilterElements/index.html>.
2010-03-16 11:38:32 -04:00
José Fonseca
93e77b0028 mesa: List Quake3 extensions first.
Quake3 truncates the extension string, and GL_EXT_compiled_vertex_array
wasn't being detected, making it very slow.

This is a quick fix. The IMHO best way to address this in a more general
fashion is to sort by year.
2010-03-13 10:41:32 +00:00
Keith Whitwell
0c9e8e6c6e mesa: Fix memory leak in decompress-with-blit.
(cherry picked from commit f05a4ee6f2840590c90da4be2fe5c6295410a5af)
2010-03-13 10:40:56 +00:00
Michel Dänzer
c50477c255 st/dri: Always try to set up R5G6B5 configs.
Allows compiz to work in depth 16.

The DRI2 getBuffersWithFormat hook is only required for 16/32 bit depth
buffers, for colour buffers the only requirement is that the format matches
the drawable depth, which we can't check here.
2010-03-12 18:24:34 +01:00
Jakob Bornecrantz
3bf13656d3 st/xorg: Include cursorstr.h 2010-02-06 16:58:32 +00:00
Brian Paul
fa4083d38b docs: updates to 7.7.1 release notes 2010-03-10 14:14:04 -07:00
Brian Paul
d311ded31d gallium/util: added surface dump code for unix 2010-03-10 10:39:46 -07:00
Brian Paul
34f0207161 st/mesa: fix incorrect glCopyPixels between window/FBO
There was a DrawBuffer/ReadBuffer typo and we were neglecting to invert
the texture coords when copying from a window to an FBO.

Plus, add some surface dump/debug code (disabled).
2010-03-10 10:39:45 -07:00
Brian Paul
8d3f629a13 st/mesa: fix incorrect glDrawPixels into FBO
We weren't inverting the textured quad when drawing into an fbo.
2010-03-10 10:39:45 -07:00
Thomas Hellstrom
b98ef495d4 st/xorg Avoid advertizing rotation / reflection support.
We don't support it yet since we don't implement the shadow allocate
functions.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
2010-03-06 15:52:31 +01:00
Michel Dänzer
21c91b410a st/xorg: Work around cursor reference counting bugs in older X servers.
Could result in use of freed memory and consequently random crashes, e.g. on
screen resize.
2010-03-10 13:16:00 +01:00
Thomas Hellstrom
a8f3b3f88a st/xorg, vmware: Make throttling configurable.
The xorg state tracker gets two new options to let the user choose
whether to enable / disable dirty throttling and swapbuffer throttling.
The default value of these options are enabled, unless the winsys
supplies a customizer with other values. The customizer record has been
extended to allow this, and also to set winsys-based throttling on a per-
context basis.

The vmware part of this patch disables the dirty throttling if the kernel
supports command submission throttling, and also in that case sets kernel
based throttling for everything but swapbuffers. The vmware winsys does not
set throttling per context, even if it theoretically could, but instead
sets throttling per screen. This should perhaps be changed, should the
xorg state tracker start to use multiple rendering contexts. Kernel throttling
is off by default for all new screens/contexts, so the dri state tracker
is not affected.

This significantly improves interactivity of the vmware xorg driver.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
2010-03-06 11:03:55 +01:00
Thomas Hellstrom
e8a8c5e339 svga: Add a winsys callback to get the svga_winsys_context
The winsys may need to extract the svga_winsys_context from a
pipe_context. Add a function to enable that functionality.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
2010-03-06 11:03:54 +01:00
Keith Whitwell
7941d31ee6 svga: Don't do culling while the software pipeline is active.
It does it for us, and additionally introduces potentially
back-facing triangles.
2010-03-09 19:19:56 +01:00
Brian Paul
842351dd76 softpipe: zero-out entire clear_flags array in sp_tile_cache_flush_clear()
Before, we only cleared the flags for the active tiles (the ones inside
the framebuffer bound).  The problem is if we later bound a different,
larger surface to the tile cache we'd have some stale clear-flags still
set (and mistakenly clear some tiles in the new surface).

Fixes fd.o bug 26932.

(cherry picked from commit e1762fb870)
2010-03-08 11:40:40 -07:00
Brian Paul
d74929702f st/mesa: don't detach renderbuffer, surface in st_finish_render_texture()
There's no reason to release the renderbuffer from the framebuffer object
or release the gallium surface in this function (they're reference counted).
In fact, we don't want to do this because we may later use the texture as a
pixel source (ex: glBlitFramebuffer) and need the surface.

Fixes fd.o bug 26923 and is part of the fix for bug 26932.

(cherry picked from commit 80dc54e308)
2010-03-08 11:40:25 -07:00
Brian Paul
1e431f0454 mesa: s/GL_DEPTH_STENCIL/GL_DEPTH_COMPONENT/ for MESA_FORMAT_Z16 renderbuffer
MESA_FORMAT_Z16 has no stencil bits.

(cherry picked from commit 614f490ca9)
2010-03-08 10:00:17 -07:00
Alex Deucher
4cc8d1d79f r600: recalculate point size, if point min/max size changes 2010-03-08 11:31:06 -05:00
Alex Deucher
3d2bc6848a r600: no need to flush on context init 2010-03-08 11:30:54 -05:00
Maciej Cencora
d5327538e7 r300: recalculate point size, if point min/max size changes
Fixes two wine d3d9 unit tests
2010-03-08 11:29:12 -05:00
Maciej Cencora
86ac140937 r300: no need to flush on context init 2010-03-08 11:28:57 -05:00
Maciej Cencora
b584e780ab r300: remove unnecessary code
_tnl_UpdateFixedFunctionProgram is already called in r300_draw.c
2010-03-08 11:28:39 -05:00
Alex Deucher
981e8a2087 r600: add new rs880 pci id 2010-03-03 14:11:10 -05:00
Brian Paul
72d380b363 glx: replace assertion with conditional
See fd.o bug 26832.
2010-03-02 07:38:12 -07:00
Dave Airlie
cf8af9bcf1 r600: fix blender picking.
This fixes the sw fallback for GL_SELECT picking modes.

Fixes object picking blender + depthpick test

http://bugs.freedesktop.org/show_bug.cgi?id=26419

Signed-off-by: Dave Airlie <airlied@redhat.com>
2010-03-02 14:14:47 +10:00
Alex Deucher
7123f3d77a r600: enable OQ on rv740 on drms with working pipe config 2010-02-26 15:39:40 -05:00
Klaus Schnass
2edb1b9534 r600: fail to validate unsupported texture formats 2010-02-26 15:39:17 -05:00
Markus Fleschutz
69334d6784 glx: fix incorrect array stack memory allocation
The array stack space wasn't allocated to the proper size.  Fixes out of
bounds memory writes when the client/array stack depth exceeds one.

See fd.o bug 26768.
2010-02-26 10:38:21 -07:00
Brian Paul
61482ddc1c mesa: fix _BaseFormat assignment in _mesa_soft_renderbuffer_storage()
The rb->InternalFormat field will be set by the caller if the allocation
succeeds.  Until then, this field's value can't be used.  Fixes a failed
assertion with FlightGear.

(cherry picked from commit fe25476c04)
2010-02-26 09:14:12 -07:00
Brian Paul
b0e84e22d5 mesa: use simplified _BaseFormat value in render-to-texture code
Fixes fd.o bug 26762.

(cherry picked from commit c9e8ff1976)
2010-02-26 09:10:27 -07:00
Jakob Bornecrantz
c0e8d443fe st/xorg: Re-enable crtc on resize 2010-02-25 16:52:02 +01:00
Jakob Bornecrantz
b95d4cd680 st/xorg: Fix copy-topy 2010-02-25 16:52:02 +01:00
Brian Paul
293f4d51b4 dri: remove old assertion (see bug 26734) 2010-02-24 14:04:26 -07:00
Alex Deucher
f0e99179bc r600: update state count for CB_COLOR0_FRAG & CB_COLOR0_TILE relocs 2010-02-24 12:03:10 -05:00
Jerome Glisse
69a94e1452 r6xx/r7xx: emit relocation for FRAG & TILE buffer
FRAG & TILE buffer are unused but still they need
to be associated with a valid relocation so that
userspace can't try to abuse them to overwritte
GART and then try to write anywhere in system
memory.
2010-02-24 12:03:00 -05:00
Dave Airlie
bc7e12e5e3 radeon/r200: fix bad state emission causes kernel to do bad depth clear
The kernel lets you clear depth without getting a depth offset
from userspace, mesa used to emit state before clear, but that got
lost in the refactoring, which made the kernel bug show up. Fix
mesa driver to emit the state properly now.

cherry-pick + squash master commits.

Signed-off-by: Dave Airlie <airlied@redhat.com>
2010-02-24 19:16:13 +10:00
Jakob Bornecrantz
7accf8ced6 vmware/xorg: Bump to match vmware driver 2010-02-22 20:07:06 +01:00
Jakob Bornecrantz
52d83efdbc Revert "mesa/st: Make ST_SURFACE_DEPTH index consistent with mesa's BUFFER_DEPTH."
This reverts commit 9d17ad2891.

Fun stuff so fixing exposes another bug which I'm having trouble
tracking down. So for now I'm just going to revert this untill
I can fix the real bug. Sorry about this.
2010-02-22 19:37:09 +01:00
Jakob Bornecrantz
1702db3a35 st/xorg: Make resize fail gracefully 2010-02-22 19:34:56 +01:00
Jakob Bornecrantz
fa6eee135e st/xorg: Obey max {width|height} from kernel and Gallium 2010-02-22 19:34:56 +01:00
José Fonseca
b5fa760972 svga: Upload user buffers only once. 2010-02-22 19:38:10 +00:00
José Fonseca
69cf45cdae svga: Fix the guest offset of piecewise buffer DMAs.
It was being erroneously set equal to the host offset, but it should be
zero.
2010-02-22 19:38:08 +00:00
José Fonseca
f5ffbe0bc3 svga: Emit a scalar rcp in shadow maps.
Small improvement in Lightsmark 2008.
2010-02-22 19:38:05 +00:00
José Fonseca
46d8ca023d svga: Don't emit zero writemasks.
This fixes a regression with Lightsmark, where more compact TGSI from Mesa
was causing a zero mask MOV to be emitted for shadow map compare, causing
problems in some backends.

Add a few more assertions to catch cases like this.
2010-02-22 19:38:04 +00:00
José Fonseca
9bef69782d tgsi: Report an error when a destination has an empty writemask. 2010-02-22 19:38:01 +00:00
Xavier Chantry
b0e5dcb859 glxinfo: Fix User error in glGetProgramivARB
glxinfo needed fixing after commit 4bccd69.

Move fragment program only parameters into their own list
so that they are not queried for a vertex program.

Signed-off-by: Xavier Chantry <chantry.xavier@gmail.com>
Signed-off-by: Brian Paul <brianp@vmware.com>
2010-02-22 08:53:03 -07:00
Brian Paul
bcd561c667 st/mesa: change viewport Z scale/bias for glBitmap/glDrawPixels
This fixes incorrect Z position of glBitmap, glDraw/CopyPixels for the
svga driver.  Now we use 0.5, 0.5 as is typical for ordinary 3D rendering.
2010-02-22 08:01:28 -07:00
José Fonseca
c98eced9ae scons: Control caching via new SCONS_CACHE_DIR environment variable.
This serves several purposes:
- disable caching in situations were is it useless or undesired
- share caches among all trees
- simplify purging the cache (when it's a single location)
- move the cache out of the tree, since that slows downs IDEs considerably

To retain previous behavior just define do

  export SCONS_CACHE_DIR=$PWD/build/cache

before invoking scons.
2010-02-22 11:28:55 +00:00
Brian Paul
13cbb5fff6 st/mesa: Add checks for ST_SURFACE_x vs MESA_BUFFER_x
The ST_SURFACE_x values should match the Mesa BUFFER_x values.
Added some assertions to prevent future mix-ups.
2010-02-21 12:38:46 +01:00
Thomas Hellstrom
dd8d78c908 st/xorg: Encapsulate all customizable stuff in a separate class.
This avoids exposing the ms driver structure to the winsys,
and nicely encapsulates driver customizable stuff.
In the future more things might be customizable by the winsys, like
throttling, 3D readback etc.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
2010-02-21 12:25:33 +01:00
Thomas Hellstrom
9d17ad2891 mesa/st: Make ST_SURFACE_DEPTH index consistent with mesa's BUFFER_DEPTH.
Some st functions assume that they are identical.
2010-02-21 10:39:38 +01:00
Brian Paul
d437d905e6 softpipe: fix depth testing problems
The optimized Z-test functions assumed that the array of incoming quads
are adjacent, but that's not always true.  The fragment shader can cull
intermediate quads, for example.

Now these Z-test functions can cope with non-adjacent quads.  A little bit
of performance is probably lost, but it's probably not worth worring about.

This fixes broken glBitmap() Z testing, among other things.
2010-02-18 16:47:27 -07:00
Jon TURNEY
551c96979e mklib: Teach mklib to fail build if link fails on cygwin
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Signed-off-by: Brian Paul <brianp@vmware.com>
2010-02-18 12:41:30 -07:00
Jon TURNEY
c1a4f249f1 configure: PTHREADS should be defined on cygwin, as well
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Signed-off-by: Brian Paul <brianp@vmware.com>
2010-02-18 12:41:08 -07:00
José Fonseca
18ff85e91d svga: Upload the dirty ranges instead of the whole buffer. 2010-02-18 18:22:31 +00:00
José Fonseca
12617c7e30 svga: Break uploads of big buffers into smaller pieces.
Fixes crash in Homeworld2 which tries to create a 14MB buffer, because we
now avoid creating GMR buffers larger than 8MB to ensure progress given
we have only a 16MB pool.
2010-02-18 18:22:31 +00:00
José Fonseca
5dbf44953c svga: Note ranges even when there is no hardware buffer around.
Not having a hardware buffer around doesn't change the fact that the
range is dirty and needs to be uploaded eventually.
2010-02-18 18:22:31 +00:00
José Fonseca
a51d638ff3 svga: Further cleanup/comment svga buffer code.
Just cosmetic changes -- no behavior change.
2010-02-18 18:22:30 +00:00
José Fonseca
770945cff4 svga: Temporarily create a sw vertex buf when failed to create a hw buf.
Many apps don't check the return of map buffer so it is better not to
fail.
2010-02-18 18:22:30 +00:00
Jakob Bornecrantz
eaa4066bfc vmware/xorg: Export modinfo just as the other vmware X drivers does 2010-02-18 17:07:32 +01:00
Jakob Bornecrantz
46cf606cd3 st/xorg: Fixup configure
Make sure we always test for XEXT version.
Make sure that the user has a recent version of libkms and libdrm installed.

Not that the st/xorg code requires so new versions to work but these are
needed to make a proper vmwgfx_drv.so driver which is the only real user.
2010-02-18 17:07:32 +01:00
Jakob Bornecrantz
a69a7b9688 st/xorg: A bit more debugging info 2010-02-18 16:13:18 +01:00
Jakob Bornecrantz
eb7590a0d9 st/xorg: Make default of debugging fallbacks smart
Set it to the same as 2d acceleration
2010-02-18 16:13:18 +01:00
Jakob Bornecrantz
86870a691c drm/vmware: Latest interface changes are backwards incopatible
Since the execbuffer change actually changed size off the ioctl
struct and not just a reuse of padded bits, we can't support
old kernels as easily as the scanout change was.
2010-02-18 16:13:18 +01:00
Brian Paul
7c34c237a2 swrast: fix left side clipping
Fixes bug 26623.  Original patch was submitted by Mathias Frohlich
and modified by Brian.
2010-02-18 09:37:58 -07:00
José Fonseca
13cd4298fb mesa: Take back some assertions.
It seems there are still some places where draw can happen with mapped
buffers... Remove the assertions since there is not much more than can
be done at this moment.

This partially reverts commit af2023e31c.
2010-02-17 20:02:32 +00:00
José Fonseca
3b724f91c5 svga: Remove unused buffer download code.
Unnecessary now that we never destroy buffer storage.
2010-02-16 21:24:38 +00:00
José Fonseca
2077f375c7 pipebuffer: Don't synchronize when checking for buffer overflows.
To avoid masking synchronization issues in debug builds.
2010-02-16 21:00:15 +00:00
Michal Krol
055265b0a3 svga: Translate point_sprite rasterizer state. 2010-02-16 19:53:13 +01:00
Mike Stroyan
3094adb3ca mesa: Lock mutex around _mesa_HashLookup linked list chase.
Remove const qualifier from _mesa_HashLookup() table parameter to
avoid LOCK/UNLOCK warnings in the function body.

Signed-off-by: Brian Paul <brianp@vmware.com>
2010-02-16 08:18:12 -07:00
Mike Stroyan
7c7247ddbf mesa: Test for failed malloc in _mesa_HashInsert.
Signed-off-by: Brian Paul <brianp@vmware.com>
2010-02-16 08:17:06 -07:00
José Fonseca
af2023e31c vbo: Ensure vertices are always unmapped before the context is flushed.
Purpose is two fold:

- when doing user-space memory management mapping a buffer stored in the
  graphics aperture effectively pins it there, increasing the likelyhood
  of failure of validating other buffers when flushing

- certain hardware/platform combinations do not allow a buffer to be
  simultaneously mapped and validated

This fixes assertion failures in HL Uplink with the svga driver, where
vbo was holding a map to a buffer which was also referred in the command
stream.

Note: this a non-invasive fix and shouldn't be just cherry-picked into
master as-is -- a cleaner fix for this problem should be searched.
2010-02-16 13:24:01 +00:00
Michal Krol
2eedbc94c2 slang: Fix handling of if/elif/else cases.
Once if/elif evalutes to true, all subsequent conditions are always false.
2010-02-16 10:34:07 +01:00
José Fonseca
672f6bb545 wgl: Be lenient when sharing contexts.
My first reading of MS docs was wrong. It says:

  All rendering contexts of a shared display list must use an identical
  pixel format. Otherwise the results depend on the implementation of
  OpenGL used.

That is, it is OK to share contexts with different pixel formats.

Adobe Premiere Pro tries to do that: share lists between a rgbx8 and a
rgba8 pixel format.
2010-02-15 19:34:38 +00:00
Brian Paul
ab6bcef99a docs: document glMultiDrawElements() fix 2010-02-15 08:56:39 -07:00
Brian Paul
c5a4cfb03f vbo: fix broken glMultiDrawElements()
Seems to be a regression from commit 60b08eb1fd.
2010-02-15 08:52:48 -07:00
Thomas Hellstrom
df944efdbf st/xorg, vmware/xorg: Fix xnfcalloc arguments.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
2010-02-15 14:26:25 +01:00
Brian Paul
1ff9cd5079 softpipe: fix broken cubemap / mipmap selection code
This is a quick-fix for the time being...

The per-face mipmap LOD computation was invalid at cube edges.  In
mip_filter_nearest/linear() we were trying to compute LOD using
texcoords that were sometimes indexes into different cube faces.
The subtraction used to compute the partial derivatives basically
gave random values, so the LOD was unpredictable.  This fix simply
uses the same cube face for all four pixels in the quad.  The per-
face texcoords all reference the same cube face so the partial
deriviates are computed properly.

A more elaborate fix would involve computing the LOD at the same
time as we choose the cube faces.  But for now, this solution works
well and allows the piglit/cubemap test to pass.
2010-02-13 17:45:05 -07:00
José Fonseca
4a2b54cbdb mesa: Export GL_EXT_texture_cube_map.
Still used by some applications.
2010-02-13 15:10:57 +00:00
José Fonseca
6bd6a15ab3 wgl: Implement wglSwapMultipleBuffers. 2010-02-13 15:10:57 +00:00
José Fonseca
c1a5c9bb4c svga: Fix texture border color.
Also opposite ordering.
2010-02-13 15:10:57 +00:00
Brian Paul
b3c7dc6ff2 st/mesa: restore draw rasterization stage after rasterpos
This fixes invalid calls to rastpos_point/line/tri() that can occur
when glRasterPos() is called while in feedback or selection mode.
2010-02-12 17:18:21 -07:00
José Fonseca
a1025ec041 svga: A few more tweaks to blend color state emission. 2010-02-12 23:17:04 +00:00
José Fonseca
3a4068474c svga: Clamp max cube texture levels to supported max 2d levels. 2010-02-12 21:31:18 +00:00
José Fonseca
1ae976be4a svga: Report the 2d/3d texture sizes supported by the host. 2010-02-12 21:31:14 +00:00
Roland Scheidegger
b685927156 svga: emit blend color 2010-02-12 22:12:55 +01:00
Zack Rusin
df0c8d029d st/dri: don't expose visuals we'll have trouble supporting
without getBuffersWithFormat some visuals will just cause headaches (crashes),
so if we're running on an older system simply don't advertise them.
2010-02-12 15:49:03 -05:00
Zack Rusin
3477dc4c48 st/dri, st/xorg: fix buffers that have attachements of different depth
we actually need to specify the formats for different attachements, otherwise
if the color buffer is 24bpp and the app asks for 16bpp depth buffer than
we end up fetching the depth from the drawable which is 24bpp and end up
creating the wrong depth buffer. use the new getBuffersWithFormat extension
to pass the depth correctly.
2010-02-12 15:48:52 -05:00
Andre Maasikas
0426bccadd r600: be more exact in vb size calculation
to make kernel cs checker happier, last attribs don't need full stride of
space. Calculate as count-1*stride + size of attrib
2010-02-12 10:21:44 -05:00
Andre Maasikas
841333cd21 r600: support GL_SHORT attributes
normalized seems to work with this setting.
2010-02-12 10:21:23 -05:00
José Fonseca
e541dceb67 wgl: Go into dormant state when DLL is unloaded unclealy.
When our DLL is unloaded, even if we leave the data structures in memory
for sake of future calls, the MS CRT will destroy the heap. Instead we
make all calls no-ops by setting stw_dev to NULL.
2010-02-12 13:59:16 +00:00
José Fonseca
fea7a70a1a scons: Target Windows7. 2010-02-12 13:22:59 +00:00
José Fonseca
426f607aaa wgl: Do not reach out and destroy contexts on cleanup.
Simply skip cleanup when contexts are still active.

This addresses two issues:

- in some situations the ICD DLL may be unloaded before the DLL that is
  using GL contexts is, so we may receive GL calls after stw_cleanup.

- when aborting (exception, or control-c) the contexts may have been left
  in an inconsistent state and attempting to destroy can cause
  unpredictable results.
2010-02-12 11:03:33 +00:00
Brian Paul
408f32dc16 svga: check min_index, max_index before assertions
It's possible for min_index and max_index to be ~0 if the min/max
values were not actually set or computed in the state tracker.
Skip some assertions in that case.

This only effects the debug build error checking.
2010-02-11 16:47:34 -07:00
José Fonseca
94028edfc5 gdi: Never fail at DLL load time.
Windows doesn't really expect things to fail at this point -- it
will try many times until it finally gives up, worse, something bad
happens.

The WGL state tracker will gracefully decline to do work even when it
is loaded.
2010-02-11 16:38:16 +00:00
José Fonseca
7fec5f88a5 wgl: Fail gracefully whenever 3D could not be enabled for some reason. 2010-02-11 16:38:13 +00:00
Michal Krol
67007670bb mesa: Enable true refcounting for NullBufferObj.
This object can be shared with another context, so we cannot just
delete it when the owning context is being destroyed.

Ensuring that buffer objects are properly refcounted guarantees
NullBufferObj is destroyed when all references to it are removed.
2010-02-10 14:12:11 +01:00
Michal Krol
e8865f199d mesa: Protect buffer objects reference counting with a mutex. 2010-02-10 14:12:10 +01:00
Zack Rusin
2d3262d47d st/xorg: fix a silly offset bug in xv
we were multiplying the difference in the wrong direction.
2010-02-09 21:15:22 -05:00
Thomas Hellstrom
3470d821ba vmware: Update vmwgfx_drm.h to kernel version.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
2010-02-09 22:54:15 +01:00
Brian Paul
0371956d66 docs: fix typo: s/osdemo/osdemos/ 2010-02-09 11:21:15 -07:00
Jakob Bornecrantz
45c4addea7 vmware/core: Support drm interface version 1.0.0 2010-02-06 01:30:29 +01:00
Jakob Bornecrantz
1eba0eb37d vmware/core: Use correct flags in scanout code 2010-02-06 01:29:47 +01:00
Dave Airlie
d87fb5e003 radeon: fix UMS since stp addition.
UMS doesn't need the STP atom.

Signed-off-by: Dave Airlie <airlied@redhat.com>
2010-02-08 12:07:04 +02:00
Pauli Nieminen
4be7922a8e r200: Fix UMS notto emit stp.
Polgon stipples are handled by kernel in UMS. Mark the
state as never to be emited for UMS.
2010-02-08 12:07:04 +02:00
Eric Anholt
a1cac0732b intel: Check aperture size when doing a blit glClear.
Fixes failure in cairo-gl firefox-planet-gnome.
(cherry picked from commit 67e5fd7397)

Conflicts:

	src/mesa/drivers/dri/intel/intel_blit.c
2010-02-06 17:45:34 +01:00
Eric Anholt
fb32e0fcc5 intel: Respect texture tiling when doing a PBO blit teximage upload.
Bug #26008.  Fixes piglit pbo-teximage-tiling-2.
(cherry picked from commit 22bbc97994)
2010-02-06 17:45:34 +01:00
Eric Anholt
9564a6fa13 intel: Set the region's tiling to none when attaching a PBO to a region.
Note that when detaching the PBO from the region and making a new BO
for the region, we don't make it tiled even if the region originally
was.

Fixes piglit pbo-teximage-tiling.
(cherry picked from commit f20e83210e)
2010-02-06 17:45:34 +01:00
Eric Anholt
0b9990b2fd intel: Fix PBO blit ReadPixels from an FBO.
Bug #25921 -- clutter PBO usage gave unreliable results.
(cherry picked from commit 63b10e8fe7)

Conflicts:

	src/mesa/drivers/dri/intel/intel_pixel_read.c
2010-02-06 17:16:51 +01:00
Eric Anholt
8ce99c85e7 i965: Fix loads of non-relative-addr constants after a reladdr load.
Fixes piglit vp-arl-constant-array-huge-overwritten.
(cherry picked from commit d5b964234c)
2010-02-06 17:08:53 +01:00
Jakob Bornecrantz
a2c402ba53 vmware/core: Handle new scanout field 2010-02-06 01:34:12 +01:00
Jakob Bornecrantz
1ceb906c12 vmware/core: Update header to latest version 2010-02-06 01:34:12 +01:00
Zack Rusin
fb1fe8e76f gallium/tgsi: fix soa dependencies in mul and cmp instructions
master has this done in a lot nicer way, this is a simple patch to
stop the bleeding in a minimally intrusive manner.
2010-02-05 19:32:01 -05:00
Zack Rusin
f8b05566aa gallium/python: support two more formats in retrace dumps
dump PIPE_FORMAT_R8G8B8A8_UNORM and PIPE_FORMAT_R16G16B16_SNORM formats.
2010-02-05 19:25:01 -05:00
Zack Rusin
a6148b8eba gallium/draw: fix overflowing element indices
we piggy back flags in the top four bits of the element indices, so if
the maximum index stored in any of the elements is greater than
sizeof(ushort) - sizeof(flags we piggy back) then we overflow. fix it by
simply falling back to the slow path if we notice the overflow.
2010-02-05 19:25:01 -05:00
Brian Paul
64be837b0b st/mesa: allow negative index for PROGRAM_STATE_VAR
The piglit vp-address-01 test uses negative address-relative
offsets.  In this test we're indexing into PROGRAM_STATE_VAR
which, in turn, contains references to ENV vars.

We previously fixed this issue for PROGRAM_CONSTANT.

piglit/vp-address-01 (the version from Feb 5) passes now.
2010-02-05 14:54:00 -07:00
Brian Paul
e070c1d183 tgsi: disable inf/nan checking
Inf/NaN can happen normally.  Only check for those values
when we need to debug something.
2010-02-05 14:48:42 -07:00
Tom Fogal
e6ee4b49c4 docs: Fix a typo in mesa3d.org HTML.
Signed-off-by: Brian Paul <brianp@vmware.com>
2010-02-05 13:17:37 -07:00
Tom Fogal
e65029e9b3 osmesa: Add OSMesaColorClamp and OSMesaGetProcAddress to symbol defs.
Without this patch, the two symbols get an underscore prepended
and an "@4" appended when compiling with VC8.

Signed-off-by: Brian Paul <brianp@vmware.com>
2010-02-05 13:15:33 -07:00
Brian Paul
3ca6cb3440 softpipe: fix bug in perspective corrected interpolants for lines
Thanks to Michal for finding this.

This will get fixed on the gallium-cylindrical-wrap branch and
then merged to master.
2010-02-05 12:57:54 -07:00
Pauli Nieminen
34b36277b7 r100: Add the polygon stipple state to the state list.
This fixes glean paths test case.
2010-02-05 11:28:01 +02:00
Pauli Nieminen
c8ea0212fe r200: Add the polygon stipple state to the state list.
This fixes glean paths test case.
2010-02-04 23:56:37 +02:00
Pauli Nieminen
7d6cbcdd9a swrast/sse: Fix _mesa_sse_transform_pointsX_3d_no_rot
PXOR user in code were causing the lowest SP float register to have NaN
values which made all math operations in that slot fail. Correct istruction
to clear float registers is XORPS which handles single precission floats
correctly.

Fixes progs/tests/fog in swrast SSE mode.

Now the correct commit instead of 9d9c1f17dc which is not even close
of correct fix for the bug.
2010-02-04 13:07:04 +02:00
Pauli Nieminen
9d9c1f17dc Revert "mesa: fix transform_points_3d_no_rot using undefined values in %xmm0"
This reverts commit 4c31632817.
2010-02-04 05:00:02 +02:00
Brian Paul
f1afb352da scons: add another prefix for mingw32 on Fedora 2010-02-03 11:46:36 -07:00
Brian Paul
e4c3abbf55 tgsi: fix XPD when dst reg is a src reg
Store XPD results in temporaries before writing to the dest register.
This issue has already been fixed in Mesa/master for XPD (and all
other instructions?).

Fixes progs/demos/bump.c when using TGSI interpreter (GALLIUM_NOSSE=1).

A new glean/glsl1 test has been added to test this case.
2010-02-03 08:17:37 -07:00
Keith Whitwell
141b5775c0 svga: fix TXD and TXL opcode translation 2010-02-02 18:01:52 +00:00
Keith Whitwell
c0d5f1d3ad svga: deriv insns not valid in dynamic flow control either 2010-02-02 17:45:32 +00:00
Keith Whitwell
70947e531e svga: texture from lod zero inside dynamic branching
Texture derivatives are potentially undefined inside dynamic branches,
so hardwire lod zero in this case.  Treating all if/endif and loop
constructs as dynamic branches.
2010-02-02 15:34:01 +00:00
Pauli Nieminen
7b92cb45b2 r200: Fix EXT_fogcoord rendering.
The fogcoord calue was not pushed to GPU because of implicit float to int conversion.
Fix is to use float pointer to buffer object so no conversion is done in assigment.
2010-02-02 06:09:36 +02:00
Brian Paul
43e4b58422 st/mesa: fix texture deallocation bug
This fixes a bug reported by Christoph Bumiller on mesa3d-dev.

When a texture is first created as RGBA, then re-defined with
glTexImage(internalFormat=GL_DEPTH_COMPONENT) we failed to deallocate
the original texture.  When this texture was bound as a FBO surface,
the depth/Z surface format was RGBA instead of Z.  Depending on the
driver this led to a failed assertion or FBO validation failure.

This patch does three things:

1. Remove ancient code that mysteriously tested if we were replacing
the smallest mipmap level and tested if the texture was not a cube map
texture.  I can't see any reason for those tests.

2. Move the width=height=depth=0 test to after the code which frees
texture data.  Calling glTexImage with width=height=depth=0 and data=NULL
is a way to free a single mipmap level.

3. Update the code comments.

There are no apparent conform, glean or piglit regressions from this change.
2010-02-01 18:55:54 -07:00
Brian Paul
e0d01c9d7f mesa: change _mesa_find_free_register() to find multiple free regs
Before, _mesa_find_free_register() would scan the given shader to
find a free/unused register of the given type.  But subsequent calls
would return the same register again.  This caused a failure in the
_mesa_remove_output_reads() function which sometimes needs several
free temps.

Now use a new function which build a vector of 'used' flags and another
function which searches that vector for an unused register starting at
a position that's incremented for each call.

Fixes fd.o bug 26317.  Note that a regression test for this has been
added to the glean/glsl1 test.
2010-02-01 17:31:24 -07:00
José Fonseca
b90b3667a1 mesa: Ensure object refcount is null when destroying the buffer.
Lets see if this is not too pedantic. Obj pointers are never exposed to
GL apps so it should be possible to get this right.

Furthermore apps with GL widgets and test suits create and destroy many
contexts and objects, so bad reference counting is not really an option.
2010-02-01 21:41:04 +00:00
José Fonseca
0123a2d042 mesa: Fix null buffer object reference counting.
Always use _mesa_reference_buffer_object, and never call
ctx->Driver.DeleteBuffer() directly to prevent dangling pointers to the
null buffer object.

This fixes crash/assertions in sharedtex_mt and Autodesk Mudbox.
2010-02-01 21:41:04 +00:00
José Fonseca
51a2cc5499 mesa: Always do proper ref counting of shared state. 2010-02-01 21:41:04 +00:00
Jakob Bornecrantz
f5145a6ec3 vmware/core: Remove old ioctl structs not used
Leftover that was never used in this driver
2010-01-29 17:14:53 +01:00
José Fonseca
ddedfe12d4 svga: Actually call fence_reference in texture downloads. 2010-01-29 16:23:46 +00:00
Brian Paul
cb5447f79c glsl: fix preprocessor bug involving //-style comments in macro definitions
See comments for details.
2010-01-29 08:26:23 -07:00
Brian Paul
9fd3c74724 tnl: check that state is validated before drawing 2010-01-29 08:24:36 -07:00
Brian Paul
4d1234e222 st/mesa: check that state is validated before drawing 2010-01-29 08:24:36 -07:00
Brian Paul
3cba779e16 vbo: fix missing state validation bugs
Commit 2708ddfb06 caused a few regressions.
We need to check/validate state after calling bind_arrays() because
it might set the _NEW_ARRAYS flag if the varying VP inputs change.

The symptom of this problem was some attribute arrays being ignored
(or interpreted as constant-valued) in glDrawRangeElements or
glMultiDrawElements.

A follow-on patch will add some additional asserts to try to catch
this kind of thing in the future.
2010-01-29 08:24:36 -07:00
Brian Paul
23eda89ec8 mesa: do state validation in _mesa_valid_to_render()
...rather than checking/validating before all the calls to
_mesa_valid_to_render() and valid_to_render().

The next patch will actually fix some bugs...
2010-01-29 08:24:36 -07:00
José Fonseca
6e68898b05 softpipe: Flush draw module when fragment pipeline state changes. 2010-01-28 20:22:44 +00:00
José Fonseca
1befcd5a2a softpipe: Flush draw module before switching framebuffer.
Otherwise geometry might end up in the wrong rendertarget.
2010-01-28 20:22:44 +00:00
José Fonseca
12ba355978 llvmpipe: Use assert instead of abort. Only verify functions on debug builds. 2010-01-28 20:22:43 +00:00
José Fonseca
a0907a645f llvmpipe: Fix memory leak. 2010-01-28 20:22:43 +00:00
José Fonseca
1acf7a09e7 llvmpipe: Use the generic conversion routine for depths.
This allows for z32f depth format to work correctly.
2010-01-28 20:22:43 +00:00
José Fonseca
14dc02a1b2 llvmpipe: Be more conservative with the supported formats.
We'll likely support much more formats, but doing this allows to run
more testsuites without immediately hit assertion failures.
2010-01-28 20:22:43 +00:00
José Fonseca
88cf87bd56 llvmpipe: Unmapping vertex/index buffers does NOT flush draw module anymore.
Not since 6094e79f4e.

Drivers now need to flush draw module explicitely (which explains why
all those previous commits adding draw_flushes calls were necessary).

This is a good thing, but it's tricky to get this right in face of user buffers
(it's not even clear who has the responsibility to flush when a user buffer
is seen -- statetracker or pipe driver), so just force flush (temporarily)
since it's not a bottleneck now.
2010-01-28 20:22:43 +00:00
José Fonseca
31b3420688 llvmpipe: Treat state changes systematically.
That is:
- check for no op
- update/flush draw module
- update bound state and mark it as dirty

In particular flushing the draw module is important since it may contain
unflushed primitives which would otherwise be draw with wrong state.
2010-01-28 20:22:43 +00:00
José Fonseca
4e95983fa8 llvmpipe: Flush draw module before switching framebuffer.
Otherwise geometry will end up in the wrong rendertarget.
2010-01-28 20:22:43 +00:00
José Fonseca
4e506eac8f llvmpipe: add LP_DEBUG env var
Cherry-picked from dec35d04ae.
2010-01-28 20:22:43 +00:00
Brian Paul
46167149ce llvmpipe: fix broken TGSI_OPCODE_FRC codegen 2010-01-28 20:22:42 +00:00
Brian Paul
96ec4eb755 llvmpipe: fix broken lp_build_abs() 2010-01-28 20:22:42 +00:00
José Fonseca
e20547042c llvmpipe: Fix yet another copynpaste typo in lp_build_log2_approx.
Now fslight looks perfect.
2010-01-28 20:22:42 +00:00
José Fonseca
0451d0fd01 llvmpipe: Fix lp_build_polynomial comment. 2010-01-28 20:22:42 +00:00
José Fonseca
aa8b23e077 llvmpipe: Fix typo in lp_build_log constant. 2010-01-28 20:22:42 +00:00
José Fonseca
4eb48a3af7 llvmpipe: Fix bad SI -> FP conversion into lp_build_log2_approx.
It should be a bitcast  as the integer value is actually an encoded FP
already.
2010-01-28 20:22:42 +00:00
Jakob Bornecrantz
8db8adfd01 st/xorg: Update to new libkms interface but be backwards compatible 2010-01-28 18:02:10 +01:00
Keith Whitwell
8e240d7e0e svga: remove sleep in DEBUG_FLUSH path 2010-01-28 17:13:50 +00:00
José Fonseca
40298bf272 python/retrace: Dump all vertices for verbosity level 3. 2010-01-28 17:13:49 +00:00
Brian Paul
a0518e66b2 docs: Fixed Windows build for 7.7.1 2010-01-27 17:08:03 -07:00
Brian Paul
82c76cd16f windows: assorted build fixes
These changes were originally submitted by Karl Schultz for Mesa 7.7-rc2
but weren't applied.
2010-01-27 17:04:49 -07:00
Rodolfo Ribeiro Gomes
50e890bc51 glx: fix possible memory leaks in dri2CreateScreen()
Original patch fixed up by Brian Paul.
2010-01-27 17:04:49 -07:00
Alex Deucher
bba9557019 r600: fix warning 2010-01-27 12:20:04 -05:00
Alex Deucher
2041d3e4b7 r600: rv670 support 8 tex instructions just like other r6xx
also clarify some other const values.
2010-01-27 12:19:54 -05:00
Andre Maasikas
77b7b3a1ab r600: increase max texture units to 16 2010-01-27 11:38:29 -05:00
Andre Maasikas
0dab80fbfb r600: fix XPD with writemask
same variable used for 2 different temp registers
fixes e.g. glsl/bump
2010-01-27 11:38:16 -05:00
José Fonseca
e3257912e0 mesa: Warn when indices are out of bounds, but do not skip the draw in debug builds.
The driver (or preferably the hardware) should handle out of bounds
indices.

If there are problems then it's better to detect those in the debug
builds.
2010-01-27 16:25:31 +00:00
José Fonseca
15fe491822 svga: Prevent buffer overflow in buffer ranges.
Do this by extending the nearest range to cover the new range.

This fixes an access fault in Call of Duty which was doing many disjoint
glBufferSubData calls.
2010-01-27 15:41:25 +00:00
José Fonseca
ac597f5acc svga: Fix PIPE_LOGICOP_INVERT.
Actually the current XOR implementation is an INVERT.

This fixes rectangle selection in Maya.
2010-01-27 14:45:56 +00:00
Keith Whitwell
5cb255f0d7 svga: better path for generating white pixels for xor logicop workaround 2010-01-27 14:26:48 +00:00
Dave Airlie
2f28ca0a27 radeon/r200/r300: don't clean non-emitted state.
So if we don't actually emit an atom to the hw because we don't
need it in the current state (e.g. lighting related atoms when
lighting is off) then don't mark it as clean, because when
lighting gets switched on we won't emit it at all.

This fixes funky gears colors.

Signed-off-by: Dave Airlie <airlied@redhat.com>
2010-01-27 12:32:46 +10:00
Dave Airlie
0580e488da radeon: remove unused file 2010-01-27 12:32:44 +10:00
José Fonseca
5435f790fd python: Add missing library on debug builds. 2010-01-26 20:37:35 +00:00
167 changed files with 2844 additions and 1994 deletions

View File

@@ -182,7 +182,7 @@ ultrix-gcc:
# Rules for making release tarballs
VERSION=7.7.1-devel
VERSION=7.7.1
DIRECTORY = Mesa-$(VERSION)
LIB_NAME = MesaLib-$(VERSION)
DEMO_NAME = MesaDemos-$(VERSION)

View File

@@ -920,6 +920,11 @@ case $ARCH in
# make lib
${LINK} ${OPTS} ${LDFLAGS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS}
# make build fail if link failed
es=$?
if [ "$es" -ne "0" ]; then
exit $es
fi
# make usual symlinks
ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a
# finish up

View File

@@ -20,6 +20,8 @@ AC_CANONICAL_HOST
dnl Versions for external dependencies
LIBDRM_REQUIRED=2.4.15
LIBDRM_RADEON_REQUIRED=2.4.17
LIBDRM_XORG_REQUIRED=2.4.17
LIBKMS_XORG_REQUIRED=1.0.0
DRI2PROTO_REQUIRED=1.99.3
dnl Check for progs
@@ -91,6 +93,9 @@ linux*|*-gnu*|gnu*)
solaris*)
DEFINES="$DEFINES -DPTHREADS -DSVR4"
;;
cygwin*)
DEFINES="$DEFINES -DPTHREADS"
;;
esac
dnl Add flags for gcc and g++
@@ -1149,7 +1154,7 @@ yes)
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl"
fi
# Have only tested st/xorg on 1.6.0 servers
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0],
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0 libdrm >= $LIBDRM_XORG_REQUIRED libkms >= $LIBKMS_XORG_REQUIRED],
HAVE_XORG="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg",
HAVE_XORG="no")
;;
@@ -1166,15 +1171,21 @@ yes)
AC_MSG_ERROR([cannot build egl state tracker without EGL library])
fi
if test "$tracker" = xorg; then
PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
HAVE_XEXTPROTO_71="no")
PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
HAVE_XORG="yes"
fi
done
GALLIUM_STATE_TRACKERS_DIRS="$state_trackers"
;;
esac
if test "x$HAVE_XORG" = xyes; then
PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
HAVE_XEXTPROTO_71="no")
fi
AC_ARG_WITH([xorg-driver-dir],
[AS_HELP_STRING([--with-xorg-driver-dir=DIR],
[Default xorg driver directory[[default=${libdir}/xorg/modules/drivers]]])],

View File

@@ -10,6 +10,15 @@
<H1>News</H1>
<h2>March 26, 2010</h2>
<p>
<a href="relnotes-7.7.1.html">Mesa 7.7.1</a> is released. This is a bug-fix
release fixing issues found in the 7.7 release.
</p>
<h2>December 21, 2009</h2>
<p>
<a href="relnotes-7.6.1.html">Mesa 7.6.1</a> is released. This is a bug-fix

View File

@@ -26,7 +26,7 @@ more information about the API functions.
</p>
<p>
There are several examples of OSMesa in the <code>progs/osdemo/</code>
There are several examples of OSMesa in the <code>progs/osdemos/</code>
directory.
</p>

View File

@@ -8,7 +8,7 @@
<body bgcolor="#eeeeee">
<H1>Mesa 7.7.1 Release Notes / date tbd</H1>
<H1>Mesa 7.7.1 Release Notes / March 28, 2010</H1>
<p>
Mesa 7.7.1 is a bug-fix release.
@@ -26,16 +26,18 @@ for DRI hardware acceleration.
<h2>MD5 checksums</h2>
<pre>
tbd
3ab0638cfa7ce8157337a229cf0db2c4 MesaLib-7.7.1.tar.gz
46664d99e03f1e3ac078a7fea02af115 MesaLib-7.7.1.tar.bz2
4e73ba8abb59aff79485eb95d7cefff7 MesaLib-7.7.1.zip
bf1b108983995f7a712cf3343df1c918 MesaDemos-7.7.1.tar.gz
aeb39645d80d656e0adebaa09e5bcd03 MesaDemos-7.7.1.tar.bz2
01c49b7454fd292244eaf8bdc6ed8cf0 MesaDemos-7.7.1.zip
37ec6386693dcb6dc770d1efd63a7a93 MesaGLUT-7.7.1.tar.gz
1e16c85282f843791a21f7bc7b6a1ca8 MesaGLUT-7.7.1.tar.bz2
d352c9e36a8e4d1059f4abc017b131e0 MesaGLUT-7.7.1.zip
</pre>
<h2>New features</h2>
<ul>
<li>tbd
</ul>
<h2>Bug fixes</h2>
<ul>
<li>Assorted fixes to VMware SVGA gallium driver.
@@ -43,6 +45,14 @@ tbd
<li>Allocate constants more tightly in GL_ARB_vertex/fragment parser.
<li>Fixed mipmap generation bug caused by invalid viewport state.
<li>Gallium SSE codegen for XPD didn't always work.
<li>Fixed Windows build.
<li>Fixed broken glMultiDrawElements().
<li>Silence bogus GL errors generated in glxinfo.
<li>Fixed several render to texture bugs.
<li>Assorted bug fixes in Mesa/Gallium state tracker including
glCopy/DrawPixels() to FBOs.
<li>Assorted fixes to Gallium drivers.
<li>Fixed broken glPush/PopClientAttrib() for vertex arrays in GLX code.
</ul>

View File

@@ -1,6 +1,6 @@
<HTML>
<TITLE>Cocd Repository</TITLE>
<TITLE>Code Repository</TITLE>
<link rel="stylesheet" type="text/css" href="mesa.css"></head>

View File

@@ -171,7 +171,7 @@ print_program_limits(GLenum target)
GLenum token;
const char *name;
};
static const struct token_name limits[] = {
static const struct token_name common_limits[] = {
{ GL_MAX_PROGRAM_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" },
{ GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" },
{ GL_MAX_PROGRAM_TEMPORARIES_ARB, "GL_MAX_PROGRAM_TEMPORARIES_ARB" },
@@ -184,6 +184,9 @@ print_program_limits(GLenum target)
{ GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" },
{ GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" },
{ GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB" },
{ (GLenum) 0, NULL }
};
static const struct token_name fragment_limits[] = {
{ GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB" },
{ GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" },
{ GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB" },
@@ -192,8 +195,10 @@ print_program_limits(GLenum target)
{ GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" },
{ (GLenum) 0, NULL }
};
PFNGLGETPROGRAMIVARBPROC GetProgramivARB_func = (PFNGLGETPROGRAMIVARBPROC)
glXGetProcAddressARB((GLubyte *) "glGetProgramivARB");
GLint max[1];
int i;
@@ -207,10 +212,18 @@ print_program_limits(GLenum target)
return; /* something's wrong */
}
for (i = 0; limits[i].token; i++) {
GetProgramivARB_func(target, limits[i].token, max);
for (i = 0; common_limits[i].token; i++) {
GetProgramivARB_func(target, common_limits[i].token, max);
if (glGetError() == GL_NO_ERROR) {
printf(" %s = %d\n", limits[i].name, max[0]);
printf(" %s = %d\n", common_limits[i].name, max[0]);
}
}
if (target == GL_FRAGMENT_PROGRAM_ARB) {
for (i = 0; fragment_limits[i].token; i++) {
GetProgramivARB_func(target, fragment_limits[i].token, max);
if (glGetError() == GL_NO_ERROR) {
printf(" %s = %d\n", fragment_limits[i].name, max[0]);
}
}
}
#endif /* GL_ARB_vertex_program / GL_ARB_fragment_program */

View File

@@ -53,6 +53,7 @@ prefixes = SCons.Util.Split("""
i486-mingw32msvc-
i586-mingw32msvc-
i686-mingw32msvc-
i686-pc-mingw32-
""")
def find(env):

View File

@@ -235,7 +235,9 @@ def generate(env):
# different scons versions building the same source file
env['build'] = build_dir
env.SConsignFile(os.path.join(build_dir, '.sconsign'))
env.CacheDir('build/cache')
if 'SCONS_CACHE_DIR' in os.environ:
print 'scons: Using build cache in %s.' % (os.environ['SCONS_CACHE_DIR'],)
env.CacheDir(os.environ['SCONS_CACHE_DIR'])
# Parallel build
if env.GetOption('num_jobs') <= 1:
@@ -255,8 +257,9 @@ def generate(env):
'_WINDOWS',
#'_UNICODE',
#'UNICODE',
('_WIN32_WINNT', '0x0501'), # minimum required OS version
('WINVER', '0x0501'),
# http://msdn.microsoft.com/en-us/library/aa383745.aspx
('_WIN32_WINNT', '0x0601'),
('WINVER', '0x0601'),
# http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx,
'WIN32_LEAN_AND_MEAN',
]

View File

@@ -347,7 +347,8 @@ vcache_check_run( struct draw_pt_front_end *frontend,
draw_count);
if (max_index == 0xffffffff ||
fetch_count > draw_count) {
fetch_count > draw_count ||
max_index != (max_index & ~DRAW_PIPE_FLAG_MASK)) {
if (0) debug_printf("fail\n");
goto fail;
}

View File

@@ -179,7 +179,9 @@ pb_debug_buffer_check(struct pb_debug_buffer *buf)
{
uint8_t *map;
map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_READ);
map = pb_map(buf->buffer,
PIPE_BUFFER_USAGE_CPU_READ |
PIPE_BUFFER_USAGE_UNSYNCHRONIZED);
assert(map);
if(map) {
boolean underflow, overflow;

View File

@@ -133,8 +133,7 @@ static const union tgsi_exec_channel ZeroVec =
{ { 0.0, 0.0, 0.0, 0.0 } };
#ifdef DEBUG
static void
static INLINE void
check_inf_or_nan(const union tgsi_exec_channel *chan)
{
assert(!util_is_inf_or_nan(chan->f[0]));
@@ -142,7 +141,6 @@ check_inf_or_nan(const union tgsi_exec_channel *chan)
assert(!util_is_inf_or_nan(chan->f[2]));
assert(!util_is_inf_or_nan(chan->f[3]));
}
#endif
#ifdef DEBUG
@@ -338,7 +336,9 @@ tgsi_exec_machine_bind_shader(
/* XXX we only handle SOA dependencies properly for MOV/SWZ
* at this time!
*/
if (opcode != TGSI_OPCODE_MOV) {
if (opcode != TGSI_OPCODE_MOV &&
opcode != TGSI_OPCODE_MUL &&
opcode != TGSI_OPCODE_CMP) {
debug_printf("Warning: SOA dependency in instruction"
" is not handled:\n");
tgsi_dump_instruction(&parse.FullToken.FullInstruction,
@@ -1424,9 +1424,9 @@ store_dest(
int offset = 0; /* indirection offset */
int index;
#ifdef DEBUG
check_inf_or_nan(chan);
#endif
if (0) {
check_inf_or_nan(chan);
}
/* There is an extra source register that indirectly subscripts
* a register file. The direct index now becomes an offset
@@ -1854,7 +1854,8 @@ exec_instruction(
int *pc )
{
uint chan_index;
union tgsi_exec_channel r[10];
union tgsi_exec_channel r[3 * NUM_CHANNELS];
union tgsi_exec_channel d[8];
(*pc)++;
@@ -1981,14 +1982,27 @@ exec_instruction(
break;
case TGSI_OPCODE_MUL:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
{
FETCH(&r[0], 0, chan_index);
FETCH(&r[1], 1, chan_index);
if (inst->Flags & SOA_DEPENDENCY_FLAG) {
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
{
FETCH(&r[chan_index], 0, chan_index);
FETCH(&r[chan_index + NUM_CHANNELS], 1, chan_index);
}
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
{
micro_mul( &r[chan_index], &r[chan_index], &r[chan_index + NUM_CHANNELS] );
STORE(&r[chan_index], 0, chan_index);
}
} else {
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
{
FETCH(&r[0], 0, chan_index);
FETCH(&r[1], 1, chan_index);
micro_mul( &r[0], &r[0], &r[1] );
micro_mul( &r[0], &r[0], &r[1] );
STORE(&r[0], 0, chan_index);
STORE(&r[0], 0, chan_index);
}
}
break;
@@ -2255,11 +2269,7 @@ exec_instruction(
FETCH(&r[4], 1, CHAN_Y);
micro_mul( &r[5], &r[3], &r[4] );
micro_sub( &r[2], &r[2], &r[5] );
if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
STORE( &r[2], 0, CHAN_X );
}
micro_sub(&d[CHAN_X], &r[2], &r[5]);
FETCH(&r[2], 1, CHAN_X);
@@ -2268,26 +2278,27 @@ exec_instruction(
FETCH(&r[5], 0, CHAN_X);
micro_mul( &r[1], &r[1], &r[5] );
micro_sub( &r[3], &r[3], &r[1] );
if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
STORE( &r[3], 0, CHAN_Y );
}
micro_sub(&d[CHAN_Y], &r[3], &r[1]);
micro_mul( &r[5], &r[5], &r[4] );
micro_mul( &r[0], &r[0], &r[2] );
micro_sub( &r[5], &r[5], &r[0] );
micro_sub(&d[CHAN_Z], &r[5], &r[0]);
if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
STORE( &r[5], 0, CHAN_Z );
if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) {
STORE(&d[CHAN_X], 0, CHAN_X);
}
if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) {
STORE(&d[CHAN_Y], 0, CHAN_Y);
}
if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) {
STORE(&d[CHAN_Z], 0, CHAN_Z);
}
if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
}
break;
case TGSI_OPCODE_ABS:
case TGSI_OPCODE_ABS:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
@@ -2667,14 +2678,28 @@ exec_instruction(
break;
case TGSI_OPCODE_CMP:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
FETCH(&r[1], 1, chan_index);
FETCH(&r[2], 2, chan_index);
if (inst->Flags & SOA_DEPENDENCY_FLAG) {
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[chan_index], 0, chan_index);
FETCH(&r[chan_index + NUM_CHANNELS], 1, chan_index);
FETCH(&r[chan_index + 2 * NUM_CHANNELS], 2, chan_index);
}
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
micro_lt( &r[chan_index], &r[chan_index],
&mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[chan_index + NUM_CHANNELS],
&r[chan_index + 2*NUM_CHANNELS] );
STORE(&r[chan_index], 0, chan_index);
}
} else {
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
FETCH(&r[1], 1, chan_index);
FETCH(&r[2], 2, chan_index);
micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] );
micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] );
STORE(&r[0], 0, chan_index);
STORE(&r[0], 0, chan_index);
}
}
break;

View File

@@ -216,6 +216,9 @@ iter_instruction(
inst->FullDstRegisters[i].DstRegister.Index,
"destination",
FALSE );
if (!inst->FullDstRegisters[i].DstRegister.WriteMask) {
report_error(ctx, "Destination register has empty writemask");
}
}
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
check_register_usage(

View File

@@ -644,6 +644,57 @@ void debug_dump_image(const char *prefix,
}
EngUnmapFile(iFile);
#elif defined(PIPE_OS_UNIX)
/* write a ppm file */
char filename[256];
FILE *f;
util_snprintf(filename, sizeof(filename), "%s.ppm", prefix);
f = fopen(filename, "w");
if (f) {
int i, x, y;
int r, g, b;
const uint8_t *ptr = (uint8_t *) data;
/* XXX this is a hack */
switch (format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
r = 2;
g = 1;
b = 0;
break;
case PIPE_FORMAT_A8R8G8B8_UNORM:
b = 0;
g = 1;
r = 2;
break;
default:
r = 0;
g = 1;
b = 2;
}
fprintf(f, "P6\n");
fprintf(f, "# ppm-file created by osdemo.c\n");
fprintf(f, "%i %i\n", width, height);
fprintf(f, "255\n");
fclose(f);
f = fopen(filename, "ab"); /* reopen in binary append mode */
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
i = y * stride + x * cpp;
fputc(ptr[i + r], f); /* write red */
fputc(ptr[i + g], f); /* write green */
fputc(ptr[i + b], f); /* write blue */
}
}
fclose(f);
}
else {
fprintf(stderr, "Can't open %s for writing\n", filename);
}
#endif
}

View File

@@ -628,7 +628,8 @@ lp_build_abs(struct lp_build_context *bld,
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);
unsigned long absMask = ~(1 << (type.width - 1));
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
a = LLVMBuildAnd(bld->builder, a, mask, "");
a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
@@ -1082,7 +1083,7 @@ lp_build_log(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log(2) */
LLVMValueRef log2 = lp_build_const_scalar(bld->type, 1.4426950408889634);
LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
}
@@ -1094,7 +1095,7 @@ lp_build_log(struct lp_build_context *bld,
/**
* Generate polynomial.
* Ex: x^2 * coeffs[0] + x * coeffs[1] + coeffs[2].
* Ex: coeffs[0] + x * coeffs[1] + x^2 * coeffs[2].
*/
static LLVMValueRef
lp_build_polynomial(struct lp_build_context *bld,
@@ -1284,13 +1285,13 @@ lp_build_log2_approx(struct lp_build_context *bld,
/* mant = (float) mantissa(x) */
mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
mant = LLVMBuildOr(bld->builder, mant, one, "");
mant = LLVMBuildSIToFP(bld->builder, mant, vec_type, "");
mant = LLVMBuildBitCast(bld->builder, mant, vec_type, "");
logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
Elements(lp_build_log2_polynomial));
/* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildMul(bld->builder, mant, bld->one, ""), "");
logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
}

View File

@@ -766,7 +766,7 @@ emit_instruction(
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
src0 = emit_fetch( bld, inst, 0, chan_index );
tmp0 = lp_build_floor(&bld->base, src0);
tmp0 = lp_build_sub(&bld->base, tmp0, src0);
tmp0 = lp_build_sub(&bld->base, src0, tmp0);
dst0[chan_index] = tmp0;
}
break;

View File

@@ -0,0 +1,71 @@
/**************************************************************************
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* 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 TUNGSTEN GRAPHICS 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.
*
**************************************************************************/
#ifndef LP_DEBUG_H
#define LP_DEBUG_H
#include "pipe/p_compiler.h"
#include "util/u_debug.h"
extern void
st_print_current(void);
#define DEBUG_PIPE 0x1
#define DEBUG_TGSI 0x2
#define DEBUG_TEX 0x4
#define DEBUG_ASM 0x8
#define DEBUG_SETUP 0x10
#define DEBUG_RAST 0x20
#define DEBUG_QUERY 0x40
#define DEBUG_SCREEN 0x80
#define DEBUG_JIT 0x100
#ifdef DEBUG
extern int LP_DEBUG;
#else
#define LP_DEBUG 0
#endif
void st_debug_init( void );
static INLINE void
LP_DBG( unsigned flag, const char *fmt, ... )
{
if (LP_DEBUG & flag)
{
va_list args;
va_start( args, fmt );
debug_vprintf( fmt, args );
va_end( args );
}
}
#endif /* LP_DEBUG_H */

View File

@@ -101,7 +101,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
draw_arrays(draw, mode, start, count);
/*
* unmap vertex/index buffers - will cause draw module to flush
* unmap vertex/index buffers
*/
for (i = 0; i < lp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
@@ -110,6 +110,12 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
draw_set_mapped_element_buffer(draw, 0, NULL);
}
/*
* TODO: Flush only when a user vertex/index buffer is present
* (or even better, modify draw module to do this
* internally when this condition is seen?)
*/
draw_flush(draw);
/* Note: leave drawing surfaces mapped */

View File

@@ -166,7 +166,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen)
if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) {
_debug_printf("%s\n", error);
LLVMDisposeMessage(error);
abort();
assert(0);
}
screen->target = LLVMGetExecutionEngineTargetData(screen->engine);

View File

@@ -27,6 +27,7 @@
#include "util/u_memory.h"
#include "util/u_format.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
@@ -35,6 +36,24 @@
#include "lp_winsys.h"
#include "lp_jit.h"
#include "lp_screen.h"
#include "lp_debug.h"
#ifdef DEBUG
int LP_DEBUG = 0;
static const struct debug_named_value lp_debug_flags[] = {
{ "pipe", DEBUG_PIPE },
{ "tgsi", DEBUG_TGSI },
{ "tex", DEBUG_TEX },
{ "asm", DEBUG_ASM },
{ "setup", DEBUG_SETUP },
{ "rast", DEBUG_RAST },
{ "query", DEBUG_QUERY },
{ "screen", DEBUG_SCREEN },
{ "jit", DEBUG_JIT },
{NULL, 0}
};
#endif
static const char *
@@ -131,17 +150,17 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
struct llvmpipe_winsys *winsys = screen->winsys;
const struct util_format_description *format_desc;
format_desc = util_format_description(format);
if(!format_desc)
return FALSE;
assert(target == PIPE_TEXTURE_1D ||
target == PIPE_TEXTURE_2D ||
target == PIPE_TEXTURE_3D ||
target == PIPE_TEXTURE_CUBE);
if(format == PIPE_FORMAT_Z16_UNORM)
return FALSE;
if(format == PIPE_FORMAT_S8_UNORM)
return FALSE;
switch(format) {
case PIPE_FORMAT_DXT1_RGB:
case PIPE_FORMAT_DXT1_RGBA:
@@ -152,8 +171,51 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
break;
}
if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
return winsys->is_displaytarget_format_supported(winsys, format);
if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
if(format_desc->block.width != 1 ||
format_desc->block.height != 1)
return FALSE;
if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
return FALSE;
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB)
return FALSE;
}
if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
if(!winsys->is_displaytarget_format_supported(winsys, format))
return FALSE;
}
if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return FALSE;
/* FIXME: Temporary restriction. See lp_state_fs.c. */
if(format_desc->block.bits != 32)
return FALSE;
}
/* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */
if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) {
if(format_desc->block.width != 1 ||
format_desc->block.height != 1)
return FALSE;
if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
return FALSE;
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return FALSE;
}
return TRUE;
}
@@ -213,6 +275,10 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
{
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
#ifdef DEBUG
LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
#endif
if (!screen)
return NULL;

View File

@@ -34,6 +34,7 @@
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_debug_dump.h"
#include "draw/draw_context.h"
#include "lp_screen.h"
#include "lp_context.h"
#include "lp_state.h"
@@ -51,6 +52,11 @@ void llvmpipe_bind_blend_state( struct pipe_context *pipe,
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
if (llvmpipe->blend == blend)
return;
draw_flush(llvmpipe->draw);
llvmpipe->blend = blend;
llvmpipe->dirty |= LP_NEW_BLEND;
@@ -69,6 +75,11 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe,
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
unsigned i, j;
if(memcmp(&llvmpipe->blend_color, blend_color, sizeof *blend_color) == 0)
return;
draw_flush(llvmpipe->draw);
memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color);
if(!llvmpipe->jit_context.blend_color)
@@ -99,7 +110,12 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
if (llvmpipe->depth_stencil == depth_stencil)
return;
draw_flush(llvmpipe->draw);
llvmpipe->depth_stencil = depth_stencil;
if(llvmpipe->depth_stencil)
llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value;

View File

@@ -85,6 +85,7 @@
#include "lp_buffer.h"
#include "lp_state.h"
#include "lp_tex_sample.h"
#include "lp_debug.h"
static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
@@ -146,6 +147,20 @@ generate_depth(LLVMBuilderRef builder,
format_desc = util_format_description(key->zsbuf_format);
assert(format_desc);
/*
* Depths are expected to be between 0 and 1, even if they are stored in
* floats. Setting these bits here will ensure that the lp_build_conv() call
* below won't try to unnecessarily clamp the incoming values.
*/
if(src_type.floating) {
src_type.sign = FALSE;
src_type.norm = TRUE;
}
else {
assert(!src_type.sign);
assert(src_type.norm);
}
/* Pick the depth type. */
dst_type = lp_depth_type(format_desc, src_type.width*src_type.length);
@@ -153,14 +168,11 @@ generate_depth(LLVMBuilderRef builder,
assert(dst_type.width == src_type.width);
assert(dst_type.length == src_type.length);
#if 1
src = lp_build_clamped_float_to_unsigned_norm(builder,
src_type,
dst_type.width,
src);
#else
lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1);
#endif
dst_ptr = LLVMBuildBitCast(builder,
dst_ptr,
LLVMPointerType(lp_build_vec_type(dst_type), 0), "");
lp_build_depth_test(builder,
&key->depth,
@@ -395,59 +407,58 @@ generate_fragment(struct llvmpipe_context *lp,
unsigned i;
unsigned chan;
#ifdef DEBUG
tgsi_dump(shader->base.tokens, 0);
if(key->depth.enabled) {
debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
debug_printf("depth.writemask = %u\n", key->depth.writemask);
}
if(key->alpha.enabled) {
debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
}
if(key->blend.logicop_enable) {
debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
}
else if(key->blend.blend_enable) {
debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
}
debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
if(key->sampler[i].format) {
debug_printf("sampler[%u] = \n", i);
debug_printf(" .format = %s\n",
pf_name(key->sampler[i].format));
debug_printf(" .target = %s\n",
debug_dump_tex_target(key->sampler[i].target, TRUE));
debug_printf(" .pot = %u %u %u\n",
key->sampler[i].pot_width,
key->sampler[i].pot_height,
key->sampler[i].pot_depth);
debug_printf(" .wrap = %s %s %s\n",
debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
debug_printf(" .min_img_filter = %s\n",
debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
debug_printf(" .min_mip_filter = %s\n",
debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
debug_printf(" .mag_img_filter = %s\n",
debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
if(key->sampler[i].compare_mode)
debug_printf(" .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords);
debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter);
if (LP_DEBUG & DEBUG_JIT) {
tgsi_dump(shader->base.tokens, 0);
if(key->depth.enabled) {
debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
debug_printf("depth.writemask = %u\n", key->depth.writemask);
}
if(key->alpha.enabled) {
debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
}
if(key->blend.logicop_enable) {
debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
}
else if(key->blend.blend_enable) {
debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
}
debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
if(key->sampler[i].format) {
debug_printf("sampler[%u] = \n", i);
debug_printf(" .format = %s\n",
pf_name(key->sampler[i].format));
debug_printf(" .target = %s\n",
debug_dump_tex_target(key->sampler[i].target, TRUE));
debug_printf(" .pot = %u %u %u\n",
key->sampler[i].pot_width,
key->sampler[i].pot_height,
key->sampler[i].pot_depth);
debug_printf(" .wrap = %s %s %s\n",
debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
debug_printf(" .min_img_filter = %s\n",
debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
debug_printf(" .min_mip_filter = %s\n",
debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
debug_printf(" .mag_img_filter = %s\n",
debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
if(key->sampler[i].compare_mode)
debug_printf(" .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords);
debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter);
}
}
}
#endif
variant = CALLOC_STRUCT(lp_fragment_shader_variant);
if(!variant)
return NULL;
@@ -586,8 +597,8 @@ generate_fragment(struct llvmpipe_context *lp,
}
lp_build_conv_mask(builder, fs_type, blend_type,
fs_mask, num_fs,
&blend_mask, 1);
fs_mask, num_fs,
&blend_mask, 1);
/*
* Blending.
@@ -609,23 +620,24 @@ generate_fragment(struct llvmpipe_context *lp,
* Translate the LLVM IR into machine code.
*/
#ifdef DEBUG
if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) {
LLVMDumpValue(variant->function);
abort();
assert(0);
}
#endif
LLVMRunFunctionPassManager(screen->pass, variant->function);
#ifdef DEBUG
LLVMDumpValue(variant->function);
debug_printf("\n");
#endif
if (LP_DEBUG & DEBUG_JIT) {
LLVMDumpValue(variant->function);
debug_printf("\n");
}
variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function);
#ifdef DEBUG
lp_disassemble(variant->jit_function);
#endif
if (LP_DEBUG & DEBUG_ASM)
lp_disassemble(variant->jit_function);
variant->next = shader->variants;
shader->variants = variant;
@@ -659,7 +671,12 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
llvmpipe->fs = (struct lp_fragment_shader *) fs;
if (llvmpipe->fs == fs)
return;
draw_flush(llvmpipe->draw);
llvmpipe->fs = fs;
llvmpipe->dirty |= LP_NEW_FS;
}
@@ -710,8 +727,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
if(shader == PIPE_SHADER_VERTEX)
draw_flush(llvmpipe->draw);
draw_flush(llvmpipe->draw);
/* note: reference counting */
pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer);

View File

@@ -41,14 +41,17 @@ llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
}
void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
void *setup)
void *rasterizer)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
/* pass-through to draw module */
draw_set_rasterizer_state(llvmpipe->draw, setup);
if (llvmpipe->rasterizer == rasterizer)
return;
llvmpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
/* pass-through to draw module */
draw_set_rasterizer_state(llvmpipe->draw, rasterizer);
llvmpipe->rasterizer = rasterizer;
llvmpipe->dirty |= LP_NEW_RASTERIZER;
}

View File

@@ -48,6 +48,8 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe,
struct llvmpipe_context *lp = llvmpipe_context(pipe);
uint i;
draw_flush(lp->draw);
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
/* check if changing cbuf */
if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) {

View File

@@ -70,14 +70,18 @@ fail:
void
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *_vs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
const struct lp_vertex_shader *vs = (const struct lp_vertex_shader *)_vs;
llvmpipe->vs = (const struct lp_vertex_shader *)vs;
if (llvmpipe->vs == vs)
return;
draw_bind_vertex_shader(llvmpipe->draw,
(llvmpipe->vs ? llvmpipe->vs->draw_data : NULL));
draw_bind_vertex_shader(llvmpipe->draw,
vs ? vs->draw_data : NULL);
llvmpipe->vs = vs;
llvmpipe->dirty |= LP_NEW_VS;
}
@@ -92,5 +96,6 @@ llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
(struct lp_vertex_shader *)vs;
draw_delete_vertex_shader(llvmpipe->draw, state->draw_data);
FREE( (void *)state->shader.tokens );
FREE( state );
}

View File

@@ -714,9 +714,14 @@ depth_test_quads_fallback(struct quad_stage *qs,
qs->next->run(qs->next, quads, nr);
}
/* XXX: this function assumes setup function actually emits linear
* spans of quads. It seems a lot more natural to do (early)
* depth-testing on spans rather than quads.
/**
* Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LESS and
* Z buffer writes enabled.
*
* NOTE: there's no guarantee that the quads are sequentially side by
* side. The fragment shader may have culled some quads, etc. Sliver
* triangles may generate non-sequential quads.
*/
static void
depth_interp_z16_less_write(struct quad_stage *qs,
@@ -733,25 +738,33 @@ depth_interp_z16_less_write(struct quad_stage *qs,
const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
struct softpipe_cached_tile *tile;
ushort (*depth16)[TILE_SIZE];
ushort idepth[4], depth_step;
ushort init_idepth[4], idepth[4], depth_step;
const float scale = 65535.0;
idepth[0] = (ushort)((z0) * scale);
idepth[1] = (ushort)((z0 + dzdx) * scale);
idepth[2] = (ushort)((z0 + dzdy) * scale);
idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
/* compute scaled depth of the four pixels in first quad */
init_idepth[0] = (ushort)((z0) * scale);
init_idepth[1] = (ushort)((z0 + dzdx) * scale);
init_idepth[2] = (ushort)((z0 + dzdy) * scale);
init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
depth_step = (ushort)(dzdx * 2 * scale);
depth_step = (ushort)(dzdx * scale);
tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
depth16 = (ushort (*)[TILE_SIZE])
&tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE];
for (i = 0; i < nr; i++) {
unsigned outmask = quads[i]->inout.mask;
const unsigned outmask = quads[i]->inout.mask;
const int dx = quads[i]->input.x0 - ix;
unsigned mask = 0;
/* compute depth for this quad */
idepth[0] = init_idepth[0] + dx * depth_step;
idepth[1] = init_idepth[1] + dx * depth_step;
idepth[2] = init_idepth[2] + dx * depth_step;
idepth[3] = init_idepth[3] + dx * depth_step;
depth16 = (ushort (*)[TILE_SIZE])
&tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
if ((outmask & 1) && idepth[0] < depth16[0][0]) {
depth16[0][0] = idepth[0];
mask |= (1 << 0);
@@ -772,13 +785,6 @@ depth_interp_z16_less_write(struct quad_stage *qs,
mask |= (1 << 3);
}
idepth[0] += depth_step;
idepth[1] += depth_step;
idepth[2] += depth_step;
idepth[3] += depth_step;
depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
quads[i]->inout.mask = mask;
if (quads[i]->inout.mask)
quads[pass++] = quads[i];
@@ -790,6 +796,14 @@ depth_interp_z16_less_write(struct quad_stage *qs,
}
/**
* Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LEQUAL and
* Z buffer writes enabled.
*
* NOTE: there's no guarantee that the quads are sequentially side by
* side. The fragment shader may have culled some quads, etc. Sliver
* triangles may generate non-sequential quads.
*/
static void
depth_interp_z16_lequal_write(struct quad_stage *qs,
struct quad_header *quads[],
@@ -805,25 +819,33 @@ depth_interp_z16_lequal_write(struct quad_stage *qs,
const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
struct softpipe_cached_tile *tile;
ushort (*depth16)[TILE_SIZE];
ushort idepth[4], depth_step;
ushort init_idepth[4], idepth[4], depth_step;
const float scale = 65535.0;
idepth[0] = (ushort)((z0) * scale);
idepth[1] = (ushort)((z0 + dzdx) * scale);
idepth[2] = (ushort)((z0 + dzdy) * scale);
idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
/* compute scaled depth of the four pixels in first quad */
init_idepth[0] = (ushort)((z0) * scale);
init_idepth[1] = (ushort)((z0 + dzdx) * scale);
init_idepth[2] = (ushort)((z0 + dzdy) * scale);
init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
depth_step = (ushort)(dzdx * 2 * scale);
depth_step = (ushort)(dzdx * scale);
tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
depth16 = (ushort (*)[TILE_SIZE])
&tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE];
for (i = 0; i < nr; i++) {
unsigned outmask = quads[i]->inout.mask;
const unsigned outmask = quads[i]->inout.mask;
const int dx = quads[i]->input.x0 - ix;
unsigned mask = 0;
/* compute depth for this quad */
idepth[0] = init_idepth[0] + dx * depth_step;
idepth[1] = init_idepth[1] + dx * depth_step;
idepth[2] = init_idepth[2] + dx * depth_step;
idepth[3] = init_idepth[3] + dx * depth_step;
depth16 = (ushort (*)[TILE_SIZE])
&tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
if ((outmask & 1) && idepth[0] <= depth16[0][0]) {
depth16[0][0] = idepth[0];
mask |= (1 << 0);
@@ -844,11 +866,6 @@ depth_interp_z16_lequal_write(struct quad_stage *qs,
mask |= (1 << 3);
}
idepth[0] += depth_step;
idepth[1] += depth_step;
idepth[2] += depth_step;
idepth[3] += depth_step;
depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
quads[i]->inout.mask = mask;

View File

@@ -805,7 +805,6 @@ line_persp_coeff(const struct setup_context *setup,
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
{
/* XXX double-check/verify this arithmetic */
const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3];
const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3];
const float da = a1 - a0;
@@ -813,7 +812,7 @@ line_persp_coeff(const struct setup_context *setup,
const float dady = da * setup->emaj.dy * setup->oneoverarea;
coef->dadx[i] = dadx;
coef->dady[i] = dady;
coef->a0[i] = (setup->vmin[vertSlot][i] -
coef->a0[i] = (a0 -
(dadx * (setup->vmin[0][0] - setup->pixel_offset) +
dady * (setup->vmin[0][1] - setup->pixel_offset)));
}

View File

@@ -29,6 +29,7 @@
*/
#include "util/u_memory.h"
#include "draw/draw_context.h"
#include "sp_context.h"
#include "sp_state.h"
@@ -45,6 +46,8 @@ void softpipe_bind_blend_state( struct pipe_context *pipe,
{
struct softpipe_context *softpipe = softpipe_context(pipe);
draw_flush(softpipe->draw);
softpipe->blend = (struct pipe_blend_state *)blend;
softpipe->dirty |= SP_NEW_BLEND;
@@ -62,6 +65,8 @@ void softpipe_set_blend_color( struct pipe_context *pipe,
{
struct softpipe_context *softpipe = softpipe_context(pipe);
draw_flush(softpipe->draw);
softpipe->blend_color = *blend_color;
softpipe->dirty |= SP_NEW_BLEND;

View File

@@ -69,7 +69,14 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
softpipe->fs = (struct sp_fragment_shader *) fs;
draw_flush(softpipe->draw);
if (softpipe->fs == fs)
return;
draw_flush(softpipe->draw);
softpipe->fs = fs;
softpipe->dirty |= SP_NEW_FS;
}
@@ -159,6 +166,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
draw_flush(softpipe->draw);
/* note: reference counting */
pipe_buffer_reference(&softpipe->constants[shader].buffer,
buf ? buf->buffer : NULL);

View File

@@ -41,14 +41,17 @@ softpipe_create_rasterizer_state(struct pipe_context *pipe,
}
void softpipe_bind_rasterizer_state(struct pipe_context *pipe,
void *setup)
void *rasterizer)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
/* pass-through to draw module */
draw_set_rasterizer_state(softpipe->draw, setup);
if (softpipe->rasterizer == rasterizer)
return;
softpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
/* pass-through to draw module */
draw_set_rasterizer_state(softpipe->draw, rasterizer);
softpipe->rasterizer = rasterizer;
softpipe->dirty |= SP_NEW_RASTERIZER;
}

View File

@@ -48,6 +48,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
struct softpipe_context *sp = softpipe_context(pipe);
uint i;
draw_flush(sp->draw);
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
/* check if changing cbuf */
if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {

View File

@@ -1306,6 +1306,11 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
}
/**
* Compute nearest mipmap level from texcoords.
* Then sample the texture level for four elements of a quad.
* \param c0 the LOD bias factors, or absolute LODs (depending on control)
*/
static void
mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
@@ -1500,8 +1505,8 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
/**
* Compute which cube face is referenced by each texcoord and put that
* info into the sampler faces[] array. Then sample the cube faces
* Use 3D texcoords to choose a cube face, then sample the 2D cube faces.
* Put face info into the sampler faces[] array.
*/
static void
sample_cube(struct tgsi_sampler *tgsi_sampler,
@@ -1514,11 +1519,12 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned j;
float ssss[4], tttt[4];
unsigned face;
/*
major axis
direction target sc tc ma
---------- ------------------------------- --- --- ---
direction target sc tc ma
---------- ------------------------------- --- --- ---
+rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
-rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
+ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
@@ -1526,56 +1532,93 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
+rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
-rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
*/
for (j = 0; j < QUAD_SIZE; j++) {
float rx = s[j];
float ry = t[j];
float rz = p[j];
/* First choose the cube face.
* Use the same cube face for all four pixels in the quad.
*
* This isn't ideal, but if we want to use a different cube face
* per pixel in the quad, we'd have to also compute the per-face
* LOD here too. That's because the four post-face-selection
* texcoords are no longer related to each other (they're
* per-face!) so we can't use subtraction to compute the partial
* deriviates to compute the LOD. Doing so (near cube edges
* anyway) gives us pretty much random values.
*/
{
/* use the average of the four pixel's texcoords to choose the face */
const float rx = 0.25 * (s[0] + s[1] + s[2] + s[3]);
const float ry = 0.25 * (t[0] + t[1] + t[2] + t[3]);
const float rz = 0.25 * (p[0] + p[1] + p[2] + p[3]);
const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
unsigned face;
float sc, tc, ma;
if (arx >= ary && arx >= arz) {
if (rx >= 0.0F) {
face = PIPE_TEX_FACE_POS_X;
sc = -rz;
tc = -ry;
ma = arx;
}
else {
face = PIPE_TEX_FACE_NEG_X;
sc = rz;
tc = -ry;
ma = arx;
}
}
else if (ary >= arx && ary >= arz) {
if (ry >= 0.0F) {
face = PIPE_TEX_FACE_POS_Y;
sc = rx;
tc = rz;
ma = ary;
}
else {
face = PIPE_TEX_FACE_NEG_Y;
sc = rx;
tc = -rz;
ma = ary;
}
}
else {
if (rz > 0.0F) {
face = PIPE_TEX_FACE_POS_Z;
sc = rx;
tc = -ry;
ma = arz;
}
else {
face = PIPE_TEX_FACE_NEG_Z;
sc = -rx;
tc = -ry;
ma = arz;
}
}
}
/* Now compute the 2D _face_ texture coords from the
* 3D _cube_ texture coords.
*/
for (j = 0; j < QUAD_SIZE; j++) {
const float rx = s[j], ry = t[j], rz = p[j];
const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
float sc, tc, ma;
switch (face) {
case PIPE_TEX_FACE_POS_X:
sc = -rz;
tc = -ry;
ma = arx;
break;
case PIPE_TEX_FACE_NEG_X:
sc = rz;
tc = -ry;
ma = arx;
break;
case PIPE_TEX_FACE_POS_Y:
sc = rx;
tc = rz;
ma = ary;
break;
case PIPE_TEX_FACE_NEG_Y:
sc = rx;
tc = -rz;
ma = ary;
break;
case PIPE_TEX_FACE_POS_Z:
sc = rx;
tc = -ry;
ma = arz;
break;
case PIPE_TEX_FACE_NEG_Z:
sc = -rx;
tc = -ry;
ma = arz;
break;
default:
assert(0 && "bad cube face");
}
{
const float ima = 1.0 / ma;

View File

@@ -297,13 +297,14 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
x, y, TILE_SIZE, TILE_SIZE,
tc->tile.data.color32, 0/*STRIDE*/);
/* do this? */
clear_clear_flag(tc->clear_flags, addr);
numCleared++;
}
}
}
/* reset all clear flags to zero */
memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
#if 0
debug_printf("num cleared: %u\n", numCleared);
#endif

View File

@@ -478,7 +478,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
struct svga_winsys_surface *host,
SVGA3dTransferType transfer, // IN
uint32 size, // IN
uint32 offset, // IN
uint32 guest_offset, // IN
uint32 host_offset, // IN
SVGA3dSurfaceDMAFlags flags) // IN
{
SVGA3dCmdSurfaceDMA *cmd;
@@ -517,19 +518,19 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
cmd->transfer = transfer;
box = (SVGA3dCopyBox *)&cmd[1];
box->x = offset;
box->x = host_offset;
box->y = 0;
box->z = 0;
box->w = size;
box->h = 1;
box->d = 1;
box->srcx = offset;
box->srcx = guest_offset;
box->srcy = 0;
box->srcz = 0;
pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
pSuffix->suffixSize = sizeof *pSuffix;
pSuffix->maximumOffset = offset + size;
pSuffix->maximumOffset = guest_offset + size;
pSuffix->flags = flags;
swc->commit(swc);

View File

@@ -111,7 +111,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
struct svga_winsys_surface *host,
SVGA3dTransferType transfer,
uint32 size,
uint32 offset,
uint32 guest_offset,
uint32 host_offset,
SVGA3dSurfaceDMAFlags flags);
/*

View File

@@ -215,7 +215,6 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen )
svga->state.hw_draw.num_views = 0;
svga->dirty = ~0;
svga->state.white_fs_id = SVGA3D_INVALID_ID;
LIST_INITHEAD(&svga->dirty_buffers);
@@ -285,3 +284,8 @@ void svga_hwtnl_flush_retry( struct svga_context *svga )
assert(ret == 0);
}
struct svga_winsys_context *
svga_winsys_context( struct pipe_context *pipe )
{
return svga_context( pipe )->swc;
}

View File

@@ -139,6 +139,7 @@ struct svga_rasterizer_state {
unsigned multisampleantialias:1;
unsigned antialiasedlineenable:1;
unsigned lastpixel:1;
unsigned pointspriteenable:1;
unsigned linepattern;
@@ -329,10 +330,6 @@ struct svga_context
unsigned texture_timestamp;
/* Internally generated shaders:
*/
unsigned white_fs_id;
/*
*/
struct svga_sw_state sw;

View File

@@ -253,7 +253,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
assert(index_bias >= 0);
assert(min_index <= max_index);
assert(offset + index_bias*stride < size);
assert(offset + (index_bias + min_index)*stride < size);
if (min_index != ~0) {
assert(offset + (index_bias + min_index) * stride < size);
}
switch (hwtnl->cmd.vdecl[i].identity.type) {
case SVGA3D_DECLTYPE_FLOAT1:
@@ -314,7 +316,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
}
assert(!stride || width <= stride);
assert(offset + (index_bias + max_index)*stride + width <= size);
if (max_index != ~0) {
assert(offset + (index_bias + max_index) * stride + width <= size);
}
}
assert(range->indexWidth == range->indexArray.stride);

View File

@@ -92,6 +92,7 @@ svga_create_blend_state(struct pipe_context *pipe,
if (templ->logicop_enable) {
switch (templ->logicop_func) {
case PIPE_LOGICOP_XOR:
case PIPE_LOGICOP_INVERT:
blend->need_white_fragments = TRUE;
blend->rt[i].blend_enable = TRUE;
blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
@@ -125,12 +126,6 @@ svga_create_blend_state(struct pipe_context *pipe,
blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE;
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
break;
case PIPE_LOGICOP_INVERT:
blend->rt[i].blend_enable = TRUE;
blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
break;
case PIPE_LOGICOP_AND:
/* Approximate with minimum - works for the 0 & anything case: */
blend->rt[i].blend_enable = TRUE;
@@ -228,7 +223,7 @@ static void svga_set_blend_color( struct pipe_context *pipe,
svga->curr.blend_color = *blend_color;
svga->dirty |= SVGA_NEW_BLEND;
svga->dirty |= SVGA_NEW_BLEND_COLOR;
}

View File

@@ -218,9 +218,6 @@ svga_draw_range_elements( struct pipe_context *pipe,
if (SVGA_DEBUG & DEBUG_FLUSH) {
static unsigned id;
debug_printf("%s %d\n", __FUNCTION__, id++);
if (id > 1300)
util_time_sleep( 2000 );
svga_hwtnl_flush_retry( svga );
svga_context_flush(svga, NULL);
}

View File

@@ -70,7 +70,6 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
/* light_twoside - XXX: need fragment shader varient */
/* poly_smooth - XXX: no fallback available */
/* poly_stipple_enable - draw module */
/* point_sprite - ? */
/* point_size_per_vertex - ? */
/* sprite_coord_mode - ??? */
/* bypass_vs_viewport_and_clip - handled by viewport setup */
@@ -86,6 +85,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
rast->multisampleantialias = templ->multisample;
rast->antialiasedlineenable = templ->line_smooth;
rast->lastpixel = templ->line_last_pixel;
rast->pointspriteenable = templ->point_sprite;
rast->pointsize = templ->point_size;
rast->pointsize_min = templ->point_size_min;
rast->pointsize_max = templ->point_size_max;

View File

@@ -27,7 +27,6 @@
#include "pipe/p_defines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_pack_color.h"
#include "tgsi/tgsi_parse.h"
#include "svga_context.h"
@@ -112,14 +111,12 @@ svga_create_sampler_state(struct pipe_context *pipe,
cso->compare_func = sampler->compare_func;
{
ubyte r = float_to_ubyte(sampler->border_color[0]);
ubyte g = float_to_ubyte(sampler->border_color[1]);
ubyte b = float_to_ubyte(sampler->border_color[2]);
ubyte a = float_to_ubyte(sampler->border_color[3]);
uint32 r = float_to_ubyte(sampler->border_color[0]);
uint32 g = float_to_ubyte(sampler->border_color[1]);
uint32 b = float_to_ubyte(sampler->border_color[2]);
uint32 a = float_to_ubyte(sampler->border_color[3]);
util_pack_color_ub( r, g, b, a,
PIPE_FORMAT_B8G8R8A8_UNORM,
&cso->bordercolor );
cso->bordercolor = (a << 24) | (r << 16) | (g << 8) | b;
}
/* No SVGA3D support for:

View File

@@ -50,7 +50,7 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
/* Adjust refcounts */
for (i = 0; i < count; i++) {
pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
if (svga_buffer(buffers[i].buffer)->user)
if (svga_buffer_is_user_buffer(buffers[i].buffer))
any_user_buffer = TRUE;
}

View File

@@ -104,7 +104,9 @@ svga_get_paramf(struct pipe_screen *screen, int param)
return 80.0;
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
return 4.0;
if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result))
return 4.0;
return result.u;
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
return 16.0;
@@ -131,12 +133,33 @@ svga_get_paramf(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return SVGA_MAX_TEXTURE_LEVELS;
{
unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
levels = MIN2(util_logbase2(result.u) + 1, levels);
else
levels = 12 /* 2048x2048 */;
if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
levels = MIN2(util_logbase2(result.u) + 1, levels);
else
levels = 12 /* 2048x2048 */;
return levels;
}
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
return 8; /* max 128x128x128 */
if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
return 8; /* max 128x128x128 */
return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return SVGA_MAX_TEXTURE_LEVELS;
/*
* No mechanism to query the host, and at least limited to 2048x2048 on
* certain hardware.
*/
return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
12.0 /* 2048x2048 */);
case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
return 1;

View File

@@ -83,7 +83,7 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
* as svga_screen_surface_create might have passed a recycled host
* buffer.
*/
sbuf->hw.flags.discard = TRUE;
sbuf->dma.flags.discard = TRUE;
SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size);
}
@@ -109,10 +109,10 @@ svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf)
struct svga_winsys_screen *sws = ss->sws;
assert(!sbuf->map.count);
assert(sbuf->hw.buf);
if(sbuf->hw.buf) {
sws->buffer_destroy(sws, sbuf->hw.buf);
sbuf->hw.buf = NULL;
assert(sbuf->hwbuf);
if(sbuf->hwbuf) {
sws->buffer_destroy(sws, sbuf->hwbuf);
sbuf->hwbuf = NULL;
}
}
@@ -151,16 +151,18 @@ static INLINE enum pipe_error
svga_buffer_create_hw_storage(struct svga_screen *ss,
struct svga_buffer *sbuf)
{
if(!sbuf->hw.buf) {
assert(!sbuf->user);
if(!sbuf->hwbuf) {
unsigned alignment = sbuf->base.alignment;
unsigned usage = 0;
unsigned size = sbuf->base.size;
sbuf->hw.buf = svga_winsys_buffer_create(ss, alignment, usage, size);
if(!sbuf->hw.buf)
sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
if(!sbuf->hwbuf)
return PIPE_ERROR_OUT_OF_MEMORY;
assert(!sbuf->needs_flush);
assert(!sbuf->dma.pending);
}
return PIPE_OK;
@@ -175,12 +177,11 @@ svga_buffer_upload_command(struct svga_context *svga,
struct svga_buffer *sbuf)
{
struct svga_winsys_context *swc = svga->swc;
struct svga_winsys_buffer *guest = sbuf->hw.buf;
struct svga_winsys_buffer *guest = sbuf->hwbuf;
struct svga_winsys_surface *host = sbuf->handle;
SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM;
SVGA3dSurfaceDMAFlags flags = sbuf->hw.flags;
SVGA3dCmdSurfaceDMA *cmd;
uint32 numBoxes = sbuf->hw.num_ranges;
uint32 numBoxes = sbuf->map.num_ranges;
SVGA3dCopyBox *boxes;
SVGA3dCmdSurfaceDMASuffix *pSuffix;
unsigned region_flags;
@@ -218,8 +219,8 @@ svga_buffer_upload_command(struct svga_context *svga,
cmd->transfer = transfer;
sbuf->hw.boxes = (SVGA3dCopyBox *)&cmd[1];
sbuf->hw.svga = svga;
sbuf->dma.boxes = (SVGA3dCopyBox *)&cmd[1];
sbuf->dma.svga = svga;
/* Increment reference count */
dummy = NULL;
@@ -228,9 +229,11 @@ svga_buffer_upload_command(struct svga_context *svga,
pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes);
pSuffix->suffixSize = sizeof *pSuffix;
pSuffix->maximumOffset = sbuf->base.size;
pSuffix->flags = flags;
pSuffix->flags = sbuf->dma.flags;
swc->commit(swc);
SVGA_FIFOCommitAll(swc);
sbuf->dma.flags.discard = FALSE;
return PIPE_OK;
}
@@ -248,10 +251,10 @@ svga_buffer_upload_flush(struct svga_context *svga,
unsigned i;
assert(sbuf->handle);
assert(sbuf->hw.buf);
assert(sbuf->hw.num_ranges);
assert(sbuf->hw.svga == svga);
assert(sbuf->hw.boxes);
assert(sbuf->hwbuf);
assert(sbuf->map.num_ranges);
assert(sbuf->dma.svga == svga);
assert(sbuf->dma.boxes);
/*
* Patch the DMA command with the final copy box.
@@ -259,36 +262,33 @@ svga_buffer_upload_flush(struct svga_context *svga,
SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle);
boxes = sbuf->hw.boxes;
for(i = 0; i < sbuf->hw.num_ranges; ++i) {
boxes = sbuf->dma.boxes;
for(i = 0; i < sbuf->map.num_ranges; ++i) {
SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n",
sbuf->hw.ranges[i].start, sbuf->hw.ranges[i].end);
sbuf->map.ranges[i].start, sbuf->map.ranges[i].end);
boxes[i].x = sbuf->hw.ranges[i].start;
boxes[i].x = sbuf->map.ranges[i].start;
boxes[i].y = 0;
boxes[i].z = 0;
boxes[i].w = sbuf->hw.ranges[i].end - sbuf->hw.ranges[i].start;
boxes[i].w = sbuf->map.ranges[i].end - sbuf->map.ranges[i].start;
boxes[i].h = 1;
boxes[i].d = 1;
boxes[i].srcx = sbuf->hw.ranges[i].start;
boxes[i].srcx = sbuf->map.ranges[i].start;
boxes[i].srcy = 0;
boxes[i].srcz = 0;
}
sbuf->hw.num_ranges = 0;
memset(&sbuf->hw.flags, 0, sizeof sbuf->hw.flags);
sbuf->map.num_ranges = 0;
assert(sbuf->head.prev && sbuf->head.next);
LIST_DEL(&sbuf->head);
#ifdef DEBUG
sbuf->head.next = sbuf->head.prev = NULL;
#endif
sbuf->needs_flush = FALSE;
sbuf->dma.pending = FALSE;
sbuf->hw.svga = NULL;
sbuf->hw.boxes = NULL;
sbuf->host_written = TRUE;
sbuf->dma.svga = NULL;
sbuf->dma.boxes = NULL;
/* Decrement reference count */
pipe_buffer_reference((struct pipe_buffer **)&sbuf, NULL);
@@ -296,7 +296,7 @@ svga_buffer_upload_flush(struct svga_context *svga,
/**
* Queue a DMA upload of a range of this buffer to the host.
* Note a dirty range.
*
* This function only notes the range down. It doesn't actually emit a DMA
* upload command. That only happens when a context tries to refer to this
@@ -305,15 +305,24 @@ svga_buffer_upload_flush(struct svga_context *svga,
* We try to lump as many contiguous DMA transfers together as possible.
*/
static void
svga_buffer_upload_queue(struct svga_buffer *sbuf,
unsigned start,
unsigned end)
svga_buffer_add_range(struct svga_buffer *sbuf,
unsigned start,
unsigned end)
{
unsigned i;
unsigned nearest_range;
unsigned nearest_dist;
assert(sbuf->hw.buf);
assert(end > start);
if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) {
nearest_range = sbuf->map.num_ranges;
nearest_dist = ~0;
} else {
nearest_range = SVGA_BUFFER_MAX_RANGES - 1;
nearest_dist = 0;
}
/*
* Try to grow one of the ranges.
*
@@ -324,12 +333,34 @@ svga_buffer_upload_queue(struct svga_buffer *sbuf,
* buffer should be flushed.
*/
for(i = 0; i < sbuf->hw.num_ranges; ++i) {
if(start <= sbuf->hw.ranges[i].end && sbuf->hw.ranges[i].start <= end) {
sbuf->hw.ranges[i].start = MIN2(sbuf->hw.ranges[i].start, start);
sbuf->hw.ranges[i].end = MAX2(sbuf->hw.ranges[i].end, end);
for(i = 0; i < sbuf->map.num_ranges; ++i) {
int left_dist;
int right_dist;
int dist;
left_dist = start - sbuf->map.ranges[i].end;
right_dist = sbuf->map.ranges[i].start - end;
dist = MAX2(left_dist, right_dist);
if (dist <= 0) {
/*
* Ranges are contiguous or overlapping -- extend this one and return.
*/
sbuf->map.ranges[i].start = MIN2(sbuf->map.ranges[i].start, start);
sbuf->map.ranges[i].end = MAX2(sbuf->map.ranges[i].end, end);
return;
}
else {
/*
* Discontiguous ranges -- keep track of the nearest range.
*/
if (dist < nearest_dist) {
nearest_range = i;
nearest_dist = dist;
}
}
}
/*
@@ -337,20 +368,34 @@ svga_buffer_upload_queue(struct svga_buffer *sbuf,
* pending DMA upload and start clean.
*/
if(sbuf->needs_flush)
svga_buffer_upload_flush(sbuf->hw.svga, sbuf);
if(sbuf->dma.pending)
svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
assert(!sbuf->needs_flush);
assert(!sbuf->hw.svga);
assert(!sbuf->hw.boxes);
assert(!sbuf->dma.pending);
assert(!sbuf->dma.svga);
assert(!sbuf->dma.boxes);
/*
* Add a new range.
*/
if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) {
/*
* Add a new range.
*/
sbuf->hw.ranges[sbuf->hw.num_ranges].start = start;
sbuf->hw.ranges[sbuf->hw.num_ranges].end = end;
++sbuf->hw.num_ranges;
sbuf->map.ranges[sbuf->map.num_ranges].start = start;
sbuf->map.ranges[sbuf->map.num_ranges].end = end;
++sbuf->map.num_ranges;
} else {
/*
* Everything else failed, so just extend the nearest range.
*
* It is OK to do this because we always keep a local copy of the
* host buffer data, for SW TNL, and the host never modifies the buffer.
*/
assert(nearest_range < SVGA_BUFFER_MAX_RANGES);
assert(nearest_range < sbuf->map.num_ranges);
sbuf->map.ranges[nearest_range].start = MIN2(sbuf->map.ranges[nearest_range].start, start);
sbuf->map.ranges[nearest_range].end = MAX2(sbuf->map.ranges[nearest_range].end, end);
}
}
@@ -365,55 +410,30 @@ svga_buffer_map_range( struct pipe_screen *screen,
struct svga_buffer *sbuf = svga_buffer( buf );
void *map;
if(sbuf->swbuf) {
if (!sbuf->swbuf && !sbuf->hwbuf) {
if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) {
/*
* We can't create a hardware buffer big enough, so create a malloc
* buffer instead.
*/
debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n",
__FUNCTION__,
(sbuf->base.size + 1023)/1024);
sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment);
}
}
if (sbuf->swbuf) {
/* User/malloc buffer */
map = sbuf->swbuf;
}
else if (sbuf->hwbuf) {
map = sws->buffer_map(sws, sbuf->hwbuf, usage);
}
else {
if(!sbuf->hw.buf) {
if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK)
return NULL;
/* Populate the hardware storage if the host surface pre-existed */
if(sbuf->host_written) {
SVGA3dSurfaceDMAFlags flags;
enum pipe_error ret;
struct pipe_fence_handle *fence = NULL;
assert(sbuf->handle);
SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n",
sbuf->handle, 0, sbuf->base.size);
memset(&flags, 0, sizeof flags);
ret = SVGA3D_BufferDMA(ss->swc,
sbuf->hw.buf,
sbuf->handle,
SVGA3D_READ_HOST_VRAM,
sbuf->base.size,
0,
flags);
if(ret != PIPE_OK) {
ss->swc->flush(ss->swc, NULL);
ret = SVGA3D_BufferDMA(ss->swc,
sbuf->hw.buf,
sbuf->handle,
SVGA3D_READ_HOST_VRAM,
sbuf->base.size,
0,
flags);
assert(ret == PIPE_OK);
}
ss->swc->flush(ss->swc, &fence);
sws->fence_finish(sws, fence, 0);
sws->fence_reference(sws, &fence, NULL);
}
}
map = sws->buffer_map(sws, sbuf->hw.buf, usage);
map = NULL;
}
if(map) {
@@ -446,8 +466,7 @@ svga_buffer_flush_mapped_range( struct pipe_screen *screen,
assert(sbuf->map.writing);
if(sbuf->map.writing) {
assert(sbuf->map.flush_explicit);
if(sbuf->hw.buf)
svga_buffer_upload_queue(sbuf, offset, offset + length);
svga_buffer_add_range(sbuf, offset, offset + length);
}
pipe_mutex_unlock(ss->swc_mutex);
}
@@ -466,16 +485,15 @@ svga_buffer_unmap( struct pipe_screen *screen,
if(sbuf->map.count)
--sbuf->map.count;
if(sbuf->hw.buf)
sws->buffer_unmap(sws, sbuf->hw.buf);
if(sbuf->hwbuf)
sws->buffer_unmap(sws, sbuf->hwbuf);
if(sbuf->map.writing) {
if(!sbuf->map.flush_explicit) {
/* No mapped range was flushed -- flush the whole buffer */
SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
if(sbuf->hw.buf)
svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
svga_buffer_add_range(sbuf, 0, sbuf->base.size);
}
sbuf->map.writing = FALSE;
@@ -493,12 +511,15 @@ svga_buffer_destroy( struct pipe_buffer *buf )
assert(!p_atomic_read(&buf->reference.count));
assert(!sbuf->needs_flush);
assert(!sbuf->dma.pending);
if(sbuf->handle)
svga_buffer_destroy_host_surface(ss, sbuf);
if(sbuf->hw.buf)
if(sbuf->uploaded.buffer)
pipe_buffer_reference(&sbuf->uploaded.buffer, NULL);
if(sbuf->hwbuf)
svga_buffer_destroy_hw_storage(ss, sbuf);
if(sbuf->swbuf && !sbuf->user)
@@ -595,13 +616,14 @@ svga_screen_init_buffer_functions(struct pipe_screen *screen)
}
/**
* Copy the contents of the user buffer / malloc buffer to a hardware buffer.
/**
* Copy the contents of the malloc buffer to a hardware buffer.
*/
static INLINE enum pipe_error
svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
{
if(!sbuf->hw.buf) {
assert(!sbuf->user);
if(!sbuf->hwbuf) {
enum pipe_error ret;
void *map;
@@ -610,20 +632,20 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
return PIPE_ERROR;
ret = svga_buffer_create_hw_storage(ss, sbuf);
assert(ret == PIPE_OK);
if(ret != PIPE_OK)
return ret;
pipe_mutex_lock(ss->swc_mutex);
map = ss->sws->buffer_map(ss->sws, sbuf->hw.buf, PIPE_BUFFER_USAGE_CPU_WRITE);
map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
assert(map);
if(!map) {
pipe_mutex_unlock(ss->swc_mutex);
return PIPE_ERROR_OUT_OF_MEMORY;
svga_buffer_destroy_hw_storage(ss, sbuf);
return PIPE_ERROR;
}
memcpy(map, sbuf->swbuf, sbuf->base.size);
ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf);
ss->sws->buffer_unmap(ss->sws, sbuf->hwbuf);
/* This user/malloc buffer is now indistinguishable from a gpu buffer */
assert(!sbuf->map.count);
@@ -635,10 +657,89 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
sbuf->swbuf = NULL;
}
svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
pipe_mutex_unlock(ss->swc_mutex);
}
pipe_mutex_unlock(ss->swc_mutex);
return PIPE_OK;
}
/**
* Upload the buffer to the host in a piecewise fashion.
*
* Used when the buffer is too big to fit in the GMR aperture.
*/
static INLINE enum pipe_error
svga_buffer_upload_piecewise(struct svga_screen *ss,
struct svga_context *svga,
struct svga_buffer *sbuf)
{
struct svga_winsys_screen *sws = ss->sws;
const unsigned alignment = sizeof(void *);
const unsigned usage = 0;
unsigned i;
assert(sbuf->map.num_ranges);
assert(!sbuf->dma.pending);
SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle);
for (i = 0; i < sbuf->map.num_ranges; ++i) {
struct svga_buffer_range *range = &sbuf->map.ranges[i];
unsigned offset = range->start;
unsigned size = range->end - range->start;
while (offset < range->end) {
struct svga_winsys_buffer *hwbuf;
uint8_t *map;
enum pipe_error ret;
if (offset + size > range->end)
size = range->end - offset;
hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
while (!hwbuf) {
size /= 2;
if (!size)
return PIPE_ERROR_OUT_OF_MEMORY;
hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
}
SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n",
offset, offset + size);
map = sws->buffer_map(sws, hwbuf,
PIPE_BUFFER_USAGE_CPU_WRITE |
PIPE_BUFFER_USAGE_DISCARD);
assert(map);
if (map) {
memcpy(map, sbuf->swbuf, size);
sws->buffer_unmap(sws, hwbuf);
}
ret = SVGA3D_BufferDMA(svga->swc,
hwbuf, sbuf->handle,
SVGA3D_WRITE_HOST_VRAM,
size, 0, offset, sbuf->dma.flags);
if(ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_BufferDMA(svga->swc,
hwbuf, sbuf->handle,
SVGA3D_WRITE_HOST_VRAM,
size, 0, offset, sbuf->dma.flags);
assert(ret == PIPE_OK);
}
sbuf->dma.flags.discard = FALSE;
sws->buffer_destroy(sws, hwbuf);
offset += size;
}
}
sbuf->map.num_ranges = 0;
return PIPE_OK;
}
@@ -658,34 +759,74 @@ svga_buffer_handle(struct svga_context *svga,
sbuf = svga_buffer(buf);
assert(!sbuf->map.count);
assert(!sbuf->user);
if(!sbuf->handle) {
ret = svga_buffer_create_host_surface(ss, sbuf);
if(ret != PIPE_OK)
return NULL;
ret = svga_buffer_update_hw(ss, sbuf);
if(ret != PIPE_OK)
return NULL;
}
if(!sbuf->needs_flush && sbuf->hw.num_ranges) {
/* Queue the buffer for flushing */
ret = svga_buffer_upload_command(svga, sbuf);
if(ret != PIPE_OK)
/* XXX: Should probably have a richer return value */
return NULL;
assert(sbuf->handle);
assert(sbuf->hw.svga == svga);
if (sbuf->map.num_ranges) {
if (!sbuf->dma.pending) {
/*
* No pending DMA upload yet, so insert a DMA upload command now.
*/
sbuf->needs_flush = TRUE;
assert(!sbuf->head.prev && !sbuf->head.next);
LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
/*
* Migrate the data from swbuf -> hwbuf if necessary.
*/
ret = svga_buffer_update_hw(ss, sbuf);
if (ret == PIPE_OK) {
/*
* Queue a dma command.
*/
ret = svga_buffer_upload_command(svga, sbuf);
if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
svga_context_flush(svga, NULL);
ret = svga_buffer_upload_command(svga, sbuf);
assert(ret == PIPE_OK);
}
if (ret == PIPE_OK) {
sbuf->dma.pending = TRUE;
assert(!sbuf->head.prev && !sbuf->head.next);
LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
}
}
else if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
/*
* The buffer is too big to fit in the GMR aperture, so break it in
* smaller pieces.
*/
ret = svga_buffer_upload_piecewise(ss, svga, sbuf);
}
if (ret != PIPE_OK) {
/*
* Something unexpected happened above. There is very little that
* we can do other than proceeding while ignoring the dirty ranges.
*/
assert(0);
sbuf->map.num_ranges = 0;
}
}
else {
/*
* There a pending dma already. Make sure it is from this context.
*/
assert(sbuf->dma.svga == svga);
}
}
assert(!sbuf->map.num_ranges || sbuf->dma.pending);
return sbuf->handle;
}
struct pipe_buffer *
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
enum SVGA3dSurfaceFormat format,
@@ -738,7 +879,7 @@ svga_context_flush_buffers(struct svga_context *svga)
sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
assert(p_atomic_read(&sbuf->base.reference.count) != 0);
assert(sbuf->needs_flush);
assert(sbuf->dma.pending);
svga_buffer_upload_flush(svga, sbuf);

View File

@@ -56,35 +56,6 @@ struct svga_buffer_range
};
/**
* Describe a
*
* This holds the information to emit a SVGA3dCmdSurfaceDMA.
*/
struct svga_buffer_upload
{
/**
* Guest memory region.
*/
struct svga_winsys_buffer *buf;
struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
unsigned num_ranges;
SVGA3dSurfaceDMAFlags flags;
/**
* Pointer to the DMA copy box *inside* the command buffer.
*/
SVGA3dCopyBox *boxes;
/**
* Context that has the pending DMA to this buffer.
*/
struct svga_context *svga;
};
/**
* SVGA pipe buffer.
*/
@@ -110,14 +81,6 @@ struct svga_buffer
*/
boolean user;
/**
* DMA'ble memory.
*
* A piece of GMR memory. It is created when mapping the buffer, and will be
* used to upload/download vertex data from the host.
*/
struct svga_buffer_upload hw;
/**
* Creation key for the host surface handle.
*
@@ -134,19 +97,94 @@ struct svga_buffer
* trying to bind
*/
struct svga_winsys_surface *handle;
/**
* Whether the host has been ever written.
*/
boolean host_written;
/**
* Information about ongoing and past map operations.
*/
struct {
/**
* Number of concurrent mappings.
*
* XXX: It is impossible to guarantee concurrent maps work in all
* circumstances -- pipe_buffers really need transfer objects too.
*/
unsigned count;
/**
* Whether this buffer is currently mapped for writing.
*/
boolean writing;
/**
* Whether the application will tell us explicity which ranges it touched
* or not.
*/
boolean flush_explicit;
/**
* Dirty ranges.
*
* Ranges that were touched by the application and need to be uploaded to
* the host.
*
* This information will be copied into dma.boxes, when emiting the
* SVGA3dCmdSurfaceDMA command.
*/
struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
unsigned num_ranges;
} map;
boolean needs_flush;
/**
* Information about uploaded version of user buffers.
*/
struct {
struct pipe_buffer *buffer;
/**
* We combine multiple user buffers into the same hardware buffer. This
* is the relative offset within that buffer.
*/
unsigned offset;
} uploaded;
/**
* DMA'ble memory.
*
* A piece of GMR memory, with the same size of the buffer. It is created
* when mapping the buffer, and will be used to upload vertex data to the
* host.
*/
struct svga_winsys_buffer *hwbuf;
/**
* Information about pending DMA uploads.
*
*/
struct {
/**
* Whether this buffer has an unfinished DMA upload command.
*
* If not set then the rest of the information is null.
*/
boolean pending;
SVGA3dSurfaceDMAFlags flags;
/**
* Pointer to the DMA copy box *inside* the command buffer.
*/
SVGA3dCopyBox *boxes;
/**
* Context that has the pending DMA to this buffer.
*/
struct svga_context *svga;
} dma;
/**
* Linked list head, used to gather all buffers with pending dma uploads on
* a context. It is only valid if the dma.pending is set above.
*/
struct list_head head;
};
@@ -176,6 +214,16 @@ svga_buffer_is_user_buffer( struct pipe_buffer *buffer )
void
svga_screen_init_buffer_functions(struct pipe_screen *screen);
/**
* Get the host surface handle for this buffer.
*
* This will ensure the host surface is updated, issuing DMAs as needed.
*
* NOTE: This may insert new commands in the context, so it *must* be called
* before reserving command buffer space. And, in order to insert commands
* it may need to call svga_context_flush().
*/
struct svga_winsys_surface *
svga_buffer_handle(struct svga_context *svga,
struct pipe_buffer *buf);

View File

@@ -203,7 +203,7 @@ svga_transfer_dma(struct svga_transfer *st,
if(transfer == SVGA3D_READ_HOST_VRAM) {
svga_screen_flush(screen, &fence);
sws->fence_finish(sws, fence, 0);
//sws->fence_reference(sws, &fence, NULL);
sws->fence_reference(sws, &fence, NULL);
}
}
else {
@@ -232,7 +232,7 @@ svga_transfer_dma(struct svga_transfer *st,
if(y) {
svga_screen_flush(screen, &fence);
sws->fence_finish(sws, fence, 0);
//sws->fence_reference(sws, &fence, NULL);
sws->fence_reference(sws, &fence, NULL);
}
hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);

View File

@@ -38,7 +38,7 @@ struct svga_winsys_surface;
enum SVGA3dSurfaceFormat;
#define SVGA_MAX_TEXTURE_LEVELS 12 /* 2048x2048 */
#define SVGA_MAX_TEXTURE_LEVELS 16
/**

View File

@@ -103,70 +103,6 @@ fail:
return ret;
}
/* The blend workaround for simulating logicop xor behaviour requires
* that the incoming fragment color be white. This change achieves
* that by hooking up a hard-wired fragment shader that just emits
* color 1,1,1,1
*
* This is a slightly incomplete solution as it assumes that the
* actual bound shader has no other effects beyond generating a
* fragment color. In particular shaders containing TEXKIL and/or
* depth-write will not have the correct behaviour, nor will those
* expecting to use alphatest.
*
* These are avoidable issues, but they are not much worse than the
* unavoidable ones associated with this technique, so it's not clear
* how much effort should be expended trying to resolve them - the
* ultimate result will still not be correct in most cases.
*
* Shader below was generated with:
* SVGA_DEBUG=tgsi ./mesa/progs/fp/fp-tri white.txt
*/
static int emit_white_fs( struct svga_context *svga )
{
int ret = PIPE_ERROR;
/* ps_3_0
* def c0, 1.000000, 0.000000, 0.000000, 1.000000
* mov oC0, c0.x
* end
*/
static const unsigned white_tokens[] = {
0xffff0300,
0x05000051,
0xa00f0000,
0x3f800000,
0x00000000,
0x00000000,
0x3f800000,
0x02000001,
0x800f0800,
0xa0000000,
0x0000ffff,
};
assert(SVGA3D_INVALID_ID == UTIL_BITMASK_INVALID_INDEX);
svga->state.white_fs_id = util_bitmask_add(svga->fs_bm);
if(svga->state.white_fs_id == SVGA3D_INVALID_ID)
goto no_fs_id;
ret = SVGA3D_DefineShader(svga->swc,
svga->state.white_fs_id,
SVGA3D_SHADERTYPE_PS,
white_tokens,
sizeof(white_tokens));
if (ret)
goto no_definition;
return 0;
no_definition:
util_bitmask_clear(svga->fs_bm, svga->state.white_fs_id);
svga->state.white_fs_id = SVGA3D_INVALID_ID;
no_fs_id:
return ret;
}
/* SVGA_NEW_TEXTURE_BINDING
* SVGA_NEW_RAST
@@ -194,6 +130,23 @@ static int make_fs_key( const struct svga_context *svga,
PIPE_WINDING_CW);
}
/* The blend workaround for simulating logicop xor behaviour
* requires that the incoming fragment color be white. This change
* achieves that by creating a varient of the current fragment
* shader that overrides all output colors with 1,1,1,1
*
* This will work for most shaders, including those containing
* TEXKIL and/or depth-write. However, it will break on the
* combination of xor-logicop plus alphatest.
*
* Ultimately, we could implement alphatest in the shader using
* texkil prior to overriding the outgoing fragment color.
*
* SVGA_NEW_BLEND
*/
if (svga->curr.blend->need_white_fragments) {
key->white_fragments = 1;
}
/* XXX: want to limit this to the textures that the shader actually
* refers to.
@@ -233,40 +186,29 @@ static int emit_hw_fs( struct svga_context *svga,
unsigned id = SVGA3D_INVALID_ID;
int ret = 0;
/* SVGA_NEW_BLEND
*/
if (svga->curr.blend->need_white_fragments) {
if (svga->state.white_fs_id == SVGA3D_INVALID_ID) {
ret = emit_white_fs( svga );
if (ret)
return ret;
}
id = svga->state.white_fs_id;
}
else {
struct svga_fragment_shader *fs = svga->curr.fs;
struct svga_fs_compile_key key;
struct svga_fragment_shader *fs = svga->curr.fs;
struct svga_fs_compile_key key;
/* SVGA_NEW_TEXTURE_BINDING
* SVGA_NEW_RAST
* SVGA_NEW_NEED_SWTNL
* SVGA_NEW_SAMPLER
*/
ret = make_fs_key( svga, &key );
/* SVGA_NEW_BLEND
* SVGA_NEW_TEXTURE_BINDING
* SVGA_NEW_RAST
* SVGA_NEW_NEED_SWTNL
* SVGA_NEW_SAMPLER
*/
ret = make_fs_key( svga, &key );
if (ret)
return ret;
result = search_fs_key( fs, &key );
if (!result) {
ret = compile_fs( svga, fs, &key, &result );
if (ret)
return ret;
result = search_fs_key( fs, &key );
if (!result) {
ret = compile_fs( svga, fs, &key, &result );
if (ret)
return ret;
}
assert (result);
id = result->id;
}
assert (result);
id = result->id;
assert(id != SVGA3D_INVALID_ID);
if (result != svga->state.hw_draw.fs) {

View File

@@ -101,6 +101,19 @@ static int emit_rss( struct svga_context *svga,
}
if (dirty & SVGA_NEW_BLEND_COLOR) {
uint32 color;
uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]);
uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]);
uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]);
uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]);
color = (a << 24) | (r << 16) | (g << 8) | b;
EMIT_RS( svga, color, BLENDCOLOR, fail );
}
if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) {
const struct svga_depth_stencil_state *curr = svga->curr.depth;
const struct svga_rasterizer_state *rast = svga->curr.rast;
@@ -179,18 +192,28 @@ static int emit_rss( struct svga_context *svga,
}
if (dirty & SVGA_NEW_RAST)
if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
{
const struct svga_rasterizer_state *curr = svga->curr.rast;
unsigned cullmode = curr->cullmode;
/* Shademode: still need to rearrange index list to move
* flat-shading PV first vertex.
*/
EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
/* Don't do culling while the software pipeline is active. It
* does it for us, and additionally introduces potentially
* back-facing triangles.
*/
if (svga->state.sw.need_pipeline)
cullmode = SVGA3D_FACE_NONE;
EMIT_RS( svga, cullmode, CULLMODE, fail );
EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
EMIT_RS( svga, curr->pointspriteenable, POINTSPRITEENABLE, fail );
EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
EMIT_RS_FLOAT( svga, curr->pointsize_min, POINTSIZEMIN, fail );
@@ -230,13 +253,10 @@ static int emit_rss( struct svga_context *svga,
memcpy( rs,
queue.rs,
queue.rs_count * sizeof queue.rs[0]);
SVGA_FIFOCommitAll( svga->swc );
}
/* Also blend color:
*/
return 0;
fail:
@@ -256,6 +276,7 @@ struct svga_tracked_state svga_hw_rss =
"hw rss state",
(SVGA_NEW_BLEND |
SVGA_NEW_BLEND_COLOR |
SVGA_NEW_DEPTH_STENCIL |
SVGA_NEW_RAST |
SVGA_NEW_FRAME_BUFFER |

View File

@@ -54,33 +54,30 @@ upload_user_buffers( struct svga_context *svga )
{
if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer))
{
struct pipe_buffer *upload_buffer = NULL;
unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0;
unsigned size = svga->curr.vb[i].buffer->size /*- offset*/;
unsigned upload_offset;
struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer);
ret = u_upload_buffer( svga->upload_vb,
offset,
size,
svga->curr.vb[i].buffer,
&upload_offset,
&upload_buffer );
if (ret)
return ret;
if (!buffer->uploaded.buffer) {
ret = u_upload_buffer( svga->upload_vb,
0,
buffer->base.size,
&buffer->base,
&buffer->uploaded.offset,
&buffer->uploaded.buffer );
if (ret)
return ret;
if (0)
debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
__FUNCTION__,
i,
svga->curr.vb[i].buffer,
upload_buffer, upload_offset, size);
if (0)
debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
__FUNCTION__,
i,
buffer,
buffer->uploaded.buffer,
buffer->uploaded.offset,
buffer->base.size);
}
/* Make sure we release the old buffer and end up with the
* correct refcount on the uploaded buffer.
*/
pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL );
svga->curr.vb[i].buffer = upload_buffer;
svga->curr.vb[i].buffer_offset = upload_offset;
pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer );
svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
}
}

View File

@@ -49,6 +49,7 @@ struct svga_fs_compile_key
{
boolean light_twoside:1;
boolean front_cw:1;
boolean white_fragments:1;
ubyte num_textures;
ubyte num_unnormalized_coords;
struct {

View File

@@ -194,8 +194,19 @@ static boolean ps30_output( struct svga_shader_emitter *emit,
switch (semantic.SemanticName) {
case TGSI_SEMANTIC_COLOR:
emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,
semantic.SemanticIndex );
if (emit->unit == PIPE_SHADER_FRAGMENT &&
emit->key.fkey.white_fragments) {
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
emit->nr_hw_temp++ );
emit->temp_col[idx] = emit->output_map[idx];
emit->true_col[idx] = dst_register( SVGA3DREG_COLOROUT,
semantic.SemanticIndex );
}
else {
emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,
semantic.SemanticIndex );
}
break;
case TGSI_SEMANTIC_POSITION:
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,

View File

@@ -79,6 +79,8 @@ struct svga_shader_emitter
int ps30_input_count;
int dynamic_branching_level;
boolean in_main_func;
boolean created_zero_immediate;
@@ -136,6 +138,7 @@ static INLINE boolean emit_dst( struct svga_shader_emitter *emit,
SVGA3dShaderDestToken dest )
{
assert(dest.reserved0);
assert(dest.mask);
return svga_shader_emit_dword( emit, dest.value );
}
@@ -199,6 +202,23 @@ static INLINE boolean emit_op3( struct svga_shader_emitter *emit,
}
static INLINE boolean emit_op4( struct svga_shader_emitter *emit,
SVGA3dShaderInstToken inst,
SVGA3dShaderDestToken dest,
struct src_register src0,
struct src_register src1,
struct src_register src2,
struct src_register src3)
{
return (emit_instruction( emit, inst ) &&
emit_dst( emit, dest ) &&
emit_src( emit, src0 ) &&
emit_src( emit, src1 ) &&
emit_src( emit, src2 ) &&
emit_src( emit, src3 ));
}
#define TRANSLATE_SWIZZLE(x,y,z,w) ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
#define SWIZZLE_XYZW \
TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W)
@@ -248,6 +268,7 @@ static INLINE SVGA3dShaderDestToken
writemask( SVGA3dShaderDestToken dest,
unsigned mask )
{
assert(dest.mask & mask);
dest.mask &= mask;
return dest;
}

View File

@@ -46,8 +46,6 @@ translate_opcode(
case TGSI_OPCODE_ABS: return SVGA3DOP_ABS;
case TGSI_OPCODE_ADD: return SVGA3DOP_ADD;
case TGSI_OPCODE_BREAKC: return SVGA3DOP_BREAKC;
case TGSI_OPCODE_DDX: return SVGA3DOP_DSX;
case TGSI_OPCODE_DDY: return SVGA3DOP_DSY;
case TGSI_OPCODE_DP2A: return SVGA3DOP_DP2ADD;
case TGSI_OPCODE_DP3: return SVGA3DOP_DP3;
case TGSI_OPCODE_DP4: return SVGA3DOP_DP4;
@@ -114,6 +112,7 @@ translate_dst_register( struct svga_shader_emitter *emit,
}
dest.mask = reg->DstRegister.WriteMask;
assert(dest.mask);
if (insn->Instruction.Saturate)
dest.dstMod = SVGA3DDSTMOD_SATURATE;
@@ -415,6 +414,88 @@ static boolean submit_op3( struct svga_shader_emitter *emit,
}
/* SVGA shaders may not refer to >1 constant register in a single
* instruction. This function checks for that usage and inserts a
* move to temporary if detected.
*/
static boolean submit_op4( struct svga_shader_emitter *emit,
SVGA3dShaderInstToken inst,
SVGA3dShaderDestToken dest,
struct src_register src0,
struct src_register src1,
struct src_register src2,
struct src_register src3)
{
SVGA3dShaderDestToken temp0;
SVGA3dShaderDestToken temp3;
boolean need_temp0 = FALSE;
boolean need_temp3 = FALSE;
SVGA3dShaderRegType type0, type1, type2, type3;
temp0.value = 0;
temp3.value = 0;
type0 = SVGA3dShaderGetRegType( src0.base.value );
type1 = SVGA3dShaderGetRegType( src1.base.value );
type2 = SVGA3dShaderGetRegType( src2.base.value );
type3 = SVGA3dShaderGetRegType( src2.base.value );
/* Make life a little easier - this is only used by the TXD
* instruction which is guaranteed not to have a constant/input reg
* in one slot at least:
*/
assert(type1 == SVGA3DREG_SAMPLER);
if (type0 == SVGA3DREG_CONST &&
((type3 == SVGA3DREG_CONST && src0.base.num != src3.base.num) ||
(type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
need_temp0 = TRUE;
if (type3 == SVGA3DREG_CONST &&
(type2 == SVGA3DREG_CONST && src3.base.num != src2.base.num))
need_temp3 = TRUE;
if (type0 == SVGA3DREG_INPUT &&
((type3 == SVGA3DREG_INPUT && src0.base.num != src3.base.num) ||
(type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
need_temp0 = TRUE;
if (type3 == SVGA3DREG_INPUT &&
(type2 == SVGA3DREG_INPUT && src3.base.num != src2.base.num))
need_temp3 = TRUE;
if (need_temp0)
{
temp0 = get_temp( emit );
if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp0, src0 ))
return FALSE;
src0 = src( temp0 );
}
if (need_temp3)
{
temp3 = get_temp( emit );
if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp3, src3 ))
return FALSE;
src3 = src( temp3 );
}
if (!emit_op4( emit, inst, dest, src0, src1, src2, src3 ))
return FALSE;
if (need_temp3)
release_temp( emit, temp3 );
if (need_temp0)
release_temp( emit, temp0 );
return TRUE;
}
static boolean emit_def_const( struct svga_shader_emitter *emit,
SVGA3dShaderConstType type,
unsigned idx,
@@ -660,6 +741,8 @@ static boolean emit_if(struct svga_shader_emitter *emit,
if_token.control = SVGA3DOPCOMPC_NE;
zero = scalar(zero, TGSI_SWIZZLE_X);
emit->dynamic_branching_level++;
return (emit_instruction( emit, if_token ) &&
emit_src( emit, src ) &&
emit_src( emit, zero ) );
@@ -668,6 +751,8 @@ static boolean emit_if(struct svga_shader_emitter *emit,
static boolean emit_endif(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
{
emit->dynamic_branching_level--;
return (emit_instruction( emit,
inst_token( SVGA3DOP_ENDIF )));
}
@@ -1011,10 +1096,10 @@ static boolean emit_kilp(struct svga_shader_emitter *emit,
{
SVGA3dShaderInstToken inst;
SVGA3dShaderDestToken temp;
struct src_register one = get_zero_immediate( emit );
struct src_register one = scalar( get_zero_immediate( emit ),
TGSI_SWIZZLE_W );
inst = inst_token( SVGA3DOP_TEXKILL );
one = scalar( one, TGSI_SWIZZLE_W );
/* texkill doesn't allow negation on the operand so lets move
* negation of {1} to a temp register */
@@ -1169,41 +1254,79 @@ static boolean emit_tex2(struct svga_shader_emitter *emit,
SVGA3dShaderDestToken dst )
{
SVGA3dShaderInstToken inst;
struct src_register src0;
struct src_register src1;
struct src_register texcoord;
struct src_register sampler;
SVGA3dShaderDestToken tmp;
inst.value = 0;
inst.op = SVGA3DOP_TEX;
switch (insn->Instruction.Opcode) {
case TGSI_OPCODE_TEX:
inst.op = SVGA3DOP_TEX;
break;
case TGSI_OPCODE_TXP:
inst.op = SVGA3DOP_TEX;
inst.control = SVGA3DOPCONT_PROJECT;
break;
case TGSI_OPCODE_TXB:
inst.op = SVGA3DOP_TEX;
inst.control = SVGA3DOPCONT_BIAS;
break;
case TGSI_OPCODE_TXL:
inst.op = SVGA3DOP_TEXLDL;
break;
default:
assert(0);
return FALSE;
}
src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
texcoord = translate_src_register( emit, &insn->FullSrcRegisters[0] );
sampler = translate_src_register( emit, &insn->FullSrcRegisters[1] );
if (emit->key.fkey.tex[src1.base.num].unnormalized) {
struct src_register wh = get_tex_dimensions( emit, src1.base.num );
SVGA3dShaderDestToken tmp = get_temp( emit );
if (emit->key.fkey.tex[sampler.base.num].unnormalized ||
emit->dynamic_branching_level > 0)
tmp = get_temp( emit );
/* Can't do mipmapping inside dynamic branch constructs. Force LOD
* zero in that case.
*/
if (emit->dynamic_branching_level > 0 &&
inst.op == SVGA3DOP_TEX &&
SVGA3dShaderGetRegType(texcoord.base.value) == SVGA3DREG_TEMP) {
struct src_register zero = get_zero_immediate( emit );
/* MOV tmp, texcoord */
if (!submit_op1( emit,
inst_token( SVGA3DOP_MOV ),
tmp,
texcoord ))
return FALSE;
/* MOV tmp.w, zero */
if (!submit_op1( emit,
inst_token( SVGA3DOP_MOV ),
writemask( tmp, TGSI_WRITEMASK_W ),
scalar( zero, TGSI_SWIZZLE_X )))
return FALSE;
texcoord = src( tmp );
inst.op = SVGA3DOP_TEXLDL;
}
/* Explicit normalization of texcoords:
*/
if (emit->key.fkey.tex[sampler.base.num].unnormalized) {
struct src_register wh = get_tex_dimensions( emit, sampler.base.num );
/* MUL tmp, SRC0, WH */
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
tmp, src0, wh ))
tmp, texcoord, wh ))
return FALSE;
src0 = src( tmp );
texcoord = src( tmp );
}
return submit_op2( emit, inst, dst, src0, src1 );
return submit_op2( emit, inst, dst, texcoord, sampler );
}
@@ -1211,31 +1334,33 @@ static boolean emit_tex2(struct svga_shader_emitter *emit,
/* Translate texture instructions to SVGA3D representation.
*/
static boolean emit_tex3(struct svga_shader_emitter *emit,
static boolean emit_tex4(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn,
SVGA3dShaderDestToken dst )
{
SVGA3dShaderInstToken inst;
struct src_register src0;
struct src_register src1;
struct src_register src2;
struct src_register texcoord;
struct src_register ddx;
struct src_register ddy;
struct src_register sampler;
texcoord = translate_src_register( emit, &insn->FullSrcRegisters[0] );
ddx = translate_src_register( emit, &insn->FullSrcRegisters[1] );
ddy = translate_src_register( emit, &insn->FullSrcRegisters[2] );
sampler = translate_src_register( emit, &insn->FullSrcRegisters[3] );
inst.value = 0;
switch (insn->Instruction.Opcode) {
case TGSI_OPCODE_TXD:
inst.op = SVGA3DOP_TEXLDD;
break;
case TGSI_OPCODE_TXL:
inst.op = SVGA3DOP_TEXLDL;
inst.op = SVGA3DOP_TEXLDD; /* 4 args! */
break;
default:
assert(0);
return FALSE;
}
src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
src2 = translate_src_register( emit, &insn->FullSrcRegisters[2] );
return submit_op3( emit, inst, dst, src0, src1, src2 );
return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy );
}
@@ -1271,12 +1396,12 @@ static boolean emit_tex(struct svga_shader_emitter *emit,
case TGSI_OPCODE_TEX:
case TGSI_OPCODE_TXB:
case TGSI_OPCODE_TXP:
case TGSI_OPCODE_TXL:
if (!emit_tex2( emit, insn, tex_result ))
return FALSE;
break;
case TGSI_OPCODE_TXL:
case TGSI_OPCODE_TXD:
if (!emit_tex3( emit, insn, tex_result ))
if (!emit_tex4( emit, insn, tex_result ))
return FALSE;
break;
default:
@@ -1285,34 +1410,42 @@ static boolean emit_tex(struct svga_shader_emitter *emit,
if (compare) {
SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
struct src_register one =
scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
if (dst.mask & TGSI_WRITEMASK_XYZ) {
SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
/* Divide texcoord R by Q */
if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
src0_zdivw,
scalar(src0, TGSI_SWIZZLE_W) ))
return FALSE;
/* Divide texcoord R by Q */
if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
writemask(src0_zdivw, TGSI_WRITEMASK_X),
scalar(src0, TGSI_SWIZZLE_W) ))
return FALSE;
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
src0_zdivw,
scalar(src0, TGSI_SWIZZLE_Z),
src(src0_zdivw) ))
return FALSE;
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
writemask(src0_zdivw, TGSI_WRITEMASK_X),
scalar(src0, TGSI_SWIZZLE_Z),
scalar(src(src0_zdivw), TGSI_SWIZZLE_X) ))
return FALSE;
if (!emit_select(
emit,
emit->key.fkey.tex[src1.base.num].compare_func,
dst,
src(src0_zdivw),
tex_src_x))
return FALSE;
if (!emit_select(
emit,
emit->key.fkey.tex[src1.base.num].compare_func,
writemask( dst, TGSI_WRITEMASK_XYZ ),
scalar(src(src0_zdivw), TGSI_SWIZZLE_X),
tex_src_x))
return FALSE;
}
return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
writemask( dst, TGSI_WRITEMASK_W),
one );
if (dst.mask & TGSI_WRITEMASK_W) {
struct src_register one =
scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
writemask( dst, TGSI_WRITEMASK_W ),
one ))
return FALSE;
}
return TRUE;
}
else if (!emit->use_sm30 && dst.mask != TGSI_WRITEMASK_XYZW)
{
@@ -1330,6 +1463,8 @@ static boolean emit_bgnloop2( struct svga_shader_emitter *emit,
struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
struct src_register const_int = get_loop_const( emit );
emit->dynamic_branching_level++;
return (emit_instruction( emit, inst ) &&
emit_src( emit, loop_reg ) &&
emit_src( emit, const_int ) );
@@ -1339,6 +1474,9 @@ static boolean emit_endloop2( struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn )
{
SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
emit->dynamic_branching_level--;
return emit_instruction( emit, inst );
}
@@ -1398,6 +1536,46 @@ static boolean emit_simple_instruction(struct svga_shader_emitter *emit,
}
}
static boolean emit_deriv(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn )
{
if (emit->dynamic_branching_level > 0 &&
insn->FullSrcRegisters[0].SrcRegister.File == TGSI_FILE_TEMPORARY)
{
struct src_register zero = get_zero_immediate( emit );
SVGA3dShaderDestToken dst =
translate_dst_register( emit, insn, 0 );
/* Deriv opcodes not valid inside dynamic branching, workaround
* by zeroing out the destination.
*/
if (!submit_op1(emit,
inst_token( SVGA3DOP_MOV ),
dst,
scalar(zero, TGSI_SWIZZLE_X)))
return FALSE;
return TRUE;
}
else {
unsigned opcode;
switch (insn->Instruction.Opcode) {
case TGSI_OPCODE_DDX:
opcode = SVGA3DOP_DSX;
break;
case TGSI_OPCODE_DDY:
opcode = SVGA3DOP_DSY;
break;
default:
return FALSE;
}
return emit_simple_instruction( emit, opcode, insn );
}
}
static boolean emit_arl(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
{
@@ -1655,13 +1833,13 @@ static boolean emit_exp(struct svga_shader_emitter *emit,
*/
if (dst.mask & TGSI_WRITEMASK_X) {
if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
writemask( dst, TGSI_WRITEMASK_X ),
src0,
scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
return FALSE;
if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
writemask( dst, TGSI_WRITEMASK_X ),
scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
return FALSE;
@@ -1673,7 +1851,7 @@ static boolean emit_exp(struct svga_shader_emitter *emit,
*/
if (dst.mask & TGSI_WRITEMASK_Z) {
if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
writemask( dst, dst.mask & TGSI_WRITEMASK_Z ),
writemask( dst, TGSI_WRITEMASK_Z ),
src0 ) )
return FALSE;
}
@@ -2002,6 +2180,10 @@ static boolean svga_emit_instruction( struct svga_shader_emitter *emit,
case TGSI_OPCODE_TXD:
return emit_tex( emit, insn );
case TGSI_OPCODE_DDX:
case TGSI_OPCODE_DDY:
return emit_deriv( emit, insn );
case TGSI_OPCODE_BGNSUB:
return emit_bgnsub( emit, position, insn );
@@ -2254,11 +2436,28 @@ static boolean emit_ps_postamble( struct svga_shader_emitter *emit )
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
if (!submit_op1( emit,
inst_token(SVGA3DOP_MOV),
emit->true_col[i],
src(emit->temp_col[i]) ))
return FALSE;
/* Potentially override output colors with white for XOR
* logicop workaround.
*/
if (emit->unit == PIPE_SHADER_FRAGMENT &&
emit->key.fkey.white_fragments) {
struct src_register one = scalar( get_zero_immediate( emit ),
TGSI_SWIZZLE_W );
if (!submit_op1( emit,
inst_token(SVGA3DOP_MOV),
emit->true_col[i],
one ))
return FALSE;
}
else {
if (!submit_op1( emit,
inst_token(SVGA3DOP_MOV),
emit->true_col[i],
src(emit->temp_col[i]) ))
return FALSE;
}
}
}
@@ -2467,6 +2666,9 @@ needs_to_create_zero( struct svga_shader_emitter *emit )
if (emit->key.fkey.light_twoside)
return TRUE;
if (emit->key.fkey.white_fragments)
return TRUE;
if (emit->emit_frontface)
return TRUE;
@@ -2476,6 +2678,10 @@ needs_to_create_zero( struct svga_shader_emitter *emit )
}
if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_BGNFOR] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
@@ -2702,6 +2908,8 @@ boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
goto done;
}
assert(emit->dynamic_branching_level == 0);
/* Need to terminate the whole shader:
*/
ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) );

View File

@@ -281,6 +281,9 @@ svga_screen_create(struct svga_winsys_screen *sws);
struct svga_winsys_screen *
svga_winsys_screen(struct pipe_screen *screen);
struct svga_winsys_context *
svga_winsys_context(struct pipe_context *context);
struct pipe_buffer *
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
enum SVGA3dSurfaceFormat format,

View File

@@ -132,14 +132,22 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
boolean have_depth = FALSE;
int i, count;
buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
&dri_drawable->w,
&dri_drawable->h,
drawable->attachments,
drawable->
num_attachments, &count,
dri_drawable->
loaderPrivate);
if ((dri_screen->dri2.loader
&& (dri_screen->dri2.loader->base.version > 2)
&& (dri_screen->dri2.loader->getBuffersWithFormat != NULL)))
buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
(dri_drawable, &dri_drawable->w, &dri_drawable->h,
drawable->attachments, drawable->num_attachments,
&count, dri_drawable->loaderPrivate);
else
buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
&dri_drawable->w,
&dri_drawable->h,
drawable->attachments,
drawable->
num_attachments, &count,
dri_drawable->
loaderPrivate);
if (buffers == NULL) {
return;
@@ -346,12 +354,12 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
case 24:
if (visual->stencilBits == 0) {
drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
PIPE_FORMAT_X8Z24_UNORM:
PIPE_FORMAT_Z24X8_UNORM;
PIPE_FORMAT_X8Z24_UNORM:
PIPE_FORMAT_Z24X8_UNORM;
} else {
drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
PIPE_FORMAT_S8Z24_UNORM:
PIPE_FORMAT_Z24S8_UNORM;
PIPE_FORMAT_S8Z24_UNORM:
PIPE_FORMAT_Z24S8_UNORM;
}
break;
case 32:
@@ -375,23 +383,49 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
/* setup dri2 buffers information */
/* TODO incase of double buffer visual, delay fake creation */
i = 0;
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
if (!screen->auto_fake_front)
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
if (visual->doubleBufferMode)
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
if (visual->depthBits && visual->stencilBits)
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
else if (visual->depthBits)
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
else if (visual->stencilBits)
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
drawable->num_attachments = i;
if (sPriv->dri2.loader
&& (sPriv->dri2.loader->base.version > 2)
&& (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
drawable->attachments[i++] = visual->rgbBits;
if (!screen->auto_fake_front) {
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
drawable->attachments[i++] = visual->rgbBits;
}
if (visual->doubleBufferMode) {
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
drawable->attachments[i++] = visual->rgbBits;
}
if (visual->depthBits && visual->stencilBits) {
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
} else if (visual->depthBits) {
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
drawable->attachments[i++] = visual->depthBits;
} else if (visual->stencilBits) {
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
drawable->attachments[i++] = visual->stencilBits;
}
drawable->num_attachments = i / 2;
} else {
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
if (!screen->auto_fake_front)
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
if (visual->doubleBufferMode)
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
if (visual->depthBits && visual->stencilBits)
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
else if (visual->depthBits)
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
else if (visual->stencilBits)
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
drawable->num_attachments = i;
}
drawable->desired_fences = 2;
return GL_TRUE;
fail:
fail:
FREE(drawable);
return GL_FALSE;
}

View File

@@ -80,6 +80,9 @@ dri_fill_in_modes(struct dri_screen *screen,
unsigned pixel_bits)
{
__DRIconfig **configs = NULL;
__DRIconfig **configs_r5g6b5 = NULL;
__DRIconfig **configs_a8r8g8b8 = NULL;
__DRIconfig **configs_x8r8g8b8 = NULL;
unsigned num_modes;
uint8_t depth_bits_array[5];
uint8_t stencil_bits_array[5];
@@ -99,12 +102,6 @@ dri_fill_in_modes(struct dri_screen *screen,
stencil_bits_array[0] = 0;
depth_buffer_factor = 1;
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
@@ -117,15 +114,30 @@ dri_fill_in_modes(struct dri_screen *screen,
pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8R8G8B8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
/* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
if (screen->sPriv->dri2.loader &&
(screen->sPriv->dri2.loader->base.version > 2) &&
(screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
} else {
pf_z16 = FALSE;
pf_z32 = FALSE;
}
if (pf_z16) {
depth_bits_array[depth_buffer_factor] = 16;
@@ -153,41 +165,43 @@ dri_fill_in_modes(struct dri_screen *screen,
num_modes =
depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
if (pixel_bits == 16 && pf_r5g6b5) {
configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
depth_bits_array, stencil_bits_array,
depth_buffer_factor, back_buffer_modes,
back_buffer_factor,
msaa_samples_array, 1);
if (pf_r5g6b5)
configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
depth_bits_array, stencil_bits_array,
depth_buffer_factor, back_buffer_modes,
back_buffer_factor,
msaa_samples_array, 1);
if (pf_a8r8g8b8)
configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
depth_bits_array,
stencil_bits_array,
depth_buffer_factor,
back_buffer_modes,
back_buffer_factor,
msaa_samples_array, 1);
if (pf_x8r8g8b8)
configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
depth_bits_array,
stencil_bits_array,
depth_buffer_factor,
back_buffer_modes,
back_buffer_factor,
msaa_samples_array, 1);
if (pixel_bits == 16) {
configs = configs_r5g6b5;
if (configs_a8r8g8b8)
configs = configs ? driConcatConfigs(configs, configs_a8r8g8b8) : configs_a8r8g8b8;
if (configs_x8r8g8b8)
configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8;
} else {
__DRIconfig **configs_a8r8g8b8 = NULL;
__DRIconfig **configs_x8r8g8b8 = NULL;
if (pf_a8r8g8b8)
configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
depth_bits_array,
stencil_bits_array,
depth_buffer_factor,
back_buffer_modes,
back_buffer_factor,
msaa_samples_array, 1);
if (pf_x8r8g8b8)
configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
depth_bits_array,
stencil_bits_array,
depth_buffer_factor,
back_buffer_modes,
back_buffer_factor,
msaa_samples_array, 1);
if (configs_a8r8g8b8 && configs_x8r8g8b8)
configs = driConcatConfigs(configs_x8r8g8b8, configs_a8r8g8b8);
else if (configs_a8r8g8b8)
configs = configs_a8r8g8b8;
else if (configs_x8r8g8b8)
configs = configs_x8r8g8b8;
else
configs = NULL;
configs = configs_a8r8g8b8;
if (configs_x8r8g8b8)
configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8;
if (configs_r5g6b5)
configs = configs ? driConcatConfigs(configs, configs_r5g6b5) : configs_r5g6b5;
}
if (configs == NULL) {

View File

@@ -21,6 +21,7 @@ if 'python' in env['statetrackers']:
'gdi32',
'user32',
'kernel32',
'ws2_32',
])
else:
env.Append(LIBS = [

View File

@@ -531,6 +531,8 @@ class Context(Object):
gallium.PIPE_FORMAT_R32G32B32_FLOAT: '3f',
gallium.PIPE_FORMAT_R32G32B32A32_FLOAT: '4f',
gallium.PIPE_FORMAT_B8G8R8A8_UNORM: '4B',
gallium.PIPE_FORMAT_R8G8B8A8_UNORM: '4B',
gallium.PIPE_FORMAT_R16G16B16_SNORM: '3h',
}[velem.src_format]
data = vbuf.buffer.read()
@@ -557,7 +559,7 @@ class Context(Object):
sys.stdout.write('\t{\n')
for i in range(start, start + count):
if i >= start + 16:
if i >= start + 16 and not self.interpreter.verbosity(3):
sys.stdout.write('\t...\n')
break
offset = i*isize

View File

@@ -362,7 +362,7 @@ EXPORTS
wglShareLists
wglSwapBuffers
wglSwapLayerBuffers
; wglSwapMultipleBuffers
wglSwapMultipleBuffers
wglUseFontBitmapsA
wglUseFontBitmapsW
wglUseFontOutlinesA

View File

@@ -362,7 +362,7 @@ EXPORTS
wglShareLists = wglShareLists@8
wglSwapBuffers = wglSwapBuffers@4
wglSwapLayerBuffers = wglSwapLayerBuffers@8
; wglSwapMultipleBuffers = wglSwapMultipleBuffers@8
wglSwapMultipleBuffers = wglSwapMultipleBuffers@8
wglUseFontBitmapsA = wglUseFontBitmapsA@16
wglUseFontBitmapsW = wglUseFontBitmapsW@16
wglUseFontOutlinesA = wglUseFontOutlinesA@32

View File

@@ -80,6 +80,9 @@ DrvCopyContext(
struct stw_context *dst;
BOOL ret = FALSE;
if (!stw_dev)
return FALSE;
pipe_mutex_lock( stw_dev->ctx_mutex );
src = stw_lookup_context_locked( dhrcSource );
@@ -107,13 +110,15 @@ DrvShareLists(
struct stw_context *ctx2;
BOOL ret = FALSE;
if (!stw_dev)
return FALSE;
pipe_mutex_lock( stw_dev->ctx_mutex );
ctx1 = stw_lookup_context_locked( dhglrc1 );
ctx2 = stw_lookup_context_locked( dhglrc2 );
if (ctx1 && ctx2 &&
ctx1->iPixelFormat == ctx2->iPixelFormat) {
if (ctx1 && ctx2) {
ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
}

View File

@@ -152,24 +152,27 @@ stw_cleanup_thread(void)
void
stw_cleanup(void)
{
unsigned i;
DHGLRC dhglrc;
debug_printf("%s\n", __FUNCTION__);
if (!stw_dev)
return;
/*
* Abort cleanup if there are still active contexts. In some situations
* this DLL may be unloaded before the DLL that is using GL contexts is.
*/
pipe_mutex_lock( stw_dev->ctx_mutex );
{
/* Ensure all contexts are destroyed */
i = handle_table_get_first_handle(stw_dev->ctx_table);
while (i) {
DrvDeleteContext(i);
i = handle_table_get_next_handle(stw_dev->ctx_table, i);
}
handle_table_destroy(stw_dev->ctx_table);
}
dhglrc = handle_table_get_first_handle(stw_dev->ctx_table);
pipe_mutex_unlock( stw_dev->ctx_mutex );
if (dhglrc) {
debug_printf("%s: contexts still active -- cleanup aborted\n", __FUNCTION__);
stw_dev = NULL;
return;
}
handle_table_destroy(stw_dev->ctx_table);
stw_framebuffer_cleanup();

View File

@@ -178,7 +178,7 @@ stw_call_window_proc(
if(!tls_data)
return 0;
if (nCode < 0)
if (nCode < 0 || !stw_dev)
return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
if (pParams->message == WM_WINDOWPOSCHANGED) {
@@ -333,6 +333,9 @@ stw_framebuffer_cleanup( void )
struct stw_framebuffer *fb;
struct stw_framebuffer *next;
if (!stw_dev)
return;
pipe_mutex_lock( stw_dev->fb_mutex );
fb = stw_dev->fb_head;
@@ -388,6 +391,9 @@ stw_framebuffer_from_hdc(
{
struct stw_framebuffer *fb;
if (!stw_dev)
return NULL;
pipe_mutex_lock( stw_dev->fb_mutex );
fb = stw_framebuffer_from_hdc_locked(hdc);
pipe_mutex_unlock( stw_dev->fb_mutex );
@@ -422,6 +428,9 @@ DrvSetPixelFormat(
uint index;
struct stw_framebuffer *fb;
if (!stw_dev)
return FALSE;
index = (uint) iPixelFormat - 1;
count = stw_pixelformat_get_extended_count();
if (index >= count)
@@ -476,6 +485,9 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
struct pipe_screen *screen;
struct pipe_surface *surface;
if (!stw_dev)
return FALSE;
fb = stw_framebuffer_from_hdc( hdc );
if (fb == NULL)
return FALSE;
@@ -577,6 +589,9 @@ DrvSwapBuffers(
struct stw_framebuffer *fb;
struct pipe_surface *surface = NULL;
if (!stw_dev)
return FALSE;
fb = stw_framebuffer_from_hdc( hdc );
if (fb == NULL)
return FALSE;

View File

@@ -34,6 +34,8 @@
#include "glapi/glapi.h"
#include "stw_ext_gallium.h"
#include "stw_device.h"
#include "stw_icd.h"
struct stw_extension_entry
{
@@ -73,6 +75,9 @@ DrvGetProcAddress(
{
const struct stw_extension_entry *entry;
if (!stw_dev)
return NULL;
if (lpszProc[0] == 'w' && lpszProc[1] == 'g' && lpszProc[2] == 'l')
for (entry = stw_extension_entries; entry->name; entry++)
if (strcmp( lpszProc, entry->name ) == 0)

View File

@@ -303,6 +303,9 @@ DrvDescribePixelFormat(
(void) hdc;
if (!stw_dev)
return 0;
count = stw_pixelformat_get_extended_count();
index = (uint) iPixelFormat - 1;

View File

@@ -97,6 +97,19 @@ wglSwapBuffers(
}
WINGDIAPI DWORD WINAPI
wglSwapMultipleBuffers(UINT n,
CONST WGLSWAP *ps)
{
UINT i;
for (i =0; i < n; ++i)
wglSwapBuffers(ps->hdc);
return 0;
}
WINGDIAPI BOOL APIENTRY
wglSwapLayerBuffers(
HDC hdc,

View File

@@ -59,5 +59,21 @@ wglSetPixelFormat(HDC hdc,
int iPixelFormat,
CONST PIXELFORMATDESCRIPTOR *ppfd);
#if defined(__MINGW32__) || (WINVER < 0x0500)
typedef struct _WGLSWAP
{
HDC hdc;
UINT uiFlags;
} WGLSWAP;
#define WGL_SWAPMULTIPLE_MAX 16
WINGDIAPI DWORD WINAPI
wglSwapMultipleBuffers(UINT n,
CONST WGLSWAP *ps);
#endif
#endif /* STW_WGL_H_ */

View File

@@ -39,6 +39,7 @@
#include <xf86.h>
#include <xf86i2c.h>
#include <xf86Crtc.h>
#include <cursorstr.h>
#include "xorg_tracker.h"
#include "xf86Modes.h"
@@ -146,6 +147,7 @@ crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
/* XXX: hockup */
}
#if 0 /* Implement and enable to enable rotation and reflection. */
static void *
crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
@@ -168,6 +170,8 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
/* ScrnInfoPtr pScrn = crtc->scrn; */
}
#endif
/*
* Cursor functions
*/
@@ -243,7 +247,11 @@ crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
unsigned attr[8];
attr[0] = KMS_BO_TYPE;
#ifdef KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8
attr[1] = KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
#else
attr[1] = KMS_BO_TYPE_CURSOR;
#endif
attr[2] = KMS_WIDTH;
attr[3] = 64;
attr[4] = KMS_HEIGHT;
@@ -272,7 +280,21 @@ err_bo_destroy:
static void
crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
modesettingPtr ms = modesettingPTR(crtc->scrn);
/* Older X servers have cursor reference counting bugs leading to use of
* freed memory and consequently random crashes. Should be fixed as of
* xserver 1.8, but this workaround shouldn't hurt anyway.
*/
if (config->cursor)
config->cursor->refcnt++;
if (ms->cursor)
FreeCursor(ms->cursor, None);
ms->cursor = config->cursor;
if (ms->screen)
crtc_load_cursor_argb_ga3d(crtc, image);
#ifdef HAVE_LIBKMS
@@ -344,9 +366,9 @@ static const xf86CrtcFuncsRec crtc_funcs = {
.hide_cursor = crtc_hide_cursor,
.load_cursor_argb = crtc_load_cursor_argb,
.shadow_create = crtc_shadow_create,
.shadow_allocate = crtc_shadow_allocate,
.shadow_destroy = crtc_shadow_destroy,
.shadow_create = NULL,
.shadow_allocate = NULL,
.shadow_destroy = NULL,
.gamma_set = crtc_gamma_set,
.destroy = crtc_destroy,

View File

@@ -102,14 +102,26 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
pipe_texture_reference(&tex, exa_priv->depth_stencil_tex);
else {
struct pipe_texture template;
unsigned depthBits = (format != 0) ? format : pDraw->depth;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
if (buffer->attachment == DRI2BufferDepth)
template.format = ms->ds_depth_bits_last ?
PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
else
template.format = ms->ds_depth_bits_last ?
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
if (buffer->attachment == DRI2BufferDepth) {
switch(depthBits) {
case 16:
template.format = PIPE_FORMAT_Z16_UNORM;
break;
case 32:
template.format = PIPE_FORMAT_Z32_UNORM;
break;
default:
template.format = ms->ds_depth_bits_last ?
PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
break;
}
} else {
template.format = ms->ds_depth_bits_last ?
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
}
pf_get_block(template.format, &template.block);
template.width[0] = pDraw->width;
template.height[0] = pDraw->height;
@@ -283,6 +295,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
GCPtr gc;
RegionPtr copy_clip;
Bool save_accel;
CustomizerPtr cust = ms->cust;
/*
* In driCreateBuffers we dewrap windows into the
@@ -336,7 +349,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
ValidateGC(dst_draw, gc);
/* If this is a full buffer swap, throttle on the previous one */
if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
if (ms->swapThrottling &&
dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
if (extents->x1 == 0 && extents->y1 == 0 &&
@@ -358,6 +372,9 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
DamageRegionAppend(src_draw, pRegion);
DamageRegionProcessPending(src_draw);
if (cust && cust->winsys_context_throttle)
cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_SWAP);
(*gc->ops->CopyArea)(src_draw, dst_draw, gc,
0, 0, pDraw->width, pDraw->height, 0, 0);
ms->exa->accel = save_accel;
@@ -365,8 +382,13 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
FreeScratchGC(gc);
ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
pDestBuffer->attachment == DRI2BufferFrontLeft ?
(pDestBuffer->attachment == DRI2BufferFrontLeft
&& ms->swapThrottling) ?
&dst_priv->fence : NULL);
if (cust && cust->winsys_context_throttle)
cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
}
Bool

View File

@@ -79,12 +79,16 @@ typedef enum
OPTION_SW_CURSOR,
OPTION_2D_ACCEL,
OPTION_DEBUG_FALLBACK,
OPTION_THROTTLE_SWAP,
OPTION_THROTTLE_DIRTY
} drv_option_enums;
static const OptionInfoRec drv_options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_THROTTLE_SWAP, "SwapThrottling", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_THROTTLE_DIRTY, "DirtyThrottling", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -155,7 +159,7 @@ drv_get_rec(ScrnInfoPtr pScrn)
if (pScrn->driverPrivate)
return TRUE;
pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
pScrn->driverPrivate = xnfcalloc(1, sizeof(modesettingRec));
return TRUE;
}
@@ -183,31 +187,66 @@ drv_probe_ddc(ScrnInfoPtr pScrn, int index)
static Bool
drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap;
ScreenPtr pScreen = pScrn->pScreen;
int old_width, old_height;
PixmapPtr rootPixmap;
int i;
if (width == pScrn->virtualX && height == pScrn->virtualY)
return TRUE;
old_width = pScrn->virtualX;
old_height = pScrn->virtualY;
pScrn->virtualX = width;
pScrn->virtualY = height;
/*
* Remove the old framebuffer & texture.
*/
drmModeRmFB(ms->fd, ms->fb_id);
if (!ms->destroy_front_buffer(pScrn))
FatalError("failed to destroy front buffer\n");
/* ms->create_front_buffer will remove the old front buffer */
rootPixmap = pScreen->GetScreenPixmap(pScreen);
if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
return FALSE;
goto error_modify;
pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
/* now create new frontbuffer */
return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn);
if (!ms->create_front_buffer(pScrn) || !ms->bind_front_buffer(pScrn))
goto error_create;
/*
* create && bind will turn off all crtc(s) in the kernel so we need to
* re-enable all the crtcs again. For real HW we might want to do this
* before destroying the old framebuffer.
*/
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
if (!crtc->enabled)
continue;
crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y);
}
return TRUE;
/*
* This is the error recovery path.
*/
error_create:
if (!pScreen->ModifyPixmapHeader(rootPixmap, old_width, old_height, -1, -1, -1, NULL))
FatalError("failed to resize rootPixmap error path\n");
pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
error_modify:
pScrn->virtualX = old_width;
pScrn->virtualY = old_height;
if (ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn))
return FALSE;
FatalError("failed to setup old framebuffer\n");
return FALSE;
}
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
@@ -333,6 +372,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
EntityInfoPtr pEnt;
EntPtr msEnt = NULL;
int max_width, max_height;
CustomizerPtr cust;
if (pScrn->numEntities != 1)
return FALSE;
@@ -344,6 +384,9 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
return TRUE;
}
cust = (CustomizerPtr) pScrn->driverPrivate;
pScrn->driverPrivate = NULL;
/* Allocate driverPrivate */
if (!drv_get_rec(pScrn))
return FALSE;
@@ -351,6 +394,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
ms = modesettingPTR(pScrn);
ms->SaveGeneration = -1;
ms->pEnt = pEnt;
ms->cust = cust;
pScrn->displayWidth = 640; /* default it */
@@ -423,8 +467,8 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
max_width = 8192;
max_height = 8192;
max_width = 2048; /* A very low default */
max_height = 2048; /* see screen_init */
xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
@@ -510,23 +554,29 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
if (ms->ctx) {
int j;
ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
ms->dirtyThrottling ?
&ms->fence[XORG_NR_FENCES-1] :
NULL);
if (ms->fence[0])
ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
if (ms->dirtyThrottling) {
if (ms->fence[0])
ms->ctx->screen->fence_finish(ms->ctx->screen,
ms->fence[0], 0);
/* The amount of rendering generated by a block handler can be
* quite small. Let us get a fair way ahead of hardware before
* throttling.
*/
for (j = 0; j < XORG_NR_FENCES - 1; j++)
ms->screen->fence_reference(ms->screen,
&ms->fence[j],
ms->fence[j+1]);
/* The amount of rendering generated by a block handler can be
* quite small. Let us get a fair way ahead of hardware before
* throttling.
*/
for (j = 0; j < XORG_NR_FENCES - 1; j++)
ms->screen->fence_reference(ms->screen,
&ms->fence[j],
ms->fence[j+1]);
ms->screen->fence_reference(ms->screen,
&ms->fence[XORG_NR_FENCES-1],
NULL);
ms->screen->fence_reference(ms->screen,
&ms->fence[XORG_NR_FENCES-1],
NULL);
}
}
@@ -607,7 +657,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
unsigned max_width, max_height;
VisualPtr visual;
CustomizerPtr cust = ms->cust;
MessageType from_st;
MessageType from_dt;
if (!drv_init_drm(pScrn)) {
FatalError("Could not init DRM");
@@ -624,6 +678,26 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
}
/* get max width and height */
{
drmModeResPtr res;
res = drmModeGetResources(ms->fd);
max_width = res->max_width;
max_height = res->max_height;
drmModeFreeResources(res);
}
if (ms->screen) {
float maxf;
int max;
maxf = ms->screen->get_paramf(ms->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
max = (1 << (int)(maxf - 1.0f));
max_width = max < max_width ? max : max_width;
max_height = max < max_height ? max : max_height;
}
xf86CrtcSetSizeRange(pScrn, 1, 1, max_width, max_height);
pScrn->pScreen = pScreen;
/* HW dependent - FIXME */
@@ -673,7 +747,20 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, TRUE);
ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d);
if (cust && cust->winsys_screen_init)
cust->winsys_screen_init(cust, ms->fd);
ms->swapThrottling = cust ? cust->swap_throttling : TRUE;
from_st = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_SWAP,
&ms->swapThrottling) ?
X_CONFIG : X_DEFAULT;
ms->dirtyThrottling = cust ? cust->dirty_throttling : TRUE;
from_dt = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_DIRTY,
&ms->dirtyThrottling) ?
X_CONFIG : X_DEFAULT;
if (ms->screen) {
ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
@@ -684,6 +771,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#endif
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Usefull debugging info follows #\n");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s backend\n",
ms->screen ? "Gallium3D" : "libkms");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n",
ms->screen && ms->accelerate_2d ? "enabled" : "disabled");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n",
@@ -694,6 +786,12 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#else
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
#endif
xf86DrvMsg(pScrn->scrnIndex, from_st, "Swap Throttling is %s.\n",
ms->swapThrottling ? "enabled" : "disabled");
xf86DrvMsg(pScrn->scrnIndex, from_dt, "Dirty Throttling is %s.\n",
ms->dirtyThrottling ? "enabled" : "disabled");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
@@ -725,9 +823,6 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
if (ms->winsys_screen_init)
ms->winsys_screen_init(pScrn);
return drv_enter_vt(scrnIndex, 1);
}
@@ -759,10 +854,11 @@ drv_leave_vt(int scrnIndex, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
CustomizerPtr cust = ms->cust;
int o;
if (ms->winsys_leave_vt)
ms->winsys_leave_vt(pScrn);
if (cust && cust->winsys_leave_vt)
cust->winsys_leave_vt(cust);
for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o];
@@ -778,6 +874,7 @@ drv_leave_vt(int scrnIndex, int flags)
}
drmModeRmFB(ms->fd, ms->fb_id);
ms->fb_id = -1;
drv_restore_hw_state(pScrn);
@@ -796,6 +893,7 @@ drv_enter_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
CustomizerPtr cust = ms->cust;
if (drmSetMaster(ms->fd)) {
if (errno == EINVAL) {
@@ -826,8 +924,8 @@ drv_enter_vt(int scrnIndex, int flags)
if (!xf86SetDesiredModes(pScrn))
return FALSE;
if (ms->winsys_enter_vt)
ms->winsys_enter_vt(pScrn);
if (cust && cust->winsys_enter_vt)
cust->winsys_enter_vt(cust);
return TRUE;
}
@@ -845,13 +943,19 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
CustomizerPtr cust = ms->cust;
if (pScrn->vtSema) {
drv_leave_vt(scrnIndex, 0);
}
if (ms->winsys_screen_close)
ms->winsys_screen_close(pScrn);
if (ms->cursor) {
FreeCursor(ms->cursor, None);
ms->cursor = NULL;
}
if (cust && cust->winsys_screen_close)
cust->winsys_screen_close(cust);
#ifdef DRI2
if (ms->screen)
@@ -900,6 +1004,15 @@ static Bool
drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
if (!ms->root_texture)
return TRUE;
if (ms->fb_id != -1) {
drmModeRmFB(ms->fd, ms->fb_id);
ms->fb_id = -1;
}
pipe_texture_reference(&ms->root_texture, NULL);
return TRUE;
}
@@ -908,7 +1021,7 @@ static Bool
drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
unsigned handle, stride;
unsigned handle, stride, fb_id;
struct pipe_texture *tex;
int ret;
@@ -933,19 +1046,23 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
pScrn->bitsPerPixel,
stride,
handle,
&ms->fb_id);
&fb_id);
if (ret) {
debug_printf("%s: failed to create framebuffer (%i, %s)",
debug_printf("%s: failed to create framebuffer (%i, %s)\n",
__func__, ret, strerror(-ret));
goto err_destroy;
}
if (!drv_destroy_front_buffer_ga3d(pScrn))
FatalError("%s: failed to take down old framebuffer\n", __func__);
pScrn->frameX0 = 0;
pScrn->frameY0 = 0;
drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
pipe_texture_reference(&ms->root_texture, tex);
pipe_texture_reference(&tex, NULL);
ms->fb_id = fb_id;
return TRUE;
@@ -993,6 +1110,11 @@ drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn)
if (!ms->root_bo)
return TRUE;
if (ms->fb_id != -1) {
drmModeRmFB(ms->fd, ms->fb_id);
ms->fb_id = -1;
}
kms_bo_unmap(ms->root_bo);
kms_bo_destroy(&ms->root_bo);
return TRUE;
@@ -1005,10 +1127,15 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
unsigned handle, stride;
struct kms_bo *bo;
unsigned attr[8];
unsigned fb_id;
int ret;
attr[0] = KMS_BO_TYPE;
#ifdef KMS_BO_TYPE_SCANOUT_X8R8G8B8
attr[1] = KMS_BO_TYPE_SCANOUT_X8R8G8B8;
#else
attr[1] = KMS_BO_TYPE_SCANOUT;
#endif
attr[2] = KMS_WIDTH;
attr[3] = pScrn->virtualX;
attr[4] = KMS_HEIGHT;
@@ -1031,17 +1158,21 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
pScrn->bitsPerPixel,
stride,
handle,
&ms->fb_id);
&fb_id);
if (ret) {
debug_printf("%s: failed to create framebuffer (%i, %s)",
__func__, ret, strerror(-ret));
goto err_destroy;
}
if (!drv_destroy_front_buffer_kms(pScrn))
FatalError("%s: could not takedown old bo", __func__);
pScrn->frameX0 = 0;
pScrn->frameY0 = 0;
drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
ms->root_bo = bo;
ms->fb_id = fb_id;
return TRUE;
@@ -1109,4 +1240,14 @@ static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn)
return TRUE;
}
CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn)
{
return modesettingPTR(pScrn)->cust;
}
Bool xorg_has_gallium(ScrnInfoPtr pScrn)
{
return modesettingPTR(pScrn)->screen != NULL;
}
/* vim: set sw=4 ts=8 sts=4: */

View File

@@ -1035,6 +1035,7 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa;
ExaDriverPtr pExa;
CustomizerPtr cust = ms->cust;
exa = xcalloc(1, sizeof(struct exa_context));
if (!exa)
@@ -1093,6 +1094,8 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
exa->pipe = ms->api->create_context(ms->api, exa->scrn);
/* Share context with DRI */
ms->ctx = exa->pipe;
if (cust && cust->winsys_context_throttle)
cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
exa->renderer = renderer_create(exa->pipe);
exa->accel = accel;

View File

@@ -586,7 +586,7 @@ void renderer_copy_pixmap(struct xorg_renderer *r,
void renderer_draw_yuv(struct xorg_renderer *r,
int src_x, int src_y, int src_w, int src_h,
float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
struct pipe_texture **textures)
{

View File

@@ -53,7 +53,7 @@ void renderer_set_constants(struct xorg_renderer *r,
void renderer_draw_yuv(struct xorg_renderer *r,
int src_x, int src_y, int src_w, int src_h,
float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
struct pipe_texture **textures);

View File

@@ -65,6 +65,24 @@ typedef struct
#define XORG_NR_FENCES 3
enum xorg_throttling_reason {
THROTTLE_RENDER,
THROTTLE_SWAP
};
typedef struct _CustomizerRec
{
Bool dirty_throttling;
Bool swap_throttling;
Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd);
Bool (*winsys_screen_close)(struct _CustomizerRec *cust);
Bool (*winsys_enter_vt)(struct _CustomizerRec *cust);
Bool (*winsys_leave_vt)(struct _CustomizerRec *cust);
void (*winsys_context_throttle)(struct _CustomizerRec *cust,
struct pipe_context *pipe,
enum xorg_throttling_reason reason);
} CustomizerRec, *CustomizerPtr;
typedef struct _modesettingRec
{
/* drm */
@@ -80,6 +98,9 @@ typedef struct _modesettingRec
Bool noAccel;
Bool SWCursor;
CursorPtr cursor;
Bool swapThrottling;
Bool dirtyThrottling;
CloseScreenProcPtr CloseScreen;
/* Broken-out options. */
@@ -115,12 +136,7 @@ typedef struct _modesettingRec
Bool accelerate_2d;
Bool debug_fallback;
/* winsys hocks */
Bool (*winsys_screen_init)(ScrnInfoPtr pScr);
Bool (*winsys_screen_close)(ScrnInfoPtr pScr);
Bool (*winsys_enter_vt)(ScrnInfoPtr pScr);
Bool (*winsys_leave_vt)(ScrnInfoPtr pScr);
void *winsys_priv;
CustomizerPtr cust;
#ifdef DRM_MODE_FEATURE_DIRTYFB
DamagePtr damage;
@@ -129,6 +145,9 @@ typedef struct _modesettingRec
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn);
Bool xorg_has_gallium(ScrnInfoPtr pScrn);
/***********************************************************************
* xorg_exa.c

View File

@@ -384,11 +384,14 @@ setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
static void
draw_yuv(struct xorg_xv_port_priv *port,
int src_x, int src_y, int src_w, int src_h,
float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h)
{
struct pipe_texture **textures = port->yuv[port->current_set];
/*debug_printf(" draw_yuv([%d, %d, %d ,%d], [%d, %d, %d, %d])\n",
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h);*/
renderer_draw_yuv(port->r,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h,
@@ -490,6 +493,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
exaMoveInPixmap(pPixmap);
dst = exaGetPixmapDriverPrivate(pPixmap);
/*debug_printf("display_video([%d, %d, %d, %d], [%d, %d, %d, %d])\n",
src_x, src_y, src_w, src_h, dstX, dstY, dst_w, dst_h);*/
if (dst && !dst->tex) {
xorg_exa_set_shared_usage(pPixmap);
pScrn->pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL);
@@ -527,10 +533,10 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
int box_y2 = pbox->y2;
float diff_x = (float)src_w / (float)dst_w;
float diff_y = (float)src_h / (float)dst_h;
int offset_x = box_x1 - dstX + pPixmap->screen_x;
int offset_y = box_y1 - dstY + pPixmap->screen_y;
int offset_w;
int offset_h;
float offset_x = box_x1 - dstX + pPixmap->screen_x;
float offset_y = box_y1 - dstY + pPixmap->screen_y;
float offset_w;
float offset_h;
x = box_x1;
y = box_y1;
@@ -540,8 +546,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
offset_w = dst_w - w;
offset_h = dst_h - h;
draw_yuv(pPriv, src_x + offset_x*diff_x, src_y + offset_y*diff_y,
src_w - offset_w*diff_x, src_h - offset_h*diff_x,
draw_yuv(pPriv,
(float) src_x + offset_x*diff_x, (float) src_y + offset_y*diff_y,
(float) src_w - offset_w*diff_x, (float) src_h - offset_h*diff_y,
x, y, w, h);
pbox++;

View File

@@ -103,6 +103,9 @@ struct vmw_svga_winsys_context
* referred.
*/
boolean preemptive_flush;
boolean throttle_set;
uint32_t throttle_us;
};
@@ -122,6 +125,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
struct pipe_fence_handle *fence = NULL;
unsigned i;
enum pipe_error ret;
uint32_t throttle_us;
ret = pb_validate_validate(vswc->validate);
assert(ret == PIPE_OK);
@@ -140,8 +144,13 @@ vmw_swc_flush(struct svga_winsys_context *swc,
*reloc->where = ptr;
}
throttle_us = vswc->throttle_set ?
vswc->throttle_us : vswc->vws->default_throttle_us;
if (vswc->command.used)
vmw_ioctl_command(vswc->vws,
vswc->base.cid,
throttle_us,
vswc->command.buffer,
vswc->command.used,
&vswc->last_fence);
@@ -385,3 +394,14 @@ vmw_svga_context_create(struct pipe_screen *screen)
{
return svga_context_create(screen);
}
void
vmw_svga_context_set_throttling(struct pipe_context *pipe,
uint32_t throttle_us)
{
struct svga_winsys_context *swc = svga_winsys_context(pipe);
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
vswc->throttle_us = throttle_us;
vswc->throttle_set = TRUE;
}

View File

@@ -55,5 +55,8 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
struct pipe_context *
vmw_svga_context_create(struct pipe_screen *screen);
void
vmw_svga_context_set_throttling(struct pipe_context *pipe,
uint32_t throttle_us);
#endif /* VMW_CONTEXT_H_ */

View File

@@ -37,13 +37,16 @@
* module.
*/
struct vmw_winsys_screen *
vmw_winsys_create( int fd )
vmw_winsys_create( int fd, boolean use_old_scanout_flag )
{
struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen);
if (!vws)
goto out_no_vws;
vws->ioctl.drm_fd = fd;
vws->use_old_scanout_flag = use_old_scanout_flag;
debug_printf("%s: use_old_scanout_flag == %s\n", __FUNCTION__,
use_old_scanout_flag ? "true" : "false");
if (!vmw_ioctl_init(vws))
goto out_no_ioctl;
@@ -72,3 +75,13 @@ vmw_winsys_destroy(struct vmw_winsys_screen *vws)
vmw_ioctl_cleanup(vws);
FREE(vws);
}
void
vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
uint32_t throttle_us)
{
struct vmw_winsys_screen *vws =
vmw_winsys_screen(svga_winsys_screen(screen));
vws->default_throttle_us = throttle_us;
}

View File

@@ -52,6 +52,9 @@ struct vmw_winsys_screen
{
struct svga_winsys_screen base;
boolean use_old_scanout_flag;
uint32_t default_throttle_us;
struct {
volatile uint32_t *fifo_map;
uint64_t last_fence;
@@ -94,9 +97,11 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
void
vmw_ioctl_command(struct vmw_winsys_screen *vws,
void *commands,
uint32_t size,
uint32_t *fence);
int32_t cid,
uint32_t throttle_us,
void *commands,
uint32_t size,
uint32_t *fence);
struct vmw_region *
vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
@@ -131,8 +136,9 @@ boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
struct vmw_winsys_screen *vmw_winsys_create(int fd);
struct vmw_winsys_screen *vmw_winsys_create(int fd, boolean use_old_scanout_flag);
void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
uint32_t throttle_us);
#endif /* VMW_SCREEN_H_ */

View File

@@ -48,8 +48,9 @@ static struct dri1_api_version ddx_required = { 0, 1, 0 };
static struct dri1_api_version ddx_compat = { 0, 0, 0 };
static struct dri1_api_version dri_required = { 4, 0, 0 };
static struct dri1_api_version dri_compat = { 4, 0, 0 };
static struct dri1_api_version drm_required = { 0, 1, 0 };
static struct dri1_api_version drm_compat = { 0, 0, 0 };
static struct dri1_api_version drm_required = { 1, 0, 0 };
static struct dri1_api_version drm_compat = { 1, 0, 0 };
static struct dri1_api_version drm_scanout = { 0, 9, 0 };
static boolean
vmw_dri1_check_version(const struct dri1_api_version *cur,
@@ -84,6 +85,7 @@ vmw_drm_create_screen(struct drm_api *drm_api,
struct vmw_winsys_screen *vws;
struct pipe_screen *screen;
struct dri1_create_screen_arg *dri1;
boolean use_old_scanout_flag = FALSE;
if (!arg || arg->mode == DRM_CREATE_NORMAL) {
struct dri1_api_version drm_ver;
@@ -95,11 +97,16 @@ vmw_drm_create_screen(struct drm_api *drm_api,
drm_ver.major = ver->version_major;
drm_ver.minor = ver->version_minor;
drm_ver.patch_level = 0; /* ??? */
drmFreeVersion(ver);
if (!vmw_dri1_check_version(&drm_ver, &drm_required,
&drm_compat, "vmwgfx drm driver"))
return NULL;
if (!vmw_dri1_check_version(&drm_ver, &drm_scanout,
&drm_compat, "use old scanout field (not a error)"))
use_old_scanout_flag = TRUE;
}
if (arg != NULL) {
@@ -117,6 +124,9 @@ vmw_drm_create_screen(struct drm_api *drm_api,
if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required,
&drm_compat, "vmwgfx drm driver"))
return NULL;
if (!vmw_dri1_check_version(&dri1->drm_version, &drm_scanout,
&drm_compat, "use old scanout field (not a error)"))
use_old_scanout_flag = TRUE;
dri1->api = &dri1_api_hooks;
break;
default:
@@ -124,7 +134,7 @@ vmw_drm_create_screen(struct drm_api *drm_api,
}
}
vws = vmw_winsys_create( fd );
vws = vmw_winsys_create( fd, use_old_scanout_flag );
if (!vws)
goto out_no_vws;
@@ -228,7 +238,7 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
cmd.rect.y,
cmd.rect.w, cmd.rect.h, cmd.rect.srcx, cmd.rect.srcy);
vmw_ioctl_command(vws, &cmd, sizeof cmd.header + cmd.header.size,
vmw_ioctl_command(vws, -1, 0, &cmd, sizeof cmd.header + cmd.header.size,
&fence_seq);
visible = TRUE;
}

View File

@@ -57,6 +57,12 @@ struct vmw_region
uint32_t size;
};
/* XXX: This isn't a real hardware flag, but just a hack for kernel to
* know about primary surfaces. In newer versions of the kernel
* interface the driver uses a special field.
*/
#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
static void
vmw_check_last_cmd(struct vmw_winsys_screen *vws)
{
@@ -169,7 +175,17 @@ vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
memset(&s_arg, 0, sizeof(s_arg));
req->flags = (uint32_t) flags;
if (vws->use_old_scanout_flag &&
(flags & SVGA3D_SURFACE_HINT_SCANOUT)) {
req->flags = (uint32_t) flags;
req->scanout = false;
} else if (flags & SVGA3D_SURFACE_HINT_SCANOUT) {
req->flags = (uint32_t) (flags & ~SVGA3D_SURFACE_HINT_SCANOUT);
req->scanout = true;
} else {
req->flags = (uint32_t) flags;
req->scanout = false;
}
req->format = (uint32_t) format;
req->shareable = 1;
@@ -225,8 +241,9 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
}
void
vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
uint32_t * pfence)
vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
uint32_t throttle_us, void *commands, uint32_t size,
uint32_t *pfence)
{
struct drm_vmw_execbuf_arg arg;
struct drm_vmw_fence_rep rep;
@@ -259,6 +276,7 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
arg.fence_rep = (unsigned long)&rep;
arg.commands = (unsigned long)commands;
arg.command_size = size;
arg.throttle_us = throttle_us;
do {
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));

View File

@@ -68,7 +68,8 @@
#define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
#define DRM_VMW_PARAM_3D 2
#define DRM_VMW_PARAM_FIFO_OFFSET 3
#define DRM_VMW_PARAM_HW_CAPS 4
#define DRM_VMW_PARAM_FIFO_CAPS 5
/**
* struct drm_vmw_getparam_arg
@@ -85,49 +86,6 @@ struct drm_vmw_getparam_arg {
uint32_t pad64;
};
/*************************************************************************/
/**
* DRM_VMW_EXTENSION - Query device extensions.
*/
/**
* struct drm_vmw_extension_rep
*
* @exists: The queried extension exists.
* @driver_ioctl_offset: Ioctl number of the first ioctl in the extension.
* @driver_sarea_offset: Offset to any space in the DRI SAREA
* used by the extension.
* @major: Major version number of the extension.
* @minor: Minor version number of the extension.
* @pl: Patch level version number of the extension.
*
* Output argument to the DRM_VMW_EXTENSION Ioctl.
*/
struct drm_vmw_extension_rep {
int32_t exists;
uint32_t driver_ioctl_offset;
uint32_t driver_sarea_offset;
uint32_t major;
uint32_t minor;
uint32_t pl;
uint32_t pad64;
};
/**
* union drm_vmw_extension_arg
*
* @extension - Ascii name of the extension to be queried. //In
* @rep - Reply as defined above. //Out
*
* Argument to the DRM_VMW_EXTENSION Ioctl.
*/
union drm_vmw_extension_arg {
char extension[DRM_VMW_EXT_NAME_LEN];
struct drm_vmw_extension_rep rep;
};
/*************************************************************************/
/**
* DRM_VMW_CREATE_CONTEXT - Create a host context.
@@ -181,6 +139,8 @@ struct drm_vmw_context_arg {
* The size of the array should equal the total number of mipmap levels.
* @shareable: Boolean whether other clients (as identified by file descriptors)
* may reference this surface.
* @scanout: Boolean whether the surface is intended to be used as a
* scanout.
*
* Input data to the DRM_VMW_CREATE_SURFACE Ioctl.
* Output data from the DRM_VMW_REF_SURFACE Ioctl.
@@ -192,7 +152,7 @@ struct drm_vmw_surface_create_req {
uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
uint64_t size_addr;
int32_t shareable;
uint32_t pad64;
int32_t scanout;
};
/**
@@ -295,17 +255,28 @@ union drm_vmw_surface_reference_arg {
*
* @commands: User-space address of a command buffer cast to an uint64_t.
* @command-size: Size in bytes of the command buffer.
* @throttle-us: Sleep until software is less than @throttle_us
* microseconds ahead of hardware. The driver may round this value
* to the nearest kernel tick.
* @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an
* uint64_t.
* @version: Allows expanding the execbuf ioctl parameters without breaking
* backwards compatibility, since user-space will always tell the kernel
* which version it uses.
* @flags: Execbuf flags. None currently.
*
* Argument to the DRM_VMW_EXECBUF Ioctl.
*/
#define DRM_VMW_EXECBUF_VERSION 0
struct drm_vmw_execbuf_arg {
uint64_t commands;
uint32_t command_size;
uint32_t pad64;
uint32_t throttle_us;
uint64_t fence_rep;
uint32_t version;
uint32_t flags;
};
/**

View File

@@ -40,8 +40,11 @@
struct vmw_dma_buffer;
struct vmw_driver
struct vmw_customizer
{
CustomizerRec base;
ScrnInfoPtr pScrn;
int fd;
void *cursor_priv;
@@ -50,11 +53,10 @@ struct vmw_driver
void *video_priv;
};
static INLINE struct vmw_driver *
vmw_driver(ScrnInfoPtr pScrn)
static INLINE struct vmw_customizer *
vmw_customizer(CustomizerPtr cust)
{
modesettingPtr ms = modesettingPTR(pScrn);
return ms ? (struct vmw_driver *)ms->winsys_priv : NULL;
return cust ? (struct vmw_customizer *) cust : NULL;
}
@@ -62,40 +64,40 @@ vmw_driver(ScrnInfoPtr pScrn)
* vmw_video.c
*/
Bool vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
Bool vmw_video_init(struct vmw_customizer *vmw);
Bool vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
Bool vmw_video_close(struct vmw_customizer *vmw);
void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
void vmw_video_stop_all(struct vmw_customizer *vmw);
/***********************************************************************
* vmw_ioctl.c
*/
int vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot);
int vmw_ioctl_cursor_bypass(struct vmw_customizer *vmw, int xhot, int yhot);
struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_driver *vmw,
struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_customizer *vmw,
uint32_t size,
unsigned *handle);
void * vmw_ioctl_buffer_map(struct vmw_driver *vmw,
void * vmw_ioctl_buffer_map(struct vmw_customizer *vmw,
struct vmw_dma_buffer *buf);
void vmw_ioctl_buffer_unmap(struct vmw_driver *vmw,
void vmw_ioctl_buffer_unmap(struct vmw_customizer *vmw,
struct vmw_dma_buffer *buf);
void vmw_ioctl_buffer_destroy(struct vmw_driver *vmw,
void vmw_ioctl_buffer_destroy(struct vmw_customizer *vmw,
struct vmw_dma_buffer *buf);
int vmw_ioctl_supports_streams(struct vmw_driver *vmw);
int vmw_ioctl_supports_streams(struct vmw_customizer *vmw);
int vmw_ioctl_num_streams(struct vmw_driver *vmw,
int vmw_ioctl_num_streams(struct vmw_customizer *vmw,
uint32_t *ntot, uint32_t *nfree);
int vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id);
int vmw_ioctl_unref_stream(struct vmw_customizer *vmw, uint32_t stream_id);
int vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out);
int vmw_ioctl_claim_stream(struct vmw_customizer *vmw, uint32_t *out);
#endif

View File

@@ -57,7 +57,7 @@ struct vmw_dma_buffer
};
static int
vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out)
vmw_ioctl_get_param(struct vmw_customizer *vmw, uint32_t param, uint64_t *out)
{
struct drm_vmw_getparam_arg gp_arg;
int ret;
@@ -75,7 +75,7 @@ vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out)
}
int
vmw_ioctl_supports_streams(struct vmw_driver *vmw)
vmw_ioctl_supports_streams(struct vmw_customizer *vmw)
{
uint64_t value;
int ret;
@@ -88,7 +88,7 @@ vmw_ioctl_supports_streams(struct vmw_driver *vmw)
}
int
vmw_ioctl_num_streams(struct vmw_driver *vmw,
vmw_ioctl_num_streams(struct vmw_customizer *vmw,
uint32_t *ntot, uint32_t *nfree)
{
uint64_t v1, v2;
@@ -109,7 +109,7 @@ vmw_ioctl_num_streams(struct vmw_driver *vmw,
}
int
vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out)
vmw_ioctl_claim_stream(struct vmw_customizer *vmw, uint32_t *out)
{
struct drm_vmw_stream_arg s_arg;
int ret;
@@ -125,7 +125,7 @@ vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out)
}
int
vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id)
vmw_ioctl_unref_stream(struct vmw_customizer *vmw, uint32_t stream_id)
{
struct drm_vmw_stream_arg s_arg;
int ret;
@@ -140,7 +140,7 @@ vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id)
}
int
vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot)
vmw_ioctl_cursor_bypass(struct vmw_customizer *vmw, int xhot, int yhot)
{
struct drm_vmw_cursor_bypass_arg arg;
int ret;
@@ -157,7 +157,7 @@ vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot)
}
struct vmw_dma_buffer *
vmw_ioctl_buffer_create(struct vmw_driver *vmw, uint32_t size, unsigned *handle)
vmw_ioctl_buffer_create(struct vmw_customizer *vmw, uint32_t size, unsigned *handle)
{
struct vmw_dma_buffer *buf;
union drm_vmw_alloc_dmabuf_arg arg;
@@ -198,7 +198,7 @@ err:
}
void
vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
vmw_ioctl_buffer_destroy(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
{
struct drm_vmw_unref_dmabuf_arg arg;
@@ -215,7 +215,7 @@ vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
}
void *
vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
vmw_ioctl_buffer_map(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
{
void *map;
@@ -236,7 +236,7 @@ vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
}
void
vmw_ioctl_buffer_unmap(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
vmw_ioctl_buffer_unmap(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
{
--buf->map_count;
}

View File

@@ -32,16 +32,22 @@
#include "vmw_hook.h"
#include "vmw_driver.h"
#include <pipe/p_context.h>
#include "cursorstr.h"
void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
uint32_t throttle_us);
/* modified version of crtc functions */
xf86CrtcFuncsRec vmw_screen_crtc_funcs;
static void
vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image)
{
struct vmw_driver *vmw = modesettingPTR(crtc->scrn)->winsys_priv;
struct vmw_customizer *vmw =
vmw_customizer(xorg_customizer(crtc->scrn));
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
xf86CrtcFuncsPtr funcs = vmw->cursor_priv;
CursorPtr c = config->cursor;
@@ -53,8 +59,9 @@ vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image)
}
static void
vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
vmw_screen_cursor_init(struct vmw_customizer *vmw)
{
ScrnInfoPtr pScrn = vmw->pScrn;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
@@ -70,9 +77,9 @@ vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
}
static void
vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
vmw_screen_cursor_close(struct vmw_customizer *vmw)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(vmw->pScrn);
int i;
vmw_ioctl_cursor_bypass(vmw, 0, 0);
@@ -81,51 +88,81 @@ vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
config->crtc[i]->funcs = vmw->cursor_priv;
}
static Bool
vmw_screen_init(ScrnInfoPtr pScrn)
static void
vmw_context_throttle(CustomizerPtr cust,
struct pipe_context *pipe,
enum xorg_throttling_reason reason)
{
modesettingPtr ms = modesettingPTR(pScrn);
struct vmw_driver *vmw;
switch (reason) {
case THROTTLE_RENDER:
vmw_winsys_screen_set_throttling(pipe->screen, 20000);
break;
default:
vmw_winsys_screen_set_throttling(pipe->screen, 0);
}
}
vmw = xnfcalloc(sizeof(*vmw), 1);
if (!vmw)
return FALSE;
static void
vmw_context_no_throttle(CustomizerPtr cust,
struct pipe_context *pipe,
enum xorg_throttling_reason reason)
{
vmw_winsys_screen_set_throttling(pipe->screen, 0);
}
static Bool
vmw_screen_init(CustomizerPtr cust, int fd)
{
struct vmw_customizer *vmw = vmw_customizer(cust);
drmVersionPtr ver;
vmw->fd = fd;
ver = drmGetVersion(fd);
if (ver == NULL ||
(ver->version_major == 1 && ver->version_minor < 1)) {
cust->swap_throttling = TRUE;
cust->dirty_throttling = TRUE;
cust->winsys_context_throttle = vmw_context_no_throttle;
} else {
cust->swap_throttling = TRUE;
cust->dirty_throttling = FALSE;
cust->winsys_context_throttle = vmw_context_throttle;
debug_printf("%s: Enabling kernel throttling.\n", __func__);
}
if (ver)
drmFreeVersion(ver);
vmw_screen_cursor_init(vmw);
vmw->fd = ms->fd;
ms->winsys_priv = vmw;
vmw_screen_cursor_init(pScrn, vmw);
/* if gallium is used then we don't need to do anything more. */
if (ms->screen)
if (xorg_has_gallium(vmw->pScrn))
return TRUE;
vmw_video_init(pScrn, vmw);
vmw_video_init(vmw);
return TRUE;
}
static Bool
vmw_screen_close(ScrnInfoPtr pScrn)
vmw_screen_close(CustomizerPtr cust)
{
modesettingPtr ms = modesettingPTR(pScrn);
struct vmw_driver *vmw = vmw_driver(pScrn);
struct vmw_customizer *vmw = vmw_customizer(cust);
if (!vmw)
return TRUE;
vmw_screen_cursor_close(pScrn, vmw);
vmw_screen_cursor_close(vmw);
vmw_video_close(pScrn, vmw);
ms->winsys_priv = NULL;
xfree(vmw);
vmw_video_close(vmw);
return TRUE;
}
static Bool
vmw_screen_enter_vt(ScrnInfoPtr pScrn)
vmw_screen_enter_vt(CustomizerPtr cust)
{
debug_printf("%s: enter\n", __func__);
@@ -133,13 +170,13 @@ vmw_screen_enter_vt(ScrnInfoPtr pScrn)
}
static Bool
vmw_screen_leave_vt(ScrnInfoPtr pScrn)
vmw_screen_leave_vt(CustomizerPtr cust)
{
struct vmw_driver *vmw = vmw_driver(pScrn);
struct vmw_customizer *vmw = vmw_customizer(cust);
debug_printf("%s: enter\n", __func__);
vmw_video_stop_all(pScrn, vmw);
vmw_video_stop_all(vmw);
return TRUE;
}
@@ -153,18 +190,27 @@ static Bool (*vmw_screen_pre_init_saved)(ScrnInfoPtr pScrn, int flags) = NULL;
static Bool
vmw_screen_pre_init(ScrnInfoPtr pScrn, int flags)
{
modesettingPtr ms;
struct vmw_customizer *vmw;
CustomizerPtr cust;
vmw = xnfcalloc(1, sizeof(*vmw));
if (!vmw)
return FALSE;
cust = &vmw->base;
cust->winsys_screen_init = vmw_screen_init;
cust->winsys_screen_close = vmw_screen_close;
cust->winsys_enter_vt = vmw_screen_enter_vt;
cust->winsys_leave_vt = vmw_screen_leave_vt;
vmw->pScrn = pScrn;
pScrn->driverPrivate = cust;
pScrn->PreInit = vmw_screen_pre_init_saved;
if (!pScrn->PreInit(pScrn, flags))
return FALSE;
ms = modesettingPTR(pScrn);
ms->winsys_screen_init = vmw_screen_init;
ms->winsys_screen_close = vmw_screen_close;
ms->winsys_enter_vt = vmw_screen_enter_vt;
ms->winsys_leave_vt = vmw_screen_leave_vt;
return TRUE;
}

View File

@@ -226,7 +226,7 @@ static void vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion,
/*
* Local functions.
*/
static XF86VideoAdaptorPtr vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
static XF86VideoAdaptorPtr vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw);
static int vmw_video_port_init(ScrnInfoPtr pScrn,
struct vmw_video_port *port,
@@ -243,9 +243,9 @@ static int vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
short height, RegionPtr clipBoxes);
static void vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port);
static int vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
static int vmw_video_buffer_alloc(struct vmw_customizer *vmw, int size,
struct vmw_video_buffer *out);
static int vmw_video_buffer_free(struct vmw_driver *vmw,
static int vmw_video_buffer_free(struct vmw_customizer *vmw,
struct vmw_video_buffer *out);
@@ -267,8 +267,9 @@ static int vmw_video_buffer_free(struct vmw_driver *vmw,
*/
Bool
vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
vmw_video_init(struct vmw_customizer *vmw)
{
ScrnInfoPtr pScrn = vmw->pScrn;
ScreenPtr pScreen = pScrn->pScreen;
XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
XF86VideoAdaptorPtr newAdaptor = NULL;
@@ -345,8 +346,9 @@ vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
*/
Bool
vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
vmw_video_close(struct vmw_customizer *vmw)
{
ScrnInfoPtr pScrn = vmw->pScrn;
struct vmw_video_private *video;
int i;
@@ -387,8 +389,9 @@ vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
*-----------------------------------------------------------------------------
*/
void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
void vmw_video_stop_all(struct vmw_customizer *vmw)
{
ScrnInfoPtr pScrn = vmw->pScrn;
struct vmw_video_private *video = vmw->video_priv;
int i;
@@ -421,7 +424,7 @@ void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
*/
static XF86VideoAdaptorPtr
vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw)
{
XF86VideoAdaptorPtr adaptor;
struct vmw_video_private *video;
@@ -515,7 +518,7 @@ vmw_video_port_init(ScrnInfoPtr pScrn, struct vmw_video_port *port,
unsigned char *buf, short width,
short height, RegionPtr clipBoxes)
{
struct vmw_driver *vmw = vmw_driver(pScrn);
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
unsigned short w, h;
int i, ret;
@@ -583,7 +586,7 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
unsigned char *buf, short width,
short height, RegionPtr clipBoxes)
{
struct vmw_driver *vmw = vmw_driver(pScrn);
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
struct drm_vmw_control_stream_arg arg;
unsigned short w, h;
int size;
@@ -675,7 +678,7 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
static void
vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port)
{
struct vmw_driver *vmw = vmw_driver(pScrn);
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
uint32 id, colorKey, flags;
Bool isAutoPaintColorkey;
int i;
@@ -721,7 +724,7 @@ vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port)
*/
static int
vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
vmw_video_buffer_alloc(struct vmw_customizer *vmw, int size,
struct vmw_video_buffer *out)
{
out->buf = vmw_ioctl_buffer_create(vmw, size, &out->handle);
@@ -764,7 +767,7 @@ vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
*/
static int
vmw_video_buffer_free(struct vmw_driver *vmw,
vmw_video_buffer_free(struct vmw_customizer *vmw,
struct vmw_video_buffer *out)
{
if (out->size == 0)
@@ -814,7 +817,7 @@ vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
Bool sync, RegionPtr clipBoxes, pointer data,
DrawablePtr dst)
{
struct vmw_driver *vmw = vmw_driver(pScrn);
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
struct vmw_video_port *port = data;
debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__,
@@ -852,7 +855,7 @@ vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
static void
vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
{
struct vmw_driver *vmw = vmw_driver(pScrn);
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
struct vmw_video_port *port = data;
struct drm_vmw_control_stream_arg arg;
int ret;

View File

@@ -33,12 +33,50 @@
#include "vmw_hook.h"
/*
* Defines and modinfo
*/
#define VMWGFX_DRIVER_NAME "vmwgfx"
#define VMW_STRING_INNER(s) #s
#define VMW_STRING(str) VMW_STRING_INNER(str)
#define VMWGFX_VERSION_MAJOR 11
#define VMWGFX_VERSION_MINOR 0
#define VMWGFX_VERSION_PATCH 0
#define VMWGFX_VERSION_STRING_MAJOR VMW_STRING(VMWGFX_VERSION_MAJOR)
#define VMWGFX_VERSION_STRING_MINOR VMW_STRING(VMWGFX_VERSION_MINOR)
#define VMWGFX_VERSION_STRING_PATCH VMW_STRING(VMWGFX_VERSION_PATCH)
#define VMWGFX_DRIVER_VERSION \
(VMWGFX_VERSION_MAJOR * 65536 + VMWGFX_VERSION_MINOR * 256 + VMWGFX_VERSION_PATCH)
#define VMWGFX_DRIVER_VERSION_STRING \
VMWGFX_VERSION_STRING_MAJOR "." VMWGFX_VERSION_STRING_MINOR \
"." VMWGFX_VERSION_STRING_PATCH
/*
* Standard four digit version string expected by VMware Tools installer.
* As the driver's version is only {major, minor, patchlevel}, simply append an
* extra zero for the fourth digit.
*/
#ifdef __GNUC__
_X_EXPORT const char vmwgfx_drv_modinfo[] __attribute__((section(".modinfo"),unused)) =
"version=" VMWGFX_DRIVER_VERSION_STRING ".0";
#endif
static void vmw_xorg_identify(int flags);
_X_EXPORT Bool vmw_xorg_pci_probe(DriverPtr driver,
int entity_num,
struct pci_device *device,
intptr_t match_data);
/*
* Tables
*/
static const struct pci_id_match vmw_xorg_device_match[] = {
{0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
@@ -55,12 +93,12 @@ static PciChipsets vmw_xorg_pci_devices[] = {
};
static XF86ModuleVersionInfo vmw_xorg_version = {
"vmwgfx",
VMWGFX_DRIVER_NAME,
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
0, 1, 0, /* major, minor, patch */
VMWGFX_VERSION_MAJOR, VMWGFX_VERSION_MINOR, VMWGFX_VERSION_PATCH,
ABI_CLASS_VIDEODRV,
ABI_VIDEODRV_VERSION,
MOD_CLASS_VIDEODRV,
@@ -73,7 +111,7 @@ static XF86ModuleVersionInfo vmw_xorg_version = {
_X_EXPORT DriverRec vmwgfx = {
1,
"vmwgfx",
VMWGFX_DRIVER_NAME,
vmw_xorg_identify,
NULL,
xorg_tracker_available_options,
@@ -92,6 +130,7 @@ _X_EXPORT XF86ModuleData vmwgfxModuleData = {
NULL
};
/*
* Xorg driver functions
*/

View File

@@ -267,13 +267,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
if (!stw_init(&stw_winsys)) {
return FALSE;
}
return stw_init_thread();
stw_init(&stw_winsys);
stw_init_thread();
break;
case DLL_THREAD_ATTACH:
return stw_init_thread();
stw_init_thread();
break;
case DLL_THREAD_DETACH:
stw_cleanup_thread();

View File

@@ -317,13 +317,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
if (!stw_init(&stw_winsys)) {
return FALSE;
}
return stw_init_thread();
stw_init(&stw_winsys);
stw_init_thread();
break;
case DLL_THREAD_ATTACH:
return stw_init_thread();
stw_init_thread();
break;
case DLL_THREAD_DETACH:
stw_cleanup_thread();

View File

@@ -437,8 +437,10 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
psc->ext_list_first_time = GL_TRUE;
if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
&driverName, &deviceName))
&driverName, &deviceName)) {
XFree(psp);
return NULL;
}
psc->driver = driOpenDriver(driverName);
if (psc->driver == NULL) {
@@ -467,17 +469,17 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
psc->fd = open(deviceName, O_RDWR);
if (psc->fd < 0) {
ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
return NULL;
goto handle_error;
}
if (drmGetMagic(psc->fd, &magic)) {
ErrorMessageF("failed to get magic\n");
return NULL;
goto handle_error;
}
if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
ErrorMessageF("failed to authenticate magic %d\n", magic);
return NULL;
goto handle_error;
}
/* If the server does not support the protocol for
@@ -491,7 +493,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
if (psc->__driScreen == NULL) {
ErrorMessageF("failed to create dri screen\n");
return NULL;
goto handle_error;
}
driBindExtensions(psc, 1);
@@ -521,6 +523,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
handle_error:
Xfree(driverName);
Xfree(deviceName);
XFree(psp);
/* FIXME: clean up here */

View File

@@ -385,7 +385,8 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig,
req->glxwindow = (GLXWindow) XAllocID(dpy);
req->numAttribs = (CARD32) i;
memcpy(data, attrib_list, 8 * i);
if (attrib_list)
memcpy(data, attrib_list, 8 * i);
UnlockDisplay(dpy);
SyncHandle();

View File

@@ -291,7 +291,8 @@ __glXInitVertexArrayState(__GLXcontext * gc)
arrays->stack_index = 0;
arrays->stack = malloc(sizeof(struct array_stack_state)
* arrays->num_arrays);
* arrays->num_arrays
* __GL_CLIENT_ATTRIB_STACK_DEPTH);
}

View File

@@ -60,14 +60,6 @@ driNewRenderbuffer(gl_format format, GLvoid *addr,
{
driRenderbuffer *drb;
assert(format == GL_RGBA ||
format == GL_RGB5 ||
format == GL_RGBA8 ||
format == GL_DEPTH_COMPONENT16 ||
format == GL_DEPTH_COMPONENT24 ||
format == GL_DEPTH_COMPONENT32 ||
format == GL_STENCIL_INDEX8_EXT);
assert(cpp > 0);
assert(pitch > 0);

View File

@@ -254,7 +254,7 @@ void intel_flush_prim(struct intel_context *intel)
BEGIN_BATCH(5, LOOP_CLIPRECTS);
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
assert((offset & !S0_VB_OFFSET_MASK) == 0);
assert((offset & ~S0_VB_OFFSET_MASK) == 0);
OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, offset);
OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) |
(intel->vertex_size << S1_VERTEX_PITCH_SHIFT));
@@ -273,7 +273,7 @@ void intel_flush_prim(struct intel_context *intel)
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(0) | I1_LOAD_S(2) | 1);
/* S0 */
assert((offset & !S0_VB_OFFSET_MASK_830) == 0);
assert((offset & ~S0_VB_OFFSET_MASK_830) == 0);
OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0,
offset | (intel->vertex_size << S0_VB_PITCH_SHIFT_830) |
S0_VB_ENABLE_830);

View File

@@ -770,7 +770,13 @@ get_constant(struct brw_vs_compile *c,
if (c->current_const[argIndex].index != src->Index || relAddr) {
struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0];
c->current_const[argIndex].index = src->Index;
/* If using a non-relative-addressed constant, then keep track of it for
* later use without reloading.
*/
if (relAddr)
c->current_const[argIndex].index = -1;
else
c->current_const[argIndex].index = src->Index;
#if 0
printf(" fetch const[%d] for arg %d into reg %d\n",

View File

@@ -376,6 +376,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
GLint cx, cy, cw, ch;
drm_clip_rect_t clear;
int i;
drm_intel_bo *aper_array[2];
/* Get clear bounds after locking */
cx = fb->_Xmin;
@@ -526,6 +527,15 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
assert(x1 < x2);
assert(y1 < y2);
/* do space check before going any further */
aper_array[0] = intel->batch->buf;
aper_array[1] = write_buffer;
if (drm_intel_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array)) != 0) {
intel_batchbuffer_flush(intel->batch);
}
BEGIN_BATCH(6, REFERENCES_CLIPRECTS);
OUT_BATCH(CMD);
OUT_BATCH(BR13);

View File

@@ -172,6 +172,8 @@ do_blit_readpixels(GLcontext * ctx,
struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
GLuint dst_offset;
GLuint rowLength;
drm_intel_bo *dst_buffer;
drm_clip_rect_t read_bounds, rect, src_rect;
if (INTEL_DEBUG & DEBUG_PIXEL)
_mesa_printf("%s\n", __FUNCTION__);
@@ -212,58 +214,47 @@ do_blit_readpixels(GLcontext * ctx,
return GL_FALSE;
}
else {
rowLength = -rowLength;
if (ctx->ReadBuffer->Name == 0)
rowLength = -rowLength;
}
dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height,
format, type, 0, 0, 0);
GLboolean all = (width * height * src->cpp == dst->Base.Size &&
x == 0 && dst_offset == 0);
/* Although the blits go on the command buffer, need to do this and
* fire with lock held to guarentee cliprects are correct.
*/
intelFlush(&intel->ctx);
LOCK_HARDWARE(intel);
dst_buffer = intel_bufferobj_buffer(intel, dst,
all ? INTEL_WRITE_FULL :
INTEL_WRITE_PART);
if (intel->driReadDrawable->numClipRects) {
GLboolean all = (width * height * src->cpp == dst->Base.Size &&
x == 0 && dst_offset == 0);
src_rect.x1 = x;
if (ctx->ReadBuffer->Name == 0)
src_rect.y1 = ctx->ReadBuffer->Height - (y + height);
else
src_rect.y1 = y;
src_rect.x2 = src_rect.x1 + width;
src_rect.y2 = src_rect.y1 + height;
dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst,
all ? INTEL_WRITE_FULL :
INTEL_WRITE_PART);
__DRIdrawablePrivate *dPriv = intel->driReadDrawable;
int nbox = dPriv->numClipRects;
drm_clip_rect_t *box = dPriv->pClipRects;
drm_clip_rect_t rect;
drm_clip_rect_t src_rect;
int i;
read_bounds.x1 = 0;
read_bounds.y1 = 0;
read_bounds.x2 = ctx->ReadBuffer->Width;
read_bounds.y2 = ctx->ReadBuffer->Height;
src_rect.x1 = dPriv->x + x;
src_rect.y1 = dPriv->y + dPriv->h - (y + height);
src_rect.x2 = src_rect.x1 + width;
src_rect.y2 = src_rect.y1 + height;
if (!intel_intersect_cliprects(&rect, &src_rect, &read_bounds))
return GL_TRUE;
for (i = 0; i < nbox; i++) {
if (!intel_intersect_cliprects(&rect, &src_rect, &box[i]))
continue;
if (!intelEmitCopyBlit(intel,
src->cpp,
src->pitch, src->buffer, 0, src->tiling,
rowLength, dst_buffer, dst_offset, GL_FALSE,
rect.x1,
rect.y1,
rect.x1 - src_rect.x1,
rect.y2 - src_rect.y2,
rect.x2 - rect.x1, rect.y2 - rect.y1,
GL_COPY)) {
UNLOCK_HARDWARE(intel);
return GL_FALSE;
}
}
if (!intelEmitCopyBlit(intel,
src->cpp,
src->pitch, src->buffer, 0, src->tiling,
rowLength, dst_buffer, dst_offset, GL_FALSE,
rect.x1,
rect.y1,
rect.x1 - src_rect.x1,
rect.y2 - src_rect.y2,
rect.x2 - rect.x1, rect.y2 - rect.y1,
GL_COPY)) {
return GL_FALSE;
}
UNLOCK_HARDWARE(intel);

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