mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-29 09:30:20 +01:00
Merge commit 'origin/gallium-0.2' into gallium-xlib-rework
This commit is contained in:
commit
e37a3aed95
110 changed files with 3106 additions and 4674 deletions
8
Makefile
8
Makefile
|
|
@ -182,10 +182,10 @@ ultrix-gcc:
|
|||
|
||||
# Rules for making release tarballs
|
||||
|
||||
DIRECTORY = Mesa-7.1-rc4
|
||||
LIB_NAME = MesaLib-7.1-rc4
|
||||
DEMO_NAME = MesaDemos-7.1-rc4
|
||||
GLUT_NAME = MesaGLUT-7.1-rc4
|
||||
DIRECTORY = Mesa-7.3-rc1
|
||||
LIB_NAME = MesaLib-7.3-rc1
|
||||
DEMO_NAME = MesaDemos-7.3-rc1
|
||||
GLUT_NAME = MesaGLUT-7.3-rc1
|
||||
|
||||
MAIN_FILES = \
|
||||
$(DIRECTORY)/Makefile* \
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
<H1>Downloading</H1>
|
||||
|
||||
<p>
|
||||
Current development release: <b>7.1</b>
|
||||
Current development release: <b>7.3</b>
|
||||
<br>
|
||||
Last stable release: <b>7.0.4</b>
|
||||
Last stable release: <b>7.2</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ The following are required for DRI-based hardware acceleration with Mesa 7.3:
|
|||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://xorg.freedesktop.org/releases/individual/proto/">driproto2</a> version 1.99.3 or later
|
||||
<li><a href="http://xorg.freedesktop.org/releases/individual/proto/">dri2proto</a> version 1.99.3 or later
|
||||
<li><a href="http://dri.freedesktop.org/libdrm/" target="_parent">DRM</a>
|
||||
version 2.4.3 or later
|
||||
<li>Xorg server version 1.4 or 1.5.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,20 @@
|
|||
<H1>News</H1>
|
||||
|
||||
|
||||
<h2>January TBD, 2009</h2>
|
||||
<p>
|
||||
<a href="relnotes-7.3.html">Mesa 7.3</a> is released.
|
||||
This is a new development release.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>September 20, 2008</h2>
|
||||
<p>
|
||||
<a href="relnotes-7.2.html">Mesa 7.2</a> is released.
|
||||
This is a stable, bug-fix release.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>August 26, 2008</h2>
|
||||
<p>
|
||||
<a href="relnotes-7.1.html">Mesa 7.1</a> is released.
|
||||
|
|
|
|||
104
docs/relnotes-7.2.html
Normal file
104
docs/relnotes-7.2.html
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<HTML>
|
||||
|
||||
<TITLE>Mesa Release Notes</TITLE>
|
||||
|
||||
<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
|
||||
|
||||
<BODY>
|
||||
|
||||
<body bgcolor="#eeeeee">
|
||||
|
||||
<H1>Mesa 7.2 Release Notes / 20 September 2008</H1>
|
||||
|
||||
<p>
|
||||
Mesa 7.2 is a stable release fixing bugs found in 7.1, which was a
|
||||
new development release.
|
||||
</p>
|
||||
<p>
|
||||
Mesa 7.2 implements the OpenGL 2.1 API, but the version reported by
|
||||
glGetString(GL_VERSION) depends on the particular driver being used.
|
||||
Some drivers don't support all the features required in OpenGL 2.1.
|
||||
</p>
|
||||
<p>
|
||||
Note that this version of Mesa does not use the GEM memory manager.
|
||||
The master branch of git uses GEM.
|
||||
The prototype DRI2 code that was in 7.1 has also been removed.
|
||||
</p>
|
||||
<p>
|
||||
DRM version 2.3.1 should be used with Mesa 7.2
|
||||
</p>
|
||||
|
||||
|
||||
<h2>MD5 checksums</h2>
|
||||
<pre>
|
||||
81a2a4b7cbfce7553f7ad8d924edbe2f MesaLib-7.2.tar.gz
|
||||
04d379292e023df0b0266825cb0dbde5 MesaLib-7.2.tar.bz2
|
||||
8bc497a37977a55e987a4d1fabc3d882 MesaLib-7.2.zip
|
||||
10c762e39486df395838af1d7b57e69c MesaDemos-7.2.tar.gz
|
||||
22e03dc4038cd63f32c21eb60994892b MesaDemos-7.2.tar.bz2
|
||||
1197bc4eb3bf44e291c14d4eb2e19381 MesaDemos-7.2.zip
|
||||
42e3c6c6d156cd9dc545dbef72407354 MesaGLUT-7.2.tar.gz
|
||||
f67daf93e12c4a459703bbf3e4004e31 MesaGLUT-7.2.tar.bz2
|
||||
0390567eb2c2d12fbf82e8523fd77e2b MesaGLUT-7.2.zip
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>New features</h2>
|
||||
<ul>
|
||||
<li>i965 driver: added support for G41 chipset (Intel)
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Bug fixes</h2>
|
||||
<ul>
|
||||
<li>Fixed display list bug involving primitives split across lists (bug 17564)
|
||||
<li>Fixed some issues with glBindAttribLocation()
|
||||
<li>Fixed crash in _tnl_InvalidateState() found with Amira (bug 15834)
|
||||
<li>Assorted bug fixes for Ming build
|
||||
<li>Fixed some vertex/pixel buffer object reference counting bugs
|
||||
<li>Fixed depth/stencil bug in i915/945 driver
|
||||
<li>Fixed some shader flow control bugs in i965 driver
|
||||
<li>Fixed a few tdfx driver bugs which prevented driver from working
|
||||
<li>Fixed multisample enable/disable bug
|
||||
</ul>
|
||||
|
||||
<h2>Changes</h2>
|
||||
<ul>
|
||||
<li>Updated SGI header files with new license terms.
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>To Do (someday) items</h2>
|
||||
<ul>
|
||||
<li>Remove the MEMCPY() and _mesa_memcpy() wrappers and just use memcpy().
|
||||
Probably do the same for malloc, calloc, etc.
|
||||
The wrappers were useful in the past for memory debugging but now we
|
||||
have valgrind. Not worried about SunOS 4 support anymore either...
|
||||
<li>Switch to freeglut
|
||||
<li>Fix linux-glide target/driver.
|
||||
<li>Improved lambda and derivative calculation for frag progs.
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Driver Status</h2>
|
||||
|
||||
<pre>
|
||||
Driver Status
|
||||
---------------------- ----------------------
|
||||
DRI drivers varies with the driver
|
||||
XMesa/GLX (on Xlib) implements OpenGL 2.1
|
||||
OSMesa (off-screen) implements OpenGL 2.1
|
||||
Windows/Win32 implements OpenGL 2.1
|
||||
Glide (3dfx Voodoo1/2) implements OpenGL 1.3
|
||||
SVGA unsupported
|
||||
Wind River UGL unsupported
|
||||
DJGPP unsupported
|
||||
GGI unsupported
|
||||
BeOS unsupported
|
||||
Allegro unsupported
|
||||
D3D unsupported
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
74
docs/relnotes-7.3.html
Normal file
74
docs/relnotes-7.3.html
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<HTML>
|
||||
|
||||
<TITLE>Mesa Release Notes</TITLE>
|
||||
|
||||
<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
|
||||
|
||||
<BODY>
|
||||
|
||||
<body bgcolor="#eeeeee">
|
||||
|
||||
<H1>Mesa 7.3 Release Notes / TBD January 2009</H1>
|
||||
|
||||
<p>
|
||||
Mesa 7.3 is a new development release.
|
||||
Users especially concerned with stability should stick with latest
|
||||
stable release: version 7.2.
|
||||
</p>
|
||||
<p>
|
||||
Mesa 7.3 implements the OpenGL 2.1 API, but the version reported by
|
||||
glGetString(GL_VERSION) depends on the particular driver being used.
|
||||
Some drivers don't support all the features required in OpenGL 2.1.
|
||||
</p>
|
||||
<p>
|
||||
<p>
|
||||
DRM version 2.4.3 or later should be used with Mesa 7.3
|
||||
</p>
|
||||
|
||||
|
||||
<h2>MD5 checksums</h2>
|
||||
<pre>
|
||||
tbd
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>New features</h2>
|
||||
<ul>
|
||||
<li>Support for GLSL 1.20
|
||||
<li>Intel DRI drivers now use GEM and DRI2
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Bug fixes</h2>
|
||||
<ul>
|
||||
<li>Assorted GLSL bug fixes
|
||||
<li>Assorted i965 driver fixes
|
||||
</ul>
|
||||
|
||||
<h2>Changes</h2>
|
||||
<ul>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>Driver Status</h2>
|
||||
|
||||
<pre>
|
||||
Driver Status
|
||||
---------------------- ----------------------
|
||||
DRI drivers varies with the driver
|
||||
XMesa/GLX (on Xlib) implements OpenGL 2.1
|
||||
OSMesa (off-screen) implements OpenGL 2.1
|
||||
Windows/Win32 implements OpenGL 2.1
|
||||
Glide (3dfx Voodoo1/2) implements OpenGL 1.3
|
||||
SVGA unsupported
|
||||
Wind River UGL unsupported
|
||||
DJGPP unsupported
|
||||
GGI unsupported
|
||||
BeOS unsupported
|
||||
Allegro unsupported
|
||||
D3D unsupported
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -20,6 +20,8 @@ The release notes summarize what's new or changed in each Mesa release.
|
|||
</p>
|
||||
|
||||
<UL>
|
||||
<LI><A HREF="relnotes-7.3.html">7.3 release notes</A>
|
||||
<LI><A HREF="relnotes-7.2.html">7.2 release notes</A>
|
||||
<LI><A HREF="relnotes-7.1.html">7.1 release notes</A>
|
||||
<LI><A HREF="relnotes-7.0.4.html">7.0.4 release notes</A>
|
||||
<LI><A HREF="relnotes-7.0.3.html">7.0.3 release notes</A>
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ extern "C" {
|
|||
/*************************************************************/
|
||||
|
||||
/* Header file version number, required by OpenGL ABI for Linux */
|
||||
/* glext.h last updated 2008/10/09 */
|
||||
/* glext.h last updated 2008/11/14 */
|
||||
/* Current version at http://www.opengl.org/registry/ */
|
||||
#define GL_GLEXT_VERSION 43
|
||||
#define GL_GLEXT_VERSION 44
|
||||
|
||||
#ifndef GL_VERSION_1_2
|
||||
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
|
||||
|
|
@ -3834,6 +3834,34 @@ extern "C" {
|
|||
/* reuse GL_BGRA */
|
||||
#endif
|
||||
|
||||
#ifndef GL_EXT_texture_swizzle
|
||||
#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42
|
||||
#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43
|
||||
#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44
|
||||
#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45
|
||||
#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46
|
||||
#endif
|
||||
|
||||
#ifndef GL_NV_explicit_multisample
|
||||
#define GL_SAMPLE_POSITION_NV 0x8E50
|
||||
#define GL_SAMPLE_MASK_NV 0x8E51
|
||||
#define GL_SAMPLE_MASK_VALUE_NV 0x8E52
|
||||
#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
|
||||
#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
|
||||
#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
|
||||
#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55
|
||||
#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56
|
||||
#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
|
||||
#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
|
||||
#endif
|
||||
|
||||
#ifndef GL_NV_transform_feedback2
|
||||
#define GL_TRANSFORM_FEEDBACK_NV 0x8E22
|
||||
#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
|
||||
#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
|
||||
#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
|
|
@ -8387,6 +8415,42 @@ typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenu
|
|||
#define GL_EXT_vertex_array_bgra 1
|
||||
#endif
|
||||
|
||||
#ifndef GL_EXT_texture_swizzle
|
||||
#define GL_EXT_texture_swizzle 1
|
||||
#endif
|
||||
|
||||
#ifndef GL_NV_explicit_multisample
|
||||
#define GL_NV_explicit_multisample 1
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glGetMultisamplefvNV (GLenum, GLuint, GLfloat *);
|
||||
GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint, GLbitfield);
|
||||
GLAPI void APIENTRY glTexRenderbufferNV (GLenum, GLuint);
|
||||
#endif /* GL_GLEXT_PROTOTYPES */
|
||||
typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val);
|
||||
typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask);
|
||||
typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer);
|
||||
#endif
|
||||
|
||||
#ifndef GL_NV_transform_feedback2
|
||||
#define GL_NV_transform_feedback2 1
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum, GLuint);
|
||||
GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei, const GLuint *);
|
||||
GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei, GLuint *);
|
||||
GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint);
|
||||
GLAPI void APIENTRY glPauseTransformFeedbackNV (void);
|
||||
GLAPI void APIENTRY glResumeTransformFeedbackNV (void);
|
||||
GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum, GLuint);
|
||||
#endif /* GL_GLEXT_PROTOTYPES */
|
||||
typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id);
|
||||
typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids);
|
||||
typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids);
|
||||
typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id);
|
||||
typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void);
|
||||
typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
|
||||
typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,14 @@ extern "C" {
|
|||
#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
|
||||
#endif
|
||||
|
||||
#ifndef GLX_ARB_create_context
|
||||
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
|
||||
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define GLX_CONTEXT_FLAGS_ARB 0x2094
|
||||
#endif
|
||||
|
||||
#ifndef GLX_SGIS_multisample
|
||||
#define GLX_SAMPLE_BUFFERS_SGIS 100000
|
||||
#define GLX_SAMPLES_SGIS 100001
|
||||
|
|
@ -366,14 +374,6 @@ extern "C" {
|
|||
#ifndef GLX_NV_swap_group
|
||||
#endif
|
||||
|
||||
#ifndef GLX_ARB_create_context
|
||||
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
|
||||
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define GLX_CONTEXT_FLAGS_ARB 0x2094
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
|
|
@ -510,6 +510,14 @@ typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procNam
|
|||
#define GLX_ARB_fbconfig_float 1
|
||||
#endif
|
||||
|
||||
#ifndef GLX_ARB_create_context
|
||||
#define GLX_ARB_create_context 1
|
||||
#ifdef GLX_GLXEXT_PROTOTYPES
|
||||
extern GLXContext glXCreateContextAttribsARB (Display *, GLXFBConfig, GLXContext, Bool, const int *);
|
||||
#endif /* GLX_GLXEXT_PROTOTYPES */
|
||||
typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
|
||||
#endif
|
||||
|
||||
#ifndef GLX_SGIS_multisample
|
||||
#define GLX_SGIS_multisample 1
|
||||
#endif
|
||||
|
|
@ -817,14 +825,6 @@ typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawab
|
|||
#define GLX_NV_swap_group 1
|
||||
#endif
|
||||
|
||||
#ifndef GLX_ARB_create_context
|
||||
#define GLX_ARB_create_context 1
|
||||
#ifdef GLX_GLXEXT_PROTOTYPES
|
||||
extern GLXContext glXCreateContextAttribsARB (Display *, GLXFBConfig, GLXContext, Bool, const int *);
|
||||
#endif /* GLX_GLXEXT_PROTOTYPES */
|
||||
typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
1
progs/glsl/.gitignore
vendored
1
progs/glsl/.gitignore
vendored
|
|
@ -14,6 +14,7 @@ pointcoord
|
|||
points
|
||||
readtex.c
|
||||
readtex.h
|
||||
samplers
|
||||
shaderutil.c
|
||||
shaderutil.h
|
||||
skinning
|
||||
|
|
|
|||
|
|
@ -111,8 +111,23 @@ free_screen:
|
|||
|
||||
int driDestroyScreen(dri_screen_t *dri_screen)
|
||||
{
|
||||
Drawable draw;
|
||||
dri_drawable_t *dri_draw;
|
||||
|
||||
assert(dri_screen);
|
||||
|
||||
if (drmHashFirst(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
|
||||
{
|
||||
dri_draw->refcount = 1;
|
||||
driDestroyDrawable(dri_draw);
|
||||
|
||||
while (drmHashNext(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
|
||||
{
|
||||
dri_draw->refcount = 1;
|
||||
driDestroyDrawable(dri_draw);
|
||||
}
|
||||
}
|
||||
|
||||
drmHashDestroy(dri_screen->drawable_hash);
|
||||
drmUnmap(dri_screen->sarea, SAREA_MAX);
|
||||
drmCloseOnce(dri_screen->fd);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#define DRAW_VBUF_H_
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
|
||||
struct pipe_rasterizer_state;
|
||||
struct draw_context;
|
||||
|
|
|
|||
|
|
@ -199,6 +199,11 @@ draw_create_vs_ppc(struct draw_context *draw,
|
|||
|
||||
ppc_init_func( &vs->ppc_program );
|
||||
|
||||
#if 0
|
||||
ppc_print_code(&vs->ppc_program, TRUE);
|
||||
ppc_indent(&vs->ppc_program, 8);
|
||||
#endif
|
||||
|
||||
if (!tgsi_emit_ppc( (struct tgsi_token *) vs->base.state.tokens,
|
||||
&vs->ppc_program,
|
||||
(float (*)[4]) vs->base.immediates,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008 Tungsten Graphics, Inc. All Rights Reserved.
|
||||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -47,6 +48,8 @@ ppc_init_func(struct ppc_function *p)
|
|||
{
|
||||
uint i;
|
||||
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
||||
p->num_inst = 0;
|
||||
p->max_inst = 100; /* first guess at buffer size */
|
||||
p->store = rtasm_exec_malloc(p->max_inst * PPC_INST_SIZE);
|
||||
|
|
@ -54,6 +57,9 @@ ppc_init_func(struct ppc_function *p)
|
|||
p->fp_used = 0x0;
|
||||
p->vec_used = 0x0;
|
||||
|
||||
p->print = FALSE;
|
||||
p->indent = 0;
|
||||
|
||||
/* only allow using gp registers 3..12 for now */
|
||||
for (i = 0; i < 3; i++)
|
||||
ppc_reserve_register(p, i);
|
||||
|
|
@ -105,6 +111,42 @@ ppc_dump_func(const struct ppc_function *p)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
ppc_print_code(struct ppc_function *p, boolean enable)
|
||||
{
|
||||
p->print = enable;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ppc_indent(struct ppc_function *p, int spaces)
|
||||
{
|
||||
p->indent += spaces;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
indent(const struct ppc_function *p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < p->indent; i++) {
|
||||
putchar(' ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ppc_comment(struct ppc_function *p, int rel_indent, const char *s)
|
||||
{
|
||||
if (p->print) {
|
||||
p->indent += rel_indent;
|
||||
indent(p);
|
||||
p->indent -= rel_indent;
|
||||
printf("# %s\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mark a register as being unavailable.
|
||||
*/
|
||||
|
|
@ -132,6 +174,7 @@ ppc_allocate_register(struct ppc_function *p)
|
|||
return i;
|
||||
}
|
||||
}
|
||||
printf("OUT OF PPC registers!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -163,6 +206,7 @@ ppc_allocate_fp_register(struct ppc_function *p)
|
|||
return i;
|
||||
}
|
||||
}
|
||||
printf("OUT OF PPC FP registers!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -194,6 +238,7 @@ ppc_allocate_vec_register(struct ppc_function *p)
|
|||
return i;
|
||||
}
|
||||
}
|
||||
printf("OUT OF PPC VEC registers!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +297,8 @@ union vx_inst {
|
|||
};
|
||||
|
||||
static INLINE void
|
||||
emit_vx(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB)
|
||||
emit_vx(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB,
|
||||
const char *format, boolean transpose)
|
||||
{
|
||||
union vx_inst inst;
|
||||
inst.inst.op = 4;
|
||||
|
|
@ -261,6 +307,13 @@ emit_vx(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB)
|
|||
inst.inst.vB = vB;
|
||||
inst.inst.op2 = op2;
|
||||
emit_instruction(p, inst.bits);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
if (transpose)
|
||||
printf(format, vD, vB, vA);
|
||||
else
|
||||
printf(format, vD, vA, vB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -277,7 +330,8 @@ union vxr_inst {
|
|||
};
|
||||
|
||||
static INLINE void
|
||||
emit_vxr(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB)
|
||||
emit_vxr(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB,
|
||||
const char *format)
|
||||
{
|
||||
union vxr_inst inst;
|
||||
inst.inst.op = 4;
|
||||
|
|
@ -287,6 +341,10 @@ emit_vxr(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB)
|
|||
inst.inst.rC = 0;
|
||||
inst.inst.op2 = op2;
|
||||
emit_instruction(p, inst.bits);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
printf(format, vD, vA, vB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -303,7 +361,8 @@ union va_inst {
|
|||
};
|
||||
|
||||
static INLINE void
|
||||
emit_va(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB, uint vC)
|
||||
emit_va(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB, uint vC,
|
||||
const char *format)
|
||||
{
|
||||
union va_inst inst;
|
||||
inst.inst.op = 4;
|
||||
|
|
@ -313,6 +372,10 @@ emit_va(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB, uint vC)
|
|||
inst.inst.vC = vC;
|
||||
inst.inst.op2 = op2;
|
||||
emit_instruction(p, inst.bits);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
printf(format, vD, vA, vB, vC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -396,7 +459,8 @@ union x_inst {
|
|||
};
|
||||
|
||||
static INLINE void
|
||||
emit_x(struct ppc_function *p, uint op, uint vrs, uint ra, uint rb, uint op2)
|
||||
emit_x(struct ppc_function *p, uint op, uint vrs, uint ra, uint rb, uint op2,
|
||||
const char *format)
|
||||
{
|
||||
union x_inst inst;
|
||||
inst.inst.op = op;
|
||||
|
|
@ -406,6 +470,10 @@ emit_x(struct ppc_function *p, uint op, uint vrs, uint ra, uint rb, uint op2)
|
|||
inst.inst.op2 = op2;
|
||||
inst.inst.unused = 0x0;
|
||||
emit_instruction(p, inst.bits);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
printf(format, vrs, ra, rb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -420,7 +488,8 @@ union d_inst {
|
|||
};
|
||||
|
||||
static INLINE void
|
||||
emit_d(struct ppc_function *p, uint op, uint rt, uint ra, int si)
|
||||
emit_d(struct ppc_function *p, uint op, uint rt, uint ra, int si,
|
||||
const char *format, boolean transpose)
|
||||
{
|
||||
union d_inst inst;
|
||||
assert(si >= -32768);
|
||||
|
|
@ -430,6 +499,13 @@ emit_d(struct ppc_function *p, uint op, uint rt, uint ra, int si)
|
|||
inst.inst.ra = ra;
|
||||
inst.inst.si = (unsigned) (si & 0xffff);
|
||||
emit_instruction(p, inst.bits);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
if (transpose)
|
||||
printf(format, rt, si, ra);
|
||||
else
|
||||
printf(format, rt, ra, si);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -448,7 +524,7 @@ union a_inst {
|
|||
|
||||
static INLINE void
|
||||
emit_a(struct ppc_function *p, uint op, uint frt, uint fra, uint frb, uint op2,
|
||||
uint rc)
|
||||
uint rc, const char *format)
|
||||
{
|
||||
union a_inst inst;
|
||||
inst.inst.op = op;
|
||||
|
|
@ -459,6 +535,10 @@ emit_a(struct ppc_function *p, uint op, uint frt, uint fra, uint frb, uint op2,
|
|||
inst.inst.op2 = op2;
|
||||
inst.inst.rc = rc;
|
||||
emit_instruction(p, inst.bits);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
printf(format, frt, fra, frb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -477,7 +557,7 @@ union xo_inst {
|
|||
|
||||
static INLINE void
|
||||
emit_xo(struct ppc_function *p, uint op, uint rt, uint ra, uint rb, uint oe,
|
||||
uint op2, uint rc)
|
||||
uint op2, uint rc, const char *format)
|
||||
{
|
||||
union xo_inst inst;
|
||||
inst.inst.op = op;
|
||||
|
|
@ -488,6 +568,10 @@ emit_xo(struct ppc_function *p, uint op, uint rt, uint ra, uint rb, uint oe,
|
|||
inst.inst.op2 = op2;
|
||||
inst.inst.rc = rc;
|
||||
emit_instruction(p, inst.bits);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
printf(format, rt, ra, rb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -502,140 +586,142 @@ emit_xo(struct ppc_function *p, uint op, uint rt, uint ra, uint rb, uint oe,
|
|||
void
|
||||
ppc_vaddfp(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 10, vD, vA, vB);
|
||||
emit_vx(p, 10, vD, vA, vB, "vaddfp\t%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float substract */
|
||||
void
|
||||
ppc_vsubfp(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 74, vD, vA, vB);
|
||||
emit_vx(p, 74, vD, vA, vB, "vsubfp\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float min */
|
||||
void
|
||||
ppc_vminfp(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 1098, vD, vA, vB);
|
||||
emit_vx(p, 1098, vD, vA, vB, "vminfp\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float max */
|
||||
void
|
||||
ppc_vmaxfp(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 1034, vD, vA, vB);
|
||||
emit_vx(p, 1034, vD, vA, vB, "vmaxfp\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float mult add: vD = vA * vB + vC */
|
||||
void
|
||||
ppc_vmaddfp(struct ppc_function *p, uint vD, uint vA, uint vB, uint vC)
|
||||
{
|
||||
emit_va(p, 46, vD, vA, vC, vB); /* note arg order */
|
||||
/* note arg order */
|
||||
emit_va(p, 46, vD, vA, vC, vB, "vmaddfp\tv%u, v%u, v%u, v%u\n");
|
||||
}
|
||||
|
||||
/** vector float negative mult subtract: vD = vA - vB * vC */
|
||||
void
|
||||
ppc_vnmsubfp(struct ppc_function *p, uint vD, uint vA, uint vB, uint vC)
|
||||
{
|
||||
emit_va(p, 47, vD, vB, vA, vC); /* note arg order */
|
||||
/* note arg order */
|
||||
emit_va(p, 47, vD, vB, vA, vC, "vnmsubfp\tv%u, v%u, v%u, v%u\n");
|
||||
}
|
||||
|
||||
/** vector float compare greater than */
|
||||
void
|
||||
ppc_vcmpgtfpx(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vxr(p, 710, vD, vA, vB);
|
||||
emit_vxr(p, 710, vD, vA, vB, "vcmpgtfpx\tv%u, v%u, v%u");
|
||||
}
|
||||
|
||||
/** vector float compare greater than or equal to */
|
||||
void
|
||||
ppc_vcmpgefpx(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vxr(p, 454, vD, vA, vB);
|
||||
emit_vxr(p, 454, vD, vA, vB, "vcmpgefpx\tv%u, v%u, v%u");
|
||||
}
|
||||
|
||||
/** vector float compare equal */
|
||||
void
|
||||
ppc_vcmpeqfpx(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vxr(p, 198, vD, vA, vB);
|
||||
emit_vxr(p, 198, vD, vA, vB, "vcmpeqfpx\tv%u, v%u, v%u");
|
||||
}
|
||||
|
||||
/** vector float 2^x */
|
||||
void
|
||||
ppc_vexptefp(struct ppc_function *p, uint vD, uint vB)
|
||||
{
|
||||
emit_vx(p, 394, vD, 0, vB);
|
||||
emit_vx(p, 394, vD, 0, vB, "vexptefp\tv%u, 0%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float log2(x) */
|
||||
void
|
||||
ppc_vlogefp(struct ppc_function *p, uint vD, uint vB)
|
||||
{
|
||||
emit_vx(p, 458, vD, 0, vB);
|
||||
emit_vx(p, 458, vD, 0, vB, "vlogefp\tv%u, 0%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float reciprocol */
|
||||
void
|
||||
ppc_vrefp(struct ppc_function *p, uint vD, uint vB)
|
||||
{
|
||||
emit_vx(p, 266, vD, 0, vB);
|
||||
emit_vx(p, 266, vD, 0, vB, "vrefp\tv%u, 0%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float reciprocol sqrt estimate */
|
||||
void
|
||||
ppc_vrsqrtefp(struct ppc_function *p, uint vD, uint vB)
|
||||
{
|
||||
emit_vx(p, 330, vD, 0, vB);
|
||||
emit_vx(p, 330, vD, 0, vB, "vrsqrtefp\tv%u, 0%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float round to negative infinity */
|
||||
void
|
||||
ppc_vrfim(struct ppc_function *p, uint vD, uint vB)
|
||||
{
|
||||
emit_vx(p, 714, vD, 0, vB);
|
||||
emit_vx(p, 714, vD, 0, vB, "vrfim\tv%u, 0%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float round to positive infinity */
|
||||
void
|
||||
ppc_vrfip(struct ppc_function *p, uint vD, uint vB)
|
||||
{
|
||||
emit_vx(p, 650, vD, 0, vB);
|
||||
emit_vx(p, 650, vD, 0, vB, "vrfip\tv%u, 0%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float round to nearest int */
|
||||
void
|
||||
ppc_vrfin(struct ppc_function *p, uint vD, uint vB)
|
||||
{
|
||||
emit_vx(p, 522, vD, 0, vB);
|
||||
emit_vx(p, 522, vD, 0, vB, "vrfin\tv%u, 0%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector float round to int toward zero */
|
||||
void
|
||||
ppc_vrfiz(struct ppc_function *p, uint vD, uint vB)
|
||||
{
|
||||
emit_vx(p, 586, vD, 0, vB);
|
||||
emit_vx(p, 586, vD, 0, vB, "vrfiz\tv%u, 0%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector store: store vR at mem[vA+vB] */
|
||||
/** vector store: store vR at mem[rA+rB] */
|
||||
void
|
||||
ppc_stvx(struct ppc_function *p, uint vR, uint vA, uint vB)
|
||||
ppc_stvx(struct ppc_function *p, uint vR, uint rA, uint rB)
|
||||
{
|
||||
emit_x(p, 31, vR, vA, vB, 231);
|
||||
emit_x(p, 31, vR, rA, rB, 231, "stvx\tv%u, r%u, r%u\n");
|
||||
}
|
||||
|
||||
/** vector load: vR = mem[vA+vB] */
|
||||
/** vector load: vR = mem[rA+rB] */
|
||||
void
|
||||
ppc_lvx(struct ppc_function *p, uint vR, uint vA, uint vB)
|
||||
ppc_lvx(struct ppc_function *p, uint vR, uint rA, uint rB)
|
||||
{
|
||||
emit_x(p, 31, vR, vA, vB, 103);
|
||||
emit_x(p, 31, vR, rA, rB, 103, "lvx\tv%u, r%u, r%u\n");
|
||||
}
|
||||
|
||||
/** load vector element word: vR = mem_word[ra+rb] */
|
||||
void
|
||||
ppc_lvewx(struct ppc_function *p, uint vr, uint ra, uint rb)
|
||||
ppc_lvewx(struct ppc_function *p, uint vR, uint rA, uint rB)
|
||||
{
|
||||
emit_x(p, 31, vr, ra, rb, 71);
|
||||
emit_x(p, 31, vR, rA, rB, 71, "lvewx\tv%u, r%u, r%u\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -649,49 +735,63 @@ ppc_lvewx(struct ppc_function *p, uint vr, uint ra, uint rb)
|
|||
void
|
||||
ppc_vand(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 1028, vD, vA, vB);
|
||||
emit_vx(p, 1028, vD, vA, vB, "vand\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector and complement */
|
||||
void
|
||||
ppc_vandc(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 1092, vD, vA, vB);
|
||||
emit_vx(p, 1092, vD, vA, vB, "vandc\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector or */
|
||||
void
|
||||
ppc_vor(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 1156, vD, vA, vB);
|
||||
emit_vx(p, 1156, vD, vA, vB, "vor\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector nor */
|
||||
void
|
||||
ppc_vnor(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 1284, vD, vA, vB);
|
||||
emit_vx(p, 1284, vD, vA, vB, "vnor\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector xor */
|
||||
void
|
||||
ppc_vxor(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 1220, vD, vA, vB);
|
||||
emit_vx(p, 1220, vD, vA, vB, "vxor\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
/** Pseudo-instruction: vector move */
|
||||
void
|
||||
ppc_vmove(struct ppc_function *p, uint vD, uint vA)
|
||||
{
|
||||
boolean print = p->print;
|
||||
p->print = FALSE;
|
||||
ppc_vor(p, vD, vA, vA);
|
||||
if (print) {
|
||||
indent(p);
|
||||
printf("vor\tv%u, v%u, v%u \t# v%u = v%u\n", vD, vA, vA, vD, vA);
|
||||
}
|
||||
p->print = print;
|
||||
}
|
||||
|
||||
/** Set vector register to {0,0,0,0} */
|
||||
void
|
||||
ppc_vzero(struct ppc_function *p, uint vr)
|
||||
{
|
||||
boolean print = p->print;
|
||||
p->print = FALSE;
|
||||
ppc_vxor(p, vr, vr, vr);
|
||||
if (print) {
|
||||
indent(p);
|
||||
printf("vxor\tv%u, v%u, v%u \t# v%u = {0,0,0,0}\n", vr, vr, vr, vr);
|
||||
}
|
||||
p->print = print;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -705,35 +805,35 @@ ppc_vzero(struct ppc_function *p, uint vr)
|
|||
void
|
||||
ppc_vperm(struct ppc_function *p, uint vD, uint vA, uint vB, uint vC)
|
||||
{
|
||||
emit_va(p, 43, vD, vA, vB, vC);
|
||||
emit_va(p, 43, vD, vA, vB, vC, "vperm\tr%u, r%u, r%u, r%u");
|
||||
}
|
||||
|
||||
/** vector select */
|
||||
void
|
||||
ppc_vsel(struct ppc_function *p, uint vD, uint vA, uint vB, uint vC)
|
||||
{
|
||||
emit_va(p, 42, vD, vA, vB, vC);
|
||||
emit_va(p, 42, vD, vA, vB, vC, "vsel\tr%u, r%u, r%u, r%u");
|
||||
}
|
||||
|
||||
/** vector splat byte */
|
||||
void
|
||||
ppc_vspltb(struct ppc_function *p, uint vD, uint vB, uint imm)
|
||||
{
|
||||
emit_vx(p, 42, vD, imm, vB);
|
||||
emit_vx(p, 42, vD, imm, vB, "vspltb\tv%u, v%u, %u\n", TRUE);
|
||||
}
|
||||
|
||||
/** vector splat half word */
|
||||
void
|
||||
ppc_vsplthw(struct ppc_function *p, uint vD, uint vB, uint imm)
|
||||
{
|
||||
emit_vx(p, 588, vD, imm, vB);
|
||||
emit_vx(p, 588, vD, imm, vB, "vsplthw\tv%u, v%u, %u\n", TRUE);
|
||||
}
|
||||
|
||||
/** vector splat word */
|
||||
void
|
||||
ppc_vspltw(struct ppc_function *p, uint vD, uint vB, uint imm)
|
||||
{
|
||||
emit_vx(p, 652, vD, imm, vB);
|
||||
emit_vx(p, 652, vD, imm, vB, "vspltw\tv%u, v%u, %u\n", TRUE);
|
||||
}
|
||||
|
||||
/** vector splat signed immediate word */
|
||||
|
|
@ -742,14 +842,14 @@ ppc_vspltisw(struct ppc_function *p, uint vD, int imm)
|
|||
{
|
||||
assert(imm >= -16);
|
||||
assert(imm < 15);
|
||||
emit_vx(p, 908, vD, imm, 0);
|
||||
emit_vx(p, 908, vD, imm, 0, "vspltisw\tv%u, %d, %u\n", FALSE);
|
||||
}
|
||||
|
||||
/** vector shift left word: vD[word] = vA[word] << (vB[word] & 0x1f) */
|
||||
void
|
||||
ppc_vslw(struct ppc_function *p, uint vD, uint vA, uint vB)
|
||||
{
|
||||
emit_vx(p, 388, vD, vA, vB);
|
||||
emit_vx(p, 388, vD, vA, vB, "vslw\tv%u, v%u, v%u\n", FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -763,63 +863,66 @@ ppc_vslw(struct ppc_function *p, uint vD, uint vA, uint vB)
|
|||
void
|
||||
ppc_addi(struct ppc_function *p, uint rt, uint ra, int imm)
|
||||
{
|
||||
emit_d(p, 14, rt, ra, imm);
|
||||
emit_d(p, 14, rt, ra, imm, "addi\tr%u, r%u, %d\n", FALSE);
|
||||
}
|
||||
|
||||
/** rt = ra + (imm << 16) */
|
||||
void
|
||||
ppc_addis(struct ppc_function *p, uint rt, uint ra, int imm)
|
||||
{
|
||||
emit_d(p, 15, rt, ra, imm);
|
||||
emit_d(p, 15, rt, ra, imm, "addis\tr%u, r%u, %d\n", FALSE);
|
||||
}
|
||||
|
||||
/** rt = ra + rb */
|
||||
void
|
||||
ppc_add(struct ppc_function *p, uint rt, uint ra, uint rb)
|
||||
{
|
||||
emit_xo(p, 31, rt, ra, rb, 0, 266, 0);
|
||||
emit_xo(p, 31, rt, ra, rb, 0, 266, 0, "add\tr%u, r%u, r%u\n");
|
||||
}
|
||||
|
||||
/** rt = ra AND ra */
|
||||
void
|
||||
ppc_and(struct ppc_function *p, uint rt, uint ra, uint rb)
|
||||
{
|
||||
emit_x(p, 31, ra, rt, rb, 28); /* note argument order */
|
||||
emit_x(p, 31, ra, rt, rb, 28, "and\tr%u, r%u, r%u\n"); /* note argument order */
|
||||
}
|
||||
|
||||
/** rt = ra AND imm */
|
||||
void
|
||||
ppc_andi(struct ppc_function *p, uint rt, uint ra, int imm)
|
||||
{
|
||||
emit_d(p, 28, ra, rt, imm); /* note argument order */
|
||||
/* note argument order */
|
||||
emit_d(p, 28, ra, rt, imm, "andi\tr%u, r%u, %d\n", FALSE);
|
||||
}
|
||||
|
||||
/** rt = ra OR ra */
|
||||
void
|
||||
ppc_or(struct ppc_function *p, uint rt, uint ra, uint rb)
|
||||
{
|
||||
emit_x(p, 31, ra, rt, rb, 444); /* note argument order */
|
||||
emit_x(p, 31, ra, rt, rb, 444, "or\tr%u, r%u, r%u\n"); /* note argument order */
|
||||
}
|
||||
|
||||
/** rt = ra OR imm */
|
||||
void
|
||||
ppc_ori(struct ppc_function *p, uint rt, uint ra, int imm)
|
||||
{
|
||||
emit_d(p, 24, ra, rt, imm); /* note argument order */
|
||||
/* note argument order */
|
||||
emit_d(p, 24, ra, rt, imm, "ori\tr%u, r%u, %d\n", FALSE);
|
||||
}
|
||||
|
||||
/** rt = ra XOR ra */
|
||||
void
|
||||
ppc_xor(struct ppc_function *p, uint rt, uint ra, uint rb)
|
||||
{
|
||||
emit_x(p, 31, ra, rt, rb, 316); /* note argument order */
|
||||
emit_x(p, 31, ra, rt, rb, 316, "xor\tr%u, r%u, r%u\n"); /* note argument order */
|
||||
}
|
||||
|
||||
/** rt = ra XOR imm */
|
||||
void
|
||||
ppc_xori(struct ppc_function *p, uint rt, uint ra, int imm)
|
||||
{
|
||||
emit_d(p, 26, ra, rt, imm); /* note argument order */
|
||||
/* note argument order */
|
||||
emit_d(p, 26, ra, rt, imm, "xori\tr%u, r%u, %d\n", FALSE);
|
||||
}
|
||||
|
||||
/** pseudo instruction: move: rt = ra */
|
||||
|
|
@ -833,7 +936,14 @@ ppc_mr(struct ppc_function *p, uint rt, uint ra)
|
|||
void
|
||||
ppc_li(struct ppc_function *p, uint rt, int imm)
|
||||
{
|
||||
boolean print = p->print;
|
||||
p->print = FALSE;
|
||||
ppc_addi(p, rt, 0, imm);
|
||||
if (print) {
|
||||
indent(p);
|
||||
printf("addi\tr%u, r0, %d \t# r%u = %d\n", rt, imm, rt, imm);
|
||||
}
|
||||
p->print = print;
|
||||
}
|
||||
|
||||
/** rt = imm << 16 */
|
||||
|
|
@ -864,21 +974,21 @@ ppc_load_int(struct ppc_function *p, uint rt, int imm)
|
|||
void
|
||||
ppc_stwu(struct ppc_function *p, uint rs, uint ra, int d)
|
||||
{
|
||||
emit_d(p, 37, rs, ra, d);
|
||||
emit_d(p, 37, rs, ra, d, "stwu\tr%u, %d(r%u)\n", TRUE);
|
||||
}
|
||||
|
||||
/** store rs at memory[(ra)+d] */
|
||||
void
|
||||
ppc_stw(struct ppc_function *p, uint rs, uint ra, int d)
|
||||
{
|
||||
emit_d(p, 36, rs, ra, d);
|
||||
emit_d(p, 36, rs, ra, d, "stw\tr%u, %d(r%u)\n", TRUE);
|
||||
}
|
||||
|
||||
/** Load rt = mem[(ra)+d]; then zero set high 32 bits to zero. */
|
||||
void
|
||||
ppc_lwz(struct ppc_function *p, uint rt, uint ra, int d)
|
||||
{
|
||||
emit_d(p, 32, rt, ra, d);
|
||||
emit_d(p, 32, rt, ra, d, "lwz\tr%u, %d(r%u)\n", TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -891,42 +1001,42 @@ ppc_lwz(struct ppc_function *p, uint rt, uint ra, int d)
|
|||
void
|
||||
ppc_fadd(struct ppc_function *p, uint frt, uint fra, uint frb)
|
||||
{
|
||||
emit_a(p, 63, frt, fra, frb, 21, 0);
|
||||
emit_a(p, 63, frt, fra, frb, 21, 0, "fadd\tf%u, f%u, f%u\n");
|
||||
}
|
||||
|
||||
/** sub: frt = fra - frb */
|
||||
void
|
||||
ppc_fsub(struct ppc_function *p, uint frt, uint fra, uint frb)
|
||||
{
|
||||
emit_a(p, 63, frt, fra, frb, 20, 0);
|
||||
emit_a(p, 63, frt, fra, frb, 20, 0, "fsub\tf%u, f%u, f%u\n");
|
||||
}
|
||||
|
||||
/** convert to int: rt = (int) ra */
|
||||
void
|
||||
ppc_fctiwz(struct ppc_function *p, uint rt, uint fra)
|
||||
{
|
||||
emit_x(p, 63, rt, 0, fra, 15);
|
||||
emit_x(p, 63, rt, 0, fra, 15, "fctiwz\tr%u, r%u, r%u\n");
|
||||
}
|
||||
|
||||
/** store frs at mem[(ra)+offset] */
|
||||
void
|
||||
ppc_stfs(struct ppc_function *p, uint frs, uint ra, int offset)
|
||||
{
|
||||
emit_d(p, 52, frs, ra, offset);
|
||||
emit_d(p, 52, frs, ra, offset, "stfs\tr%u, %d(r%u)\n", TRUE);
|
||||
}
|
||||
|
||||
/** store frs at mem[(ra)+(rb)] */
|
||||
void
|
||||
ppc_stfiwx(struct ppc_function *p, uint frs, uint ra, uint rb)
|
||||
{
|
||||
emit_x(p, 31, frs, ra, rb, 983);
|
||||
emit_x(p, 31, frs, ra, rb, 983, "stfiwx\tr%u, r%u, r%u\n");
|
||||
}
|
||||
|
||||
/** load frt = mem[(ra)+offset] */
|
||||
void
|
||||
ppc_lfs(struct ppc_function *p, uint frt, uint ra, int offset)
|
||||
{
|
||||
emit_d(p, 48, frt, ra, offset);
|
||||
emit_d(p, 48, frt, ra, offset, "stfs\tr%u, %d(r%u)\n", TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -942,6 +1052,10 @@ void
|
|||
ppc_blr(struct ppc_function *p)
|
||||
{
|
||||
emit_i(p, 18, 0, 0, 1);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
printf("blr\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** Branch Conditional to Link Register (p. 36) */
|
||||
|
|
@ -949,6 +1063,10 @@ void
|
|||
ppc_bclr(struct ppc_function *p, uint condOp, uint branchHint, uint condReg)
|
||||
{
|
||||
emit_xl(p, 19, condOp, condReg, branchHint, 16, 0);
|
||||
if (p->print) {
|
||||
indent(p);
|
||||
printf("bclr\t%u %u %u\n", condOp, branchHint, condReg);
|
||||
}
|
||||
}
|
||||
|
||||
/** Pseudo instruction: return from subroutine */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008 Tungsten Graphics, Inc. All Rights Reserved.
|
||||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -58,6 +59,8 @@ struct ppc_function
|
|||
uint32_t reg_used; /** used/free general-purpose registers bitmask */
|
||||
uint32_t fp_used; /** used/free floating point registers bitmask */
|
||||
uint32_t vec_used; /** used/free vector registers bitmask */
|
||||
int indent;
|
||||
boolean print;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -68,6 +71,10 @@ extern uint ppc_num_instructions(const struct ppc_function *p);
|
|||
extern void (*ppc_get_func( struct ppc_function *p ))( void );
|
||||
extern void ppc_dump_func(const struct ppc_function *p);
|
||||
|
||||
extern void ppc_print_code(struct ppc_function *p, boolean enable);
|
||||
extern void ppc_indent(struct ppc_function *p, int spaces);
|
||||
extern void ppc_comment(struct ppc_function *p, int rel_indent, const char *s);
|
||||
|
||||
extern int ppc_reserve_register(struct ppc_function *p, int reg);
|
||||
extern int ppc_allocate_register(struct ppc_function *p);
|
||||
extern void ppc_release_register(struct ppc_function *p, int reg);
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ void spe_init_func(struct spe_function *p, unsigned code_size)
|
|||
p->regs[i] = 1;
|
||||
}
|
||||
|
||||
p->print = false;
|
||||
p->print = FALSE;
|
||||
p->indent = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,15 +78,7 @@ const float ppc_builtin_constants[] ALIGN16_ATTRIB = {
|
|||
* How many TGSI temps should be implemented with real PPC vector registers
|
||||
* rather than memory.
|
||||
*/
|
||||
#define MAX_PPC_TEMPS 4
|
||||
|
||||
|
||||
struct reg_chan_vec
|
||||
{
|
||||
struct tgsi_full_src_register src;
|
||||
uint chan;
|
||||
uint vec;
|
||||
};
|
||||
#define MAX_PPC_TEMPS 3
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -157,6 +149,29 @@ init_gen_context(struct gen_context *gen, struct ppc_function *func)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is the given TGSI register stored as a real PPC vector register?
|
||||
*/
|
||||
static boolean
|
||||
is_ppc_vec_temporary(const struct tgsi_full_src_register *reg)
|
||||
{
|
||||
return (reg->SrcRegister.File == TGSI_FILE_TEMPORARY &&
|
||||
reg->SrcRegister.Index < MAX_PPC_TEMPS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is the given TGSI register stored as a real PPC vector register?
|
||||
*/
|
||||
static boolean
|
||||
is_ppc_vec_temporary_dst(const struct tgsi_full_dst_register *reg)
|
||||
{
|
||||
return (reg->DstRegister.File == TGSI_FILE_TEMPORARY &&
|
||||
reg->DstRegister.Index < MAX_PPC_TEMPS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* All PPC vector load/store instructions form an effective address
|
||||
* by adding the contents of two registers. For example:
|
||||
|
|
@ -285,7 +300,7 @@ emit_fetch(struct gen_context *gen,
|
|||
}
|
||||
break;
|
||||
case TGSI_FILE_TEMPORARY:
|
||||
if (reg->SrcRegister.Index < MAX_PPC_TEMPS) {
|
||||
if (is_ppc_vec_temporary(reg)) {
|
||||
/* use PPC vec register */
|
||||
dst_vec = gen->temps_map[reg->SrcRegister.Index][swizzle];
|
||||
}
|
||||
|
|
@ -353,23 +368,33 @@ emit_fetch(struct gen_context *gen,
|
|||
uint sign_op = tgsi_util_get_full_src_register_sign_mode(reg, chan_index);
|
||||
if (sign_op != TGSI_UTIL_SIGN_KEEP) {
|
||||
int bit31_vec = gen_get_bit31_vec(gen);
|
||||
int dst_vec2;
|
||||
|
||||
if (is_ppc_vec_temporary(reg)) {
|
||||
/* need to use a new temp */
|
||||
dst_vec2 = ppc_allocate_vec_register(gen->f);
|
||||
}
|
||||
else {
|
||||
dst_vec2 = dst_vec;
|
||||
}
|
||||
|
||||
switch (sign_op) {
|
||||
case TGSI_UTIL_SIGN_CLEAR:
|
||||
/* vec = vec & ~bit31 */
|
||||
ppc_vandc(gen->f, dst_vec, dst_vec, bit31_vec);
|
||||
ppc_vandc(gen->f, dst_vec2, dst_vec, bit31_vec);
|
||||
break;
|
||||
case TGSI_UTIL_SIGN_SET:
|
||||
/* vec = vec | bit31 */
|
||||
ppc_vor(gen->f, dst_vec, dst_vec, bit31_vec);
|
||||
ppc_vor(gen->f, dst_vec2, dst_vec, bit31_vec);
|
||||
break;
|
||||
case TGSI_UTIL_SIGN_TOGGLE:
|
||||
/* vec = vec ^ bit31 */
|
||||
ppc_vxor(gen->f, dst_vec, dst_vec, bit31_vec);
|
||||
ppc_vxor(gen->f, dst_vec2, dst_vec, bit31_vec);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return dst_vec2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -452,8 +477,7 @@ release_src_vecs(struct gen_context *gen)
|
|||
uint i;
|
||||
for (i = 0; i < gen->num_regs; i++) {
|
||||
const const struct tgsi_full_src_register src = gen->regs[i].src;
|
||||
if (!(src.SrcRegister.File == TGSI_FILE_TEMPORARY &&
|
||||
src.SrcRegister.Index < MAX_PPC_TEMPS)) {
|
||||
if (!is_ppc_vec_temporary(&src)) {
|
||||
ppc_release_vec_register(gen->f, gen->regs[i].vec);
|
||||
}
|
||||
}
|
||||
|
|
@ -469,8 +493,7 @@ get_dst_vec(struct gen_context *gen,
|
|||
{
|
||||
const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[0];
|
||||
|
||||
if (reg->DstRegister.File == TGSI_FILE_TEMPORARY &&
|
||||
reg->DstRegister.Index < MAX_PPC_TEMPS) {
|
||||
if (is_ppc_vec_temporary_dst(reg)) {
|
||||
int vec = gen->temps_map[reg->DstRegister.Index][chan_index];
|
||||
return vec;
|
||||
}
|
||||
|
|
@ -502,7 +525,7 @@ emit_store(struct gen_context *gen,
|
|||
}
|
||||
break;
|
||||
case TGSI_FILE_TEMPORARY:
|
||||
if (reg->DstRegister.Index < MAX_PPC_TEMPS) {
|
||||
if (is_ppc_vec_temporary_dst(reg)) {
|
||||
if (!free_vec) {
|
||||
int dst_vec = gen->temps_map[reg->DstRegister.Index][chan_index];
|
||||
if (dst_vec != src_vec)
|
||||
|
|
@ -584,6 +607,7 @@ static void
|
|||
emit_unaryop(struct gen_context *gen, struct tgsi_full_instruction *inst)
|
||||
{
|
||||
uint chan_index;
|
||||
|
||||
FOR_EACH_DST0_ENABLED_CHANNEL(*inst, chan_index) {
|
||||
int v0 = get_src_vec(gen, inst, 0, chan_index); /* v0 = srcreg[0] */
|
||||
int v1 = get_dst_vec(gen, inst, chan_index);
|
||||
|
|
@ -770,7 +794,7 @@ emit_dotprod(struct gen_context *gen, struct tgsi_full_instruction *inst)
|
|||
|
||||
v2 = ppc_allocate_vec_register(gen->f);
|
||||
|
||||
ppc_vxor(gen->f, v2, v2, v2); /* v2 = {0, 0, 0, 0} */
|
||||
ppc_vzero(gen->f, v2); /* v2 = {0, 0, 0, 0} */
|
||||
|
||||
v0 = get_src_vec(gen, inst, 0, CHAN_X); /* v0 = src0.XXXX */
|
||||
v1 = get_src_vec(gen, inst, 1, CHAN_X); /* v1 = src1.XXXX */
|
||||
|
|
@ -815,7 +839,7 @@ ppc_vec_pow(struct ppc_function *f, int vr, int va, int vb)
|
|||
ppc_vzero(f, zero_vec);
|
||||
|
||||
ppc_vlogefp(f, t_vec, va); /* t = log2(va) */
|
||||
ppc_vmaddfp(f, t_vec, t_vec, vb, zero_vec); /* t = t * vb */
|
||||
ppc_vmaddfp(f, t_vec, t_vec, vb, zero_vec); /* t = t * vb + zero */
|
||||
ppc_vexptefp(f, vr, t_vec); /* vr = 2^t */
|
||||
|
||||
ppc_release_vec_register(f, t_vec);
|
||||
|
|
@ -1221,9 +1245,12 @@ emit_prologue(struct ppc_function *func)
|
|||
static void
|
||||
emit_epilogue(struct ppc_function *func)
|
||||
{
|
||||
ppc_comment(func, -4, "Epilogue:");
|
||||
ppc_return(func);
|
||||
/* XXX restore prev stack frame */
|
||||
#if 0
|
||||
debug_printf("PPC: Emitted %u instructions\n", func->num_inst);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1248,6 +1275,7 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
|
|||
unsigned ok = 1;
|
||||
uint num_immediates = 0;
|
||||
struct gen_context gen;
|
||||
uint ic = 0;
|
||||
|
||||
if (use_ppc_asm < 0) {
|
||||
/* If GALLIUM_NOPPC is set, don't use PPC codegen */
|
||||
|
|
@ -1280,6 +1308,12 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
|
|||
break;
|
||||
|
||||
case TGSI_TOKEN_TYPE_INSTRUCTION:
|
||||
if (func->print) {
|
||||
_debug_printf("# ");
|
||||
ic++;
|
||||
tgsi_dump_instruction(&parse.FullToken.FullInstruction, ic);
|
||||
}
|
||||
|
||||
ok = emit_instruction(&gen, &parse.FullToken.FullInstruction);
|
||||
|
||||
if (!ok) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ INCLUDE_DIRS = \
|
|||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
.c.s:
|
||||
$(CC) -S $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
default: $(CELL_LIB)
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ get_const_one_reg(struct codegen *gen)
|
|||
gen->one_reg = spe_allocate_available_register(gen->f);
|
||||
|
||||
spe_indent(gen->f, 4);
|
||||
spe_comment(gen->f, -4, "INIT CONSTANT 1.0:");
|
||||
spe_comment(gen->f, -4, "init constant reg = 1.0:");
|
||||
|
||||
/* one = {1.0, 1.0, 1.0, 1.0} */
|
||||
spe_load_float(gen->f, gen->one_reg, 1.0f);
|
||||
|
|
@ -168,7 +168,7 @@ get_address_reg(struct codegen *gen)
|
|||
gen->addr_reg = spe_allocate_available_register(gen->f);
|
||||
|
||||
spe_indent(gen->f, 4);
|
||||
spe_comment(gen->f, -4, "INIT CONSTANT 1.0:");
|
||||
spe_comment(gen->f, -4, "init address reg = 0:");
|
||||
|
||||
/* init addr = {0, 0, 0, 0} */
|
||||
spe_zero(gen->f, gen->addr_reg);
|
||||
|
|
@ -479,7 +479,7 @@ emit_prologue(struct codegen *gen)
|
|||
{
|
||||
gen->frame_size = 1024; /* XXX temporary, should be dynamic */
|
||||
|
||||
spe_comment(gen->f, -4, "Function prologue:");
|
||||
spe_comment(gen->f, 0, "Function prologue:");
|
||||
|
||||
/* save $lr on stack # stqd $lr,16($sp) */
|
||||
spe_stqd(gen->f, SPE_REG_RA, SPE_REG_SP, 16);
|
||||
|
|
@ -515,7 +515,7 @@ emit_epilogue(struct codegen *gen)
|
|||
{
|
||||
const int return_reg = 3;
|
||||
|
||||
spe_comment(gen->f, -4, "Function epilogue:");
|
||||
spe_comment(gen->f, 0, "Function epilogue:");
|
||||
|
||||
spe_comment(gen->f, 0, "return the killed mask");
|
||||
if (gen->kill_mask_reg > 0) {
|
||||
|
|
@ -561,8 +561,6 @@ emit_ARL(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch = 0, src_reg, addr_reg;
|
||||
|
||||
spe_comment(gen->f, -4, "ARL:");
|
||||
|
||||
src_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
addr_reg = get_address_reg(gen);
|
||||
|
||||
|
|
@ -580,8 +578,6 @@ emit_MOV(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch, src_reg[4], dst_reg[4];
|
||||
|
||||
spe_comment(gen->f, -4, "MOV:");
|
||||
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
src_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
dst_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
|
||||
|
|
@ -612,20 +608,6 @@ emit_binop(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch, s1_reg[4], s2_reg[4], d_reg[4];
|
||||
|
||||
switch (inst->Instruction.Opcode) {
|
||||
case TGSI_OPCODE_ADD:
|
||||
spe_comment(gen->f, -4, "ADD:");
|
||||
break;
|
||||
case TGSI_OPCODE_SUB:
|
||||
spe_comment(gen->f, -4, "SUB:");
|
||||
break;
|
||||
case TGSI_OPCODE_MUL:
|
||||
spe_comment(gen->f, -4, "MUL:");
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* Loop over Red/Green/Blue/Alpha channels, fetch src operands */
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
|
|
@ -670,7 +652,7 @@ static boolean
|
|||
emit_MAD(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
||||
{
|
||||
int ch, s1_reg[4], s2_reg[4], s3_reg[4], d_reg[4];
|
||||
spe_comment(gen->f, -4, "MAD:");
|
||||
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
s2_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
|
||||
|
|
@ -695,7 +677,7 @@ static boolean
|
|||
emit_LERP(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
||||
{
|
||||
int ch, s1_reg[4], s2_reg[4], s3_reg[4], d_reg[4], tmp_reg[4];
|
||||
spe_comment(gen->f, -4, "LERP:");
|
||||
|
||||
/* setup/get src/dst/temp regs */
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
|
|
@ -730,14 +712,6 @@ emit_RCP_RSQ(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch, s1_reg[4], d_reg[4], tmp_reg[4];
|
||||
|
||||
if (inst->Instruction.Opcode == TGSI_OPCODE_RCP) {
|
||||
spe_comment(gen->f, -4, "RCP:");
|
||||
}
|
||||
else {
|
||||
assert(inst->Instruction.Opcode == TGSI_OPCODE_RSQ);
|
||||
spe_comment(gen->f, -4, "RSQ:");
|
||||
}
|
||||
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
|
||||
|
|
@ -778,8 +752,6 @@ emit_ABS(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
int ch, s1_reg[4], d_reg[4];
|
||||
const int bit31mask_reg = get_itemp(gen);
|
||||
|
||||
spe_comment(gen->f, -4, "ABS:");
|
||||
|
||||
/* mask with bit 31 set, the rest cleared */
|
||||
spe_load_uint(gen->f, bit31mask_reg, (1 << 31));
|
||||
|
||||
|
|
@ -812,8 +784,6 @@ emit_DP3(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
int s2x_reg, s2y_reg, s2z_reg;
|
||||
int t0_reg = get_itemp(gen), t1_reg = get_itemp(gen);
|
||||
|
||||
spe_comment(gen->f, -4, "DP3:");
|
||||
|
||||
s1x_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
|
||||
s2x_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[1]);
|
||||
s1y_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
|
||||
|
|
@ -854,8 +824,6 @@ emit_DP4(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
int s1x_reg, s1y_reg, s1z_reg, s1w_reg;
|
||||
int t0_reg = get_itemp(gen), t1_reg = get_itemp(gen);
|
||||
|
||||
spe_comment(gen->f, -4, "DP4:");
|
||||
|
||||
s0x_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
|
||||
s1x_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[1]);
|
||||
s0y_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
|
||||
|
|
@ -898,8 +866,6 @@ emit_DPH(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
/* XXX rewrite this function to look more like DP3/DP4 */
|
||||
int ch;
|
||||
spe_comment(gen->f, -4, "DPH:");
|
||||
|
||||
int s1_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
|
||||
int s2_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[1]);
|
||||
int tmp_reg = get_itemp(gen);
|
||||
|
|
@ -941,8 +907,6 @@ emit_NRM3(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
int src_reg[3];
|
||||
int t0_reg = get_itemp(gen), t1_reg = get_itemp(gen);
|
||||
|
||||
spe_comment(gen->f, -4, "NRM3:");
|
||||
|
||||
src_reg[0] = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
|
||||
src_reg[1] = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
|
||||
src_reg[2] = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[0]);
|
||||
|
|
@ -981,8 +945,6 @@ emit_NRM3(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
static boolean
|
||||
emit_XPD(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
||||
{
|
||||
spe_comment(gen->f, -4, "XPD:");
|
||||
|
||||
int s1_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[0]);
|
||||
int s2_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[1]);
|
||||
int tmp_reg = get_itemp(gen);
|
||||
|
|
@ -1044,32 +1006,6 @@ emit_inequality(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
int ch, s1_reg[4], s2_reg[4], d_reg[4], one_reg;
|
||||
bool complement = FALSE;
|
||||
|
||||
switch (inst->Instruction.Opcode) {
|
||||
case TGSI_OPCODE_SGT:
|
||||
spe_comment(gen->f, -4, "SGT:");
|
||||
break;
|
||||
case TGSI_OPCODE_SLT:
|
||||
spe_comment(gen->f, -4, "SLT:");
|
||||
break;
|
||||
case TGSI_OPCODE_SGE:
|
||||
spe_comment(gen->f, -4, "SGE:");
|
||||
complement = TRUE;
|
||||
break;
|
||||
case TGSI_OPCODE_SLE:
|
||||
spe_comment(gen->f, -4, "SLE:");
|
||||
complement = TRUE;
|
||||
break;
|
||||
case TGSI_OPCODE_SEQ:
|
||||
spe_comment(gen->f, -4, "SEQ:");
|
||||
break;
|
||||
case TGSI_OPCODE_SNE:
|
||||
spe_comment(gen->f, -4, "SNE:");
|
||||
complement = TRUE;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
one_reg = get_const_one_reg(gen);
|
||||
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
|
|
@ -1088,15 +1024,18 @@ emit_inequality(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
break;
|
||||
case TGSI_OPCODE_SGE:
|
||||
spe_fcgt(gen->f, d_reg[ch], s2_reg[ch], s1_reg[ch]);
|
||||
complement = TRUE;
|
||||
break;
|
||||
case TGSI_OPCODE_SLE:
|
||||
spe_fcgt(gen->f, d_reg[ch], s1_reg[ch], s2_reg[ch]);
|
||||
complement = TRUE;
|
||||
break;
|
||||
case TGSI_OPCODE_SEQ:
|
||||
spe_fceq(gen->f, d_reg[ch], s1_reg[ch], s2_reg[ch]);
|
||||
break;
|
||||
case TGSI_OPCODE_SNE:
|
||||
spe_fceq(gen->f, d_reg[ch], s1_reg[ch], s2_reg[ch]);
|
||||
complement = TRUE;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
|
@ -1129,8 +1068,6 @@ emit_CMP(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch;
|
||||
|
||||
spe_comment(gen->f, -4, "CMP:");
|
||||
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
int s1_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
int s2_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
|
||||
|
|
@ -1161,8 +1098,6 @@ emit_TRUNC(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch, s1_reg[4], d_reg[4];
|
||||
|
||||
spe_comment(gen->f, -4, "TRUNC:");
|
||||
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
|
||||
|
|
@ -1198,8 +1133,6 @@ emit_FLR(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch, s1_reg[4], d_reg[4], tmp_reg[4], zero_reg, one_reg;
|
||||
|
||||
spe_comment(gen->f, -4, "FLR:");
|
||||
|
||||
zero_reg = get_itemp(gen);
|
||||
spe_zero(gen->f, zero_reg);
|
||||
one_reg = get_const_one_reg(gen);
|
||||
|
|
@ -1248,8 +1181,6 @@ emit_FRC(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch, s1_reg[4], d_reg[4], tmp_reg[4], zero_reg, one_reg;
|
||||
|
||||
spe_comment(gen->f, -4, "FRC:");
|
||||
|
||||
zero_reg = get_itemp(gen);
|
||||
spe_zero(gen->f, zero_reg);
|
||||
one_reg = get_const_one_reg(gen);
|
||||
|
|
@ -1577,8 +1508,6 @@ emit_MIN_MAX(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int ch, s0_reg[4], s1_reg[4], d_reg[4], tmp_reg[4];
|
||||
|
||||
spe_comment(gen->f, -4, "MAX:");
|
||||
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
s0_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
|
||||
|
|
@ -1646,8 +1575,6 @@ emit_IF(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
const int channel = 0;
|
||||
int cond_reg;
|
||||
|
||||
spe_comment(gen->f, -4, "IF:");
|
||||
|
||||
cond_reg = get_cond_mask_reg(gen);
|
||||
|
||||
/* XXX push cond exec mask */
|
||||
|
|
@ -1682,8 +1609,6 @@ emit_ELSE(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
const int cond_reg = get_cond_mask_reg(gen);
|
||||
|
||||
spe_comment(gen->f, -4, "ELSE:");
|
||||
|
||||
spe_comment(gen->f, 0, "cond exec mask = !cond exec mask");
|
||||
spe_complement(gen->f, cond_reg, cond_reg);
|
||||
emit_update_exec_mask(gen);
|
||||
|
|
@ -1695,8 +1620,6 @@ emit_ELSE(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
static boolean
|
||||
emit_ENDIF(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
||||
{
|
||||
spe_comment(gen->f, -4, "ENDIF:");
|
||||
|
||||
/* XXX todo: pop cond exec mask */
|
||||
|
||||
gen->if_nesting--;
|
||||
|
|
@ -1712,8 +1635,6 @@ emit_BGNLOOP(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
{
|
||||
int exec_reg, loop_reg;
|
||||
|
||||
spe_comment(gen->f, -4, "BGNLOOP:");
|
||||
|
||||
exec_reg = get_exec_mask_reg(gen);
|
||||
loop_reg = get_loop_mask_reg(gen);
|
||||
|
||||
|
|
@ -1736,8 +1657,6 @@ emit_ENDLOOP(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
const int tmp_reg = get_itemp(gen);
|
||||
int offset;
|
||||
|
||||
spe_comment(gen->f, -4, "ENDLOOP:");
|
||||
|
||||
/* tmp_reg = exec[0] | exec[1] | exec[2] | exec[3] */
|
||||
spe_orx(gen->f, tmp_reg, loop_reg);
|
||||
|
||||
|
|
@ -1762,8 +1681,6 @@ emit_BRK(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
const int exec_reg = get_exec_mask_reg(gen);
|
||||
const int loop_reg = get_loop_mask_reg(gen);
|
||||
|
||||
spe_comment(gen->f, -4, "BREAK:");
|
||||
|
||||
assert(gen->loop_nesting > 0);
|
||||
|
||||
spe_comment(gen->f, 0, "loop exec mask &= ~master exec mask");
|
||||
|
|
@ -1778,8 +1695,6 @@ emit_BRK(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
|||
static boolean
|
||||
emit_CONT(struct codegen *gen, const struct tgsi_full_instruction *inst)
|
||||
{
|
||||
spe_comment(gen->f, -4, "CONT:");
|
||||
|
||||
assert(gen->loop_nesting > 0);
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -1792,8 +1707,6 @@ emit_DDX_DDY(struct codegen *gen, const struct tgsi_full_instruction *inst,
|
|||
{
|
||||
int ch;
|
||||
|
||||
spe_comment(gen->f, -4, ddx ? "DDX:" : "DDY:");
|
||||
|
||||
FOR_EACH_ENABLED_CHANNEL(inst, ch) {
|
||||
int s_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
|
||||
int d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
|
||||
|
|
@ -1829,7 +1742,6 @@ emit_DDX_DDY(struct codegen *gen, const struct tgsi_full_instruction *inst,
|
|||
static boolean
|
||||
emit_END(struct codegen *gen)
|
||||
{
|
||||
spe_comment(gen->f, -4, "END:");
|
||||
emit_epilogue(gen);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1962,8 +1874,6 @@ emit_immediate(struct codegen *gen, const struct tgsi_full_immediate *immed)
|
|||
|
||||
assert(gen->num_imm < MAX_TEMPS);
|
||||
|
||||
spe_comment(gen->f, -4, "IMMEDIATE:");
|
||||
|
||||
for (ch = 0; ch < 4; ch++) {
|
||||
float val = immed->u.ImmediateFloat32[ch].Float;
|
||||
|
||||
|
|
@ -2028,7 +1938,7 @@ emit_declaration(struct cell_context *cell,
|
|||
sprintf(buf, "TGSI temp[%d] maps to SPU regs [$%d $%d $%d $%d]", i,
|
||||
gen->temp_regs[i][0], gen->temp_regs[i][1],
|
||||
gen->temp_regs[i][2], gen->temp_regs[i][3]);
|
||||
spe_comment(gen->f, -4, buf);
|
||||
spe_comment(gen->f, 0, buf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -2056,6 +1966,7 @@ cell_gen_fragment_program(struct cell_context *cell,
|
|||
{
|
||||
struct tgsi_parse_context parse;
|
||||
struct codegen gen;
|
||||
uint ic = 0;
|
||||
|
||||
memset(&gen, 0, sizeof(gen));
|
||||
gen.cell = cell;
|
||||
|
|
@ -2073,7 +1984,7 @@ cell_gen_fragment_program(struct cell_context *cell,
|
|||
|
||||
if (cell->debug_flags & CELL_DEBUG_ASM) {
|
||||
spe_print_code(f, TRUE);
|
||||
spe_indent(f, 8);
|
||||
spe_indent(f, 2*8);
|
||||
printf("Begin %s\n", __FUNCTION__);
|
||||
tgsi_dump(tokens, 0);
|
||||
}
|
||||
|
|
@ -2087,16 +1998,29 @@ cell_gen_fragment_program(struct cell_context *cell,
|
|||
|
||||
switch (parse.FullToken.Token.Type) {
|
||||
case TGSI_TOKEN_TYPE_IMMEDIATE:
|
||||
if (f->print) {
|
||||
_debug_printf(" # ");
|
||||
tgsi_dump_immediate(&parse.FullToken.FullImmediate);
|
||||
}
|
||||
if (!emit_immediate(&gen, &parse.FullToken.FullImmediate))
|
||||
gen.error = TRUE;
|
||||
break;
|
||||
|
||||
case TGSI_TOKEN_TYPE_DECLARATION:
|
||||
if (f->print) {
|
||||
_debug_printf(" # ");
|
||||
tgsi_dump_declaration(&parse.FullToken.FullDeclaration);
|
||||
}
|
||||
if (!emit_declaration(cell, &gen, &parse.FullToken.FullDeclaration))
|
||||
gen.error = TRUE;
|
||||
break;
|
||||
|
||||
case TGSI_TOKEN_TYPE_INSTRUCTION:
|
||||
if (f->print) {
|
||||
_debug_printf(" # ");
|
||||
ic++;
|
||||
tgsi_dump_instruction(&parse.FullToken.FullInstruction, ic);
|
||||
}
|
||||
if (!emit_instruction(&gen, &parse.FullToken.FullInstruction))
|
||||
gen.error = TRUE;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
|
|||
} else {
|
||||
nr_faces = 1;
|
||||
}
|
||||
|
||||
|
||||
pitch = pt->width[0];
|
||||
for (l = 0; l <= pt->last_level; l++) {
|
||||
pt->width[l] = width;
|
||||
|
|
@ -76,13 +76,15 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
|
|||
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
|
||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET))
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
else
|
||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
else {
|
||||
switch (pt->format) {
|
||||
/* TODO: Figure out which formats can be swizzled */
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
||||
/* XXX: Re-enable when SIFM size limits are fixed */
|
||||
/*case PIPE_FORMAT_R16_SNORM:*/
|
||||
case PIPE_FORMAT_R16_SNORM:
|
||||
break;
|
||||
default:
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
|
|
@ -192,4 +194,3 @@ nv30_screen_init_miptree_functions(struct pipe_screen *pscreen)
|
|||
pscreen->get_tex_surface = nv30_miptree_surface_new;
|
||||
pscreen->tex_surface_release = nv30_miptree_surface_del;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen,
|
|||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return TRUE;
|
||||
|
|
@ -110,7 +110,7 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen,
|
|||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
||||
case PIPE_FORMAT_A4R4G4B4_UNORM:
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
case PIPE_FORMAT_L8_UNORM:
|
||||
case PIPE_FORMAT_A8_UNORM:
|
||||
case PIPE_FORMAT_I8_UNORM:
|
||||
|
|
@ -139,7 +139,8 @@ nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
|
|||
|
||||
if (!mt->shadow_tex) {
|
||||
unsigned old_tex_usage = surface->texture->tex_usage;
|
||||
surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR |
|
||||
PIPE_TEXTURE_USAGE_DYNAMIC;
|
||||
mt->shadow_tex = screen->texture_create(screen, surface->texture);
|
||||
surface->texture->tex_usage = old_tex_usage;
|
||||
|
||||
|
|
@ -326,7 +327,7 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
|
|||
so_data (so, 3);
|
||||
so_method(so, screen->rankine, 0x1450, 1);
|
||||
so_data (so, 0x00030004);
|
||||
|
||||
|
||||
/* NEW */
|
||||
so_method(so, screen->rankine, 0x1e98, 1);
|
||||
so_data (so, 0);
|
||||
|
|
@ -382,4 +383,3 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
|
|||
|
||||
return &screen->pipe;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
|
|||
{
|
||||
struct pipe_winsys *ws = pscreen->winsys;
|
||||
struct nv40_miptree *mt;
|
||||
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
|
||||
NOUVEAU_BUFFER_USAGE_TEXTURE;
|
||||
|
||||
mt = MALLOC(sizeof(struct nv40_miptree));
|
||||
if (!mt)
|
||||
|
|
@ -75,25 +77,27 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
|
|||
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
|
||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET))
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
else
|
||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
else {
|
||||
switch (pt->format) {
|
||||
/* TODO: Figure out which formats can be swizzled */
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
||||
/* XXX: Re-enable when SIFM size limits are fixed */
|
||||
/*case PIPE_FORMAT_R16_SNORM:*/
|
||||
case PIPE_FORMAT_R16_SNORM:
|
||||
break;
|
||||
default:
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
|
||||
buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
|
||||
|
||||
nv40_miptree_layout(mt);
|
||||
|
||||
mt->buffer = ws->buffer_create(ws, 256,
|
||||
PIPE_BUFFER_USAGE_PIXEL |
|
||||
NOUVEAU_BUFFER_USAGE_TEXTURE,
|
||||
mt->total_size);
|
||||
mt->buffer = ws->buffer_create(ws, 256, buf_usage, mt->total_size);
|
||||
if (!mt->buffer) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -148,7 +148,8 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
|
|||
|
||||
if (!mt->shadow_tex) {
|
||||
unsigned old_tex_usage = surface->texture->tex_usage;
|
||||
surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR |
|
||||
PIPE_TEXTURE_USAGE_DYNAMIC;
|
||||
mt->shadow_tex = screen->texture_create(screen, surface->texture);
|
||||
surface->texture->tex_usage = old_tex_usage;
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ enum pipe_texture_target {
|
|||
#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */
|
||||
#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8
|
||||
#define PIPE_TEXTURE_USAGE_SAMPLER 0x10
|
||||
#define PIPE_TEXTURE_USAGE_DYNAMIC 0x20
|
||||
/** Pipe driver custom usage flags should be greater or equal to this value */
|
||||
#define PIPE_TEXTURE_USAGE_CUSTOM (1 << 16)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
TARGET = libg3dvl.a
|
||||
OBJECTS = vl_display.o vl_screen.o vl_context.o vl_surface.o vl_shader_build.o vl_util.o vl_basic_csc.o \
|
||||
vl_r16snorm_mc.o vl_r16snorm_mc_buf.o
|
||||
vl_r16snorm_mc_buf.o
|
||||
GALLIUMDIR = ../..
|
||||
|
||||
CFLAGS += -g -Wall -fPIC -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary -I${GALLIUMDIR}/winsys/g3dvl
|
||||
CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \
|
||||
-I${GALLIUMDIR}/include \
|
||||
-I${GALLIUMDIR}/auxiliary \
|
||||
-I${GALLIUMDIR}/winsys/g3dvl \
|
||||
|
||||
#############################################
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#define VL_INTERNAL
|
||||
#include "vl_basic_csc.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_winsys.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <pipe/p_inlines.h>
|
||||
#include <tgsi/tgsi_parse.h>
|
||||
#include <tgsi/tgsi_build.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "vl_csc.h"
|
||||
#include "vl_surface.h"
|
||||
#include "vl_shader_build.h"
|
||||
|
|
@ -237,7 +237,7 @@ static int vlDestroy
|
|||
pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vs_const_buf.buffer);
|
||||
pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->fs_const_buf.buffer);
|
||||
|
||||
free(basic_csc);
|
||||
FREE(basic_csc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -369,7 +369,7 @@ static int vlCreateVertexShader
|
|||
assert(context);
|
||||
|
||||
pipe = csc->pipe;
|
||||
tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
|
||||
tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token));
|
||||
|
||||
/* Version */
|
||||
*(struct tgsi_version*)&tokens[0] = tgsi_build_version();
|
||||
|
|
@ -430,7 +430,7 @@ static int vlCreateVertexShader
|
|||
|
||||
vs.tokens = tokens;
|
||||
csc->vertex_shader = pipe->create_vs_state(pipe, &vs);
|
||||
free(tokens);
|
||||
FREE(tokens);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -456,7 +456,7 @@ static int vlCreateFragmentShader
|
|||
assert(context);
|
||||
|
||||
pipe = csc->pipe;
|
||||
tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
|
||||
tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token));
|
||||
|
||||
/* Version */
|
||||
*(struct tgsi_version*)&tokens[0] = tgsi_build_version();
|
||||
|
|
@ -517,7 +517,7 @@ static int vlCreateFragmentShader
|
|||
|
||||
fs.tokens = tokens;
|
||||
csc->fragment_shader = pipe->create_fs_state(pipe, &fs);
|
||||
free(tokens);
|
||||
FREE(tokens);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -626,7 +626,7 @@ static int vlCreateDataBufs
|
|||
memcpy
|
||||
(
|
||||
pipe->winsys->buffer_map(pipe->winsys, csc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
|
||||
&bt_601,
|
||||
&bt_601_full,
|
||||
sizeof(struct vlFragmentShaderConsts)
|
||||
);
|
||||
|
||||
|
|
@ -691,7 +691,7 @@ int vlCreateBasicCSC
|
|||
assert(pipe);
|
||||
assert(csc);
|
||||
|
||||
basic_csc = calloc(1, sizeof(struct vlBasicCSC));
|
||||
basic_csc = CALLOC_STRUCT(vlBasicCSC);
|
||||
|
||||
if (!basic_csc)
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
#define VL_INTERNAL
|
||||
#include "vl_context.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "vl_render.h"
|
||||
#include "vl_r16snorm_mc.h"
|
||||
#include "vl_r16snorm_mc_buf.h"
|
||||
#include "vl_csc.h"
|
||||
#include "vl_basic_csc.h"
|
||||
|
|
@ -112,7 +111,7 @@ int vlCreateContext
|
|||
assert(context);
|
||||
assert(pipe);
|
||||
|
||||
ctx = calloc(1, sizeof(struct vlContext));
|
||||
ctx = CALLOC_STRUCT(vlContext);
|
||||
|
||||
if (!ctx)
|
||||
return 1;
|
||||
|
|
@ -127,7 +126,6 @@ int vlCreateContext
|
|||
|
||||
vlInitCommon(ctx);
|
||||
|
||||
/*vlCreateR16SNormMC(pipe, picture_width, picture_height, picture_format, &ctx->render);*/
|
||||
vlCreateR16SNormBufferedMC(pipe, picture_width, picture_height, picture_format, &ctx->render);
|
||||
vlCreateBasicCSC(pipe, &ctx->csc);
|
||||
|
||||
|
|
@ -154,7 +152,7 @@ int vlDestroyContext
|
|||
context->pipe->delete_rasterizer_state(context->pipe, context->raster);
|
||||
context->pipe->delete_depth_stencil_alpha_state(context->pipe, context->dsa);
|
||||
|
||||
free(context);
|
||||
FREE(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#define VL_INTERNAL
|
||||
#include "vl_display.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <util/u_memory.h>
|
||||
|
||||
int vlCreateDisplay
|
||||
(
|
||||
|
|
@ -14,7 +14,7 @@ int vlCreateDisplay
|
|||
assert(native_display);
|
||||
assert(display);
|
||||
|
||||
dpy = calloc(1, sizeof(struct vlDisplay));
|
||||
dpy = CALLOC_STRUCT(vlDisplay);
|
||||
|
||||
if (!dpy)
|
||||
return 1;
|
||||
|
|
@ -32,7 +32,7 @@ int vlDestroyDisplay
|
|||
{
|
||||
assert(display);
|
||||
|
||||
free(display);
|
||||
FREE(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef vl_r16snorm_mc_h
|
||||
#define vl_r16snorm_mc_h
|
||||
|
||||
#include "vl_types.h"
|
||||
|
||||
struct pipe_context;
|
||||
struct vlRender;
|
||||
|
||||
int vlCreateR16SNormMC
|
||||
(
|
||||
struct pipe_context *pipe,
|
||||
unsigned int video_width,
|
||||
unsigned int video_height,
|
||||
enum vlFormat video_format,
|
||||
struct vlRender **render
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
#define VL_INTERNAL
|
||||
#include "vl_r16snorm_mc_buf.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_winsys.h>
|
||||
#include <pipe/p_screen.h>
|
||||
|
|
@ -10,6 +9,7 @@
|
|||
#include <tgsi/tgsi_parse.h>
|
||||
#include <tgsi/tgsi_build.h>
|
||||
#include <util/u_math.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "vl_render.h"
|
||||
#include "vl_shader_build.h"
|
||||
#include "vl_surface.h"
|
||||
|
|
@ -17,16 +17,7 @@
|
|||
#include "vl_types.h"
|
||||
#include "vl_defs.h"
|
||||
|
||||
/*
|
||||
* TODO: Dynamically determine number of buf sets to use, based on
|
||||
* video size and available mem, since we can easily run out of memory
|
||||
* for high res videos.
|
||||
* Note: Destroying previous frame's buffers and creating new ones
|
||||
* doesn't work, since the buffer are not actually destroyed until their
|
||||
* fence is signalled, and if we render fast enough we will create faster
|
||||
* than we destroy.
|
||||
*/
|
||||
#define NUM_BUF_SETS 4 /* Number of rotating buffer sets to use */
|
||||
const unsigned int DEFAULT_BUF_ALIGNMENT = 1;
|
||||
|
||||
enum vlMacroBlockTypeEx
|
||||
{
|
||||
|
|
@ -52,36 +43,79 @@ struct vlFragmentShaderConsts
|
|||
struct vlVertex4f div;
|
||||
};
|
||||
|
||||
struct vlMacroBlockVertexStream0
|
||||
{
|
||||
struct vlVertex2f pos;
|
||||
struct vlVertex2f luma_tc;
|
||||
struct vlVertex2f cb_tc;
|
||||
struct vlVertex2f cr_tc;
|
||||
};
|
||||
|
||||
struct vlR16SnormBufferedMC
|
||||
{
|
||||
struct vlRender base;
|
||||
|
||||
unsigned int picture_width, picture_height;
|
||||
unsigned int picture_width;
|
||||
unsigned int picture_height;
|
||||
enum vlFormat picture_format;
|
||||
unsigned int macroblocks_per_picture;
|
||||
|
||||
unsigned int cur_buf;
|
||||
struct vlSurface *buffered_surface;
|
||||
struct vlSurface *past_surface, *future_surface;
|
||||
struct vlSurface *past_surface;
|
||||
struct vlSurface *future_surface;
|
||||
struct vlVertex2f surface_tex_inv_size;
|
||||
struct vlVertex2f zero_block[3];
|
||||
unsigned int num_macroblocks;
|
||||
struct vlMpeg2MacroBlock *macroblocks;
|
||||
struct pipe_surface *tex_surface[3];
|
||||
short *texels[3];
|
||||
|
||||
struct pipe_context *pipe;
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_framebuffer_state render_target;
|
||||
struct pipe_sampler_state *samplers[5];
|
||||
struct pipe_texture *textures[NUM_BUF_SETS][5];
|
||||
struct pipe_surface *tex_surface[3];
|
||||
short *texels[3];
|
||||
|
||||
union
|
||||
{
|
||||
void *all[5];
|
||||
struct
|
||||
{
|
||||
void *y;
|
||||
void *cb;
|
||||
void *cr;
|
||||
void *ref[2];
|
||||
};
|
||||
} samplers;
|
||||
|
||||
union
|
||||
{
|
||||
struct pipe_texture *all[5];
|
||||
struct
|
||||
{
|
||||
struct pipe_texture *y;
|
||||
struct pipe_texture *cb;
|
||||
struct pipe_texture *cr;
|
||||
struct pipe_texture *ref[2];
|
||||
};
|
||||
} textures;
|
||||
|
||||
union
|
||||
{
|
||||
struct pipe_vertex_buffer all[3];
|
||||
struct
|
||||
{
|
||||
struct pipe_vertex_buffer ycbcr;
|
||||
struct pipe_vertex_buffer ref[2];
|
||||
};
|
||||
} vertex_bufs;
|
||||
|
||||
void *i_vs, *p_vs[2], *b_vs[2];
|
||||
void *i_fs, *p_fs[2], *b_fs[2];
|
||||
struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][3];
|
||||
struct pipe_vertex_element vertex_elems[8];
|
||||
struct pipe_constant_buffer vs_const_buf, fs_const_buf;
|
||||
struct pipe_constant_buffer vs_const_buf;
|
||||
struct pipe_constant_buffer fs_const_buf;
|
||||
};
|
||||
|
||||
static int vlBegin
|
||||
static inline int vlBegin
|
||||
(
|
||||
struct vlRender *render
|
||||
)
|
||||
|
|
@ -360,11 +394,13 @@ static inline int vlGrabMacroBlock
|
|||
(vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \
|
||||
}
|
||||
|
||||
static inline int vlGrabMacroBlockVB
|
||||
static inline int vlGenMacroblockVerts
|
||||
(
|
||||
struct vlR16SnormBufferedMC *mc,
|
||||
struct vlMpeg2MacroBlock *macroblock,
|
||||
unsigned int pos
|
||||
unsigned int pos,
|
||||
struct vlMacroBlockVertexStream0 *ycbcr_vb,
|
||||
struct vlVertex2f **ref_vb
|
||||
)
|
||||
{
|
||||
struct vlVertex2f mo_vec[2];
|
||||
|
|
@ -372,6 +408,7 @@ static inline int vlGrabMacroBlockVB
|
|||
|
||||
assert(mc);
|
||||
assert(macroblock);
|
||||
assert(ycbcr_vb);
|
||||
|
||||
switch (macroblock->mb_type)
|
||||
{
|
||||
|
|
@ -379,12 +416,9 @@ static inline int vlGrabMacroBlockVB
|
|||
{
|
||||
struct vlVertex2f *vb;
|
||||
|
||||
vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
|
||||
(
|
||||
mc->pipe->winsys,
|
||||
mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
) + pos * 2 * 24;
|
||||
assert(ref_vb && ref_vb[1]);
|
||||
|
||||
vb = ref_vb[1] + pos * 2 * 24;
|
||||
|
||||
mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x;
|
||||
mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y;
|
||||
|
|
@ -411,8 +445,6 @@ static inline int vlGrabMacroBlockVB
|
|||
}
|
||||
}
|
||||
|
||||
mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer);
|
||||
|
||||
/* fall-through */
|
||||
}
|
||||
case vlMacroBlockTypeFwdPredicted:
|
||||
|
|
@ -420,12 +452,9 @@ static inline int vlGrabMacroBlockVB
|
|||
{
|
||||
struct vlVertex2f *vb;
|
||||
|
||||
vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
|
||||
(
|
||||
mc->pipe->winsys,
|
||||
mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
) + pos * 2 * 24;
|
||||
assert(ref_vb && ref_vb[0]);
|
||||
|
||||
vb = ref_vb[0] + pos * 2 * 24;
|
||||
|
||||
if (macroblock->mb_type == vlMacroBlockTypeBkwdPredicted)
|
||||
{
|
||||
|
|
@ -469,8 +498,6 @@ static inline int vlGrabMacroBlockVB
|
|||
}
|
||||
}
|
||||
|
||||
mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer);
|
||||
|
||||
/* fall-through */
|
||||
}
|
||||
case vlMacroBlockTypeIntra:
|
||||
|
|
@ -486,20 +513,9 @@ static inline int vlGrabMacroBlockVB
|
|||
mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2)
|
||||
};
|
||||
|
||||
struct vlMacroBlockVertexStream0
|
||||
{
|
||||
struct vlVertex2f pos;
|
||||
struct vlVertex2f luma_tc;
|
||||
struct vlVertex2f cb_tc;
|
||||
struct vlVertex2f cr_tc;
|
||||
} *vb;
|
||||
struct vlMacroBlockVertexStream0 *vb;
|
||||
|
||||
vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
|
||||
(
|
||||
mc->pipe->winsys,
|
||||
mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
) + pos * 24;
|
||||
vb = ycbcr_vb + pos * 24;
|
||||
|
||||
SET_BLOCK
|
||||
(
|
||||
|
|
@ -533,8 +549,6 @@ static inline int vlGrabMacroBlockVB
|
|||
4, 2, 1, mc->zero_block
|
||||
);
|
||||
|
||||
mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -555,9 +569,6 @@ static int vlFlush
|
|||
unsigned int num_macroblocks[vlNumMacroBlockExTypes] = {0};
|
||||
unsigned int offset[vlNumMacroBlockExTypes];
|
||||
unsigned int vb_start = 0;
|
||||
unsigned int mbw;
|
||||
unsigned int mbh;
|
||||
unsigned int num_mb_per_frame;
|
||||
unsigned int i;
|
||||
|
||||
assert(render);
|
||||
|
|
@ -567,11 +578,7 @@ static int vlFlush
|
|||
if (!mc->buffered_surface)
|
||||
return 0;
|
||||
|
||||
mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH;
|
||||
mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT;
|
||||
num_mb_per_frame = mbw * mbh;
|
||||
|
||||
if (mc->num_macroblocks < num_mb_per_frame)
|
||||
if (mc->num_macroblocks < mc->macroblocks_per_picture)
|
||||
return 0;
|
||||
|
||||
pipe = mc->pipe;
|
||||
|
|
@ -588,15 +595,39 @@ static int vlFlush
|
|||
for (i = 1; i < vlNumMacroBlockExTypes; ++i)
|
||||
offset[i] = offset[i - 1] + num_macroblocks[i - 1];
|
||||
|
||||
for (i = 0; i < mc->num_macroblocks; ++i)
|
||||
{
|
||||
enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
|
||||
struct vlMacroBlockVertexStream0 *ycbcr_vb;
|
||||
struct vlVertex2f *ref_vb[2];
|
||||
|
||||
vlGrabMacroBlockVB(mc, &mc->macroblocks[i], offset[mb_type_ex]);
|
||||
ycbcr_vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
|
||||
(
|
||||
mc->pipe->winsys,
|
||||
mc->vertex_bufs.ycbcr.buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
offset[mb_type_ex]++;
|
||||
for (i = 0; i < 2; ++i)
|
||||
ref_vb[i] = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
|
||||
(
|
||||
mc->pipe->winsys,
|
||||
mc->vertex_bufs.ref[i].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
for (i = 0; i < mc->num_macroblocks; ++i)
|
||||
{
|
||||
enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
|
||||
|
||||
vlGenMacroblockVerts(mc, &mc->macroblocks[i], offset[mb_type_ex], ycbcr_vb, ref_vb);
|
||||
|
||||
offset[mb_type_ex]++;
|
||||
}
|
||||
|
||||
mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ycbcr.buffer);
|
||||
for (i = 0; i < 2; ++i)
|
||||
mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ref[i].buffer);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
pipe_surface_unmap(mc->tex_surface[i]);
|
||||
|
|
@ -628,10 +659,10 @@ static int vlFlush
|
|||
|
||||
if (num_macroblocks[vlMacroBlockExTypeIntra] > 0)
|
||||
{
|
||||
pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs.all);
|
||||
pipe->set_vertex_elements(pipe, 4, mc->vertex_elems);
|
||||
pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers);
|
||||
pipe->set_sampler_textures(pipe, 3, mc->textures.all);
|
||||
pipe->bind_sampler_states(pipe, 3, mc->samplers.all);
|
||||
pipe->bind_vs_state(pipe, mc->i_vs);
|
||||
pipe->bind_fs_state(pipe, mc->i_fs);
|
||||
|
||||
|
|
@ -641,11 +672,11 @@ static int vlFlush
|
|||
|
||||
if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0)
|
||||
{
|
||||
pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
|
||||
pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
|
||||
mc->textures.ref[0] = mc->past_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, mc->textures.all);
|
||||
pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
|
||||
pipe->bind_vs_state(pipe, mc->p_vs[0]);
|
||||
pipe->bind_fs_state(pipe, mc->p_fs[0]);
|
||||
|
||||
|
|
@ -655,11 +686,11 @@ static int vlFlush
|
|||
|
||||
if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0)
|
||||
{
|
||||
pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
|
||||
pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
|
||||
mc->textures.ref[0] = mc->past_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, mc->textures.all);
|
||||
pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
|
||||
pipe->bind_vs_state(pipe, mc->p_vs[1]);
|
||||
pipe->bind_fs_state(pipe, mc->p_fs[1]);
|
||||
|
||||
|
|
@ -669,11 +700,11 @@ static int vlFlush
|
|||
|
||||
if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0)
|
||||
{
|
||||
pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
|
||||
pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
|
||||
mc->textures.ref[0] = mc->future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, mc->textures.all);
|
||||
pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
|
||||
pipe->bind_vs_state(pipe, mc->p_vs[0]);
|
||||
pipe->bind_fs_state(pipe, mc->p_fs[0]);
|
||||
|
||||
|
|
@ -683,11 +714,11 @@ static int vlFlush
|
|||
|
||||
if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0)
|
||||
{
|
||||
pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
|
||||
pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
|
||||
mc->textures.ref[0] = mc->future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, mc->textures.all);
|
||||
pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
|
||||
pipe->bind_vs_state(pipe, mc->p_vs[1]);
|
||||
pipe->bind_fs_state(pipe, mc->p_fs[1]);
|
||||
|
||||
|
|
@ -697,12 +728,12 @@ static int vlFlush
|
|||
|
||||
if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0)
|
||||
{
|
||||
pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs.all);
|
||||
pipe->set_vertex_elements(pipe, 8, mc->vertex_elems);
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers);
|
||||
mc->textures.ref[0] = mc->past_surface->texture;
|
||||
mc->textures.ref[1] = mc->future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 5, mc->textures.all);
|
||||
pipe->bind_sampler_states(pipe, 5, mc->samplers.all);
|
||||
pipe->bind_vs_state(pipe, mc->b_vs[0]);
|
||||
pipe->bind_fs_state(pipe, mc->b_fs[0]);
|
||||
|
||||
|
|
@ -712,12 +743,12 @@ static int vlFlush
|
|||
|
||||
if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0)
|
||||
{
|
||||
pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs.all);
|
||||
pipe->set_vertex_elements(pipe, 8, mc->vertex_elems);
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
|
||||
pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers);
|
||||
mc->textures.ref[0] = mc->past_surface->texture;
|
||||
mc->textures.ref[1] = mc->future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 5, mc->textures.all);
|
||||
pipe->bind_sampler_states(pipe, 5, mc->samplers.all);
|
||||
pipe->bind_vs_state(pipe, mc->b_vs[1]);
|
||||
pipe->bind_fs_state(pipe, mc->b_fs[1]);
|
||||
|
||||
|
|
@ -726,13 +757,13 @@ static int vlFlush
|
|||
}
|
||||
|
||||
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence);
|
||||
pipe->screen->tex_surface_release(pipe->screen, &mc->render_target.cbufs[0]);
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
mc->zero_block[i].x = -1.0f;
|
||||
|
||||
mc->buffered_surface = NULL;
|
||||
mc->num_macroblocks = 0;
|
||||
mc->cur_buf++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -745,6 +776,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
|
|||
)
|
||||
{
|
||||
struct vlR16SnormBufferedMC *mc;
|
||||
bool new_surface = false;
|
||||
unsigned int i;
|
||||
|
||||
assert(render);
|
||||
|
|
@ -756,39 +788,26 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
|
|||
if (mc->buffered_surface != surface)
|
||||
{
|
||||
vlFlush(&mc->base);
|
||||
mc->buffered_surface = surface;
|
||||
mc->past_surface = batch->past_surface;
|
||||
mc->future_surface = batch->future_surface;
|
||||
mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0];
|
||||
mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0];
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
mc->tex_surface[i] = mc->pipe->screen->get_tex_surface
|
||||
(
|
||||
mc->pipe->screen,
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][i],
|
||||
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
}
|
||||
new_surface = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
new_surface = true;
|
||||
|
||||
if (new_surface)
|
||||
{
|
||||
mc->buffered_surface = surface;
|
||||
mc->past_surface = batch->past_surface;
|
||||
mc->future_surface = batch->future_surface;
|
||||
mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0];
|
||||
mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0];
|
||||
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
mc->tex_surface[i] = mc->pipe->screen->get_tex_surface
|
||||
(
|
||||
mc->pipe->screen,
|
||||
mc->textures[mc->cur_buf % NUM_BUF_SETS][i],
|
||||
mc->textures.all[i],
|
||||
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
|
|
@ -802,7 +821,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vlEnd
|
||||
static inline int vlEnd
|
||||
(
|
||||
struct vlRender *render
|
||||
)
|
||||
|
|
@ -819,7 +838,7 @@ static int vlDestroy
|
|||
{
|
||||
struct vlR16SnormBufferedMC *mc;
|
||||
struct pipe_context *pipe;
|
||||
unsigned int h, i;
|
||||
unsigned int i;
|
||||
|
||||
assert(render);
|
||||
|
||||
|
|
@ -827,19 +846,14 @@ static int vlDestroy
|
|||
pipe = mc->pipe;
|
||||
|
||||
for (i = 0; i < 5; ++i)
|
||||
pipe->delete_sampler_state(pipe, mc->samplers[i]);
|
||||
pipe->delete_sampler_state(pipe, mc->samplers.all[i]);
|
||||
|
||||
for (h = 0; h < NUM_BUF_SETS; ++h)
|
||||
for (i = 0; i < 3; ++i)
|
||||
pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[h][i].buffer);
|
||||
for (i = 0; i < 3; ++i)
|
||||
pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs.all[i].buffer);
|
||||
|
||||
/* Textures 3 & 4 are not created directly, no need to release them here */
|
||||
for (i = 0; i < NUM_BUF_SETS; ++i)
|
||||
{
|
||||
pipe_texture_release(&mc->textures[i][0]);
|
||||
pipe_texture_release(&mc->textures[i][1]);
|
||||
pipe_texture_release(&mc->textures[i][2]);
|
||||
}
|
||||
for (i = 0; i < 3; ++i)
|
||||
pipe_texture_release(&mc->textures.all[i]);
|
||||
|
||||
pipe->delete_vs_state(pipe, mc->i_vs);
|
||||
pipe->delete_fs_state(pipe, mc->i_fs);
|
||||
|
|
@ -855,8 +869,8 @@ static int vlDestroy
|
|||
pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer);
|
||||
pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer);
|
||||
|
||||
free(mc->macroblocks);
|
||||
free(mc);
|
||||
FREE(mc->macroblocks);
|
||||
FREE(mc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -882,42 +896,39 @@ static int vlCreateDataBufs
|
|||
{
|
||||
const unsigned int mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH;
|
||||
const unsigned int mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT;
|
||||
const unsigned int num_mb_per_frame = mbw * mbh;
|
||||
|
||||
struct pipe_context *pipe;
|
||||
unsigned int h, i;
|
||||
unsigned int i;
|
||||
|
||||
assert(mc);
|
||||
|
||||
pipe = mc->pipe;
|
||||
mc->macroblocks_per_picture = mbw * mbh;
|
||||
|
||||
/* Create our vertex buffers */
|
||||
for (h = 0; h < NUM_BUF_SETS; ++h)
|
||||
mc->vertex_bufs.ycbcr.pitch = sizeof(struct vlVertex2f) * 4;
|
||||
mc->vertex_bufs.ycbcr.max_index = 24 * mc->macroblocks_per_picture - 1;
|
||||
mc->vertex_bufs.ycbcr.buffer_offset = 0;
|
||||
mc->vertex_bufs.ycbcr.buffer = pipe->winsys->buffer_create
|
||||
(
|
||||
pipe->winsys,
|
||||
DEFAULT_BUF_ALIGNMENT,
|
||||
PIPE_BUFFER_USAGE_VERTEX,
|
||||
sizeof(struct vlVertex2f) * 4 * 24 * mc->macroblocks_per_picture
|
||||
);
|
||||
|
||||
for (i = 1; i < 3; ++i)
|
||||
{
|
||||
mc->vertex_bufs[h][0].pitch = sizeof(struct vlVertex2f) * 4;
|
||||
mc->vertex_bufs[h][0].max_index = 24 * num_mb_per_frame - 1;
|
||||
mc->vertex_bufs[h][0].buffer_offset = 0;
|
||||
mc->vertex_bufs[h][0].buffer = pipe->winsys->buffer_create
|
||||
mc->vertex_bufs.all[i].pitch = sizeof(struct vlVertex2f) * 2;
|
||||
mc->vertex_bufs.all[i].max_index = 24 * mc->macroblocks_per_picture - 1;
|
||||
mc->vertex_bufs.all[i].buffer_offset = 0;
|
||||
mc->vertex_bufs.all[i].buffer = pipe->winsys->buffer_create
|
||||
(
|
||||
pipe->winsys,
|
||||
1,
|
||||
DEFAULT_BUF_ALIGNMENT,
|
||||
PIPE_BUFFER_USAGE_VERTEX,
|
||||
sizeof(struct vlVertex2f) * 4 * 24 * num_mb_per_frame
|
||||
sizeof(struct vlVertex2f) * 2 * 24 * mc->macroblocks_per_picture
|
||||
);
|
||||
|
||||
for (i = 1; i < 3; ++i)
|
||||
{
|
||||
mc->vertex_bufs[h][i].pitch = sizeof(struct vlVertex2f) * 2;
|
||||
mc->vertex_bufs[h][i].max_index = 24 * num_mb_per_frame - 1;
|
||||
mc->vertex_bufs[h][i].buffer_offset = 0;
|
||||
mc->vertex_bufs[h][i].buffer = pipe->winsys->buffer_create
|
||||
(
|
||||
pipe->winsys,
|
||||
1,
|
||||
PIPE_BUFFER_USAGE_VERTEX,
|
||||
sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* Position element */
|
||||
|
|
@ -973,7 +984,7 @@ static int vlCreateDataBufs
|
|||
mc->vs_const_buf.buffer = pipe->winsys->buffer_create
|
||||
(
|
||||
pipe->winsys,
|
||||
1,
|
||||
DEFAULT_BUF_ALIGNMENT,
|
||||
PIPE_BUFFER_USAGE_CONSTANT,
|
||||
mc->vs_const_buf.size
|
||||
);
|
||||
|
|
@ -982,7 +993,7 @@ static int vlCreateDataBufs
|
|||
mc->fs_const_buf.buffer = pipe->winsys->buffer_create
|
||||
(
|
||||
pipe->winsys,
|
||||
1,
|
||||
DEFAULT_BUF_ALIGNMENT,
|
||||
PIPE_BUFFER_USAGE_CONSTANT,
|
||||
mc->fs_const_buf.size
|
||||
);
|
||||
|
|
@ -996,7 +1007,7 @@ static int vlCreateDataBufs
|
|||
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer);
|
||||
|
||||
mc->macroblocks = malloc(sizeof(struct vlMpeg2MacroBlock) * num_mb_per_frame);
|
||||
mc->macroblocks = MALLOC(sizeof(struct vlMpeg2MacroBlock) * mc->macroblocks_per_picture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1016,6 +1027,13 @@ static int vlInit
|
|||
|
||||
pipe = mc->pipe;
|
||||
|
||||
mc->buffered_surface = NULL;
|
||||
mc->past_surface = NULL;
|
||||
mc->future_surface = NULL;
|
||||
for (i = 0; i < 3; ++i)
|
||||
mc->zero_block[i].x = -1.0f;
|
||||
mc->num_macroblocks = 0;
|
||||
|
||||
/* For MC we render to textures, which are rounded up to nearest POT */
|
||||
mc->viewport.scale[0] = vlRoundUpPOT(mc->picture_width);
|
||||
mc->viewport.scale[1] = vlRoundUpPOT(mc->picture_height);
|
||||
|
|
@ -1057,7 +1075,7 @@ static int vlInit
|
|||
/*sampler.max_lod = ;*/
|
||||
/*sampler.border_color[i] = ;*/
|
||||
/*sampler.max_anisotropy = ;*/
|
||||
mc->samplers[i] = pipe->create_sampler_state(pipe, &sampler);
|
||||
mc->samplers.all[i] = pipe->create_sampler_state(pipe, &sampler);
|
||||
}
|
||||
|
||||
memset(&template, 0, sizeof(struct pipe_texture));
|
||||
|
|
@ -1069,10 +1087,9 @@ static int vlInit
|
|||
template.depth[0] = 1;
|
||||
template.compressed = 0;
|
||||
pf_get_block(template.format, &template.block);
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC;
|
||||
|
||||
for (i = 0; i < NUM_BUF_SETS; ++i)
|
||||
mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template);
|
||||
mc->textures.y = pipe->screen->texture_create(pipe->screen, &template);
|
||||
|
||||
if (mc->picture_format == vlFormatYCbCr420)
|
||||
{
|
||||
|
|
@ -1082,13 +1099,10 @@ static int vlInit
|
|||
else if (mc->picture_format == vlFormatYCbCr422)
|
||||
template.height[0] = vlRoundUpPOT(mc->picture_height / 2);
|
||||
|
||||
for (i = 0; i < NUM_BUF_SETS; ++i)
|
||||
{
|
||||
mc->textures[i][1] = pipe->screen->texture_create(pipe->screen, &template);
|
||||
mc->textures[i][2] = pipe->screen->texture_create(pipe->screen, &template);
|
||||
}
|
||||
mc->textures.cb = pipe->screen->texture_create(pipe->screen, &template);
|
||||
mc->textures.cr = pipe->screen->texture_create(pipe->screen, &template);
|
||||
|
||||
/* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */
|
||||
/* textures.all[3] & textures.all[4] are assigned from vlSurfaces for P and B macroblocks at render time */
|
||||
|
||||
vlCreateVertexShaderIMB(mc);
|
||||
vlCreateFragmentShaderIMB(mc);
|
||||
|
|
@ -1114,13 +1128,12 @@ int vlCreateR16SNormBufferedMC
|
|||
struct vlRender **render
|
||||
)
|
||||
{
|
||||
struct vlR16SnormBufferedMC *mc;
|
||||
unsigned int i;
|
||||
struct vlR16SnormBufferedMC *mc;
|
||||
|
||||
assert(pipe);
|
||||
assert(render);
|
||||
|
||||
mc = calloc(1, sizeof(struct vlR16SnormBufferedMC));
|
||||
mc = CALLOC_STRUCT(vlR16SnormBufferedMC);
|
||||
|
||||
mc->base.vlBegin = &vlBegin;
|
||||
mc->base.vlRenderMacroBlocksMpeg2 = &vlRenderMacroBlocksMpeg2R16SnormBuffered;
|
||||
|
|
@ -1131,14 +1144,6 @@ int vlCreateR16SNormBufferedMC
|
|||
mc->picture_width = picture_width;
|
||||
mc->picture_height = picture_height;
|
||||
|
||||
mc->cur_buf = 0;
|
||||
mc->buffered_surface = NULL;
|
||||
mc->past_surface = NULL;
|
||||
mc->future_surface = NULL;
|
||||
for (i = 0; i < 3; ++i)
|
||||
mc->zero_block[i].x = -1.0f;
|
||||
mc->num_macroblocks = 0;
|
||||
|
||||
vlInit(mc);
|
||||
|
||||
*render = &mc->base;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#define VL_INTERNAL
|
||||
#include "vl_screen.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <util/u_memory.h>
|
||||
|
||||
int vlCreateScreen
|
||||
(
|
||||
|
|
@ -17,7 +17,7 @@ int vlCreateScreen
|
|||
assert(pscreen);
|
||||
assert(vl_screen);
|
||||
|
||||
scrn = calloc(1, sizeof(struct vlScreen));
|
||||
scrn = CALLOC_STRUCT(vlScreen);
|
||||
|
||||
if (!scrn)
|
||||
return 1;
|
||||
|
|
@ -37,7 +37,7 @@ int vlDestroyScreen
|
|||
{
|
||||
assert(screen);
|
||||
|
||||
free(screen);
|
||||
FREE(screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#define VL_INTERNAL
|
||||
#include "vl_surface.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pipe/p_screen.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <pipe/p_inlines.h>
|
||||
#include <util/u_memory.h>
|
||||
#include <vl_winsys.h>
|
||||
#include "vl_screen.h"
|
||||
#include "vl_context.h"
|
||||
|
|
@ -28,7 +28,7 @@ int vlCreateSurface
|
|||
assert(screen);
|
||||
assert(surface);
|
||||
|
||||
sfc = calloc(1, sizeof(struct vlSurface));
|
||||
sfc = CALLOC_STRUCT(vlSurface);
|
||||
|
||||
if (!sfc)
|
||||
return 1;
|
||||
|
|
@ -64,7 +64,7 @@ int vlDestroySurface
|
|||
assert(surface);
|
||||
|
||||
pipe_texture_release(&surface->texture);
|
||||
free(surface);
|
||||
FREE(surface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +1,25 @@
|
|||
|
||||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = nouveau_dri.so
|
||||
|
||||
MINIGLX_SOURCES =
|
||||
SUBDIRS = common dri
|
||||
|
||||
PIPE_DRIVERS = \
|
||||
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
|
||||
$(TOP)/src/gallium/drivers/nv04/libnv04.a \
|
||||
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
|
||||
$(TOP)/src/gallium/drivers/nv20/libnv20.a \
|
||||
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
||||
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
||||
$(TOP)/src/gallium/drivers/nv50/libnv50.a
|
||||
|
||||
DRIVER_SOURCES = \
|
||||
nouveau_bo.c \
|
||||
nouveau_channel.c \
|
||||
nouveau_context.c \
|
||||
nouveau_device.c \
|
||||
nouveau_dma.c \
|
||||
nouveau_fence.c \
|
||||
nouveau_grobj.c \
|
||||
nouveau_lock.c \
|
||||
nouveau_notifier.c \
|
||||
nouveau_pushbuf.c \
|
||||
nouveau_resource.c \
|
||||
nouveau_screen.c \
|
||||
nouveau_swapbuffers.c \
|
||||
nouveau_winsys.c \
|
||||
nouveau_winsys_pipe.c \
|
||||
nouveau_winsys_softpipe.c \
|
||||
nv04_surface.c \
|
||||
nv50_surface.c
|
||||
default: subdirs
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_GALLIUM_SOURCES) \
|
||||
$(DRIVER_SOURCES)
|
||||
|
||||
ASM_SOURCES =
|
||||
subdirs:
|
||||
@for dir in $(SUBDIRS) ; do \
|
||||
if [ -d $$dir ] ; then \
|
||||
(cd $$dir && $(MAKE)) || exit 1 ; \
|
||||
fi \
|
||||
done
|
||||
|
||||
include ../Makefile.template
|
||||
|
||||
symlinks:
|
||||
clean:
|
||||
rm -f `find . -name \*.[oa]`
|
||||
rm -f `find . -name depend`
|
||||
|
||||
|
||||
# Dummy install target
|
||||
install:
|
||||
|
|
|
|||
32
src/gallium/winsys/drm/nouveau/common/Makefile
Normal file
32
src/gallium/winsys/drm/nouveau/common/Makefile
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
TOP = ../../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = nouveaudrm
|
||||
|
||||
C_SOURCES = \
|
||||
nouveau_bo.c \
|
||||
nouveau_channel.c \
|
||||
nouveau_context.c \
|
||||
nouveau_device.c \
|
||||
nouveau_dma.c \
|
||||
nouveau_fence.c \
|
||||
nouveau_grobj.c \
|
||||
nouveau_lock.c \
|
||||
nouveau_notifier.c \
|
||||
nouveau_pushbuf.c \
|
||||
nouveau_resource.c \
|
||||
nouveau_screen.c \
|
||||
nouveau_winsys.c \
|
||||
nouveau_winsys_pipe.c \
|
||||
nouveau_winsys_softpipe.c \
|
||||
nv04_surface.c \
|
||||
nv50_surface.c
|
||||
|
||||
|
||||
include ./Makefile.template
|
||||
|
||||
DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \
|
||||
&& pkg-config libdrm --atleast-version=2.3.1 \
|
||||
&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
|
||||
symlinks:
|
||||
|
||||
59
src/gallium/winsys/drm/nouveau/common/Makefile.template
Normal file
59
src/gallium/winsys/drm/nouveau/common/Makefile.template
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# -*-makefile-*-
|
||||
|
||||
COMMON_SOURCES =
|
||||
|
||||
OBJECTS = $(C_SOURCES:.c=.o) \
|
||||
$(CPP_SOURCES:.cpp=.o) \
|
||||
$(ASM_SOURCES:.S=.o)
|
||||
|
||||
|
||||
### Include directories
|
||||
INCLUDES = \
|
||||
-I. \
|
||||
-I$(TOP)/src/gallium/include \
|
||||
-I$(TOP)/src/gallium/auxiliary \
|
||||
-I$(TOP)/src/gallium/drivers \
|
||||
-I$(TOP)/include \
|
||||
$(DRIVER_INCLUDES)
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@
|
||||
|
||||
.S.o:
|
||||
$(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
|
||||
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
default: depend symlinks $(LIBNAME)
|
||||
|
||||
|
||||
$(LIBNAME): $(OBJECTS) Makefile Makefile.template
|
||||
$(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS)
|
||||
|
||||
|
||||
depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
|
||||
rm -f depend
|
||||
touch depend
|
||||
$(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \
|
||||
$(ASM_SOURCES) 2> /dev/null
|
||||
|
||||
|
||||
# Emacs tags
|
||||
tags:
|
||||
etags `find . -name \*.[ch]` `find ../include`
|
||||
|
||||
|
||||
# Remove .o and backup files
|
||||
clean::
|
||||
-rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS)
|
||||
-rm -f depend depend.bak
|
||||
|
||||
|
||||
include depend
|
||||
|
|
@ -272,6 +272,40 @@ nouveau_bo_del(struct nouveau_bo **bo)
|
|||
nouveau_bo_del_cb(nvbo);
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags)
|
||||
{
|
||||
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
|
||||
struct nouveau_fence *fence;
|
||||
|
||||
if (!nvbo)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the buffer is pending it must be busy, unless
|
||||
* both are RD, in which case we can allow access */
|
||||
if (nvbo->pending) {
|
||||
if ((nvbo->pending->flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD &&
|
||||
(flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
fence = nvbo->fence;
|
||||
else
|
||||
fence = nvbo->wr_fence;
|
||||
|
||||
/* If the buffer is not pending and doesn't have a fence
|
||||
* that conflicts with our flags then it can't be busy
|
||||
*/
|
||||
if (!fence)
|
||||
return 0;
|
||||
else
|
||||
/* If the fence is signalled the buffer is not busy, else is busy */
|
||||
return !nouveau_fence(fence)->signalled;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
|
||||
{
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_dma.h"
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma,
|
|||
if (!nvdev || !chan || *chan)
|
||||
return -EINVAL;
|
||||
|
||||
nvchan = calloc(1, sizeof(struct nouveau_channel_priv));
|
||||
nvchan = CALLOC_STRUCT(nouveau_channel_priv);
|
||||
if (!nvchan)
|
||||
return -ENOMEM;
|
||||
nvchan->base.device = dev;
|
||||
|
|
@ -48,7 +48,7 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma,
|
|||
ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
|
||||
&nvchan->drm, sizeof(nvchan->drm));
|
||||
if (ret) {
|
||||
free(nvchan);
|
||||
FREE(nvchan);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -111,16 +111,16 @@ nouveau_channel_free(struct nouveau_channel **chan)
|
|||
nvchan = nouveau_channel(*chan);
|
||||
*chan = NULL;
|
||||
nvdev = nouveau_device(nvchan->base.device);
|
||||
|
||||
|
||||
FIRE_RING_CH(&nvchan->base);
|
||||
|
||||
nouveau_grobj_free(&nvchan->base.vram);
|
||||
nouveau_grobj_free(&nvchan->base.gart);
|
||||
nouveau_grobj_free(&nvchan->base.nullobj);
|
||||
|
||||
FREE(nvchan->pb.buffers);
|
||||
FREE(nvchan->pb.relocs);
|
||||
cf.channel = nvchan->drm.channel;
|
||||
drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf));
|
||||
free(nvchan);
|
||||
FREE(nvchan);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,28 +1,13 @@
|
|||
#include "main/glheader.h"
|
||||
#include "glapi/glthread.h"
|
||||
#include <GL/internal/glcore.h>
|
||||
#include "utils.h"
|
||||
|
||||
#include "state_tracker/st_public.h"
|
||||
#include "state_tracker/st_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_screen.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_dri.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
static const struct dri_debug_control debug_control[] = {
|
||||
{ "bo", DEBUG_BO },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
int __nouveau_debug = 0;
|
||||
#endif
|
||||
|
||||
static void
|
||||
nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
|
||||
{
|
||||
|
|
@ -87,24 +72,17 @@ nouveau_channel_context_create(struct nouveau_device *dev)
|
|||
return nvc;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_context_create(const __GLcontextModes *glVis,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
int
|
||||
nouveau_context_init(struct nouveau_screen *nv_screen,
|
||||
drm_context_t hHWContext, drmLock *sarea_lock,
|
||||
struct nouveau_context *nv_share,
|
||||
struct nouveau_context *nv)
|
||||
{
|
||||
__DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
|
||||
struct nouveau_screen *nv_screen = driScrnPriv->private;
|
||||
struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context);
|
||||
struct pipe_context *pipe = NULL;
|
||||
struct st_context *st_share = NULL;
|
||||
struct nouveau_channel_context *nvc = NULL;
|
||||
struct nouveau_device *dev = nv_screen->device;
|
||||
int i;
|
||||
|
||||
if (sharedContextPrivate) {
|
||||
st_share = ((struct nouveau_context *)sharedContextPrivate)->st;
|
||||
}
|
||||
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x10:
|
||||
case 0x20:
|
||||
|
|
@ -121,27 +99,18 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset);
|
||||
return GL_FALSE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
driContextPriv->driverPrivate = (void *)nv;
|
||||
nv->nv_screen = nv_screen;
|
||||
nv->dri_screen = driScrnPriv;
|
||||
|
||||
{
|
||||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
|
||||
nvdev->ctx = driContextPriv->hHWContext;
|
||||
nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock;
|
||||
nvdev->ctx = hHWContext;
|
||||
nvdev->lock = sarea_lock;
|
||||
}
|
||||
|
||||
driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
|
||||
nv->dri_screen->myNum, "nouveau");
|
||||
#ifdef DEBUG
|
||||
__nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
|
||||
debug_control);
|
||||
#endif
|
||||
|
||||
/*XXX: Hack up a fake region and buffer object for front buffer.
|
||||
* This will go away with TTM, replaced with a simple reference
|
||||
* of the front buffer handle passed to us by the DDX.
|
||||
|
|
@ -185,12 +154,8 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
* a single process.
|
||||
*/
|
||||
nvc = nv_screen->nvc;
|
||||
if (!nvc && st_share) {
|
||||
struct nouveau_context *snv = st_share->pipe->priv;
|
||||
if (snv) {
|
||||
nvc = snv->nvc;
|
||||
}
|
||||
}
|
||||
if (!nvc && nv_share)
|
||||
nvc = nv_share->nvc;
|
||||
|
||||
/*XXX: temporary - disable multi-context/single-channel on pre-NV4x */
|
||||
switch (dev->chipset & 0xf0) {
|
||||
|
|
@ -211,7 +176,7 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
nvc = nouveau_channel_context_create(dev);
|
||||
if (!nvc) {
|
||||
NOUVEAU_ERR("Failed initialising GPU context\n");
|
||||
return GL_FALSE;
|
||||
return 1;
|
||||
}
|
||||
nv_screen->nvc = nvc;
|
||||
}
|
||||
|
|
@ -241,11 +206,11 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
case 0x80:
|
||||
case 0x90:
|
||||
if (nouveau_surface_init_nv50(nv))
|
||||
return GL_FALSE;
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
if (nouveau_surface_init_nv04(nv))
|
||||
return GL_FALSE;
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -268,26 +233,22 @@ nouveau_context_create(const __GLcontextModes *glVis,
|
|||
pipe = nouveau_create_softpipe(nv);
|
||||
if (!pipe) {
|
||||
NOUVEAU_ERR("Error creating pipe, bailing\n");
|
||||
return GL_FALSE;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
pipe->priv = nv;
|
||||
nv->st = st_create_context(pipe, glVis, st_share);
|
||||
return GL_TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
|
||||
nouveau_context_cleanup(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_context *nv = driContextPriv->driverPrivate;
|
||||
struct nouveau_channel_context *nvc = nv->nvc;
|
||||
|
||||
assert(nv);
|
||||
|
||||
st_finish(nv->st);
|
||||
st_destroy_context(nv->st);
|
||||
|
||||
if (nv->pctx_id >= 0) {
|
||||
nvc->pctx[nv->pctx_id] = NULL;
|
||||
if (--nvc->refcount <= 0) {
|
||||
|
|
@ -295,52 +256,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
|
|||
nv->nv_screen->nvc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(nv);
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
__DRIdrawablePrivate *driReadPriv)
|
||||
{
|
||||
struct nouveau_context *nv;
|
||||
struct nouveau_framebuffer *draw, *read;
|
||||
|
||||
if (!driContextPriv) {
|
||||
st_make_current(NULL, NULL, NULL);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
nv = driContextPriv->driverPrivate;
|
||||
draw = driDrawPriv->driverPrivate;
|
||||
read = driReadPriv->driverPrivate;
|
||||
|
||||
st_make_current(nv->st, draw->stfb, read->stfb);
|
||||
|
||||
if ((nv->dri_drawable != driDrawPriv) ||
|
||||
(nv->last_stamp != driDrawPriv->lastStamp)) {
|
||||
nv->dri_drawable = driDrawPriv;
|
||||
st_resize_framebuffer(draw->stfb, driDrawPriv->w,
|
||||
driDrawPriv->h);
|
||||
nv->last_stamp = driDrawPriv->lastStamp;
|
||||
}
|
||||
|
||||
if (driDrawPriv != driReadPriv) {
|
||||
st_resize_framebuffer(read->stfb, driReadPriv->w,
|
||||
driReadPriv->h);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_context_unbind(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
struct nouveau_context *nv = driContextPriv->driverPrivate;
|
||||
(void)nv;
|
||||
|
||||
st_flush(nv->st, 0, NULL);
|
||||
return GL_TRUE;
|
||||
|
||||
/* XXX: Who cleans up the pipe? */
|
||||
}
|
||||
|
||||
|
|
@ -1,17 +1,10 @@
|
|||
#ifndef __NOUVEAU_CONTEXT_H__
|
||||
#define __NOUVEAU_CONTEXT_H__
|
||||
|
||||
#include "dri_util.h"
|
||||
#include "xmlconfig.h"
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_dma.h"
|
||||
|
||||
struct nouveau_framebuffer {
|
||||
struct st_framebuffer *stfb;
|
||||
};
|
||||
|
||||
struct nouveau_channel_context {
|
||||
struct pipe_screen *pscreen;
|
||||
int refcount;
|
||||
|
|
@ -41,16 +34,7 @@ struct nouveau_channel_context {
|
|||
};
|
||||
|
||||
struct nouveau_context {
|
||||
struct st_context *st;
|
||||
|
||||
/* DRI stuff */
|
||||
__DRIscreenPrivate *dri_screen;
|
||||
__DRIdrawablePrivate *dri_drawable;
|
||||
unsigned int last_stamp;
|
||||
driOptionCache dri_option_cache;
|
||||
drm_context_t drm_context;
|
||||
drmLock drm_lock;
|
||||
GLboolean locked;
|
||||
int locked;
|
||||
struct nouveau_screen *nv_screen;
|
||||
struct pipe_surface *frontbuffer;
|
||||
|
||||
|
|
@ -76,26 +60,11 @@ struct nouveau_context {
|
|||
unsigned, unsigned, unsigned, unsigned, unsigned);
|
||||
};
|
||||
|
||||
extern GLboolean nouveau_context_create(const __GLcontextModes *,
|
||||
__DRIcontextPrivate *, void *);
|
||||
extern void nouveau_context_destroy(__DRIcontextPrivate *);
|
||||
extern GLboolean nouveau_context_bind(__DRIcontextPrivate *,
|
||||
__DRIdrawablePrivate *draw,
|
||||
__DRIdrawablePrivate *read);
|
||||
extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int __nouveau_debug;
|
||||
|
||||
#define DEBUG_BO (1 << 0)
|
||||
|
||||
#define DBG(flag, ...) do { \
|
||||
if (__nouveau_debug & (DEBUG_##flag)) \
|
||||
NOUVEAU_ERR(__VA_ARGS__); \
|
||||
} while(0)
|
||||
#else
|
||||
#define DBG(flag, ...)
|
||||
#endif
|
||||
extern int nouveau_context_init(struct nouveau_screen *nv_screen,
|
||||
drm_context_t hHWContext, drmLock *sarea_lock,
|
||||
struct nouveau_context *nv_share,
|
||||
struct nouveau_context *nv);
|
||||
extern void nouveau_context_cleanup(struct nouveau_context *nv);
|
||||
|
||||
extern void LOCK_HARDWARE(struct nouveau_context *);
|
||||
extern void UNLOCK_HARDWARE(struct nouveau_context *);
|
||||
|
|
@ -110,4 +79,8 @@ extern int nouveau_surface_init_nv50(struct nouveau_context *);
|
|||
extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int);
|
||||
extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *);
|
||||
|
||||
/* Must be provided by clients of common code */
|
||||
extern void
|
||||
nouveau_contended_lock(struct nouveau_context *nv);
|
||||
|
||||
#endif
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_drmif.h"
|
||||
|
||||
int
|
||||
|
|
@ -36,7 +36,7 @@ nouveau_device_open_existing(struct nouveau_device **dev, int close,
|
|||
if (!dev || *dev)
|
||||
return -EINVAL;
|
||||
|
||||
nvdev = calloc(1, sizeof(*nvdev));
|
||||
nvdev = CALLOC_STRUCT(nouveau_device_priv);
|
||||
if (!nvdev)
|
||||
return -ENOMEM;
|
||||
nvdev->fd = fd;
|
||||
|
|
@ -112,7 +112,7 @@ nouveau_device_close(struct nouveau_device **dev)
|
|||
drmDestroyContext(nvdev->fd, nvdev->ctx);
|
||||
drmClose(nvdev->fd);
|
||||
}
|
||||
free(nvdev);
|
||||
FREE(nvdev);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -286,6 +286,9 @@ nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags);
|
|||
extern void
|
||||
nouveau_bo_del(struct nouveau_bo **);
|
||||
|
||||
extern int
|
||||
nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags);
|
||||
|
||||
extern int
|
||||
nouveau_bo_map(struct nouveau_bo *, uint32_t flags);
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_drmif.h"
|
||||
|
||||
int
|
||||
|
|
@ -37,7 +37,7 @@ nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle,
|
|||
if (!nvdev || !grobj || *grobj)
|
||||
return -EINVAL;
|
||||
|
||||
nvgrobj = calloc(1, sizeof(*nvgrobj));
|
||||
nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv);
|
||||
if (!nvgrobj)
|
||||
return -ENOMEM;
|
||||
nvgrobj->base.channel = chan;
|
||||
|
|
@ -67,7 +67,7 @@ nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle,
|
|||
if (!chan || !grobj || *grobj)
|
||||
return -EINVAL;
|
||||
|
||||
nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv));
|
||||
nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv);
|
||||
if (!nvgrobj)
|
||||
return -ENOMEM;
|
||||
nvgrobj->base.channel = chan;
|
||||
|
|
@ -102,6 +102,6 @@ nouveau_grobj_free(struct nouveau_grobj **grobj)
|
|||
drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
|
||||
&f, sizeof(f));
|
||||
}
|
||||
free(nvgrobj);
|
||||
FREE(nvgrobj);
|
||||
}
|
||||
|
||||
|
|
@ -5,8 +5,6 @@
|
|||
#include "nouveau_winsys_pipe.h"
|
||||
#include <stdio.h>
|
||||
|
||||
struct pipe_buffer;
|
||||
|
||||
/* Debug output */
|
||||
#define NOUVEAU_MSG(fmt, args...) do { \
|
||||
fprintf(stdout, "nouveau: "fmt, ##args); \
|
||||
|
|
@ -25,34 +25,11 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "glapi/glthread.h"
|
||||
#include <GL/internal/glcore.h>
|
||||
|
||||
#include <pipe/p_thread.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen.h"
|
||||
|
||||
_glthread_DECLARE_STATIC_MUTEX( lockMutex );
|
||||
|
||||
static void
|
||||
nouveau_contended_lock(struct nouveau_context *nv, GLuint flags)
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = nv->dri_drawable;
|
||||
__DRIscreenPrivate *sPriv = nv->dri_screen;
|
||||
struct nouveau_screen *nv_screen = nv->nv_screen;
|
||||
struct nouveau_device *dev = nv_screen->device;
|
||||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
|
||||
drmGetLock(nvdev->fd, nvdev->ctx, flags);
|
||||
|
||||
/* If the window moved, may need to set a new cliprect now.
|
||||
*
|
||||
* NOTE: This releases and regains the hw lock, so all state
|
||||
* checking must be done *after* this call:
|
||||
*/
|
||||
if (dPriv)
|
||||
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
|
||||
}
|
||||
pipe_static_mutex(lockMutex);
|
||||
|
||||
/* Lock the hardware and validate our state.
|
||||
*/
|
||||
|
|
@ -64,20 +41,21 @@ LOCK_HARDWARE(struct nouveau_context *nv)
|
|||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
char __ret=0;
|
||||
|
||||
_glthread_LOCK_MUTEX(lockMutex);
|
||||
assert(!nv->locked);
|
||||
|
||||
pipe_mutex_lock(lockMutex);
|
||||
|
||||
DRM_CAS(nvdev->lock, nvdev->ctx,
|
||||
(DRM_LOCK_HELD | nvdev->ctx), __ret);
|
||||
|
||||
if (__ret)
|
||||
nouveau_contended_lock(nv, 0);
|
||||
nv->locked = GL_TRUE;
|
||||
|
||||
if (__ret) {
|
||||
drmGetLock(nvdev->fd, nvdev->ctx, 0);
|
||||
nouveau_contended_lock(nv);
|
||||
}
|
||||
nv->locked = 1;
|
||||
}
|
||||
|
||||
|
||||
/* Unlock the hardware using the global current context
|
||||
*/
|
||||
/* Unlock the hardware using the global current context
|
||||
*/
|
||||
void
|
||||
UNLOCK_HARDWARE(struct nouveau_context *nv)
|
||||
{
|
||||
|
|
@ -86,9 +64,9 @@ UNLOCK_HARDWARE(struct nouveau_context *nv)
|
|||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
|
||||
assert(nv->locked);
|
||||
nv->locked = GL_FALSE;
|
||||
nv->locked = 0;
|
||||
|
||||
DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx);
|
||||
|
||||
_glthread_UNLOCK_MUTEX(lockMutex);
|
||||
pipe_mutex_unlock(lockMutex);
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_dma.h"
|
||||
|
||||
|
|
@ -97,9 +97,9 @@ nouveau_pushbuf_init(struct nouveau_channel *chan)
|
|||
nouveau_pushbuf_space(chan, 0);
|
||||
chan->pushbuf = &nvchan->pb.base;
|
||||
|
||||
nvchan->pb.buffers = calloc(NOUVEAU_PUSHBUF_MAX_BUFFERS,
|
||||
nvchan->pb.buffers = CALLOC(NOUVEAU_PUSHBUF_MAX_BUFFERS,
|
||||
sizeof(struct nouveau_pushbuf_bo));
|
||||
nvchan->pb.relocs = calloc(NOUVEAU_PUSHBUF_MAX_RELOCS,
|
||||
nvchan->pb.relocs = CALLOC(NOUVEAU_PUSHBUF_MAX_RELOCS,
|
||||
sizeof(struct nouveau_pushbuf_reloc));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -268,4 +268,3 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,
|
|||
*(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_local.h"
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ nouveau_resource_init(struct nouveau_resource **heap,
|
|||
{
|
||||
struct nouveau_resource *r;
|
||||
|
||||
r = calloc(1, sizeof(struct nouveau_resource));
|
||||
r = CALLOC_STRUCT(nouveau_resource);
|
||||
if (!r)
|
||||
return 1;
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv,
|
|||
|
||||
while (heap) {
|
||||
if (!heap->in_use && heap->size >= size) {
|
||||
r = calloc(1, sizeof(struct nouveau_resource));
|
||||
r = CALLOC_STRUCT(nouveau_resource);
|
||||
if (!r)
|
||||
return 1;
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv,
|
|||
*res = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
heap = heap->next;
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ nouveau_resource_free(struct nouveau_resource **res)
|
|||
if (r->next)
|
||||
r->next->prev = r->prev;
|
||||
r->prev->size += r->size;
|
||||
free(r);
|
||||
FREE(r);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
31
src/gallium/winsys/drm/nouveau/common/nouveau_screen.c
Normal file
31
src/gallium/winsys/drm/nouveau/common/nouveau_screen.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#include <util/u_memory.h>
|
||||
#include "nouveau_dri.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
|
||||
int
|
||||
nouveau_screen_init(struct nouveau_dri *nv_dri, int dev_fd,
|
||||
struct nouveau_screen *nv_screen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nouveau_device_open_existing(&nv_screen->device, 0,
|
||||
dev_fd, 0);
|
||||
if (ret) {
|
||||
NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nv_screen->front_offset = nv_dri->front_offset;
|
||||
nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8);
|
||||
nv_screen->front_cpp = nv_dri->bpp / 8;
|
||||
nv_screen->front_height = nv_dri->height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_screen_cleanup(struct nouveau_screen *nv_screen)
|
||||
{
|
||||
nouveau_device_close(&nv_screen->device);
|
||||
}
|
||||
27
src/gallium/winsys/drm/nouveau/common/nouveau_screen.h
Normal file
27
src/gallium/winsys/drm/nouveau/common/nouveau_screen.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef __NOUVEAU_SCREEN_H__
|
||||
#define __NOUVEAU_SCREEN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct nouveau_device;
|
||||
struct nouveau_dri;
|
||||
|
||||
struct nouveau_screen {
|
||||
struct nouveau_device *device;
|
||||
|
||||
uint32_t front_offset;
|
||||
uint32_t front_pitch;
|
||||
uint32_t front_cpp;
|
||||
uint32_t front_height;
|
||||
|
||||
void *nvc;
|
||||
};
|
||||
|
||||
int
|
||||
nouveau_screen_init(struct nouveau_dri *nv_dri, int dev_fd,
|
||||
struct nouveau_screen *nv_screen);
|
||||
|
||||
void
|
||||
nouveau_screen_cleanup(struct nouveau_screen *nv_screen);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,55 +1,29 @@
|
|||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include <pipe/p_winsys.h>
|
||||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_inlines.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_swapbuffers.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
static void
|
||||
nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
|
||||
void *context_private)
|
||||
{
|
||||
struct nouveau_context *nv = context_private;
|
||||
__DRIdrawablePrivate *dPriv = nv->dri_drawable;
|
||||
|
||||
nouveau_copy_buffer(dPriv, surf, NULL);
|
||||
}
|
||||
|
||||
static const char *
|
||||
nouveau_get_name(struct pipe_winsys *pws)
|
||||
{
|
||||
return "Nouveau/DRI";
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
|
||||
unsigned usage, unsigned size)
|
||||
static uint32_t
|
||||
nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
|
||||
{
|
||||
struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
|
||||
struct nouveau_context *nv = nvpws->nv;
|
||||
struct nouveau_device *dev = nv->nv_screen->device;
|
||||
struct nouveau_pipe_buffer *nvbuf;
|
||||
uint32_t flags;
|
||||
|
||||
nvbuf = calloc(1, sizeof(*nvbuf));
|
||||
if (!nvbuf)
|
||||
return NULL;
|
||||
nvbuf->base.refcount = 1;
|
||||
nvbuf->base.alignment = alignment;
|
||||
nvbuf->base.usage = usage;
|
||||
nvbuf->base.size = size;
|
||||
|
||||
flags = NOUVEAU_BO_LOCAL;
|
||||
uint32_t flags = NOUVEAU_BO_LOCAL;
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_PIXEL) {
|
||||
if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
flags |= NOUVEAU_BO_VRAM;
|
||||
if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
|
||||
flags |= NOUVEAU_BO_VRAM;
|
||||
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x50:
|
||||
|
|
@ -74,8 +48,31 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
|
|||
flags |= NOUVEAU_BO_GART;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
|
||||
unsigned usage, unsigned size)
|
||||
{
|
||||
struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
|
||||
struct nouveau_context *nv = nvpws->nv;
|
||||
struct nouveau_device *dev = nv->nv_screen->device;
|
||||
struct nouveau_pipe_buffer *nvbuf;
|
||||
uint32_t flags;
|
||||
|
||||
nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
|
||||
if (!nvbuf)
|
||||
return NULL;
|
||||
nvbuf->base.refcount = 1;
|
||||
nvbuf->base.alignment = alignment;
|
||||
nvbuf->base.usage = usage;
|
||||
nvbuf->base.size = size;
|
||||
|
||||
flags = nouveau_flags_from_usage(nv, flags);
|
||||
|
||||
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
|
||||
free(nvbuf);
|
||||
FREE(nvbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -89,14 +86,14 @@ nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
|
|||
struct nouveau_device *dev = nvpws->nv->nv_screen->device;
|
||||
struct nouveau_pipe_buffer *nvbuf;
|
||||
|
||||
nvbuf = calloc(1, sizeof(*nvbuf));
|
||||
nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
|
||||
if (!nvbuf)
|
||||
return NULL;
|
||||
nvbuf->base.refcount = 1;
|
||||
nvbuf->base.size = bytes;
|
||||
|
||||
if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) {
|
||||
free(nvbuf);
|
||||
FREE(nvbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +106,7 @@ nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf)
|
|||
struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf);
|
||||
|
||||
nouveau_bo_del(&nvbuf->bo);
|
||||
free(nvbuf);
|
||||
FREE(nvbuf);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
|
@ -124,6 +121,26 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
|
|||
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
|
||||
map_flags |= NOUVEAU_BO_WR;
|
||||
|
||||
/* XXX: Technically incorrect. If the client maps a buffer for write-only
|
||||
* and leaves part of the buffer untouched it probably expects those parts
|
||||
* to remain intact. This is violated because we allocate a whole new buffer
|
||||
* and don't copy the previous buffer's contents, so this optimization is
|
||||
* only valid if the client intends to overwrite the whole buffer.
|
||||
*/
|
||||
if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR &&
|
||||
!nouveau_bo_busy(nvbuf->bo, map_flags)) {
|
||||
struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
|
||||
struct nouveau_context *nv = nvpws->nv;
|
||||
struct nouveau_device *dev = nv->nv_screen->device;
|
||||
struct nouveau_bo *rename;
|
||||
uint32_t flags = nouveau_flags_from_usage(nv, buf->usage);
|
||||
|
||||
if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) {
|
||||
nouveau_bo_del(&nvbuf->bo);
|
||||
nvbuf->bo = rename;
|
||||
}
|
||||
}
|
||||
|
||||
if (nouveau_bo_map(nvbuf->bo, map_flags))
|
||||
return NULL;
|
||||
return nvbuf->bo->map;
|
||||
|
|
@ -175,6 +192,12 @@ nouveau_pipe_fence_finish(struct pipe_winsys *ws,
|
|||
return nouveau_fence_wait(&ref);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_destroy(struct pipe_winsys *pws)
|
||||
{
|
||||
FREE(pws);
|
||||
}
|
||||
|
||||
struct pipe_winsys *
|
||||
nouveau_create_pipe_winsys(struct nouveau_context *nv)
|
||||
{
|
||||
|
|
@ -200,7 +223,7 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv)
|
|||
pws->fence_finish = nouveau_pipe_fence_finish;
|
||||
|
||||
pws->get_name = nouveau_get_name;
|
||||
pws->destroy = nouveau_destroy;
|
||||
|
||||
return &nvpws->pws;
|
||||
}
|
||||
|
||||
|
|
@ -31,4 +31,9 @@ nouveau_create_softpipe(struct nouveau_context *nv);
|
|||
struct pipe_context *
|
||||
nouveau_pipe_create(struct nouveau_context *nv);
|
||||
|
||||
/* Must be provided by clients of common code */
|
||||
extern void
|
||||
nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
|
||||
void *context_private);
|
||||
|
||||
#endif
|
||||
|
|
@ -29,12 +29,12 @@
|
|||
* Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
|
||||
*/
|
||||
|
||||
#include "imports.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "softpipe/sp_winsys.h"
|
||||
|
||||
#include <pipe/p_winsys.h>
|
||||
#include <pipe/p_screen.h>
|
||||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_format.h>
|
||||
#include <softpipe/sp_winsys.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ struct nouveau_softpipe_winsys {
|
|||
*/
|
||||
static boolean
|
||||
nouveau_is_format_supported(struct softpipe_winsys *sws,
|
||||
enum pipe_format format)
|
||||
enum pipe_format format)
|
||||
{
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
|
|
@ -68,19 +68,34 @@ nouveau_create_softpipe(struct nouveau_context *nv)
|
|||
struct nouveau_softpipe_winsys *nvsws;
|
||||
struct pipe_screen *pscreen;
|
||||
struct pipe_winsys *ws;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
ws = nouveau_create_pipe_winsys(nv);
|
||||
if (!ws)
|
||||
return NULL;
|
||||
pscreen = softpipe_create_screen(ws);
|
||||
|
||||
nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys);
|
||||
if (!nvsws)
|
||||
if (!pscreen) {
|
||||
ws->destroy(ws);
|
||||
return NULL;
|
||||
}
|
||||
nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys);
|
||||
if (!nvsws) {
|
||||
ws->destroy(ws);
|
||||
pscreen->destroy(pscreen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nvsws->sws.is_format_supported = nouveau_is_format_supported;
|
||||
nvsws->nv = nv;
|
||||
|
||||
return softpipe_create(pscreen, ws, &nvsws->sws);
|
||||
pipe = softpipe_create(pscreen, ws, &nvsws->sws);
|
||||
if (!pipe) {
|
||||
ws->destroy(ws);
|
||||
pscreen->destroy(pscreen);
|
||||
FREE(nvsws);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
|
|
@ -82,6 +82,37 @@ nv04_scaled_image_format(enum pipe_format format)
|
|||
}
|
||||
}
|
||||
|
||||
static INLINE unsigned
|
||||
nv04_swizzle_bits(unsigned x, unsigned y)
|
||||
{
|
||||
unsigned u = (x & 0x001) << 0 |
|
||||
(x & 0x002) << 1 |
|
||||
(x & 0x004) << 2 |
|
||||
(x & 0x008) << 3 |
|
||||
(x & 0x010) << 4 |
|
||||
(x & 0x020) << 5 |
|
||||
(x & 0x040) << 6 |
|
||||
(x & 0x080) << 7 |
|
||||
(x & 0x100) << 8 |
|
||||
(x & 0x200) << 9 |
|
||||
(x & 0x400) << 10 |
|
||||
(x & 0x800) << 11;
|
||||
|
||||
unsigned v = (y & 0x001) << 1 |
|
||||
(y & 0x002) << 2 |
|
||||
(y & 0x004) << 3 |
|
||||
(y & 0x008) << 4 |
|
||||
(y & 0x010) << 5 |
|
||||
(y & 0x020) << 6 |
|
||||
(y & 0x040) << 7 |
|
||||
(y & 0x080) << 8 |
|
||||
(y & 0x100) << 9 |
|
||||
(y & 0x200) << 10 |
|
||||
(y & 0x400) << 11 |
|
||||
(y & 0x800) << 12;
|
||||
return v | u;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy,
|
||||
unsigned sx, unsigned sy, unsigned w, unsigned h)
|
||||
|
|
@ -90,19 +121,23 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy,
|
|||
struct pipe_surface *dst = nv->surf_dst;
|
||||
struct pipe_surface *src = nv->surf_src;
|
||||
|
||||
const unsigned max_w = 1024;
|
||||
const unsigned max_h = 1024;
|
||||
const unsigned sub_w = w > max_w ? max_w : w;
|
||||
const unsigned sub_h = h > max_h ? max_h : h;
|
||||
unsigned cx = 0;
|
||||
unsigned cy = 0;
|
||||
|
||||
/* POT or GTFO */
|
||||
assert(!(w & (w - 1)) && !(h & (h - 1)));
|
||||
|
||||
BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1);
|
||||
OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo,
|
||||
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
|
||||
BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 2);
|
||||
BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 1);
|
||||
OUT_RING (chan, nv04_surface_format(dst->format) |
|
||||
log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT |
|
||||
log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT);
|
||||
OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset,
|
||||
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
|
||||
BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1);
|
||||
OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo,
|
||||
|
|
@ -110,24 +145,35 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy,
|
|||
BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1);
|
||||
OUT_RING (chan, nv->nvc->NvSwzSurf->handle);
|
||||
|
||||
BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9);
|
||||
OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
|
||||
OUT_RING (chan, nv04_scaled_image_format(src->format));
|
||||
OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, h << 16 | w);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, h << 16 | w);
|
||||
OUT_RING (chan, 1 << 20);
|
||||
OUT_RING (chan, 1 << 20);
|
||||
BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
|
||||
OUT_RING (chan, h << 16 | w);
|
||||
OUT_RING (chan, src->stride |
|
||||
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
|
||||
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
|
||||
OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset,
|
||||
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, 0);
|
||||
for (cy = 0; cy < h; cy += sub_h) {
|
||||
for (cx = 0; cx < w; cx += sub_w) {
|
||||
BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_OFFSET, 1);
|
||||
OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo,
|
||||
dst->offset + nv04_swizzle_bits(cx, cy) * dst->block.size,
|
||||
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
|
||||
BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9);
|
||||
OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
|
||||
OUT_RING (chan, nv04_scaled_image_format(src->format));
|
||||
OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, sub_h << 16 | sub_w);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, sub_h << 16 | sub_w);
|
||||
OUT_RING (chan, 1 << 20);
|
||||
OUT_RING (chan, 1 << 20);
|
||||
|
||||
BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
|
||||
OUT_RING (chan, sub_h << 16 | sub_w);
|
||||
OUT_RING (chan, src->stride |
|
||||
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
|
||||
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
|
||||
OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo,
|
||||
src->offset + cy * src->stride + cx * src->block.size,
|
||||
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
31
src/gallium/winsys/drm/nouveau/dri/Makefile
Normal file
31
src/gallium/winsys/drm/nouveau/dri/Makefile
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
TOP = ../../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = nouveau_dri.so
|
||||
|
||||
MINIGLX_SOURCES =
|
||||
|
||||
PIPE_DRIVERS = \
|
||||
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
|
||||
$(TOP)/src/gallium/drivers/nv04/libnv04.a \
|
||||
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
|
||||
$(TOP)/src/gallium/drivers/nv20/libnv20.a \
|
||||
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
||||
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
||||
$(TOP)/src/gallium/drivers/nv50/libnv50.a
|
||||
|
||||
DRIVER_SOURCES = \
|
||||
nouveau_context_dri.c \
|
||||
nouveau_screen_dri.c \
|
||||
nouveau_swapbuffers.c \
|
||||
../common/libnouveaudrm.a
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_GALLIUM_SOURCES) \
|
||||
$(DRIVER_SOURCES)
|
||||
|
||||
ASM_SOURCES =
|
||||
|
||||
include ../../Makefile.template
|
||||
|
||||
symlinks:
|
||||
124
src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
Normal file
124
src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#include <main/glheader.h>
|
||||
#include <glapi/glthread.h>
|
||||
#include <GL/internal/glcore.h>
|
||||
#include <utils.h>
|
||||
|
||||
#include <state_tracker/st_public.h>
|
||||
#include <state_tracker/st_context.h>
|
||||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_screen.h>
|
||||
|
||||
#include "../common/nouveau_winsys_pipe.h"
|
||||
#include "../common/nouveau_dri.h"
|
||||
#include "../common/nouveau_local.h"
|
||||
#include "nouveau_context_dri.h"
|
||||
#include "nouveau_screen_dri.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
static const struct dri_debug_control debug_control[] = {
|
||||
{ "bo", DEBUG_BO },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
int __nouveau_debug = 0;
|
||||
#endif
|
||||
|
||||
GLboolean
|
||||
nouveau_context_create(const __GLcontextModes *glVis,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
__DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
|
||||
struct nouveau_screen_dri *nv_screen = driScrnPriv->private;
|
||||
struct nouveau_context_dri *nv = CALLOC_STRUCT(nouveau_context_dri);
|
||||
struct st_context *st_share = NULL;
|
||||
struct nouveau_context_dri *nv_share = NULL;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
if (sharedContextPrivate) {
|
||||
st_share = ((struct nouveau_context_dri *)sharedContextPrivate)->st;
|
||||
nv_share = st_share->pipe->priv;
|
||||
}
|
||||
|
||||
if (nouveau_context_init(&nv_screen->base, driContextPriv->hHWContext,
|
||||
(drmLock *)&driScrnPriv->pSAREA->lock,
|
||||
nv_share, &nv->base)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
pipe = nv->base.nvc->pctx[nv->base.pctx_id];
|
||||
driContextPriv->driverPrivate = (void *)nv;
|
||||
//nv->nv_screen = nv_screen;
|
||||
nv->dri_screen = driScrnPriv;
|
||||
|
||||
driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
|
||||
nv->dri_screen->myNum, "nouveau");
|
||||
#ifdef DEBUG
|
||||
__nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
|
||||
debug_control);
|
||||
#endif
|
||||
|
||||
nv->st = st_create_context(pipe, glVis, st_share);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
struct nouveau_context_dri *nv = driContextPriv->driverPrivate;
|
||||
|
||||
assert(nv);
|
||||
|
||||
st_finish(nv->st);
|
||||
st_destroy_context(nv->st);
|
||||
|
||||
nouveau_context_cleanup(&nv->base);
|
||||
|
||||
FREE(nv);
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
__DRIdrawablePrivate *driReadPriv)
|
||||
{
|
||||
struct nouveau_context_dri *nv;
|
||||
struct nouveau_framebuffer *draw, *read;
|
||||
|
||||
if (!driContextPriv) {
|
||||
st_make_current(NULL, NULL, NULL);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
nv = driContextPriv->driverPrivate;
|
||||
draw = driDrawPriv->driverPrivate;
|
||||
read = driReadPriv->driverPrivate;
|
||||
|
||||
st_make_current(nv->st, draw->stfb, read->stfb);
|
||||
|
||||
if ((nv->dri_drawable != driDrawPriv) ||
|
||||
(nv->last_stamp != driDrawPriv->lastStamp)) {
|
||||
nv->dri_drawable = driDrawPriv;
|
||||
st_resize_framebuffer(draw->stfb, driDrawPriv->w,
|
||||
driDrawPriv->h);
|
||||
nv->last_stamp = driDrawPriv->lastStamp;
|
||||
}
|
||||
|
||||
if (driDrawPriv != driReadPriv) {
|
||||
st_resize_framebuffer(read->stfb, driReadPriv->w,
|
||||
driReadPriv->h);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_context_unbind(__DRIcontextPrivate *driContextPriv)
|
||||
{
|
||||
struct nouveau_context_dri *nv = driContextPriv->driverPrivate;
|
||||
(void)nv;
|
||||
|
||||
st_flush(nv->st, 0, NULL);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
49
src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h
Normal file
49
src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef __NOUVEAU_CONTEXT_DRI_H__
|
||||
#define __NOUVEAU_CONTEXT_DRI_H__
|
||||
|
||||
#include <dri_util.h>
|
||||
#include <xmlconfig.h>
|
||||
#include <nouveau/nouveau_winsys.h>
|
||||
#include "../common/nouveau_context.h"
|
||||
#include "../common/nouveau_drmif.h"
|
||||
#include "../common/nouveau_dma.h"
|
||||
|
||||
struct nouveau_framebuffer {
|
||||
struct st_framebuffer *stfb;
|
||||
};
|
||||
|
||||
struct nouveau_context_dri {
|
||||
struct nouveau_context base;
|
||||
struct st_context *st;
|
||||
|
||||
/* DRI stuff */
|
||||
__DRIscreenPrivate *dri_screen;
|
||||
__DRIdrawablePrivate *dri_drawable;
|
||||
unsigned int last_stamp;
|
||||
driOptionCache dri_option_cache;
|
||||
drm_context_t drm_context;
|
||||
drmLock drm_lock;
|
||||
};
|
||||
|
||||
extern GLboolean nouveau_context_create(const __GLcontextModes *,
|
||||
__DRIcontextPrivate *, void *);
|
||||
extern void nouveau_context_destroy(__DRIcontextPrivate *);
|
||||
extern GLboolean nouveau_context_bind(__DRIcontextPrivate *,
|
||||
__DRIdrawablePrivate *draw,
|
||||
__DRIdrawablePrivate *read);
|
||||
extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int __nouveau_debug;
|
||||
|
||||
#define DEBUG_BO (1 << 0)
|
||||
|
||||
#define DBG(flag, ...) do { \
|
||||
if (__nouveau_debug & (DEBUG_##flag)) \
|
||||
NOUVEAU_ERR(__VA_ARGS__); \
|
||||
} while(0)
|
||||
#else
|
||||
#define DBG(flag, ...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,16 +1,15 @@
|
|||
#include "utils.h"
|
||||
#include "vblank.h"
|
||||
#include "xmlpool.h"
|
||||
#include <utils.h>
|
||||
#include <vblank.h>
|
||||
#include <xmlpool.h>
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "state_tracker/st_public.h"
|
||||
#include "state_tracker/st_cb_fbo.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_dri.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include <pipe/p_context.h>
|
||||
#include <state_tracker/st_public.h>
|
||||
#include <state_tracker/st_cb_fbo.h>
|
||||
#include <nouveau_drm.h>
|
||||
#include "../common/nouveau_dri.h"
|
||||
#include "../common/nouveau_local.h"
|
||||
#include "nouveau_context_dri.h"
|
||||
#include "nouveau_screen_dri.h"
|
||||
#include "nouveau_swapbuffers.h"
|
||||
|
||||
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11
|
||||
|
|
@ -183,13 +182,12 @@ static const __DRIconfig **
|
|||
nouveau_screen_create(__DRIscreenPrivate *psp)
|
||||
{
|
||||
struct nouveau_dri *nv_dri = psp->pDevPriv;
|
||||
struct nouveau_screen *nv_screen;
|
||||
struct nouveau_screen_dri *nv_screen;
|
||||
static const __DRIversion ddx_expected =
|
||||
{ 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
|
||||
static const __DRIversion dri_expected = { 4, 0, 0 };
|
||||
static const __DRIversion drm_expected =
|
||||
{ 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
|
||||
int ret;
|
||||
|
||||
if (!driCheckDriDdxDrmVersions2("nouveau",
|
||||
&psp->dri_version, &dri_expected,
|
||||
|
|
@ -209,28 +207,23 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
|
|||
|
||||
if (psp->devPrivSize != sizeof(struct nouveau_dri)) {
|
||||
NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
|
||||
return GL_FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nv_screen = CALLOC_STRUCT(nouveau_screen);
|
||||
nv_screen = CALLOC_STRUCT(nouveau_screen_dri);
|
||||
if (!nv_screen)
|
||||
return GL_FALSE;
|
||||
nv_screen->driScrnPriv = psp;
|
||||
psp->private = (void *)nv_screen;
|
||||
return NULL;
|
||||
|
||||
driParseOptionInfo(&nv_screen->option_cache,
|
||||
__driConfigOptions, __driNConfigOptions);
|
||||
|
||||
if ((ret = nouveau_device_open_existing(&nv_screen->device, 0,
|
||||
psp->fd, 0))) {
|
||||
NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret);
|
||||
return GL_FALSE;
|
||||
if (nouveau_screen_init(nv_dri, psp->fd, &nv_screen->base)) {
|
||||
FREE(nv_screen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nv_screen->front_offset = nv_dri->front_offset;
|
||||
nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8);
|
||||
nv_screen->front_cpp = nv_dri->bpp / 8;
|
||||
nv_screen->front_height = nv_dri->height;
|
||||
nv_screen->driScrnPriv = psp;
|
||||
psp->private = (void *)nv_screen;
|
||||
|
||||
return (const __DRIconfig **)
|
||||
nouveau_fill_in_modes(psp, nv_dri->bpp,
|
||||
|
|
@ -241,9 +234,10 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
|
|||
static void
|
||||
nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv)
|
||||
{
|
||||
struct nouveau_screen *nv_screen = driScrnPriv->private;
|
||||
struct nouveau_screen_dri *nv_screen = driScrnPriv->private;
|
||||
|
||||
driScrnPriv->private = NULL;
|
||||
nouveau_screen_cleanup(&nv_screen->base);
|
||||
FREE(nv_screen);
|
||||
}
|
||||
|
||||
13
src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h
Normal file
13
src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef __NOUVEAU_SCREEN_DRI_H__
|
||||
#define __NOUVEAU_SCREEN_DRI_H__
|
||||
|
||||
#include "../common/nouveau_screen.h"
|
||||
#include "xmlconfig.h"
|
||||
|
||||
struct nouveau_screen_dri {
|
||||
struct nouveau_screen base;
|
||||
__DRIscreenPrivate *driScrnPriv;
|
||||
driOptionCache option_cache;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,34 +1,34 @@
|
|||
#include "main/glheader.h"
|
||||
#include "glapi/glthread.h"
|
||||
#include <main/glheader.h>
|
||||
#include <glapi/glthread.h>
|
||||
#include <GL/internal/glcore.h>
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "state_tracker/st_public.h"
|
||||
#include "state_tracker/st_context.h"
|
||||
#include "state_tracker/st_cb_fbo.h"
|
||||
#include <pipe/p_context.h>
|
||||
#include <state_tracker/st_public.h>
|
||||
#include <state_tracker/st_context.h>
|
||||
#include <state_tracker/st_cb_fbo.h>
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "../common/nouveau_local.h"
|
||||
#include "nouveau_context_dri.h"
|
||||
#include "nouveau_screen_dri.h"
|
||||
#include "nouveau_swapbuffers.h"
|
||||
|
||||
void
|
||||
nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
|
||||
const drm_clip_rect_t *rect)
|
||||
{
|
||||
struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate;
|
||||
struct nouveau_context_dri *nv = dPriv->driContextPriv->driverPrivate;
|
||||
drm_clip_rect_t *pbox;
|
||||
int nbox, i;
|
||||
|
||||
LOCK_HARDWARE(nv);
|
||||
LOCK_HARDWARE(&nv->base);
|
||||
if (!dPriv->numClipRects) {
|
||||
UNLOCK_HARDWARE(nv);
|
||||
UNLOCK_HARDWARE(&nv->base);
|
||||
return;
|
||||
}
|
||||
pbox = dPriv->pClipRects;
|
||||
nbox = dPriv->numClipRects;
|
||||
|
||||
nv->surface_copy_prep(nv, nv->frontbuffer, surf);
|
||||
nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf);
|
||||
for (i = 0; i < nbox; i++, pbox++) {
|
||||
int sx, sy, dx, dy, w, h;
|
||||
|
||||
|
|
@ -39,11 +39,11 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
|
|||
w = pbox->x2 - pbox->x1;
|
||||
h = pbox->y2 - pbox->y1;
|
||||
|
||||
nv->surface_copy(nv, dx, dy, sx, sy, w, h);
|
||||
nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h);
|
||||
}
|
||||
|
||||
FIRE_RING(nv->nvc->channel);
|
||||
UNLOCK_HARDWARE(nv);
|
||||
FIRE_RING(nv->base.nvc->channel);
|
||||
UNLOCK_HARDWARE(&nv->base);
|
||||
|
||||
if (nv->last_stamp != dPriv->lastStamp) {
|
||||
struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
|
||||
|
|
@ -84,3 +84,29 @@ nouveau_swap_buffers(__DRIdrawablePrivate *dPriv)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
|
||||
void *context_private)
|
||||
{
|
||||
struct nouveau_context_dri *nv = context_private;
|
||||
__DRIdrawablePrivate *dPriv = nv->dri_drawable;
|
||||
|
||||
nouveau_copy_buffer(dPriv, surf, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_contended_lock(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_context_dri *nv_sub = (struct nouveau_context_dri*)nv;
|
||||
__DRIdrawablePrivate *dPriv = nv_sub->dri_drawable;
|
||||
__DRIscreenPrivate *sPriv = nv_sub->dri_screen;
|
||||
|
||||
/* If the window moved, may need to set a new cliprect now.
|
||||
*
|
||||
* NOTE: This releases and regains the hw lock, so all state
|
||||
* checking must be done *after* this call:
|
||||
*/
|
||||
if (dPriv)
|
||||
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
|
||||
}
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef __NOUVEAU_SCREEN_H__
|
||||
#define __NOUVEAU_SCREEN_H__
|
||||
|
||||
#include "xmlconfig.h"
|
||||
|
||||
struct nouveau_screen {
|
||||
__DRIscreenPrivate *driScrnPriv;
|
||||
driOptionCache option_cache;
|
||||
|
||||
struct nouveau_device *device;
|
||||
|
||||
uint32_t front_offset;
|
||||
uint32_t front_pitch;
|
||||
uint32_t front_cpp;
|
||||
uint32_t front_height;
|
||||
|
||||
void *nvc;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -3,35 +3,33 @@ GALLIUMDIR = ../../..
|
|||
DRMDIR ?= /usr
|
||||
DRIDIR = ../../../../driclient
|
||||
|
||||
OBJECTS = nouveau_bo.o nouveau_fence.o nouveau_swapbuffers.o nouveau_channel.o \
|
||||
nouveau_grobj.o nouveau_context.o nouveau_winsys.o nouveau_lock.o \
|
||||
nouveau_winsys_pipe.o nouveau_device.o nouveau_notifier.o nouveau_dma.o \
|
||||
nouveau_pushbuf.o nouveau_resource.o nouveau_screen.o nv04_surface.o \
|
||||
nv50_surface.o #nouveau_winsys_softpipe.o
|
||||
OBJECTS = nouveau_screen_vl.o nouveau_context_vl.o nouveau_swapbuffers.o
|
||||
|
||||
CFLAGS += -g -Wall -fPIC \
|
||||
-I${GALLIUMDIR}/include \
|
||||
-I${GALLIUMDIR}/winsys/g3dvl \
|
||||
-I${DRMDIR}/include \
|
||||
-I${DRMDIR}/include/drm \
|
||||
-I${GALLIUMDIR}/drivers \
|
||||
-I${GALLIUMDIR}/auxiliary \
|
||||
CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \
|
||||
-I${GALLIUMDIR}/include \
|
||||
-I${GALLIUMDIR}/winsys/g3dvl \
|
||||
-I${GALLIUMDIR}/winsys/drm/nouveau \
|
||||
-I${DRMDIR}/include \
|
||||
-I${DRMDIR}/include/drm \
|
||||
-I${GALLIUMDIR}/drivers \
|
||||
-I${GALLIUMDIR}/auxiliary \
|
||||
-I${DRIDIR}/include
|
||||
|
||||
LDFLAGS += -L${DRMDIR}/lib \
|
||||
-L${DRIDIR}/lib \
|
||||
-L${GALLIUMDIR}/auxiliary/draw \
|
||||
-L${GALLIUMDIR}/auxiliary/tgsi \
|
||||
-L${GALLIUMDIR}/auxiliary/translate \
|
||||
-L${GALLIUMDIR}/auxiliary/rtasm \
|
||||
-L${GALLIUMDIR}/auxiliary/cso_cache \
|
||||
-L${GALLIUMDIR}/drivers/nv10 \
|
||||
-L${GALLIUMDIR}/drivers/nv20 \
|
||||
-L${GALLIUMDIR}/drivers/nv30 \
|
||||
-L${GALLIUMDIR}/drivers/nv40 \
|
||||
LDFLAGS += -L${DRMDIR}/lib \
|
||||
-L${DRIDIR}/lib \
|
||||
-L${GALLIUMDIR}/winsys/drm/nouveau/common \
|
||||
-L${GALLIUMDIR}/auxiliary/draw \
|
||||
-L${GALLIUMDIR}/auxiliary/tgsi \
|
||||
-L${GALLIUMDIR}/auxiliary/translate \
|
||||
-L${GALLIUMDIR}/auxiliary/rtasm \
|
||||
-L${GALLIUMDIR}/auxiliary/cso_cache \
|
||||
-L${GALLIUMDIR}/drivers/nv10 \
|
||||
-L${GALLIUMDIR}/drivers/nv20 \
|
||||
-L${GALLIUMDIR}/drivers/nv30 \
|
||||
-L${GALLIUMDIR}/drivers/nv40 \
|
||||
-L${GALLIUMDIR}/drivers/nv50
|
||||
|
||||
LIBS += -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm
|
||||
LIBS += -lnouveaudrm -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm
|
||||
|
||||
#############################################
|
||||
|
||||
|
|
|
|||
|
|
@ -1,370 +0,0 @@
|
|||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_dri.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_winsys_pipe.h"
|
||||
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
static const struct dri_debug_control debug_control[] = {
|
||||
{ "bo", DEBUG_BO },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
int __nouveau_debug = 0;
|
||||
#endif
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: Re-examine dri_screen, dri_context, nouveau_screen, nouveau_context
|
||||
* relationships, seems like there is a lot of room for simplification there.
|
||||
*/
|
||||
|
||||
static void
|
||||
nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
|
||||
{
|
||||
nouveau_grobj_free(&nvc->NvCtxSurf2D);
|
||||
nouveau_grobj_free(&nvc->NvImageBlit);
|
||||
nouveau_grobj_free(&nvc->NvGdiRect);
|
||||
nouveau_grobj_free(&nvc->NvM2MF);
|
||||
nouveau_grobj_free(&nvc->Nv2D);
|
||||
nouveau_grobj_free(&nvc->NvSwzSurf);
|
||||
nouveau_grobj_free(&nvc->NvSIFM);
|
||||
|
||||
nouveau_notifier_free(&nvc->sync_notifier);
|
||||
|
||||
nouveau_channel_free(&nvc->channel);
|
||||
|
||||
FREE(nvc);
|
||||
}
|
||||
|
||||
static struct nouveau_channel_context *
|
||||
nouveau_channel_context_create(struct nouveau_device *dev)
|
||||
{
|
||||
struct nouveau_channel_context *nvc;
|
||||
int ret;
|
||||
|
||||
nvc = CALLOC_STRUCT(nouveau_channel_context);
|
||||
if (!nvc)
|
||||
return NULL;
|
||||
|
||||
if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002,
|
||||
&nvc->channel))) {
|
||||
NOUVEAU_ERR("Error creating GPU channel: %d\n", ret);
|
||||
nouveau_channel_context_destroy(nvc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nvc->next_handle = 0x80000000;
|
||||
|
||||
if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1,
|
||||
&nvc->sync_notifier))) {
|
||||
NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret);
|
||||
nouveau_channel_context_destroy(nvc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x50:
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
ret = nouveau_surface_channel_create_nv50(nvc);
|
||||
break;
|
||||
default:
|
||||
ret = nouveau_surface_channel_create_nv04(nvc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
NOUVEAU_ERR("Error initialising surface objects: %d\n", ret);
|
||||
nouveau_channel_context_destroy(nvc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nvc;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_context_create(dri_context_t *dri_context)
|
||||
{
|
||||
dri_screen_t *dri_screen = dri_context->dri_screen;
|
||||
struct nouveau_screen *nv_screen = dri_screen->private;
|
||||
struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context);
|
||||
struct pipe_context *pipe = NULL;
|
||||
struct nouveau_channel_context *nvc = NULL;
|
||||
struct nouveau_device *dev = nv_screen->device;
|
||||
int i;
|
||||
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x10:
|
||||
case 0x20:
|
||||
/* NV10 */
|
||||
case 0x30:
|
||||
/* NV30 */
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
/* NV40 */
|
||||
case 0x50:
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
/* G80 */
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dri_context->private = (void*)nv;
|
||||
nv->dri_context = dri_context;
|
||||
nv->nv_screen = nv_screen;
|
||||
|
||||
{
|
||||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
|
||||
nvdev->ctx = dri_context->drm_context;
|
||||
nvdev->lock = (drmLock*)&dri_screen->sarea->lock;
|
||||
}
|
||||
|
||||
/*
|
||||
driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
|
||||
nv->dri_screen->myNum, "nouveau");
|
||||
#ifdef DEBUG
|
||||
__nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
|
||||
debug_control);
|
||||
#endif
|
||||
*/
|
||||
|
||||
/*XXX: Hack up a fake region and buffer object for front buffer.
|
||||
* This will go away with TTM, replaced with a simple reference
|
||||
* of the front buffer handle passed to us by the DDX.
|
||||
*/
|
||||
{
|
||||
struct pipe_surface *fb_surf;
|
||||
struct nouveau_pipe_buffer *fb_buf;
|
||||
struct nouveau_bo_priv *fb_bo;
|
||||
|
||||
fb_bo = calloc(1, sizeof(struct nouveau_bo_priv));
|
||||
fb_bo->drm.offset = nv_screen->front_offset;
|
||||
fb_bo->drm.flags = NOUVEAU_MEM_FB;
|
||||
fb_bo->drm.size = nv_screen->front_pitch *
|
||||
nv_screen->front_height;
|
||||
fb_bo->refcount = 1;
|
||||
fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM;
|
||||
fb_bo->base.offset = fb_bo->drm.offset;
|
||||
fb_bo->base.handle = (unsigned long)fb_bo;
|
||||
fb_bo->base.size = fb_bo->drm.size;
|
||||
fb_bo->base.device = nv_screen->device;
|
||||
|
||||
fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer));
|
||||
fb_buf->bo = &fb_bo->base;
|
||||
|
||||
fb_surf = calloc(1, sizeof(struct pipe_surface));
|
||||
if (nv_screen->front_cpp == 2)
|
||||
fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM;
|
||||
else
|
||||
fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM;
|
||||
pf_get_block(fb_surf->format, &fb_surf->block);
|
||||
fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp;
|
||||
fb_surf->height = nv_screen->front_height;
|
||||
fb_surf->stride = fb_surf->width * fb_surf->block.size;
|
||||
fb_surf->refcount = 1;
|
||||
fb_surf->buffer = &fb_buf->base;
|
||||
|
||||
nv->frontbuffer = fb_surf;
|
||||
}
|
||||
|
||||
nvc = nv_screen->nvc;
|
||||
|
||||
if (!nvc) {
|
||||
nvc = nouveau_channel_context_create(dev);
|
||||
if (!nvc) {
|
||||
NOUVEAU_ERR("Failed initialising GPU context\n");
|
||||
return 1;
|
||||
}
|
||||
nv_screen->nvc = nvc;
|
||||
}
|
||||
|
||||
nvc->refcount++;
|
||||
nv->nvc = nvc;
|
||||
|
||||
/* Find a free slot for a pipe context, allocate a new one if needed */
|
||||
nv->pctx_id = -1;
|
||||
for (i = 0; i < nvc->nr_pctx; i++) {
|
||||
if (nvc->pctx[i] == NULL) {
|
||||
nv->pctx_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nv->pctx_id < 0) {
|
||||
nv->pctx_id = nvc->nr_pctx++;
|
||||
nvc->pctx =
|
||||
realloc(nvc->pctx,
|
||||
sizeof(struct pipe_context *) * nvc->nr_pctx);
|
||||
}
|
||||
|
||||
/* Create pipe */
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x50:
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
if (nouveau_surface_init_nv50(nv))
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
if (nouveau_surface_init_nv04(nv))
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) {
|
||||
struct pipe_screen *pscreen;
|
||||
|
||||
pipe = nouveau_pipe_create(nv);
|
||||
if (!pipe)
|
||||
NOUVEAU_ERR("Couldn't create hw pipe\n");
|
||||
pscreen = nvc->pscreen;
|
||||
|
||||
nv->cap.hw_vertex_buffer =
|
||||
pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF);
|
||||
nv->cap.hw_index_buffer =
|
||||
pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF);
|
||||
}
|
||||
|
||||
/* XXX: nouveau_winsys_softpipe needs a mesa header removed before we can compile it. */
|
||||
/*
|
||||
if (!pipe) {
|
||||
NOUVEAU_MSG("Using softpipe\n");
|
||||
pipe = nouveau_create_softpipe(nv);
|
||||
if (!pipe) {
|
||||
NOUVEAU_ERR("Error creating pipe, bailing\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!pipe) {
|
||||
NOUVEAU_ERR("Error creating pipe, bailing\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pipe->priv = nv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_context_destroy(dri_context_t *dri_context)
|
||||
{
|
||||
struct nouveau_context *nv = dri_context->private;
|
||||
struct nouveau_channel_context *nvc = nv->nvc;
|
||||
|
||||
assert(nv);
|
||||
|
||||
if (nv->pctx_id >= 0) {
|
||||
nvc->pctx[nv->pctx_id] = NULL;
|
||||
if (--nvc->refcount <= 0) {
|
||||
nouveau_channel_context_destroy(nvc);
|
||||
nv->nv_screen->nvc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(nv);
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_context_bind(struct nouveau_context *nv, dri_drawable_t *dri_drawable)
|
||||
{
|
||||
assert(nv);
|
||||
assert(dri_drawable);
|
||||
|
||||
if (nv->dri_drawable != dri_drawable)
|
||||
{
|
||||
nv->dri_drawable = dri_drawable;
|
||||
dri_drawable->private = nv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_context_unbind(struct nouveau_context *nv)
|
||||
{
|
||||
assert(nv);
|
||||
|
||||
nv->dri_drawable = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Show starts here */
|
||||
|
||||
int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable)
|
||||
{
|
||||
struct nouveau_context *nv;
|
||||
dri_drawable_t *dri_drawable;
|
||||
|
||||
nv = pipe->priv;
|
||||
|
||||
driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable);
|
||||
|
||||
nouveau_context_bind(nv, dri_drawable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unbind_pipe_drawable(struct pipe_context *pipe)
|
||||
{
|
||||
nouveau_context_unbind(pipe->priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pipe_context* create_pipe_context(Display *display, int screen)
|
||||
{
|
||||
dri_screen_t *dri_screen;
|
||||
dri_framebuffer_t dri_framebuf;
|
||||
dri_context_t *dri_context;
|
||||
struct nouveau_context *nv;
|
||||
|
||||
driCreateScreen(display, screen, &dri_screen, &dri_framebuf);
|
||||
driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context);
|
||||
|
||||
nouveau_screen_create(dri_screen, &dri_framebuf);
|
||||
nouveau_context_create(dri_context);
|
||||
|
||||
nv = dri_context->private;
|
||||
|
||||
return nv->nvc->pctx[nv->pctx_id];
|
||||
}
|
||||
|
||||
int destroy_pipe_context(struct pipe_context *pipe)
|
||||
{
|
||||
struct pipe_screen *screen;
|
||||
struct pipe_winsys *winsys;
|
||||
struct nouveau_context *nv;
|
||||
dri_screen_t *dri_screen;
|
||||
dri_context_t *dri_context;
|
||||
|
||||
assert(pipe);
|
||||
|
||||
screen = pipe->screen;
|
||||
winsys = pipe->winsys;
|
||||
nv = pipe->priv;
|
||||
dri_context = nv->dri_context;
|
||||
dri_screen = dri_context->dri_screen;
|
||||
|
||||
pipe->destroy(pipe);
|
||||
screen->destroy(screen);
|
||||
free(winsys);
|
||||
|
||||
nouveau_context_destroy(dri_context);
|
||||
nouveau_screen_destroy(dri_screen);
|
||||
driDestroyContext(dri_context);
|
||||
driDestroyScreen(dri_screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
#ifndef __NOUVEAU_CONTEXT_H__
|
||||
#define __NOUVEAU_CONTEXT_H__
|
||||
|
||||
/*#include "xmlconfig.h"*/
|
||||
|
||||
#include <driclient.h>
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_dma.h"
|
||||
|
||||
struct nouveau_channel_context {
|
||||
struct pipe_screen *pscreen;
|
||||
int refcount;
|
||||
|
||||
unsigned cur_pctx;
|
||||
unsigned nr_pctx;
|
||||
struct pipe_context **pctx;
|
||||
|
||||
struct nouveau_channel *channel;
|
||||
|
||||
struct nouveau_notifier *sync_notifier;
|
||||
|
||||
/* Common */
|
||||
struct nouveau_grobj *NvM2MF;
|
||||
/* NV04-NV40 */
|
||||
struct nouveau_grobj *NvCtxSurf2D;
|
||||
struct nouveau_grobj *NvSwzSurf;
|
||||
struct nouveau_grobj *NvImageBlit;
|
||||
struct nouveau_grobj *NvGdiRect;
|
||||
struct nouveau_grobj *NvSIFM;
|
||||
/* G80 */
|
||||
struct nouveau_grobj *Nv2D;
|
||||
|
||||
uint32_t next_handle;
|
||||
uint32_t next_subchannel;
|
||||
uint32_t next_sequence;
|
||||
};
|
||||
|
||||
struct nouveau_context {
|
||||
/* DRI stuff */
|
||||
dri_context_t *dri_context;
|
||||
dri_drawable_t *dri_drawable;
|
||||
unsigned int last_stamp;
|
||||
/*driOptionCache dri_option_cache;*/
|
||||
drm_context_t drm_context;
|
||||
drmLock drm_lock;
|
||||
int locked;
|
||||
struct nouveau_screen *nv_screen;
|
||||
struct pipe_surface *frontbuffer;
|
||||
|
||||
struct {
|
||||
int hw_vertex_buffer;
|
||||
int hw_index_buffer;
|
||||
} cap;
|
||||
|
||||
/* Hardware context */
|
||||
struct nouveau_channel_context *nvc;
|
||||
int pctx_id;
|
||||
|
||||
/* pipe_surface accel */
|
||||
struct pipe_surface *surf_src, *surf_dst;
|
||||
unsigned surf_src_offset, surf_dst_offset;
|
||||
|
||||
int (*surface_copy_prep)(struct nouveau_context *,
|
||||
struct pipe_surface *dst,
|
||||
struct pipe_surface *src);
|
||||
void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy,
|
||||
unsigned sx, unsigned sy, unsigned w, unsigned h);
|
||||
void (*surface_copy_done)(struct nouveau_context *);
|
||||
int (*surface_fill)(struct nouveau_context *, struct pipe_surface *,
|
||||
unsigned, unsigned, unsigned, unsigned, unsigned);
|
||||
};
|
||||
|
||||
extern int nouveau_context_create(dri_context_t *);
|
||||
extern void nouveau_context_destroy(dri_context_t *);
|
||||
extern int nouveau_context_bind(struct nouveau_context *, dri_drawable_t *);
|
||||
extern int nouveau_context_unbind(struct nouveau_context *);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int __nouveau_debug;
|
||||
|
||||
#define DEBUG_BO (1 << 0)
|
||||
|
||||
#define DBG(flag, ...) do { \
|
||||
if (__nouveau_debug & (DEBUG_##flag)) \
|
||||
NOUVEAU_ERR(__VA_ARGS__); \
|
||||
} while(0)
|
||||
#else
|
||||
#define DBG(flag, ...)
|
||||
#endif
|
||||
|
||||
extern void LOCK_HARDWARE(struct nouveau_context *);
|
||||
extern void UNLOCK_HARDWARE(struct nouveau_context *);
|
||||
|
||||
extern int
|
||||
nouveau_surface_channel_create_nv04(struct nouveau_channel_context *);
|
||||
extern int
|
||||
nouveau_surface_channel_create_nv50(struct nouveau_channel_context *);
|
||||
extern int nouveau_surface_init_nv04(struct nouveau_context *);
|
||||
extern int nouveau_surface_init_nv50(struct nouveau_context *);
|
||||
|
||||
extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int);
|
||||
extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *);
|
||||
|
||||
#endif
|
||||
172
src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c
Normal file
172
src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
#include "nouveau_context_vl.h"
|
||||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_screen.h>
|
||||
#include <util/u_memory.h>
|
||||
#include <common/nouveau_dri.h>
|
||||
#include <common/nouveau_local.h>
|
||||
#include <common/nouveau_winsys_pipe.h>
|
||||
#include "nouveau_screen_vl.h"
|
||||
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
static const struct dri_debug_control debug_control[] = {
|
||||
{ "bo", DEBUG_BO },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
int __nouveau_debug = 0;
|
||||
#endif
|
||||
*/
|
||||
|
||||
int
|
||||
nouveau_context_create(dri_context_t *dri_context)
|
||||
{
|
||||
dri_screen_t *dri_screen;
|
||||
struct nouveau_screen_vl *nv_screen;
|
||||
struct nouveau_context_vl *nv;
|
||||
|
||||
assert (dri_context);
|
||||
|
||||
dri_screen = dri_context->dri_screen;
|
||||
nv_screen = dri_screen->private;
|
||||
nv = CALLOC_STRUCT(nouveau_context_vl);
|
||||
|
||||
if (!nv)
|
||||
return 1;
|
||||
|
||||
if (nouveau_context_init(&nv_screen->base, dri_context->drm_context,
|
||||
(drmLock*)&dri_screen->sarea->lock, NULL, &nv->base))
|
||||
{
|
||||
FREE(nv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dri_context->private = (void*)nv;
|
||||
nv->dri_context = dri_context;
|
||||
nv->nv_screen = nv_screen;
|
||||
|
||||
/*
|
||||
driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
|
||||
nv->dri_screen->myNum, "nouveau");
|
||||
#ifdef DEBUG
|
||||
__nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
|
||||
debug_control);
|
||||
#endif
|
||||
*/
|
||||
|
||||
nv->base.nvc->pctx[nv->base.pctx_id]->priv = nv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_context_destroy(dri_context_t *dri_context)
|
||||
{
|
||||
struct nouveau_context_vl *nv = dri_context->private;
|
||||
|
||||
assert(dri_context);
|
||||
|
||||
nouveau_context_cleanup(&nv->base);
|
||||
|
||||
FREE(nv);
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_context_bind(struct nouveau_context_vl *nv, dri_drawable_t *dri_drawable)
|
||||
{
|
||||
assert(nv);
|
||||
assert(dri_drawable);
|
||||
|
||||
if (nv->dri_drawable != dri_drawable)
|
||||
{
|
||||
nv->dri_drawable = dri_drawable;
|
||||
dri_drawable->private = nv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_context_unbind(struct nouveau_context_vl *nv)
|
||||
{
|
||||
assert(nv);
|
||||
|
||||
nv->dri_drawable = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Show starts here */
|
||||
|
||||
int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable)
|
||||
{
|
||||
struct nouveau_context_vl *nv;
|
||||
dri_drawable_t *dri_drawable;
|
||||
|
||||
assert(pipe);
|
||||
|
||||
nv = pipe->priv;
|
||||
|
||||
driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable);
|
||||
|
||||
nouveau_context_bind(nv, dri_drawable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unbind_pipe_drawable(struct pipe_context *pipe)
|
||||
{
|
||||
assert (pipe);
|
||||
|
||||
nouveau_context_unbind(pipe->priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pipe_context* create_pipe_context(Display *display, int screen)
|
||||
{
|
||||
dri_screen_t *dri_screen;
|
||||
dri_framebuffer_t dri_framebuf;
|
||||
dri_context_t *dri_context;
|
||||
struct nouveau_context_vl *nv;
|
||||
|
||||
assert(display);
|
||||
|
||||
driCreateScreen(display, screen, &dri_screen, &dri_framebuf);
|
||||
driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context);
|
||||
|
||||
nouveau_screen_create(dri_screen, &dri_framebuf);
|
||||
nouveau_context_create(dri_context);
|
||||
|
||||
nv = dri_context->private;
|
||||
|
||||
return nv->base.nvc->pctx[nv->base.pctx_id];
|
||||
}
|
||||
|
||||
int destroy_pipe_context(struct pipe_context *pipe)
|
||||
{
|
||||
struct pipe_screen *screen;
|
||||
struct pipe_winsys *winsys;
|
||||
struct nouveau_context_vl *nv;
|
||||
dri_screen_t *dri_screen;
|
||||
dri_context_t *dri_context;
|
||||
|
||||
assert(pipe);
|
||||
|
||||
screen = pipe->screen;
|
||||
winsys = pipe->winsys;
|
||||
nv = pipe->priv;
|
||||
dri_context = nv->dri_context;
|
||||
dri_screen = dri_context->dri_screen;
|
||||
|
||||
pipe->destroy(pipe);
|
||||
screen->destroy(screen);
|
||||
FREE(winsys);
|
||||
|
||||
nouveau_context_destroy(dri_context);
|
||||
nouveau_screen_destroy(dri_screen);
|
||||
driDestroyContext(dri_context);
|
||||
driDestroyScreen(dri_screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
39
src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h
Normal file
39
src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef __NOUVEAU_CONTEXT_VL_H__
|
||||
#define __NOUVEAU_CONTEXT_VL_H__
|
||||
|
||||
#include <driclient.h>
|
||||
#include <nouveau/nouveau_winsys.h>
|
||||
#include <common/nouveau_context.h>
|
||||
|
||||
/*#include "xmlconfig.h"*/
|
||||
|
||||
struct nouveau_context_vl {
|
||||
struct nouveau_context base;
|
||||
struct nouveau_screen_vl *nv_screen;
|
||||
dri_context_t *dri_context;
|
||||
dri_drawable_t *dri_drawable;
|
||||
unsigned int last_stamp;
|
||||
/*driOptionCache dri_option_cache;*/
|
||||
drm_context_t drm_context;
|
||||
drmLock drm_lock;
|
||||
};
|
||||
|
||||
extern int nouveau_context_create(dri_context_t *);
|
||||
extern void nouveau_context_destroy(dri_context_t *);
|
||||
extern int nouveau_context_bind(struct nouveau_context_vl *, dri_drawable_t *);
|
||||
extern int nouveau_context_unbind(struct nouveau_context_vl *);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int __nouveau_debug;
|
||||
|
||||
#define DEBUG_BO (1 << 0)
|
||||
|
||||
#define DBG(flag, ...) do { \
|
||||
if (__nouveau_debug & (DEBUG_##flag)) \
|
||||
NOUVEAU_ERR(__VA_ARGS__); \
|
||||
} while(0)
|
||||
#else
|
||||
#define DBG(flag, ...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -25,12 +25,12 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <pipe/p_thread.h>
|
||||
#include <driclient.h>
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen.h"
|
||||
|
||||
static pthread_mutex_t lockMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pipe_static_mutex(lockMutex);
|
||||
|
||||
static void
|
||||
nouveau_contended_lock(struct nouveau_context *nv, unsigned int flags)
|
||||
|
|
@ -62,7 +62,7 @@ LOCK_HARDWARE(struct nouveau_context *nv)
|
|||
struct nouveau_device_priv *nvdev = nouveau_device(dev);
|
||||
char __ret=0;
|
||||
|
||||
pthread_mutex_lock(&lockMutex);
|
||||
pipe_mutex_lock(lockMutex);
|
||||
assert(!nv->locked);
|
||||
|
||||
DRM_CAS(nvdev->lock, nvdev->ctx,
|
||||
|
|
@ -88,5 +88,5 @@ UNLOCK_HARDWARE(struct nouveau_context *nv)
|
|||
|
||||
DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx);
|
||||
|
||||
pthread_mutex_unlock(&lockMutex);
|
||||
pipe_mutex_unlock(lockMutex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
#include "pipe/p_context.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen_vl.h"
|
||||
#include <util/u_memory.h>
|
||||
#include <nouveau_drm.h>
|
||||
#include "nouveau_dri.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_swapbuffers.h"
|
||||
#include <common/nouveau_dri.h>
|
||||
#include <common/nouveau_local.h>
|
||||
|
||||
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11
|
||||
#error nouveau_drm.h version does not match expected version
|
||||
|
|
@ -50,34 +47,33 @@ int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_versio
|
|||
int
|
||||
nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf)
|
||||
{
|
||||
struct nouveau_dri *nv_dri = dri_framebuf->private;
|
||||
struct nouveau_screen *nv_screen;
|
||||
int ret;
|
||||
struct nouveau_dri *nv_dri = dri_framebuf->private;
|
||||
struct nouveau_screen_vl *nv_screen;
|
||||
|
||||
assert(dri_screen);
|
||||
assert(dri_framebuf);
|
||||
|
||||
if (nouveau_check_dri_drm_ddx(&dri_screen->dri, &dri_screen->drm, &dri_screen->ddx))
|
||||
return 1;
|
||||
|
||||
nv_screen = CALLOC_STRUCT(nouveau_screen);
|
||||
nv_screen = CALLOC_STRUCT(nouveau_screen_vl);
|
||||
|
||||
if (!nv_screen)
|
||||
return 1;
|
||||
nv_screen->dri_screen = dri_screen;
|
||||
dri_screen->private = (void*)nv_screen;
|
||||
|
||||
if (nouveau_screen_init(nv_dri, dri_screen->fd, &nv_screen->base))
|
||||
{
|
||||
FREE(nv_screen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
driParseOptionInfo(&nv_screen->option_cache,
|
||||
__driConfigOptions, __driNConfigOptions);
|
||||
*/
|
||||
|
||||
if ((ret = nouveau_device_open_existing(&nv_screen->device, 0,
|
||||
dri_screen->fd, 0))) {
|
||||
NOUVEAU_ERR("Failed opening nouveau device: %d.\n", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nv_screen->front_offset = nv_dri->front_offset;
|
||||
nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8);
|
||||
nv_screen->front_cpp = nv_dri->bpp / 8;
|
||||
nv_screen->front_height = nv_dri->height;
|
||||
nv_screen->dri_screen = dri_screen;
|
||||
dri_screen->private = (void*)nv_screen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -85,7 +81,8 @@ nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf)
|
|||
void
|
||||
nouveau_screen_destroy(dri_screen_t *dri_screen)
|
||||
{
|
||||
struct nouveau_screen *nv_screen = dri_screen->private;
|
||||
struct nouveau_screen_vl *nv_screen = dri_screen->private;
|
||||
|
||||
nouveau_screen_cleanup(&nv_screen->base);
|
||||
FREE(nv_screen);
|
||||
}
|
||||
|
|
@ -1,19 +1,16 @@
|
|||
#ifndef __NOUVEAU_SCREEN_H__
|
||||
#define __NOUVEAU_SCREEN_H__
|
||||
#ifndef __NOUVEAU_SCREEN_VL_H__
|
||||
#define __NOUVEAU_SCREEN_VL_H__
|
||||
|
||||
#include <driclient.h>
|
||||
#include <common/nouveau_screen.h>
|
||||
|
||||
/* TODO: Investigate using DRI options for interesting things */
|
||||
/*#include "xmlconfig.h"*/
|
||||
|
||||
struct nouveau_screen {
|
||||
struct nouveau_screen_vl
|
||||
{
|
||||
struct nouveau_screen base;
|
||||
dri_screen_t *dri_screen;
|
||||
struct nouveau_device *device;
|
||||
struct nouveau_channel_context *nvc;
|
||||
|
||||
uint32_t front_offset;
|
||||
uint32_t front_pitch;
|
||||
uint32_t front_cpp;
|
||||
uint32_t front_height;
|
||||
|
||||
/*driOptionCache option_cache;*/
|
||||
};
|
||||
|
||||
|
|
@ -21,4 +18,3 @@ int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_frame
|
|||
void nouveau_screen_destroy(dri_screen_t *dri_screen);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,26 +1,26 @@
|
|||
#include "pipe/p_context.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_local.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include <driclient.h>
|
||||
#include <common/nouveau_local.h>
|
||||
#include <common/nouveau_screen.h>
|
||||
#include "nouveau_context_vl.h"
|
||||
#include "nouveau_swapbuffers.h"
|
||||
|
||||
void
|
||||
nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf,
|
||||
const drm_clip_rect_t *rect)
|
||||
{
|
||||
struct nouveau_context *nv = dri_drawable->private;
|
||||
drm_clip_rect_t *pbox;
|
||||
int nbox, i;
|
||||
struct nouveau_context_vl *nv = dri_drawable->private;
|
||||
drm_clip_rect_t *pbox;
|
||||
int nbox, i;
|
||||
|
||||
LOCK_HARDWARE(nv);
|
||||
LOCK_HARDWARE(&nv->base);
|
||||
if (!dri_drawable->num_cliprects) {
|
||||
UNLOCK_HARDWARE(nv);
|
||||
UNLOCK_HARDWARE(&nv->base);
|
||||
return;
|
||||
}
|
||||
pbox = dri_drawable->cliprects;
|
||||
nbox = dri_drawable->num_cliprects;
|
||||
|
||||
nv->surface_copy_prep(nv, nv->frontbuffer, surf);
|
||||
nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf);
|
||||
for (i = 0; i < nbox; i++, pbox++) {
|
||||
int sx, sy, dx, dy, w, h;
|
||||
|
||||
|
|
@ -31,14 +31,11 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf,
|
|||
w = pbox->x2 - pbox->x1;
|
||||
h = pbox->y2 - pbox->y1;
|
||||
|
||||
nv->surface_copy(nv, dx, dy, sx, sy, w, h);
|
||||
nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h);
|
||||
}
|
||||
|
||||
FIRE_RING(nv->nvc->channel);
|
||||
UNLOCK_HARDWARE(nv);
|
||||
|
||||
//if (nv->last_stamp != dri_drawable->last_sarea_stamp)
|
||||
//nv->last_stamp = dri_drawable->last_sarea_stamp;
|
||||
FIRE_RING(nv->base.nvc->channel);
|
||||
UNLOCK_HARDWARE(&nv->base);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -62,3 +59,35 @@ nouveau_swap_buffers(dri_drawable_t *dri_drawable, struct pipe_surface *surf)
|
|||
nouveau_copy_buffer(dri_drawable, surf, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
|
||||
void *context_private)
|
||||
{
|
||||
struct nouveau_context_vl *nv;
|
||||
dri_drawable_t *dri_drawable;
|
||||
|
||||
assert(pws);
|
||||
assert(surf);
|
||||
assert(context_private);
|
||||
|
||||
nv = context_private;
|
||||
dri_drawable = nv->dri_drawable;
|
||||
|
||||
nouveau_copy_buffer(dri_drawable, surf, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_contended_lock(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_context_vl *nv_vl = (struct nouveau_context_vl*)nv;
|
||||
dri_drawable_t *dri_drawable = nv_vl->dri_drawable;
|
||||
dri_screen_t *dri_screen = nv_vl->dri_context->dri_screen;
|
||||
|
||||
/* If the window moved, may need to set a new cliprect now.
|
||||
*
|
||||
* NOTE: This releases and regains the hw lock, so all state
|
||||
* checking must be done *after* this call:
|
||||
*/
|
||||
if (dri_drawable)
|
||||
DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,31 @@ nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
|
||||
{
|
||||
uint32_t flags = NOUVEAU_BO_LOCAL;
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_PIXEL) {
|
||||
if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
|
||||
flags |= NOUVEAU_BO_VRAM;
|
||||
}
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_VERTEX) {
|
||||
if (nv->cap.hw_vertex_buffer)
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
}
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_INDEX) {
|
||||
if (nv->cap.hw_index_buffer)
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
|
||||
unsigned usage, unsigned size)
|
||||
|
|
@ -107,23 +132,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
|
|||
nvbuf->base.usage = usage;
|
||||
nvbuf->base.size = size;
|
||||
|
||||
flags = NOUVEAU_BO_LOCAL;
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_PIXEL) {
|
||||
if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
flags |= NOUVEAU_BO_VRAM;
|
||||
}
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_VERTEX) {
|
||||
if (nv->cap.hw_vertex_buffer)
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
}
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_INDEX) {
|
||||
if (nv->cap.hw_index_buffer)
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
}
|
||||
flags = nouveau_flags_from_usage(nv, usage);
|
||||
|
||||
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
|
||||
free(nvbuf);
|
||||
|
|
@ -175,6 +184,26 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
|
|||
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
|
||||
map_flags |= NOUVEAU_BO_WR;
|
||||
|
||||
if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR &&
|
||||
!nouveau_bo_busy(nvbuf->bo, map_flags)) {
|
||||
/* XXX: Technically incorrect. If the client maps a buffer for write-only
|
||||
* and leaves part of the buffer untouched it probably expects those parts
|
||||
* to remain intact. This is violated because we allocate a whole new buffer
|
||||
* and don't copy the previous buffer's contents, so this optimization is
|
||||
* only valid if the client intends to overwrite the whole buffer.
|
||||
*/
|
||||
struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
|
||||
struct nouveau_context *nv = nvpws->nv;
|
||||
struct nouveau_device *dev = nv->nv_screen->device;
|
||||
struct nouveau_bo *rename;
|
||||
uint32_t flags = nouveau_flags_from_usage(nv, buf->usage);
|
||||
|
||||
if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) {
|
||||
nouveau_bo_del(&nvbuf->bo);
|
||||
nvbuf->bo = rename;
|
||||
}
|
||||
}
|
||||
|
||||
if (nouveau_bo_map(nvbuf->bo, map_flags))
|
||||
return NULL;
|
||||
return nvbuf->bo->map;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ ifeq (${DRIVER}, softpipe)
|
|||
OBJECTS += ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o
|
||||
endif
|
||||
|
||||
CFLAGS += -g -fPIC -Wall \
|
||||
CFLAGS += -g -fPIC -Wall -Werror=implicit-function-declaration \
|
||||
-I${GALLIUMDIR}/state_trackers/g3dvl \
|
||||
-I${GALLIUMDIR}/winsys/g3dvl \
|
||||
-I${GALLIUMDIR}/include \
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
#include <util/u_memory.h>
|
||||
#include <vl_display.h>
|
||||
#include <vl_screen.h>
|
||||
#include <vl_context.h>
|
||||
|
|
@ -26,7 +26,7 @@ Status XvMCCreateBlocks(Display *display, XvMCContext *context, unsigned int num
|
|||
|
||||
blocks->context_id = context->context_id;
|
||||
blocks->num_blocks = num_blocks;
|
||||
blocks->blocks = malloc(BLOCK_SIZE * num_blocks);
|
||||
blocks->blocks = MALLOC(BLOCK_SIZE * num_blocks);
|
||||
/* Since we don't have a VL type for blocks, set privData to the display so we can catch mismatches */
|
||||
blocks->privData = display;
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *blocks)
|
|||
assert(display);
|
||||
assert(blocks);
|
||||
assert(display == blocks->privData);
|
||||
free(blocks->blocks);
|
||||
FREE(blocks->blocks);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, unsigned in
|
|||
|
||||
blocks->context_id = context->context_id;
|
||||
blocks->num_blocks = num_blocks;
|
||||
blocks->macro_blocks = malloc(sizeof(XvMCMacroBlock) * num_blocks);
|
||||
blocks->macro_blocks = MALLOC(sizeof(XvMCMacroBlock) * num_blocks);
|
||||
/* Since we don't have a VL type for blocks, set privData to the display so we can catch mismatches */
|
||||
blocks->privData = display;
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *blocks)
|
|||
assert(display);
|
||||
assert(blocks);
|
||||
assert(display == blocks->privData);
|
||||
free(blocks->macro_blocks);
|
||||
FREE(blocks->macro_blocks);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,6 +182,8 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i
|
|||
Status XvMCDestroyContext(Display *display, XvMCContext *context)
|
||||
{
|
||||
struct vlContext *vl_ctx;
|
||||
struct vlScreen *vl_screen;
|
||||
struct vlDisplay *vl_dpy;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
assert(display);
|
||||
|
|
@ -194,7 +196,11 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context)
|
|||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
|
||||
|
||||
pipe = vlGetPipeContext(vl_ctx);
|
||||
vl_screen = vlContextGetScreen(vl_ctx);
|
||||
vl_dpy = vlGetDisplay(vl_screen);
|
||||
vlDestroyContext(vl_ctx);
|
||||
vlDestroyScreen(vl_screen);
|
||||
vlDestroyDisplay(vl_dpy);
|
||||
destroy_pipe_context(pipe);
|
||||
|
||||
return Success;
|
||||
|
|
|
|||
|
|
@ -261,8 +261,14 @@ Status XvMCPutSurface
|
|||
|
||||
assert(srcx + srcw - 1 < surface->width);
|
||||
assert(srcy + srch - 1 < surface->height);
|
||||
assert(destx + destw - 1 < width);
|
||||
assert(desty + desth - 1 < height);
|
||||
/* XXX: Some apps (mplayer) hit these asserts because they call
|
||||
* this function after the window has been resized by the WM
|
||||
* but before they've handled the corresponding XEvent and
|
||||
* know about the new dimensions. The output will be clipped
|
||||
* for a few frames until the app updates destw and desth.
|
||||
*/
|
||||
/*assert(destx + destw - 1 < width);
|
||||
assert(desty + desth - 1 < height);*/
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,6 @@ i915CreateContext(const __GLcontextModes * mesaVis,
|
|||
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */
|
||||
|
||||
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
|
||||
ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE;
|
||||
|
||||
driInitExtensions(ctx, i915_extensions, GL_FALSE);
|
||||
|
||||
|
|
|
|||
|
|
@ -569,7 +569,7 @@ i915_update_fog(GLcontext * ctx)
|
|||
GLboolean enabled;
|
||||
GLboolean try_pixel_fog;
|
||||
|
||||
if (ctx->FragmentProgram._Active) {
|
||||
if (ctx->FragmentProgram._Current) {
|
||||
/* Pull in static fog state from program */
|
||||
mode = ctx->FragmentProgram._Current->FogOption;
|
||||
enabled = (mode != GL_NONE);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ DRIVER_SOURCES = \
|
|||
brw_vs_constval.c \
|
||||
brw_vs_emit.c \
|
||||
brw_vs_state.c \
|
||||
brw_vs_tnl.c \
|
||||
brw_vtbl.c \
|
||||
brw_wm.c \
|
||||
brw_wm_debug.c \
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ const struct brw_tracked_state brw_wm_unit;
|
|||
|
||||
const struct brw_tracked_state brw_psp_urb_cbs;
|
||||
|
||||
const struct brw_tracked_state brw_active_vertprog;
|
||||
const struct brw_tracked_state brw_pipe_control;
|
||||
|
||||
const struct brw_tracked_state brw_clear_surface_cache;
|
||||
|
|
|
|||
|
|
@ -314,12 +314,8 @@ void brw_validate_state( struct brw_context *brw )
|
|||
state->brw |= ~0;
|
||||
}
|
||||
|
||||
/* texenv program needs to notify us somehow when this happens:
|
||||
* Some confusion about which state flag should represent this change.
|
||||
*/
|
||||
if (brw->fragment_program != brw->attribs.FragmentProgram->_Current) {
|
||||
brw->fragment_program = brw->attribs.FragmentProgram->_Current;
|
||||
brw->state.dirty.mesa |= _NEW_PROGRAM;
|
||||
brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@ static void unalias1( struct brw_vs_compile *c,
|
|||
struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
|
||||
func(c, tmp, arg0);
|
||||
brw_MOV(p, dst, tmp);
|
||||
release_tmp(c, tmp);
|
||||
}
|
||||
else {
|
||||
func(c, dst, arg0);
|
||||
|
|
@ -214,12 +215,38 @@ static void unalias2( struct brw_vs_compile *c,
|
|||
struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
|
||||
func(c, tmp, arg0, arg1);
|
||||
brw_MOV(p, dst, tmp);
|
||||
release_tmp(c, tmp);
|
||||
}
|
||||
else {
|
||||
func(c, dst, arg0, arg1);
|
||||
}
|
||||
}
|
||||
|
||||
static void unalias3( struct brw_vs_compile *c,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg arg0,
|
||||
struct brw_reg arg1,
|
||||
struct brw_reg arg2,
|
||||
void (*func)( struct brw_vs_compile *,
|
||||
struct brw_reg,
|
||||
struct brw_reg,
|
||||
struct brw_reg,
|
||||
struct brw_reg ))
|
||||
{
|
||||
if ((dst.file == arg0.file && dst.nr == arg0.nr) ||
|
||||
(dst.file == arg1.file && dst.nr == arg1.nr) ||
|
||||
(dst.file == arg2.file && dst.nr == arg2.nr)) {
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
|
||||
func(c, tmp, arg0, arg1, arg2);
|
||||
brw_MOV(p, dst, tmp);
|
||||
release_tmp(c, tmp);
|
||||
}
|
||||
else {
|
||||
func(c, dst, arg0, arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_sop( struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg arg0,
|
||||
|
|
@ -590,6 +617,18 @@ static void emit_lit_noalias( struct brw_vs_compile *c,
|
|||
brw_ENDIF(p, if_insn);
|
||||
}
|
||||
|
||||
static void emit_lrp_noalias(struct brw_vs_compile *c,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg arg0,
|
||||
struct brw_reg arg1,
|
||||
struct brw_reg arg2)
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
|
||||
brw_ADD(p, dst, negate(arg0), brw_imm_f(1.0));
|
||||
brw_MUL(p, brw_null_reg(), dst, arg2);
|
||||
brw_MAC(p, dst, arg0, arg1);
|
||||
}
|
||||
|
||||
/** 3 or 4-component vector normalization */
|
||||
static void emit_nrm( struct brw_vs_compile *c,
|
||||
|
|
@ -1025,6 +1064,11 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
|||
else
|
||||
dst = get_dst(c, inst->DstReg);
|
||||
|
||||
if (inst->SaturateMode != SATURATE_OFF) {
|
||||
_mesa_problem(NULL, "Unsupported saturate %d in vertex shader",
|
||||
inst->SaturateMode);
|
||||
}
|
||||
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_ABS:
|
||||
brw_MOV(p, dst, brw_abs(args[0]));
|
||||
|
|
@ -1077,6 +1121,9 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
|||
case OPCODE_LIT:
|
||||
unalias1(c, dst, args[0], emit_lit_noalias);
|
||||
break;
|
||||
case OPCODE_LRP:
|
||||
unalias3(c, dst, args[0], args[1], args[2], emit_lrp_noalias);
|
||||
break;
|
||||
case OPCODE_MAD:
|
||||
brw_MOV(p, brw_acc_reg(), args[2]);
|
||||
brw_MAC(p, dst, args[0], args[1]);
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Tungsten Graphics All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file t_vp_build.c
|
||||
* Create a vertex program to execute the current fixed function T&L pipeline.
|
||||
* \author Keith Whitwell
|
||||
*/
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "brw_vs.h"
|
||||
#include "brw_state.h"
|
||||
|
||||
|
||||
static void prepare_active_vertprog( struct brw_context *brw )
|
||||
{
|
||||
const struct gl_vertex_program *prev = brw->vertex_program;
|
||||
|
||||
brw->vertex_program = brw->attribs.VertexProgram->_Current;
|
||||
|
||||
if (brw->vertex_program != prev)
|
||||
brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_active_vertprog = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_PROGRAM,
|
||||
.brw = 0,
|
||||
.cache = 0
|
||||
},
|
||||
.prepare = prepare_active_vertprog
|
||||
};
|
||||
|
|
@ -122,10 +122,11 @@ static struct prog_dst_register dst_reg(GLuint file, GLuint idx)
|
|||
reg.File = file;
|
||||
reg.Index = idx;
|
||||
reg.WriteMask = WRITEMASK_XYZW;
|
||||
reg.RelAddr = 0;
|
||||
reg.CondMask = 0;
|
||||
reg.CondSwizzle = 0;
|
||||
reg.pad = 0;
|
||||
reg.CondSrc = 0;
|
||||
reg.pad = 0;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
|
@ -863,9 +864,9 @@ static void emit_fog( struct brw_wm_compile *c )
|
|||
|
||||
static void emit_fb_write( struct brw_wm_compile *c )
|
||||
{
|
||||
struct prog_src_register outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
|
||||
struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
|
||||
struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR);
|
||||
struct prog_src_register outcolor;
|
||||
GLuint i;
|
||||
|
||||
struct prog_instruction *inst, *last_inst;
|
||||
|
|
@ -889,7 +890,14 @@ static void emit_fb_write( struct brw_wm_compile *c )
|
|||
}
|
||||
}
|
||||
last_inst->Sampler |= 1; //eot
|
||||
}else {
|
||||
}
|
||||
else {
|
||||
/* if gl_FragData[0] is written, use it, else use gl_FragColor */
|
||||
if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_DATA0))
|
||||
outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
|
||||
else
|
||||
outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
|
||||
|
||||
inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
|
||||
0, 0, 0, outcolor, payload_r0_depth, outdepth);
|
||||
inst->Sampler = 1|(0<<1);
|
||||
|
|
|
|||
|
|
@ -623,7 +623,7 @@ static void emit_dph(struct brw_wm_compile *c,
|
|||
brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
|
||||
brw_MAC(p, dst, src0[2], src1[2]);
|
||||
brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
|
||||
brw_ADD(p, dst, src0[3], src1[3]);
|
||||
brw_ADD(p, dst, dst, src1[3]);
|
||||
brw_set_saturate(p, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -386,27 +386,6 @@ intelDrawPixels(GLcontext * ctx,
|
|||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||
_mesa_printf("%s: fallback to swrast\n", __FUNCTION__);
|
||||
|
||||
if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) {
|
||||
/*
|
||||
* We don't want the i915 texenv program to be applied to DrawPixels.
|
||||
* This is really just a performance optimization (mesa will other-
|
||||
* wise happily run the fragment program on each pixel in the image).
|
||||
*/
|
||||
struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current;
|
||||
/* can't just set current frag prog to 0 here as on buffer resize
|
||||
we'll get new state checks which will segfault. Remains a hack. */
|
||||
ctx->FragmentProgram._Current = NULL;
|
||||
ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE;
|
||||
ctx->FragmentProgram._Active = GL_FALSE;
|
||||
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
|
||||
unpack, pixels );
|
||||
ctx->FragmentProgram._Current = fpSave;
|
||||
ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE;
|
||||
ctx->FragmentProgram._Active = GL_TRUE;
|
||||
_swrast_InvalidateState(ctx, _NEW_PROGRAM);
|
||||
}
|
||||
else {
|
||||
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
|
||||
unpack, pixels );
|
||||
}
|
||||
_swrast_DrawPixels(ctx, x, y, width, height, format, type,
|
||||
unpack, pixels);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ CORE_MESA = $(TOP)/src/mesa/libmesa.a $(TOP)/src/mesa/libglapi.a
|
|||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
default:
|
||||
# $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
|
||||
default: $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
|
||||
@ if [ "${DRIVER_DIRS}" = "osmesa" ] ; then \
|
||||
$(MAKE) osmesa16 ; \
|
||||
else \
|
||||
|
|
@ -42,9 +41,9 @@ default:
|
|||
|
||||
|
||||
# The normal libOSMesa is used in conjuction with libGL
|
||||
osmesa8: $(TOP)/lib/$(OSMESA_LIB_NAME)
|
||||
osmesa8: $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
|
||||
|
||||
$(TOP)/lib/$(OSMESA_LIB_NAME): $(OBJECTS)
|
||||
$(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OBJECTS)
|
||||
$(MKLIB) -o $(OSMESA_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
|
||||
|
|
|
|||
|
|
@ -1226,7 +1226,6 @@ _mesa_initialize_context(GLcontext *ctx,
|
|||
|
||||
ctx->FragmentProgram._MaintainTexEnvProgram
|
||||
= (_mesa_getenv("MESA_TEX_PROG") != NULL);
|
||||
ctx->FragmentProgram._UseTexEnvProgram = ctx->FragmentProgram._MaintainTexEnvProgram;
|
||||
|
||||
ctx->VertexProgram._MaintainTnlProgram
|
||||
= (_mesa_getenv("MESA_TNL_PROG") != NULL);
|
||||
|
|
|
|||
|
|
@ -2014,8 +2014,6 @@ struct gl_fragment_program_state
|
|||
|
||||
/** Should fixed-function texturing be implemented with a fragment prog? */
|
||||
GLboolean _MaintainTexEnvProgram;
|
||||
GLboolean _UseTexEnvProgram;
|
||||
GLboolean _Active; /**< Use internal texenv program? */
|
||||
|
||||
/** Program to emulate fixed-function texture env/combine (see above) */
|
||||
struct gl_fragment_program *_TexEnvProgram;
|
||||
|
|
|
|||
|
|
@ -254,17 +254,6 @@ update_program(GLcontext *ctx)
|
|||
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
|
||||
}
|
||||
|
||||
/* XXX: get rid of _Active flag.
|
||||
*/
|
||||
#if 1
|
||||
ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
|
||||
if (ctx->FragmentProgram._MaintainTexEnvProgram &&
|
||||
!ctx->FragmentProgram._Enabled) {
|
||||
if (ctx->FragmentProgram._UseTexEnvProgram)
|
||||
ctx->FragmentProgram._Active = GL_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Let the driver know what's happening:
|
||||
*/
|
||||
if (ctx->FragmentProgram._Current != prevFP && ctx->Driver.BindProgram) {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#define MESA_MAJOR 7
|
||||
#define MESA_MINOR 3
|
||||
#define MESA_PATCH 0
|
||||
#define MESA_VERSION_STRING "7.3-devel"
|
||||
#define MESA_VERSION_STRING "7.3-rc1"
|
||||
|
||||
/* To make version comparison easy */
|
||||
#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ file_string(enum register_file f, gl_prog_print_mode mode)
|
|||
return "ADDR";
|
||||
case PROGRAM_SAMPLER:
|
||||
return "SAMPLER";
|
||||
case PROGRAM_UNDEFINED:
|
||||
return "UNDEFINED";
|
||||
default:
|
||||
return "Unknown program file!";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ _mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count)
|
|||
for (i = 0; i < prog->NumInstructions; i++) {
|
||||
struct prog_instruction *inst = prog->Instructions + i;
|
||||
if (inst->BranchTarget > 0) {
|
||||
if (inst->BranchTarget >= start) {
|
||||
if (inst->BranchTarget > start) {
|
||||
inst->BranchTarget -= count;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1207,370 +1207,381 @@ float dot(const vec4 a, const vec4 b)
|
|||
|
||||
//// int assignment operators
|
||||
|
||||
void __operator += (inout int a, const int b)
|
||||
int __operator += (inout int a, const int b)
|
||||
{
|
||||
__asm vec4_add a, a, b;
|
||||
a = a + b;
|
||||
return a;
|
||||
}
|
||||
|
||||
void __operator -= (inout int a, const int b)
|
||||
int __operator -= (inout int a, const int b)
|
||||
{
|
||||
__asm vec4_subtract a, a, b;
|
||||
a = a - b;
|
||||
return a;
|
||||
}
|
||||
|
||||
void __operator *= (inout int a, const int b)
|
||||
int __operator *= (inout int a, const int b)
|
||||
{
|
||||
__asm vec4_multiply a, a, b;
|
||||
a = a * b;
|
||||
return a;
|
||||
}
|
||||
|
||||
void __operator /= (inout int a, const int b)
|
||||
int __operator /= (inout int a, const int b)
|
||||
{
|
||||
float invB;
|
||||
__asm float_rcp invB, b;
|
||||
__asm vec4_multiply a, a, invB;
|
||||
__asm vec4_to_ivec4 a, a;
|
||||
a = a / b;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
//// ivec2 assignment operators
|
||||
|
||||
void __operator += (inout ivec2 v, const ivec2 u)
|
||||
ivec2 __operator += (inout ivec2 v, const ivec2 u)
|
||||
{
|
||||
__asm vec4_add v, v, u;
|
||||
v = v + u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout ivec2 v, const ivec2 u)
|
||||
ivec2 __operator -= (inout ivec2 v, const ivec2 u)
|
||||
{
|
||||
__asm vec4_subtract v, v, u;
|
||||
v = v - u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout ivec2 v, const ivec2 u)
|
||||
ivec2 __operator *= (inout ivec2 v, const ivec2 u)
|
||||
{
|
||||
__asm vec4_multiply v, v, u;
|
||||
v = v * u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout ivec2 v, const ivec2 u)
|
||||
ivec2 __operator /= (inout ivec2 v, const ivec2 u)
|
||||
{
|
||||
ivec2 inv, z;
|
||||
__asm float_rcp inv.x, u.x;
|
||||
__asm float_rcp inv.y, u.y;
|
||||
__asm vec4_multiply z, v, inv;
|
||||
__asm vec4_to_ivec4 v, z;
|
||||
v = v / u;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// ivec3 assignment operators
|
||||
|
||||
void __operator += (inout ivec3 v, const ivec3 u)
|
||||
ivec3 __operator += (inout ivec3 v, const ivec3 u)
|
||||
{
|
||||
__asm vec4_add v, v, u;
|
||||
v = v + u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout ivec3 v, const ivec3 u)
|
||||
ivec3 __operator -= (inout ivec3 v, const ivec3 u)
|
||||
{
|
||||
__asm vec4_subtract v, v, u;
|
||||
v = v - u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout ivec3 v, const ivec3 u)
|
||||
ivec3 __operator *= (inout ivec3 v, const ivec3 u)
|
||||
{
|
||||
__asm vec4_multiply v, v, u;
|
||||
v = v * u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout ivec3 v, const ivec3 u)
|
||||
ivec3 __operator /= (inout ivec3 v, const ivec3 u)
|
||||
{
|
||||
ivec3 inv, z;
|
||||
__asm float_rcp inv.x, u.x;
|
||||
__asm float_rcp inv.y, u.y;
|
||||
__asm vec4_multiply z, v, inv;
|
||||
__asm vec4_to_ivec4 v, z;
|
||||
v = v / u;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// ivec4 assignment operators
|
||||
|
||||
void __operator += (inout ivec4 v, const ivec4 u)
|
||||
ivec4 __operator += (inout ivec4 v, const ivec4 u)
|
||||
{
|
||||
__asm vec4_add v, v, u;
|
||||
v = v + u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout ivec4 v, const ivec4 u)
|
||||
ivec4 __operator -= (inout ivec4 v, const ivec4 u)
|
||||
{
|
||||
__asm vec4_subtract v, v, u;
|
||||
v = v - u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout ivec4 v, const ivec4 u)
|
||||
ivec4 __operator *= (inout ivec4 v, const ivec4 u)
|
||||
{
|
||||
__asm vec4_multiply v, v, u;
|
||||
v = v * u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout ivec4 v, const ivec4 u)
|
||||
ivec4 __operator /= (inout ivec4 v, const ivec4 u)
|
||||
{
|
||||
ivec4 inv, z;
|
||||
__asm float_rcp inv.x, u.x;
|
||||
__asm float_rcp inv.y, u.y;
|
||||
__asm vec4_multiply z, v, inv;
|
||||
__asm vec4_to_ivec4 v, z;
|
||||
v = v / u;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// float assignment operators
|
||||
|
||||
void __operator += (inout float a, const float b)
|
||||
float __operator += (inout float a, const float b)
|
||||
{
|
||||
__asm vec4_add a.x, a.x, b.x;
|
||||
a = a + b;
|
||||
return a;
|
||||
}
|
||||
|
||||
void __operator -= (inout float a, const float b)
|
||||
float __operator -= (inout float a, const float b)
|
||||
{
|
||||
__asm vec4_subtract a.x, a, b;
|
||||
a = a - b;
|
||||
return a;
|
||||
}
|
||||
|
||||
void __operator *= (inout float a, const float b)
|
||||
float __operator *= (inout float a, const float b)
|
||||
{
|
||||
__asm vec4_multiply a.x, a, b;
|
||||
a = a * b;
|
||||
return a;
|
||||
}
|
||||
|
||||
void __operator /= (inout float a, const float b)
|
||||
float __operator /= (inout float a, const float b)
|
||||
{
|
||||
float w; // = 1 / b
|
||||
__asm float_rcp w.x, b;
|
||||
__asm vec4_multiply a.x, a, w;
|
||||
a = a / b;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
//// vec2 assignment operators
|
||||
|
||||
void __operator += (inout vec2 v, const vec2 u)
|
||||
vec2 __operator += (inout vec2 v, const vec2 u)
|
||||
{
|
||||
__asm vec4_add v.xy, v.xy, u.xy;
|
||||
v = v + u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout vec2 v, const vec2 u)
|
||||
vec2 __operator -= (inout vec2 v, const vec2 u)
|
||||
{
|
||||
__asm vec4_subtract v.xy, v.xy, u.xy;
|
||||
v = v - u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout vec2 v, const vec2 u)
|
||||
vec2 __operator *= (inout vec2 v, const vec2 u)
|
||||
{
|
||||
__asm vec4_multiply v.xy, v.xy, u.xy;
|
||||
v = v * u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout vec2 v, const vec2 u)
|
||||
vec2 __operator /= (inout vec2 v, const vec2 u)
|
||||
{
|
||||
vec2 w;
|
||||
__asm float_rcp w.x, u.x;
|
||||
__asm float_rcp w.y, u.y;
|
||||
__asm vec4_multiply v.xy, v.xy, w.xy;
|
||||
v = v / u;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// vec3 assignment operators
|
||||
|
||||
void __operator += (inout vec3 v, const vec3 u)
|
||||
vec3 __operator += (inout vec3 v, const vec3 u)
|
||||
{
|
||||
__asm vec4_add v.xyz, v, u;
|
||||
v = v + u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout vec3 v, const vec3 u)
|
||||
vec3 __operator -= (inout vec3 v, const vec3 u)
|
||||
{
|
||||
__asm vec4_subtract v.xyz, v, u;
|
||||
v = v - u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout vec3 v, const vec3 u)
|
||||
vec3 __operator *= (inout vec3 v, const vec3 u)
|
||||
{
|
||||
__asm vec4_multiply v.xyz, v, u;
|
||||
v = v * u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout vec3 v, const vec3 u)
|
||||
vec3 __operator /= (inout vec3 v, const vec3 u)
|
||||
{
|
||||
vec3 w;
|
||||
__asm float_rcp w.x, u.x;
|
||||
__asm float_rcp w.y, u.y;
|
||||
__asm float_rcp w.z, u.z;
|
||||
__asm vec4_multiply v.xyz, v.xyz, w.xyz;
|
||||
v = v / u;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// vec4 assignment operators
|
||||
|
||||
void __operator += (inout vec4 v, const vec4 u)
|
||||
vec4 __operator += (inout vec4 v, const vec4 u)
|
||||
{
|
||||
__asm vec4_add v, v, u;
|
||||
v = v + u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout vec4 v, const vec4 u)
|
||||
vec4 __operator -= (inout vec4 v, const vec4 u)
|
||||
{
|
||||
__asm vec4_subtract v, v, u;
|
||||
v = v - u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout vec4 v, const vec4 u)
|
||||
vec4 __operator *= (inout vec4 v, const vec4 u)
|
||||
{
|
||||
__asm vec4_multiply v, v, u;
|
||||
v = v * u;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout vec4 v, const vec4 u)
|
||||
vec4 __operator /= (inout vec4 v, const vec4 u)
|
||||
{
|
||||
vec4 w;
|
||||
__asm float_rcp w.x, u.x;
|
||||
__asm float_rcp w.y, u.y;
|
||||
__asm float_rcp w.z, u.z;
|
||||
__asm float_rcp w.w, u.w;
|
||||
__asm vec4_multiply v, v, w;
|
||||
v = v / u;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// ivec2/int assignment operators
|
||||
|
||||
void __operator += (inout ivec2 v, const int a)
|
||||
ivec2 __operator += (inout ivec2 v, const int a)
|
||||
{
|
||||
__asm vec4_add v.xy, v.xy, a;
|
||||
v = v + ivec2(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout ivec2 v, const int a)
|
||||
ivec2 __operator -= (inout ivec2 v, const int a)
|
||||
{
|
||||
__asm vec4_subtract v.xy, v.xy, a;
|
||||
v = v - ivec2(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout ivec2 v, const int a)
|
||||
ivec2 __operator *= (inout ivec2 v, const int a)
|
||||
{
|
||||
__asm vec4_multiply v.xy, v.xy, a;
|
||||
v.x *= a;
|
||||
v.y *= a;
|
||||
v = v * ivec2(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout ivec2 v, const int a)
|
||||
ivec2 __operator /= (inout ivec2 v, const int a)
|
||||
{
|
||||
// XXX rcp
|
||||
v.x /= a;
|
||||
v.y /= a;
|
||||
v = v / ivec2(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// ivec3/int assignment operators
|
||||
|
||||
void __operator += (inout ivec3 v, const int a)
|
||||
ivec3 __operator += (inout ivec3 v, const int a)
|
||||
{
|
||||
__asm vec4_add v.xyz, v.xyz, a;
|
||||
v = v + ivec3(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout ivec3 v, const int a)
|
||||
ivec3 __operator -= (inout ivec3 v, const int a)
|
||||
{
|
||||
__asm vec4_subtract v.xyz, v.xyz, a;
|
||||
v = v - ivec3(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout ivec3 v, const int a)
|
||||
ivec3 __operator *= (inout ivec3 v, const int a)
|
||||
{
|
||||
__asm vec4_multiply v.xyz, v.xyz, a;
|
||||
v = v * ivec3(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout ivec3 v, const int a)
|
||||
ivec4 __operator /= (inout ivec3 v, const int a)
|
||||
{
|
||||
// XXX rcp
|
||||
v.x /= a;
|
||||
v.y /= a;
|
||||
v.z /= a;
|
||||
v = v / ivec3(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// ivec4/int assignment operators
|
||||
|
||||
void __operator += (inout ivec4 v, const int a)
|
||||
ivec4 __operator += (inout ivec4 v, const int a)
|
||||
{
|
||||
__asm vec4_add v, v, a;
|
||||
v = v + ivec4(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout ivec4 v, const int a)
|
||||
ivec4 __operator -= (inout ivec4 v, const int a)
|
||||
{
|
||||
__asm vec4_subtract v, v, a;
|
||||
v = v - ivec4(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout ivec4 v, const int a)
|
||||
ivec4 __operator *= (inout ivec4 v, const int a)
|
||||
{
|
||||
__asm vec4_multiply v, v, a;
|
||||
v = v * ivec4(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout ivec4 v, const int a)
|
||||
ivec4 __operator /= (inout ivec4 v, const int a)
|
||||
{
|
||||
v.x /= a;
|
||||
v.y /= a;
|
||||
v.z /= a;
|
||||
v.w /= a;
|
||||
v = v / ivec4(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// vec2/float assignment operators
|
||||
|
||||
void __operator += (inout vec2 v, const float a)
|
||||
vec2 __operator += (inout vec2 v, const float a)
|
||||
{
|
||||
__asm vec4_add v.xy, v, a;
|
||||
v = v + vec2(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout vec2 v, const float a)
|
||||
vec2 __operator -= (inout vec2 v, const float a)
|
||||
{
|
||||
__asm vec4_subtract v.xy, v, a;
|
||||
v = v - vec2(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout vec2 v, const float a)
|
||||
vec2 __operator *= (inout vec2 v, const float a)
|
||||
{
|
||||
__asm vec4_multiply v.xy, v, a;
|
||||
v = v * vec2(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout vec2 v, const float a)
|
||||
vec2 __operator /= (inout vec2 v, const float a)
|
||||
{
|
||||
float invA;
|
||||
__asm float_rcp invA, a;
|
||||
__asm vec4_multiply v.xy, v.xy, invA;
|
||||
v = v / vec2(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// vec3/float assignment operators
|
||||
|
||||
void __operator += (inout vec3 v, const float a)
|
||||
vec3 __operator += (inout vec3 v, const float a)
|
||||
{
|
||||
__asm vec4_add v.xyz, v, a;
|
||||
v = v + vec3(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout vec3 v, const float a)
|
||||
vec3 __operator -= (inout vec3 v, const float a)
|
||||
{
|
||||
__asm vec4_subtract v.xyz, v, a;
|
||||
v = v - vec3(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout vec3 v, const float a)
|
||||
vec3 __operator *= (inout vec3 v, const float a)
|
||||
{
|
||||
__asm vec4_multiply v.xyz, v, a;
|
||||
v = v * vec3(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout vec3 v, const float a)
|
||||
vec3 __operator /= (inout vec3 v, const float a)
|
||||
{
|
||||
float invA;
|
||||
__asm float_rcp invA, a;
|
||||
__asm vec4_multiply v.xyz, v.xyz, invA;
|
||||
v = v / vec3(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//// vec4/float assignment operators
|
||||
|
||||
void __operator += (inout vec4 v, const float a)
|
||||
vec4 __operator += (inout vec4 v, const float a)
|
||||
{
|
||||
__asm vec4_add v, v, a;
|
||||
v = v + vec4(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator -= (inout vec4 v, const float a)
|
||||
vec4 __operator -= (inout vec4 v, const float a)
|
||||
{
|
||||
__asm vec4_subtract v, v, a;
|
||||
v = v - vec4(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout vec4 v, const float a)
|
||||
vec4 __operator *= (inout vec4 v, const float a)
|
||||
{
|
||||
__asm vec4_multiply v, v, a;
|
||||
v = v * vec4(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator /= (inout vec4 v, const float a)
|
||||
vec4 __operator /= (inout vec4 v, const float a)
|
||||
{
|
||||
float invA;
|
||||
__asm float_rcp invA, a;
|
||||
__asm vec4_multiply v, v, invA;
|
||||
v = v / vec4(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1896,187 +1907,239 @@ vec4 __operator * (const vec4 v, const mat4 m)
|
|||
|
||||
//// mat2 assignment operators
|
||||
|
||||
void __operator += (inout mat2 m, const mat2 n)
|
||||
mat2 __operator += (inout mat2 m, const mat2 n)
|
||||
{
|
||||
m[0] += n[0];
|
||||
m[1] += n[1];
|
||||
m[0] = m[0] + n[0];
|
||||
m[1] = m[1] + n[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator -= (inout mat2 m, const mat2 n)
|
||||
mat2 __operator -= (inout mat2 m, const mat2 n)
|
||||
{
|
||||
m[0] -= n[0];
|
||||
m[1] -= n[1];
|
||||
m[0] = m[0] - n[0];
|
||||
m[1] = m[1] - n[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator *= (inout mat2 m, const mat2 n)
|
||||
mat2 __operator *= (inout mat2 m, const mat2 n)
|
||||
{
|
||||
m = m * n;
|
||||
m = m * n;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator /= (inout mat2 m, const mat2 n)
|
||||
mat2 __operator /= (inout mat2 m, const mat2 n)
|
||||
{
|
||||
m[0] /= n[0];
|
||||
m[1] /= n[1];
|
||||
m[0] = m[0] / n[0];
|
||||
m[1] = m[1] / n[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//// mat3 assignment operators
|
||||
|
||||
void __operator += (inout mat3 m, const mat3 n)
|
||||
mat3 __operator += (inout mat3 m, const mat3 n)
|
||||
{
|
||||
m[0] += n[0];
|
||||
m[1] += n[1];
|
||||
m[2] += n[2];
|
||||
m[0] = m[0] + n[0];
|
||||
m[1] = m[1] + n[1];
|
||||
m[2] = m[2] + n[2];
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator -= (inout mat3 m, const mat3 n)
|
||||
mat3 __operator -= (inout mat3 m, const mat3 n)
|
||||
{
|
||||
m[0] -= n[0];
|
||||
m[1] -= n[1];
|
||||
m[2] -= n[2];
|
||||
m[0] = m[0] - n[0];
|
||||
m[1] = m[1] - n[1];
|
||||
m[2] = m[2] - n[2];
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator *= (inout mat3 m, const mat3 n)
|
||||
mat3 __operator *= (inout mat3 m, const mat3 n)
|
||||
{
|
||||
m = m * n;
|
||||
m = m * n;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator /= (inout mat3 m, const mat3 n)
|
||||
mat3 __operator /= (inout mat3 m, const mat3 n)
|
||||
{
|
||||
m[0] /= n[0];
|
||||
m[1] /= n[1];
|
||||
m[2] /= n[2];
|
||||
m[0] = m[0] / n[0];
|
||||
m[1] = m[1] / n[1];
|
||||
m[2] = m[2] / n[2];
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
// mat4 assignment operators
|
||||
|
||||
void __operator += (inout mat4 m, const mat4 n)
|
||||
mat4 __operator += (inout mat4 m, const mat4 n)
|
||||
{
|
||||
m[0] += n[0];
|
||||
m[1] += n[1];
|
||||
m[2] += n[2];
|
||||
m[3] += n[3];
|
||||
m[0] = m[0] + n[0];
|
||||
m[1] = m[1] + n[1];
|
||||
m[2] = m[2] + n[2];
|
||||
m[3] = m[3] + n[3];
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator -= (inout mat4 m, const mat4 n) {
|
||||
m[0] -= n[0];
|
||||
m[1] -= n[1];
|
||||
m[2] -= n[2];
|
||||
m[3] -= n[3];
|
||||
mat4 __operator -= (inout mat4 m, const mat4 n)
|
||||
{
|
||||
m[0] = m[0] - n[0];
|
||||
m[1] = m[1] - n[1];
|
||||
m[2] = m[2] - n[2];
|
||||
m[3] = m[3] - n[3];
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator *= (inout mat4 m, const mat4 n)
|
||||
mat4 __operator *= (inout mat4 m, const mat4 n)
|
||||
{
|
||||
m = m * n;
|
||||
m = m * n;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator /= (inout mat4 m, const mat4 n)
|
||||
mat4 __operator /= (inout mat4 m, const mat4 n)
|
||||
{
|
||||
m[0] /= n[0];
|
||||
m[1] /= n[1];
|
||||
m[2] /= n[2];
|
||||
m[3] /= n[3];
|
||||
m[0] = m[0] / n[0];
|
||||
m[1] = m[1] / n[1];
|
||||
m[2] = m[2] / n[2];
|
||||
m[3] = m[3] / n[3];
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//// mat2/float assignment operators
|
||||
|
||||
void __operator += (inout mat2 m, const float a) {
|
||||
m[0] += a;
|
||||
m[1] += a;
|
||||
mat2 __operator += (inout mat2 m, const float a)
|
||||
{
|
||||
vec2 v = vec2(a);
|
||||
m[0] = m[0] + v;
|
||||
m[1] = m[1] + v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator -= (inout mat2 m, const float a) {
|
||||
m[0] -= a;
|
||||
m[1] -= a;
|
||||
mat2 __operator -= (inout mat2 m, const float a)
|
||||
{
|
||||
vec2 v = vec2(a);
|
||||
m[0] = m[0] - v;
|
||||
m[1] = m[1] - v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator *= (inout mat2 m, const float a) {
|
||||
m[0] *= a;
|
||||
m[1] *= a;
|
||||
mat2 __operator *= (inout mat2 m, const float a)
|
||||
{
|
||||
vec2 v = vec2(a);
|
||||
m[0] = m[0] * v;
|
||||
m[1] = m[1] * v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator /= (inout mat2 m, const float a) {
|
||||
m[0] /= a;
|
||||
m[1] /= a;
|
||||
mat2 __operator /= (inout mat2 m, const float a)
|
||||
{
|
||||
vec2 v = vec2(1.0 / a);
|
||||
m[0] = m[0] * v;
|
||||
m[1] = m[1] * v;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//// mat3/float assignment operators
|
||||
|
||||
void __operator += (inout mat3 m, const float a) {
|
||||
m[0] += a;
|
||||
m[1] += a;
|
||||
m[2] += a;
|
||||
mat3 __operator += (inout mat3 m, const float a)
|
||||
{
|
||||
vec3 v = vec3(a);
|
||||
m[0] = m[0] + v;
|
||||
m[1] = m[1] + v;
|
||||
m[2] = m[2] + v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator -= (inout mat3 m, const float a) {
|
||||
m[0] -= a;
|
||||
m[1] -= a;
|
||||
m[2] -= a;
|
||||
mat3 __operator -= (inout mat3 m, const float a)
|
||||
{
|
||||
vec3 v = vec3(a);
|
||||
m[0] = m[0] - v;
|
||||
m[1] = m[1] - v;
|
||||
m[2] = m[2] - v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator *= (inout mat3 m, const float a) {
|
||||
m[0] *= a;
|
||||
m[1] *= a;
|
||||
m[2] *= a;
|
||||
mat3 __operator *= (inout mat3 m, const float a)
|
||||
{
|
||||
vec3 v = vec3(a);
|
||||
m[0] = m[0] * v;
|
||||
m[1] = m[1] * v;
|
||||
m[2] = m[2] * v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator /= (inout mat3 m, const float a) {
|
||||
m[0] /= a;
|
||||
m[1] /= a;
|
||||
m[2] /= a;
|
||||
mat3 __operator /= (inout mat3 m, const float a)
|
||||
{
|
||||
vec3 v = vec3(1.0 / a);
|
||||
m[0] = m[0] * v;
|
||||
m[1] = m[1] * v;
|
||||
m[2] = m[2] * v;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//// mat4/float assignment operators
|
||||
|
||||
void __operator += (inout mat4 m, const float a) {
|
||||
m[0] += a;
|
||||
m[1] += a;
|
||||
m[2] += a;
|
||||
m[3] += a;
|
||||
mat4 __operator += (inout mat4 m, const float a)
|
||||
{
|
||||
vec4 v = vec4(a);
|
||||
m[0] = m[0] + v;
|
||||
m[1] = m[1] + v;
|
||||
m[2] = m[2] + v;
|
||||
m[3] = m[3] + v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator -= (inout mat4 m, const float a) {
|
||||
m[0] -= a;
|
||||
m[1] -= a;
|
||||
m[2] -= a;
|
||||
m[3] -= a;
|
||||
mat4 __operator -= (inout mat4 m, const float a)
|
||||
{
|
||||
vec4 v = vec4(a);
|
||||
m[0] = m[0] - v;
|
||||
m[1] = m[1] - v;
|
||||
m[2] = m[2] - v;
|
||||
m[3] = m[3] - v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator *= (inout mat4 m, const float a) {
|
||||
m[0] *= a;
|
||||
m[1] *= a;
|
||||
m[2] *= a;
|
||||
m[3] *= a;
|
||||
mat4 __operator *= (inout mat4 m, const float a)
|
||||
{
|
||||
vec4 v = vec4(a);
|
||||
m[0] = m[0] * v;
|
||||
m[1] = m[1] * v;
|
||||
m[2] = m[2] * v;
|
||||
m[3] = m[3] * v;
|
||||
return m;
|
||||
}
|
||||
|
||||
void __operator /= (inout mat4 m, const float a) {
|
||||
m[0] /= a;
|
||||
m[1] /= a;
|
||||
m[2] /= a;
|
||||
m[3] /= a;
|
||||
mat4 __operator /= (inout mat4 m, const float a)
|
||||
{
|
||||
vec4 v = vec4(1.0 / a);
|
||||
m[0] = m[0] * v;
|
||||
m[1] = m[1] * v;
|
||||
m[2] = m[2] * v;
|
||||
m[3] = m[3] * v;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// vec/mat assignment operators
|
||||
|
||||
void __operator *= (inout vec2 v, const mat2 m)
|
||||
vec2 __operator *= (inout vec2 v, const mat2 m)
|
||||
{
|
||||
v = v * m;
|
||||
v = v * m;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout vec3 v, const mat3 m)
|
||||
vec3 __operator *= (inout vec3 v, const mat3 m)
|
||||
{
|
||||
v = v * m;
|
||||
v = v * m;
|
||||
return v;
|
||||
}
|
||||
|
||||
void __operator *= (inout vec4 v, const mat4 m)
|
||||
vec4 __operator *= (inout vec4 v, const mat4 m)
|
||||
{
|
||||
v = v * m;
|
||||
v = v * m;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue