Merge commit 'origin/gallium-0.2' into gallium-xlib-rework

This commit is contained in:
Keith Whitwell
2009-01-19 10:15:04 +00:00
169 changed files with 4049 additions and 3001 deletions
+5 -11
View File
@@ -182,10 +182,10 @@ ultrix-gcc:
# Rules for making release tarballs
DIRECTORY = Mesa-7.3-rc1
LIB_NAME = MesaLib-7.3-rc1
DEMO_NAME = MesaDemos-7.3-rc1
GLUT_NAME = MesaGLUT-7.3-rc1
DIRECTORY = Mesa-7.3-rc2
LIB_NAME = MesaLib-7.3-rc2
DEMO_NAME = MesaDemos-7.3-rc2
GLUT_NAME = MesaGLUT-7.3-rc2
MAIN_FILES = \
$(DIRECTORY)/Makefile* \
@@ -208,9 +208,7 @@ MAIN_FILES = \
$(DIRECTORY)/docs/RELNOTES* \
$(DIRECTORY)/docs/*.spec \
$(DIRECTORY)/include/GL/internal/glcore.h \
$(DIRECTORY)/include/GL/amesa.h \
$(DIRECTORY)/include/GL/dmesa.h \
$(DIRECTORY)/include/GL/fxmesa.h \
$(DIRECTORY)/include/GL/ggimesa.h \
$(DIRECTORY)/include/GL/gl.h \
$(DIRECTORY)/include/GL/glext.h \
@@ -225,19 +223,15 @@ MAIN_FILES = \
$(DIRECTORY)/include/GL/mglmesa.h \
$(DIRECTORY)/include/GL/osmesa.h \
$(DIRECTORY)/include/GL/svgamesa.h \
$(DIRECTORY)/include/GL/ugl*.h \
$(DIRECTORY)/include/GL/vms_x_fix.h \
$(DIRECTORY)/include/GL/wmesa.h \
$(DIRECTORY)/include/GL/xmesa.h \
$(DIRECTORY)/include/GL/xmesa_x.h \
$(DIRECTORY)/include/GL/xmesa_xf86.h \
$(DIRECTORY)/include/GLView.h \
$(DIRECTORY)/src/Makefile \
$(DIRECTORY)/src/descrip.mms \
$(DIRECTORY)/src/mesa/Makefile* \
$(DIRECTORY)/src/mesa/sources \
$(DIRECTORY)/src/mesa/descrip.mms \
$(DIRECTORY)/src/mesa/gl.pc.in \
$(DIRECTORY)/src/mesa/osmesa.pc.in \
$(DIRECTORY)/src/mesa/depend \
$(DIRECTORY)/src/mesa/main/*.[chS] \
$(DIRECTORY)/src/mesa/main/descrip.mms \
+1 -1
View File
@@ -133,7 +133,7 @@ if dri:
# LLVM
if llvm:
# See also http://www.scons.org/wiki/UsingPkgConfig
env.ParseConfig('llvm-config --cflags --ldflags --libs')
env.ParseConfig('llvm-config --cflags --ldflags --libs backend bitreader engine ipo')
env.Append(CPPDEFINES = ['MESA_LLVM'])
# Force C++ linkage
env['LINK'] = env['CXX']
+3 -3
View File
@@ -22,9 +22,9 @@ endif
ifeq ($(MESA_LLVM),1)
# LLVM_CFLAGS=`llvm-config --cflags`
LLVM_CXXFLAGS=`llvm-config --cxxflags` -Wno-long-long
LLVM_LDFLAGS=`llvm-config --ldflags`
LLVM_LIBS=`llvm-config --libs`
LLVM_CXXFLAGS=`llvm-config --cxxflags backend bitreader engine ipo` -Wno-long-long
LLVM_LDFLAGS=`llvm-config --ldflags backend bitreader engine ipo`
LLVM_LIBS=`llvm-config --libs backend bitreader engine ipo`
MKLIB_OPTIONS=-cplusplus
else
LLVM_CFLAGS=
+3 -6
View File
@@ -22,7 +22,7 @@ AC_CONFIG_AUX_DIR([bin])
AC_CANONICAL_HOST
dnl Versions for external dependencies
LIBDRM_REQUIRED=2.3.1
LIBDRM_REQUIRED=2.4.3
DRI2PROTO_REQUIRED=1.99.3
dnl Check for progs
@@ -83,11 +83,8 @@ dnl Compiler macros
DEFINES=""
AC_SUBST([DEFINES])
case "$host_os" in
*-gnu)
if test "x$GCC" = xyes; then
DEFINES="$DEFINES -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE"
fi
DEFINES="$DEFINES -D_SVID_SOURCE -D_GNU_SOURCE -DPTHREADS"
*-gnu*)
DEFINES="$DEFINES -D_GNU_SOURCE -DPTHREADS"
;;
solaris*)
DEFINES="$DEFINES -DPTHREADS -DSVR4"
+10 -2
View File
@@ -16,7 +16,7 @@ Status
Version
Last Modified Date: 8 June 2000
Last Modified Date: 12 January 2009
Number
@@ -69,6 +69,12 @@ Additions to Chapter 3 of the GLX 1.3 Specification (Functions and Errors)
<width> and <height> indicate the size in pixels. Coordinate (0,0)
corresponds to the lower-left pixel of the window, like glReadPixels.
If dpy and drawable are the display and drawable for the calling
thread's current context, glXCopySubBufferMESA performs an
implicit glFlush before it returns. Subsequent OpenGL commands
may be issued immediately after calling glXCopySubBufferMESA, but
are not executed until the copy is completed.
GLX Protocol
None at this time. The extension is implemented in terms of ordinary
@@ -84,5 +90,7 @@ New State
Revision History
8 June 2000 - initial specification
12 January 2009 Ian Romanick - Added language about implicit flush
and command completion.
8 June 2000 Brian Paul - initial specification
+3 -2
View File
@@ -39,9 +39,10 @@ The following are required for DRI-based hardware acceleration with Mesa 7.3:
<ul>
<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>
<li>Linux 2.6.28
<li><a href="http://dri.freedesktop.org/libdrm/" target="_parent">libDRM</a>
version 2.4.3 or later
<li>Xorg server version 1.4 or 1.5.
<li>Xorg server version 1.5 or later
</ul>
</p>
+11 -2
View File
@@ -21,8 +21,8 @@ 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
See the <a href="install.html">Compiling/Installing page</a> for prerequisites
for DRI ardware acceleration.
</p>
@@ -43,10 +43,19 @@ tbd
<ul>
<li>Assorted GLSL bug fixes
<li>Assorted i965 driver fixes
<li>Fix for wglCreateLayerContext() in WGL/Windows driver
<li>Build fixes for OpenBSD and gcc 2.95
<li>GLSL preprocessor handles #pragma now
<li>Fix incorrect transformation of GL_SPOT_DIRECTION
</ul>
<h2>Changes</h2>
<ul>
<li>Deprecated the "XMesa" interface (include/GL/xmesa*.h files)
<li>Deprecated the "FXMesa" interface (include/GL/fxmesa.h file)
<li>Deprecated the "Allegro" interface (include/GL/amesa.h file)
<li>Removed include/GL/uglmesa.h header
<li>Removed include/GLView.h header for BeOS
</ul>
+3 -8
View File
@@ -2,17 +2,12 @@
GLincludedir = $(includedir)/GL
INC_FX = fxmesa.h
INC_GGI = ggimesa.h
INC_OSMESA = osmesa.h
INC_SVGA = svgamesa.h
INC_X11 = glx.h glxext.h glx_mangle.h xmesa.h xmesa_x.h xmesa_xf86.h
INC_X11 = glx.h glxext.h glx_mangle.h
INC_GLUT = glut.h glutf90.h
if HAVE_FX
sel_inc_fx = $(INC_FX)
endif
if HAVE_GGI
sel_inc_ggi = $(INC_GGI)
endif
@@ -35,9 +30,9 @@ endif
EXTRA_HEADERS = amesa.h dosmesa.h foomesa.h glut_h.dja mesa_wgl.h mglmesa.h \
vms_x_fix.h wmesa.h \
$(INC_FX) $(INC_GGI) $(INC_OSMESA) $(INC_SVGA) $(INC_X11) $(INC_GLUT)
$(INC_GGI) $(INC_OSMESA) $(INC_SVGA) $(INC_X11) $(INC_GLUT)
GLinclude_HEADERS = gl.h glext.h gl_mangle.h glu.h glu_mangle.h \
$(sel_inc_fx) $(sel_inc_ggi) $(sel_inc_osmesa) $(sel_inc_svga) \
$(sel_inc_ggi) $(sel_inc_osmesa) $(sel_inc_svga) \
$(sel_inc_x11) $(sel_inc_glut)
include $(top_srcdir)/common_rules.make
-45
View File
@@ -1,45 +0,0 @@
/* uglglutshapes.h - Public header GLUT Shapes */
/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */
/* This program is freely distributable without licensing fees and is
provided without guarantee or warrantee expressed or implied. This
program is -not- in the public domain. */
#ifndef GLUTSHAPES_H
#define GLUTSHAPES_H
#ifdef __cplusplus
extern "C" {
#endif
#include <GL/gl.h>
void glutWireSphere (GLdouble radius, GLint slices, GLint stacks);
void glutSolidSphere (GLdouble radius, GLint slices, GLint stacks);
void glutWireCone (GLdouble base, GLdouble height,
GLint slices, GLint stacks);
void glutSolidCone (GLdouble base, GLdouble height,
GLint slices, GLint stacks);
void glutWireCube (GLdouble size);
void glutSolidCube (GLdouble size);
void glutWireTorus (GLdouble innerRadius, GLdouble outerRadius,
GLint sides, GLint rings);
void glutSolidTorus (GLdouble innerRadius, GLdouble outerRadius,
GLint sides, GLint rings);
void glutWireDodecahedron (void);
void glutSolidDodecahedron (void);
void glutWireOctahedron (void);
void glutSolidOctahedron (void);
void glutWireTetrahedron (void);
void glutSolidTetrahedron (void);
void glutWireIcosahedron (void);
void glutSolidIcosahedron (void);
void glutWireTeapot (GLdouble size);
void glutSolidTeapot (GLdouble size);
#ifdef __cplusplus
}
#endif
#endif
-155
View File
@@ -1,155 +0,0 @@
/* uglmesa.h - Public header UGL/Mesa */
/* Copyright (C) 2001 by Wind River Systems, Inc */
/*
* Mesa 3-D graphics library
* Version: 4.0
*
* The MIT License
* 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
* THE AUTHORS OR COPYRIGHT 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.
*/
/*
* Author:
* Stephane Raimbault <stephane.raimbault@windriver.com>
*/
#ifndef UGLMESA_H
#define UGLMESA_H
#ifdef __cplusplus
extern "C" {
#endif
#define UGL_MESA_MAJOR_VERSION 4
#define UGL_MESA_MINOR_VERSION 0
#include <GL/gl.h>
#include <ugl/ugl.h>
/*
* Values for display mode of uglMesaCreateContext ()
*/
/*
* With these mask values, it's possible to test double buffer mode
* with UGL_MESA_DOUBLE mask
*
* SINGLE 0000 0001
* DOUBLE 0000 0110
* - SOFT 0000 0010
* - HARD 0000 0100
* WINDML 0001 0000
*
*
*/
#define UGL_MESA_SINGLE 0x01
#define UGL_MESA_DOUBLE 0x06
#define UGL_MESA_DOUBLE_SOFTWARE 0x02
#define UGL_MESA_DOUBLE_HARDWARE 0x04
#define UGL_MESA_WINDML_EXCLUSIVE 0x10
#define UGL_MESA_FULLSCREEN_WIDTH 0x0
#define UGL_MESA_FULLSCREEN_HEIGHT 0x0
/*
* uglMesaPixelStore() parameters:
*/
#define UGL_MESA_ROW_LENGTH 0x20
#define UGL_MESA_Y_UP 0x21
/*
* Accepted by uglMesaGetIntegerv:
*/
#define UGL_MESA_LEFT_X 0x01
#define UGL_MESA_TOP_Y 0x02
#define UGL_MESA_WIDTH 0x03
#define UGL_MESA_HEIGHT 0x04
#define UGL_MESA_DISPLAY_WIDTH 0x05
#define UGL_MESA_DISPLAY_HEIGHT 0x06
#define UGL_MESA_COLOR_FORMAT 0x07
#define UGL_MESA_COLOR_MODEL 0x08
#define UGL_MESA_PIXEL_FORMAT 0x09
#define UGL_MESA_TYPE 0x0A
#define UGL_MESA_RGB 0x0B
#define UGL_MESA_COLOR_INDEXED 0x0C
#define UGL_MESA_SINGLE_BUFFER 0x0D
#define UGL_MESA_DOUBLE_BUFFER 0x0E
#define UGL_MESA_DOUBLE_BUFFER_SOFTWARE 0x0F
#define UGL_MESA_DOUBLE_BUFFER_HARDWARE 0x10
/*
* typedefs
*/
typedef struct uglMesaContext * UGL_MESA_CONTEXT;
UGL_MESA_CONTEXT uglMesaCreateNewContext (GLenum mode,
UGL_MESA_CONTEXT share_list);
UGL_MESA_CONTEXT uglMesaCreateNewContextExt (GLenum mode,
GLint depth_bits,
GLint stencil_bits,
GLint accum_red_bits,
GLint accum_green_bits,
GLint accum_blue_bits,
GLint accum_alpha_bits,
UGL_MESA_CONTEXT share_list);
GLboolean uglMesaMakeCurrentContext (UGL_MESA_CONTEXT umc,
GLsizei left, GLsizei top,
GLsizei width, GLsizei height);
GLboolean uglMesaMoveWindow (GLsizei dx, GLsizei dy);
GLboolean uglMesaMoveToWindow (GLsizei left, GLsizei top);
GLboolean uglMesaResizeWindow (GLsizei dw, GLsizei dh);
GLboolean uglMesaResizeToWindow (GLsizei width, GLsizei height);
void uglMesaDestroyContext (void);
UGL_MESA_CONTEXT uglMesaGetCurrentContext (void);
void uglMesaSwapBuffers (void);
void uglMesaPixelStore (GLint pname, GLint value);
void uglMesaGetIntegerv (GLint pname, GLint *value);
GLboolean uglMesaGetDepthBuffer (GLint *width, GLint *height,
GLint *bytesPerValue, void **buffer);
GLboolean uglMesaGetColorBuffer (GLint *width, GLint *height,
GLint *format, void **buffer);
GLboolean uglMesaSetColor (GLubyte index, GLfloat red,
GLfloat green, GLfloat blue);
#ifdef __cplusplus
}
#endif
#endif
-192
View File
@@ -1,192 +0,0 @@
/*******************************************************************************
/
/ File: GLView.h
/
/ Copyright 1993-98, Be Incorporated, All Rights Reserved.
/
*******************************************************************************/
#ifndef BGLVIEW_H
#define BGLVIEW_H
#include <GL/gl.h>
#define BGL_RGB 0
#define BGL_INDEX 1
#define BGL_SINGLE 0
#define BGL_DOUBLE 2
#define BGL_DIRECT 0
#define BGL_INDIRECT 4
#define BGL_ACCUM 8
#define BGL_ALPHA 16
#define BGL_DEPTH 32
#define BGL_OVERLAY 64
#define BGL_UNDERLAY 128
#define BGL_STENCIL 512
#ifdef __cplusplus
#include <AppKit.h>
#include <interface/Window.h>
#include <interface/View.h>
#include <interface/Bitmap.h>
#include <game/WindowScreen.h>
#include <game/DirectWindow.h>
class BGLView : public BView {
public:
BGLView(BRect rect, char *name,
ulong resizingMode, ulong mode,
ulong options);
virtual ~BGLView();
void LockGL();
void UnlockGL();
void SwapBuffers();
void SwapBuffers( bool vSync );
BView * EmbeddedView();
status_t CopyPixelsOut(BPoint source, BBitmap *dest);
status_t CopyPixelsIn(BBitmap *source, BPoint dest);
virtual void ErrorCallback(unsigned long errorCode); // Mesa's GLenum is uint where Be's ones was ulong!
virtual void Draw(BRect updateRect);
virtual void AttachedToWindow();
virtual void AllAttached();
virtual void DetachedFromWindow();
virtual void AllDetached();
virtual void FrameResized(float width, float height);
virtual status_t Perform(perform_code d, void *arg);
/* The public methods below, for the moment,
are just pass-throughs to BView */
virtual status_t Archive(BMessage *data, bool deep = true) const;
virtual void MessageReceived(BMessage *msg);
virtual void SetResizingMode(uint32 mode);
virtual void Show();
virtual void Hide();
virtual BHandler *ResolveSpecifier(BMessage *msg, int32 index,
BMessage *specifier, int32 form,
const char *property);
virtual status_t GetSupportedSuites(BMessage *data);
/* New public functions */
void DirectConnected( direct_buffer_info *info );
void EnableDirectMode( bool enabled );
void * getGC() { return m_gc; }
private:
virtual void _ReservedGLView1();
virtual void _ReservedGLView2();
virtual void _ReservedGLView3();
virtual void _ReservedGLView4();
virtual void _ReservedGLView5();
virtual void _ReservedGLView6();
virtual void _ReservedGLView7();
virtual void _ReservedGLView8();
BGLView(const BGLView &);
BGLView &operator=(const BGLView &);
void dither_front();
bool confirm_dither();
void draw(BRect r);
void * m_gc;
uint32 m_options;
uint32 m_ditherCount;
BLocker m_drawLock;
BLocker m_displayLock;
void * m_clip_info;
void * _Unused1;
BBitmap * m_ditherMap;
BRect m_bounds;
int16 * m_errorBuffer[2];
uint64 _reserved[8];
/* Direct Window stuff */
private:
void drawScanline( int x1, int x2, int y, void *data );
static void scanlineHandler(struct rasStateRec *state, GLint x1, GLint x2);
void lock_draw();
void unlock_draw();
bool validateView();
};
class BGLScreen : public BWindowScreen {
public:
BGLScreen(char *name,
ulong screenMode, ulong options,
status_t *error, bool debug=false);
~BGLScreen();
void LockGL();
void UnlockGL();
void SwapBuffers();
virtual void ErrorCallback(GLenum errorCode);
virtual void ScreenConnected(bool connected);
virtual void FrameResized(float width, float height);
virtual status_t Perform(perform_code d, void *arg);
/* The public methods below, for the moment,
are just pass-throughs to BWindowScreen */
virtual status_t Archive(BMessage *data, bool deep = true) const;
virtual void MessageReceived(BMessage *msg);
virtual void Show();
virtual void Hide();
virtual BHandler *ResolveSpecifier(BMessage *msg,
int32 index,
BMessage *specifier,
int32 form,
const char *property);
virtual status_t GetSupportedSuites(BMessage *data);
private:
virtual void _ReservedGLScreen1();
virtual void _ReservedGLScreen2();
virtual void _ReservedGLScreen3();
virtual void _ReservedGLScreen4();
virtual void _ReservedGLScreen5();
virtual void _ReservedGLScreen6();
virtual void _ReservedGLScreen7();
virtual void _ReservedGLScreen8();
BGLScreen(const BGLScreen &);
BGLScreen &operator=(const BGLScreen &);
void * m_gc;
long m_options;
BLocker m_drawLock;
int32 m_colorSpace;
uint32 m_screen_mode;
uint64 _reserved[7];
};
#endif // __cplusplus
#endif // BGLVIEW_H
+1
View File
@@ -3,6 +3,7 @@ demo2
demo3
eglgears
eglinfo
eglscreen
egltri
peglgears
xeglgears
+6
View File
@@ -15,6 +15,7 @@ PROGRAMS = \
egltri \
eglinfo \
eglgears \
eglscreen \
peglgears \
xeglgears \
xegl_tri
@@ -69,6 +70,11 @@ eglgears: eglgears.o $(TOP)/$(LIB_DIR)/libEGL.so
eglgears.o: eglgears.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include eglgears.c
eglscreen: eglscreen.o $(TOP)/$(LIB_DIR)/libEGL.so
$(CC) $(CFLAGS) $(LDFLAGS) eglscreen.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
eglscreen.o: eglscreen.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include eglscreen.c
peglgears: peglgears.o $(TOP)/$(LIB_DIR)/libEGL.so
$(CC) $(CFLAGS) peglgears.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
+4 -2
View File
@@ -24,8 +24,10 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -35,7 +37,6 @@
#define MAX_MODES 1000
#define MAX_SCREENS 10
/**
* Print table of all available configurations.
*/
@@ -146,7 +147,8 @@ int
main(int argc, char *argv[])
{
int maj, min;
EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
//EGLDisplay d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
EGLDisplay d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
if (!eglInitialize(d, &maj, &min)) {
printf("eglinfo: eglInitialize failed\n");
+119
View File
@@ -0,0 +1,119 @@
/*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Stolen from eglgears
*
* Creates a surface and show that on the first screen
*/
#define EGL_EGLEXT_PROTOTYPES
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <GL/gl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#define MAX_CONFIGS 10
#define MAX_MODES 100
int
main(int argc, char *argv[])
{
int maj, min;
EGLSurface screen_surf;
EGLConfig configs[MAX_CONFIGS];
EGLint numConfigs, i;
EGLBoolean b;
EGLDisplay d;
EGLint screenAttribs[10];
EGLModeMESA mode[MAX_MODES];
EGLScreenMESA screen;
EGLint count, chosenMode;
EGLint width = 0, height = 0;
d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
assert(d);
if (!eglInitialize(d, &maj, &min)) {
printf("eglscreen: eglInitialize failed\n");
exit(1);
}
printf("eglscreen: EGL version = %d.%d\n", maj, min);
printf("eglscreen: EGL_VENDOR = %s\n", eglQueryString(d, EGL_VENDOR));
/* XXX use ChooseConfig */
eglGetConfigs(d, configs, MAX_CONFIGS, &numConfigs);
eglGetScreensMESA(d, &screen, 1, &count);
if (!eglGetModesMESA(d, screen, mode, MAX_MODES, &count) || count == 0) {
printf("eglscreen: eglGetModesMESA failed!\n");
return 0;
}
/* Print list of modes, and find the one to use */
printf("eglscreen: Found %d modes:\n", count);
for (i = 0; i < count; i++) {
EGLint w, h;
eglGetModeAttribMESA(d, mode[i], EGL_WIDTH, &w);
eglGetModeAttribMESA(d, mode[i], EGL_HEIGHT, &h);
printf("%3d: %d x %d\n", i, w, h);
if (w > width && h > height) {
width = w;
height = h;
chosenMode = i;
}
}
printf("eglscreen: Using screen mode/size %d: %d x %d\n", chosenMode, width, height);
/* build up screenAttribs array */
i = 0;
screenAttribs[i++] = EGL_WIDTH;
screenAttribs[i++] = width;
screenAttribs[i++] = EGL_HEIGHT;
screenAttribs[i++] = height;
screenAttribs[i++] = EGL_NONE;
screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs);
if (screen_surf == EGL_NO_SURFACE) {
printf("eglscreen: Failed to create screen surface\n");
return 0;
}
b = eglShowScreenSurfaceMESA(d, screen, screen_surf, mode[chosenMode]);
if (!b) {
printf("eglscreen: Show surface failed\n");
return 0;
}
usleep(5000000);
eglDestroySurface(d, screen_surf);
eglTerminate(d);
return 0;
}
+6
View File
@@ -24,6 +24,7 @@ PROGS = \
points \
pointcoord \
samplers \
samplers_array \
skinning \
texdemo1 \
toyball \
@@ -166,6 +167,11 @@ samplers.o: samplers.c readtex.h extfuncs.h shaderutil.h
samplers: samplers.o readtex.o shaderutil.o
$(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) samplers.o readtex.o shaderutil.o $(LIBS) -o $@
samplers_array.o: samplers.c readtex.h extfuncs.h shaderutil.h
$(APP_CC) -c -DSAMPLERS_ARRAY -I$(INCDIR) $(CFLAGS) samplers.c -o samplers_array.o
samplers_array: samplers_array.o readtex.o shaderutil.o
$(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) samplers_array.o readtex.o shaderutil.o $(LIBS) -o $@
skinning.o: skinning.c readtex.h extfuncs.h shaderutil.h
$(APP_CC) -c -I$(INCDIR) $(CFLAGS) skinning.c
+12
View File
@@ -245,14 +245,22 @@ GenFragmentShader(GLint numSamplers)
int s;
p += sprintf(p, "// Generated fragment shader:\n");
#ifndef SAMPLERS_ARRAY
for (s = 0; s < numSamplers; s++) {
p += sprintf(p, "uniform sampler2D tex%d;\n", s);
}
#else
p += sprintf(p, "uniform sampler2D tex[%d];\n", numSamplers);
#endif
p += sprintf(p, "void main()\n");
p += sprintf(p, "{\n");
p += sprintf(p, " vec4 color = vec4(0.0);\n");
for (s = 0; s < numSamplers; s++) {
#ifndef SAMPLERS_ARRAY
p += sprintf(p, " color += texture2D(tex%d, gl_TexCoord[0].xy);\n", s);
#else
p += sprintf(p, " color += texture2D(tex[%d], gl_TexCoord[0].xy);\n", s);
#endif
}
p += sprintf(p, " gl_FragColor = color;\n");
p += sprintf(p, "}\n");
@@ -302,7 +310,11 @@ InitProgram(void)
char uname[10];
GLint loc;
#ifndef SAMPLERS_ARRAY
sprintf(uname, "tex%d", s);
#else
sprintf(uname, "tex[%d]", s);
#endif
loc = glGetUniformLocation_func(Program, uname);
assert(loc >= 0);
+1
View File
@@ -81,6 +81,7 @@ progs = [
'tri-blend-sub',
'tri-blend',
'tri-clip',
'tri-clear',
'tri-cull-both',
'tri-cull',
'tri-dlist',
+4 -6
View File
@@ -162,18 +162,16 @@ def generate(env):
# Some setting from the platform also have to be overridden:
env['OBJPREFIX'] = ''
env['OBJSUFFIX'] = '.o'
env['LIBPREFIX'] = 'lib'
env['LIBSUFFIX'] = '.a'
env['SHOBJPREFIX'] = '$OBJPREFIX'
env['SHOBJSUFFIX'] = '$OBJSUFFIX'
env['PROGPREFIX'] = ''
env['PROGSUFFIX'] = '.exe'
env['LIBPREFIX'] = ''
env['LIBSUFFIX'] = '.lib'
env['LIBPREFIX'] = 'lib'
env['LIBSUFFIX'] = '.a'
env['SHLIBPREFIX'] = ''
env['SHLIBSUFFIX'] = '.dll'
env['LIBPREFIXES'] = [ '$LIBPREFIX' ]
env['LIBSUFFIXES'] = [ '$LIBSUFFIX' ]
env['LIBPREFIXES'] = [ 'lib', '' ]
env['LIBSUFFIXES'] = [ '.a', '.lib' ]
env.AppendUnique(LIBS = ['iberty'])
env.AppendUnique(LINKFLAGS = ['-Wl,--enable-stdcall-fixup'])
+1 -1
View File
@@ -313,7 +313,7 @@ def generate(env):
'-Wmissing-prototypes',
'-Wno-long-long',
'-ffast-math',
'-std=c99',
'-std=gnu99',
'-pedantic',
'-fmessage-length=0', # be nice to Eclipse
]
+1 -1
View File
@@ -578,7 +578,7 @@ GLX_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
return EGL_FALSE;
#ifdef GLX_VERSION_1_3
if (!glXMakeContextCurrent(disp->Xdpy, GLX_dsurf->drawable, GLX_rsurf->drawable, GLX_ctx->context))
if (!glXMakeContextCurrent(disp->Xdpy, GLX_dsurf ? GLX_dsurf->drawable : 0, GLX_rsurf ? GLX_rsurf->drawable : 0, GLX_ctx ? GLX_ctx->context : NULL))
#endif
if (!glXMakeCurrent(disp->Xdpy, GLX_dsurf ? GLX_dsurf->drawable : 0, GLX_ctx ? GLX_ctx->context : NULL))
return EGL_FALSE;
+2 -2
View File
@@ -66,12 +66,12 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES)
gallivm_builtins.cpp: llvm_builtins.c
clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp1.bin
(echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@
(echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
rm temp1.bin
gallivmsoabuiltins.cpp: soabuiltins.c
clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin
(echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@
(echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
rm temp2.bin
# Emacs tags
+1 -1
View File
@@ -53,7 +53,7 @@
#include <llvm/ModuleProvider.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Attributes.h>
#include <llvm/Support/PatternMatch.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/Interpreter.h>
@@ -137,4 +137,4 @@ static const unsigned char llvm_builtins_data[] = {
0x58,0x85,0x05,0x14,0xbe,0x34,0x45,0xb5,0x21,0x10,0x82,0x23,0x15,0x46,0x30,0x2c,
0xc8,0x64,0x02,0x06,0xf0,0x3c,0x91,0x73,0x19,0x00,0xe1,0x4b,0x53,0x64,0x0a,0x84,
0x84,0x34,0x85,0x25,0x0c,0x92,0x20,0x59,0xc1,0x20,0x30,0x8f,0x2d,0x10,0x95,0x84,
0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
@@ -56,7 +56,7 @@
#include <llvm/ModuleProvider.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Attributes.h>
#include <llvm/Support/PatternMatch.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/Interpreter.h>
@@ -43,7 +43,7 @@
#include <llvm/Function.h>
#include <llvm/InstrTypes.h>
#include <llvm/Instructions.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Attributes.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Bitcode/ReaderWriter.h>
@@ -37,7 +37,7 @@
#include <llvm/Function.h>
#include <llvm/Instructions.h>
#include <llvm/Transforms/Utils/Cloning.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Attributes.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Bitcode/ReaderWriter.h>
@@ -206,11 +206,12 @@ llvm::Module * InstructionsSoa::currentModule() const
void InstructionsSoa::createBuiltins()
{
std::string ErrMsg;
MemoryBuffer *buffer = MemoryBuffer::getMemBuffer(
(const char*)&soabuiltins_data[0],
(const char*)&soabuiltins_data[Elements(soabuiltins_data)]);
m_builtins = ParseBitcodeFile(buffer);
std::cout<<"Builtins created at "<<m_builtins<<std::endl;
(const char*)&soabuiltins_data[Elements(soabuiltins_data) - 1]);
m_builtins = ParseBitcodeFile(buffer, &ErrMsg);
std::cout<<"Builtins created at "<<m_builtins<<" ("<<ErrMsg<<")"<<std::endl;
assert(m_builtins);
createDependencies();
}
+1 -1
View File
@@ -25,7 +25,7 @@
#include <llvm/ModuleProvider.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Attributes.h>
#include <llvm/Support/PatternMatch.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/Interpreter.h>
+62 -61
View File
@@ -213,8 +213,8 @@ emit_instruction(struct spe_function *p, uint32_t inst_bits)
static void emit_RR(struct spe_function *p, unsigned op, unsigned rT,
unsigned rA, unsigned rB, const char *name)
static void emit_RR(struct spe_function *p, unsigned op, int rT,
int rA, int rB, const char *name)
{
union spe_inst_RR inst;
inst.inst.op = op;
@@ -230,8 +230,8 @@ static void emit_RR(struct spe_function *p, unsigned op, unsigned rT,
}
static void emit_RRR(struct spe_function *p, unsigned op, unsigned rT,
unsigned rA, unsigned rB, unsigned rC, const char *name)
static void emit_RRR(struct spe_function *p, unsigned op, int rT,
int rA, int rB, int rC, const char *name)
{
union spe_inst_RRR inst;
inst.inst.op = op;
@@ -248,8 +248,8 @@ static void emit_RRR(struct spe_function *p, unsigned op, unsigned rT,
}
static void emit_RI7(struct spe_function *p, unsigned op, unsigned rT,
unsigned rA, int imm, const char *name)
static void emit_RI7(struct spe_function *p, unsigned op, int rT,
int rA, int imm, const char *name)
{
union spe_inst_RI7 inst;
inst.inst.op = op;
@@ -266,8 +266,8 @@ static void emit_RI7(struct spe_function *p, unsigned op, unsigned rT,
static void emit_RI8(struct spe_function *p, unsigned op, unsigned rT,
unsigned rA, int imm, const char *name)
static void emit_RI8(struct spe_function *p, unsigned op, int rT,
int rA, int imm, const char *name)
{
union spe_inst_RI8 inst;
inst.inst.op = op;
@@ -284,8 +284,8 @@ static void emit_RI8(struct spe_function *p, unsigned op, unsigned rT,
static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT,
unsigned rA, int imm, const char *name)
static void emit_RI10(struct spe_function *p, unsigned op, int rT,
int rA, int imm, const char *name)
{
union spe_inst_RI10 inst;
inst.inst.op = op;
@@ -302,8 +302,8 @@ static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT,
/** As above, but do range checking on signed immediate value */
static void emit_RI10s(struct spe_function *p, unsigned op, unsigned rT,
unsigned rA, int imm, const char *name)
static void emit_RI10s(struct spe_function *p, unsigned op, int rT,
int rA, int imm, const char *name)
{
assert(imm <= 511);
assert(imm >= -512);
@@ -311,7 +311,7 @@ static void emit_RI10s(struct spe_function *p, unsigned op, unsigned rT,
}
static void emit_RI16(struct spe_function *p, unsigned op, unsigned rT,
static void emit_RI16(struct spe_function *p, unsigned op, int rT,
int imm, const char *name)
{
union spe_inst_RI16 inst;
@@ -326,7 +326,7 @@ static void emit_RI16(struct spe_function *p, unsigned op, unsigned rT,
}
static void emit_RI18(struct spe_function *p, unsigned op, unsigned rT,
static void emit_RI18(struct spe_function *p, unsigned op, int rT,
int imm, const char *name)
{
union spe_inst_RI18 inst;
@@ -348,61 +348,61 @@ void _name (struct spe_function *p) \
}
#define EMIT_(_name, _op) \
void _name (struct spe_function *p, unsigned rT) \
void _name (struct spe_function *p, int rT) \
{ \
emit_RR(p, _op, rT, 0, 0, __FUNCTION__); \
}
#define EMIT_R(_name, _op) \
void _name (struct spe_function *p, unsigned rT, unsigned rA) \
void _name (struct spe_function *p, int rT, int rA) \
{ \
emit_RR(p, _op, rT, rA, 0, __FUNCTION__); \
}
#define EMIT_RR(_name, _op) \
void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB) \
void _name (struct spe_function *p, int rT, int rA, int rB) \
{ \
emit_RR(p, _op, rT, rA, rB, __FUNCTION__); \
}
#define EMIT_RRR(_name, _op) \
void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB, unsigned rC) \
void _name (struct spe_function *p, int rT, int rA, int rB, int rC) \
{ \
emit_RRR(p, _op, rT, rA, rB, rC, __FUNCTION__); \
}
#define EMIT_RI7(_name, _op) \
void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
void _name (struct spe_function *p, int rT, int rA, int imm) \
{ \
emit_RI7(p, _op, rT, rA, imm, __FUNCTION__); \
}
#define EMIT_RI8(_name, _op, bias) \
void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
void _name (struct spe_function *p, int rT, int rA, int imm) \
{ \
emit_RI8(p, _op, rT, rA, bias - imm, __FUNCTION__); \
}
#define EMIT_RI10(_name, _op) \
void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
void _name (struct spe_function *p, int rT, int rA, int imm) \
{ \
emit_RI10(p, _op, rT, rA, imm, __FUNCTION__); \
}
#define EMIT_RI10s(_name, _op) \
void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
void _name (struct spe_function *p, int rT, int rA, int imm) \
{ \
emit_RI10s(p, _op, rT, rA, imm, __FUNCTION__); \
}
#define EMIT_RI16(_name, _op) \
void _name (struct spe_function *p, unsigned rT, int imm) \
void _name (struct spe_function *p, int rT, int imm) \
{ \
emit_RI16(p, _op, rT, imm, __FUNCTION__); \
}
#define EMIT_RI18(_name, _op) \
void _name (struct spe_function *p, unsigned rT, int imm) \
void _name (struct spe_function *p, int rT, int imm) \
{ \
emit_RI18(p, _op, rT, imm, __FUNCTION__); \
}
@@ -424,7 +424,7 @@ void _name (struct spe_function *p, int imm) \
*/
void spe_init_func(struct spe_function *p, unsigned code_size)
{
unsigned int i;
uint i;
if (!code_size)
code_size = 64;
@@ -503,6 +503,7 @@ int spe_allocate_register(struct spe_function *p, int reg)
*/
void spe_release_register(struct spe_function *p, int reg)
{
assert(reg >= 0);
assert(reg < SPE_NUM_REGS);
assert(p->regs[reg] == 1);
@@ -517,7 +518,7 @@ void spe_release_register(struct spe_function *p, int reg)
*/
void spe_allocate_register_set(struct spe_function *p)
{
unsigned int i;
uint i;
/* Keep track of the set count. If it ever wraps around to 0,
* we're in trouble.
@@ -538,7 +539,7 @@ void spe_allocate_register_set(struct spe_function *p)
void spe_release_register_set(struct spe_function *p)
{
unsigned int i;
uint i;
/* If the set count drops below zero, we're in trouble. */
assert(p->set_count > 0);
@@ -599,7 +600,7 @@ spe_comment(struct spe_function *p, int rel_indent, const char *s)
* Load quad word.
* NOTE: offset is in bytes and the least significant 4 bits must be zero!
*/
void spe_lqd(struct spe_function *p, unsigned rT, unsigned rA, int offset)
void spe_lqd(struct spe_function *p, int rT, int rA, int offset)
{
const boolean pSave = p->print;
@@ -624,7 +625,7 @@ void spe_lqd(struct spe_function *p, unsigned rT, unsigned rA, int offset)
* Store quad word.
* NOTE: offset is in bytes and the least significant 4 bits must be zero!
*/
void spe_stqd(struct spe_function *p, unsigned rT, unsigned rA, int offset)
void spe_stqd(struct spe_function *p, int rT, int rA, int offset)
{
const boolean pSave = p->print;
@@ -653,51 +654,51 @@ void spe_stqd(struct spe_function *p, unsigned rT, unsigned rA, int offset)
*/
/** Branch Indirect to address in rA */
void spe_bi(struct spe_function *p, unsigned rA, int d, int e)
void spe_bi(struct spe_function *p, int rA, int d, int e)
{
emit_RI7(p, 0x1a8, 0, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Interupt Return */
void spe_iret(struct spe_function *p, unsigned rA, int d, int e)
void spe_iret(struct spe_function *p, int rA, int d, int e)
{
emit_RI7(p, 0x1aa, 0, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect and set link on external data */
void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, int d,
void spe_bisled(struct spe_function *p, int rT, int rA, int d,
int e)
{
emit_RI7(p, 0x1ab, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect and set link. Save PC in rT, jump to rA. */
void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, int d,
void spe_bisl(struct spe_function *p, int rT, int rA, int d,
int e)
{
emit_RI7(p, 0x1a9, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect if zero word. If rT.word[0]==0, jump to rA. */
void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
void spe_biz(struct spe_function *p, int rT, int rA, int d, int e)
{
emit_RI7(p, 0x128, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect if non-zero word. If rT.word[0]!=0, jump to rA. */
void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
void spe_binz(struct spe_function *p, int rT, int rA, int d, int e)
{
emit_RI7(p, 0x129, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect if zero halfword. If rT.halfword[1]==0, jump to rA. */
void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
void spe_bihz(struct spe_function *p, int rT, int rA, int d, int e)
{
emit_RI7(p, 0x12a, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect if non-zero halfword. If rT.halfword[1]!=0, jump to rA. */
void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
void spe_bihnz(struct spe_function *p, int rT, int rA, int d, int e)
{
emit_RI7(p, 0x12b, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
@@ -733,7 +734,7 @@ EMIT_R (spe_mtspr, 0x10c);
void
spe_load_float(struct spe_function *p, unsigned rT, float x)
spe_load_float(struct spe_function *p, int rT, float x)
{
if (x == 0.0f) {
spe_il(p, rT, 0x0);
@@ -760,7 +761,7 @@ spe_load_float(struct spe_function *p, unsigned rT, float x)
void
spe_load_int(struct spe_function *p, unsigned rT, int i)
spe_load_int(struct spe_function *p, int rT, int i)
{
if (-32768 <= i && i <= 32767) {
spe_il(p, rT, i);
@@ -772,7 +773,7 @@ spe_load_int(struct spe_function *p, unsigned rT, int i)
}
}
void spe_load_uint(struct spe_function *p, unsigned rT, unsigned int ui)
void spe_load_uint(struct spe_function *p, int rT, uint ui)
{
/* If the whole value is in the lower 18 bits, use ila, which
* doesn't sign-extend. Otherwise, if the two halfwords of
@@ -793,7 +794,7 @@ void spe_load_uint(struct spe_function *p, unsigned rT, unsigned int ui)
((ui & 0x00ff0000) == 0 || (ui & 0x00ff0000) == 0x00ff0000) &&
((ui & 0xff000000) == 0 || (ui & 0xff000000) == 0xff000000)
) {
unsigned int mask = 0;
uint mask = 0;
/* fsmbi duplicates each bit in the given mask eight times,
* using a 16-bit value to initialize a 16-byte quadword.
* Each 4-bit nybble of the mask corresponds to a full word
@@ -822,7 +823,7 @@ void spe_load_uint(struct spe_function *p, unsigned rT, unsigned int ui)
* Changes to one should be made in the other.
*/
void
spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
spe_and_uint(struct spe_function *p, int rT, int rA, uint ui)
{
/* If we can, emit a single instruction, either And Byte Immediate
* (which uses the same constant across each byte), And Halfword Immediate
@@ -832,7 +833,7 @@ spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
*
* Otherwise, we'll need to use a temporary register.
*/
unsigned int tmp;
uint tmp;
/* If the upper 23 bits are all 0s or all 1s, sign extension
* will work and we can use And Word Immediate
@@ -863,7 +864,7 @@ spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
}
/* Otherwise, we'll have to use a temporary register. */
unsigned int tmp_reg = spe_allocate_available_register(p);
int tmp_reg = spe_allocate_available_register(p);
spe_load_uint(p, tmp_reg, ui);
spe_and(p, rT, rA, tmp_reg);
spe_release_register(p, tmp_reg);
@@ -875,7 +876,7 @@ spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
* Changes to one should be made in the other.
*/
void
spe_xor_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
spe_xor_uint(struct spe_function *p, int rT, int rA, uint ui)
{
/* If we can, emit a single instruction, either Exclusive Or Byte
* Immediate (which uses the same constant across each byte), Exclusive
@@ -885,7 +886,7 @@ spe_xor_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
*
* Otherwise, we'll need to use a temporary register.
*/
unsigned int tmp;
uint tmp;
/* If the upper 23 bits are all 0s or all 1s, sign extension
* will work and we can use Exclusive Or Word Immediate
@@ -916,14 +917,14 @@ spe_xor_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
}
/* Otherwise, we'll have to use a temporary register. */
unsigned int tmp_reg = spe_allocate_available_register(p);
int tmp_reg = spe_allocate_available_register(p);
spe_load_uint(p, tmp_reg, ui);
spe_xor(p, rT, rA, tmp_reg);
spe_release_register(p, tmp_reg);
}
void
spe_compare_equal_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
spe_compare_equal_uint(struct spe_function *p, int rT, int rA, uint ui)
{
/* If the comparison value is 9 bits or less, it fits inside a
* Compare Equal Word Immediate instruction.
@@ -933,7 +934,7 @@ spe_compare_equal_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigne
}
/* Otherwise, we're going to have to load a word first. */
else {
unsigned int tmp_reg = spe_allocate_available_register(p);
int tmp_reg = spe_allocate_available_register(p);
spe_load_uint(p, tmp_reg, ui);
spe_ceq(p, rT, rA, tmp_reg);
spe_release_register(p, tmp_reg);
@@ -941,7 +942,7 @@ spe_compare_equal_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigne
}
void
spe_compare_greater_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
spe_compare_greater_uint(struct spe_function *p, int rT, int rA, uint ui)
{
/* If the comparison value is 10 bits or less, it fits inside a
* Compare Logical Greater Than Word Immediate instruction.
@@ -951,7 +952,7 @@ spe_compare_greater_uint(struct spe_function *p, unsigned rT, unsigned rA, unsig
}
/* Otherwise, we're going to have to load a word first. */
else {
unsigned int tmp_reg = spe_allocate_available_register(p);
int tmp_reg = spe_allocate_available_register(p);
spe_load_uint(p, tmp_reg, ui);
spe_clgt(p, rT, rA, tmp_reg);
spe_release_register(p, tmp_reg);
@@ -959,10 +960,10 @@ spe_compare_greater_uint(struct spe_function *p, unsigned rT, unsigned rA, unsig
}
void
spe_splat(struct spe_function *p, unsigned rT, unsigned rA)
spe_splat(struct spe_function *p, int rT, int rA)
{
/* Use a temporary, just in case rT == rA */
unsigned int tmp_reg = spe_allocate_available_register(p);
int tmp_reg = spe_allocate_available_register(p);
/* Duplicate bytes 0, 1, 2, and 3 across the whole register */
spe_ila(p, tmp_reg, 0x00010203);
spe_shufb(p, rT, rA, rA, tmp_reg);
@@ -971,14 +972,14 @@ spe_splat(struct spe_function *p, unsigned rT, unsigned rA)
void
spe_complement(struct spe_function *p, unsigned rT, unsigned rA)
spe_complement(struct spe_function *p, int rT, int rA)
{
spe_nor(p, rT, rA, rA);
}
void
spe_move(struct spe_function *p, unsigned rT, unsigned rA)
spe_move(struct spe_function *p, int rT, int rA)
{
/* Use different instructions depending on the instruction address
* to take advantage of the dual pipelines.
@@ -991,14 +992,14 @@ spe_move(struct spe_function *p, unsigned rT, unsigned rA)
void
spe_zero(struct spe_function *p, unsigned rT)
spe_zero(struct spe_function *p, int rT)
{
spe_xor(p, rT, rT, rT);
}
void
spe_splat_word(struct spe_function *p, unsigned rT, unsigned rA, int word)
spe_splat_word(struct spe_function *p, int rT, int rA, int word)
{
assert(word >= 0);
assert(word <= 3);
@@ -1038,9 +1039,9 @@ spe_splat_word(struct spe_function *p, unsigned rT, unsigned rA, int word)
* like "x = min(x, a)", we always allocate a new register to be safe.
*/
void
spe_float_min(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB)
spe_float_min(struct spe_function *p, int rT, int rA, int rB)
{
unsigned int compare_reg = spe_allocate_available_register(p);
int compare_reg = spe_allocate_available_register(p);
spe_fcgt(p, compare_reg, rA, rB);
spe_selb(p, rT, rA, rB, compare_reg);
spe_release_register(p, compare_reg);
@@ -1055,9 +1056,9 @@ spe_float_min(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB)
* so that the larger of the two is selected instead of the smaller.
*/
void
spe_float_max(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB)
spe_float_max(struct spe_function *p, int rT, int rA, int rB)
{
unsigned int compare_reg = spe_allocate_available_register(p);
int compare_reg = spe_allocate_available_register(p);
spe_fcgt(p, compare_reg, rA, rB);
spe_selb(p, rT, rB, rA, compare_reg);
spe_release_register(p, compare_reg);
+37 -44
View File
@@ -79,9 +79,9 @@ struct spe_function
};
extern void spe_init_func(struct spe_function *p, unsigned code_size);
extern void spe_init_func(struct spe_function *p, uint code_size);
extern void spe_release_func(struct spe_function *p);
extern unsigned spe_code_size(const struct spe_function *p);
extern uint spe_code_size(const struct spe_function *p);
extern int spe_allocate_available_register(struct spe_function *p);
extern int spe_allocate_register(struct spe_function *p, int reg);
@@ -89,8 +89,7 @@ extern void spe_release_register(struct spe_function *p, int reg);
extern void spe_allocate_register_set(struct spe_function *p);
extern void spe_release_register_set(struct spe_function *p);
extern unsigned
spe_get_registers_used(const struct spe_function *p, ubyte used[]);
extern uint spe_get_registers_used(const struct spe_function *p, ubyte used[]);
extern void spe_print_code(struct spe_function *p, boolean enable);
extern void spe_indent(struct spe_function *p, int spaces);
@@ -103,31 +102,25 @@ extern void spe_comment(struct spe_function *p, int rel_indent, const char *s);
#define EMIT(_name, _op) \
extern void _name (struct spe_function *p);
#define EMIT_(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT);
extern void _name (struct spe_function *p, int rT);
#define EMIT_R(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA);
extern void _name (struct spe_function *p, int rT, int rA);
#define EMIT_RR(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
unsigned rB);
extern void _name (struct spe_function *p, int rT, int rA, int rB);
#define EMIT_RRR(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
unsigned rB, unsigned rC);
extern void _name (struct spe_function *p, int rT, int rA, int rB, int rC);
#define EMIT_RI7(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
int imm);
extern void _name (struct spe_function *p, int rT, int rA, int imm);
#define EMIT_RI8(_name, _op, bias) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
int imm);
extern void _name (struct spe_function *p, int rT, int rA, int imm);
#define EMIT_RI10(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
int imm);
extern void _name (struct spe_function *p, int rT, int rA, int imm);
#define EMIT_RI10s(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
int imm);
extern void _name (struct spe_function *p, int rT, int rA, int imm);
#define EMIT_RI16(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, int imm);
extern void _name (struct spe_function *p, int rT, int imm);
#define EMIT_RI18(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, int imm);
extern void _name (struct spe_function *p, int rT, int imm);
#define EMIT_I16(_name, _op) \
extern void _name (struct spe_function *p, int imm);
#define UNDEF_EMIT_MACROS
@@ -301,82 +294,82 @@ EMIT_RI16(spe_brhz, 0x044)
EMIT (spe_lnop, 0x001)
extern void
spe_lqd(struct spe_function *p, unsigned rT, unsigned rA, int offset);
spe_lqd(struct spe_function *p, int rT, int rA, int offset);
extern void
spe_stqd(struct spe_function *p, unsigned rT, unsigned rA, int offset);
spe_stqd(struct spe_function *p, int rT, int rA, int offset);
extern void spe_bi(struct spe_function *p, unsigned rA, int d, int e);
extern void spe_iret(struct spe_function *p, unsigned rA, int d, int e);
extern void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA,
extern void spe_bi(struct spe_function *p, int rA, int d, int e);
extern void spe_iret(struct spe_function *p, int rA, int d, int e);
extern void spe_bisled(struct spe_function *p, int rT, int rA,
int d, int e);
extern void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA,
extern void spe_bisl(struct spe_function *p, int rT, int rA,
int d, int e);
extern void spe_biz(struct spe_function *p, unsigned rT, unsigned rA,
extern void spe_biz(struct spe_function *p, int rT, int rA,
int d, int e);
extern void spe_binz(struct spe_function *p, unsigned rT, unsigned rA,
extern void spe_binz(struct spe_function *p, int rT, int rA,
int d, int e);
extern void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA,
extern void spe_bihz(struct spe_function *p, int rT, int rA,
int d, int e);
extern void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA,
extern void spe_bihnz(struct spe_function *p, int rT, int rA,
int d, int e);
/** Load/splat immediate float into rT. */
extern void
spe_load_float(struct spe_function *p, unsigned rT, float x);
spe_load_float(struct spe_function *p, int rT, float x);
/** Load/splat immediate int into rT. */
extern void
spe_load_int(struct spe_function *p, unsigned rT, int i);
spe_load_int(struct spe_function *p, int rT, int i);
/** Load/splat immediate unsigned int into rT. */
extern void
spe_load_uint(struct spe_function *p, unsigned rT, unsigned int ui);
spe_load_uint(struct spe_function *p, int rT, uint ui);
/** And immediate value into rT. */
extern void
spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui);
spe_and_uint(struct spe_function *p, int rT, int rA, uint ui);
/** Xor immediate value into rT. */
extern void
spe_xor_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui);
spe_xor_uint(struct spe_function *p, int rT, int rA, uint ui);
/** Compare equal with immediate value. */
extern void
spe_compare_equal_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui);
spe_compare_equal_uint(struct spe_function *p, int rT, int rA, uint ui);
/** Compare greater with immediate value. */
extern void
spe_compare_greater_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui);
spe_compare_greater_uint(struct spe_function *p, int rT, int rA, uint ui);
/** Replicate word 0 of rA across rT. */
extern void
spe_splat(struct spe_function *p, unsigned rT, unsigned rA);
spe_splat(struct spe_function *p, int rT, int rA);
/** rT = complement_all_bits(rA). */
extern void
spe_complement(struct spe_function *p, unsigned rT, unsigned rA);
spe_complement(struct spe_function *p, int rT, int rA);
/** rT = rA. */
extern void
spe_move(struct spe_function *p, unsigned rT, unsigned rA);
spe_move(struct spe_function *p, int rT, int rA);
/** rT = {0,0,0,0}. */
extern void
spe_zero(struct spe_function *p, unsigned rT);
spe_zero(struct spe_function *p, int rT);
/** rT = splat(rA, word) */
extern void
spe_splat_word(struct spe_function *p, unsigned rT, unsigned rA, int word);
spe_splat_word(struct spe_function *p, int rT, int rA, int word);
/** rT = float min(rA, rB) */
extern void
spe_float_min(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB);
spe_float_min(struct spe_function *p, int rT, int rA, int rB);
/** rT = float max(rA, rB) */
extern void
spe_float_max(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB);
spe_float_max(struct spe_function *p, int rT, int rA, int rB);
/* Floating-point instructions
+1 -1
View File
@@ -52,7 +52,7 @@ extern "C" {
#endif
#if defined(PIPE_OS_WINDOWS) && defined(DEBUG)
#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG)
/* memory debugging */
+32 -11
View File
@@ -49,6 +49,15 @@
}
#define JOIN(x, y) JOIN_AGAIN(x, y)
#define JOIN_AGAIN(x, y) x ## y
#define STATIC_ASSERT(e) \
{typedef char JOIN(assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1];}
/** for sanity checking */
#define ASSERT_ALIGN16(ptr) \
ASSERT((((unsigned long) (ptr)) & 0xf) == 0);
@@ -134,6 +143,11 @@ struct cell_fence
volatile uint status[CELL_MAX_SPUS][4];
};
#ifdef __SPU__
typedef vector unsigned int opcode_t;
#else
typedef unsigned int opcode_t[4];
#endif
/**
* Fence command sent to SPUs. In response, the SPUs will write
@@ -141,8 +155,9 @@ struct cell_fence
*/
struct cell_command_fence
{
uint64_t opcode; /**< CELL_CMD_FENCE */
opcode_t opcode; /**< CELL_CMD_FENCE */
struct cell_fence *fence;
uint32_t pad_[3];
};
@@ -163,7 +178,7 @@ struct cell_command_fence
*/
struct cell_command_fragment_ops
{
uint64_t opcode; /**< CELL_CMD_STATE_FRAGMENT_OPS */
opcode_t opcode; /**< CELL_CMD_STATE_FRAGMENT_OPS */
/* Fields for the fallback case */
struct pipe_depth_stencil_alpha_state dsa;
@@ -189,8 +204,9 @@ struct cell_command_fragment_ops
*/
struct cell_command_fragment_program
{
uint64_t opcode; /**< CELL_CMD_STATE_FRAGMENT_PROGRAM */
opcode_t opcode; /**< CELL_CMD_STATE_FRAGMENT_PROGRAM */
uint num_inst; /**< Number of instructions */
uint32_t pad[3];
unsigned code[SPU_MAX_FRAGMENT_PROGRAM_INSTS];
};
@@ -200,10 +216,11 @@ struct cell_command_fragment_program
*/
struct cell_command_framebuffer
{
uint64_t opcode; /**< CELL_CMD_STATE_FRAMEBUFFER */
opcode_t opcode; /**< CELL_CMD_STATE_FRAMEBUFFER */
int width, height;
void *color_start, *depth_start;
enum pipe_format color_format, depth_format;
uint32_t pad_[2];
};
@@ -212,7 +229,7 @@ struct cell_command_framebuffer
*/
struct cell_command_rasterizer
{
uint64_t opcode; /**< CELL_CMD_STATE_RASTERIZER */
opcode_t opcode; /**< CELL_CMD_STATE_RASTERIZER */
struct pipe_rasterizer_state rasterizer;
};
@@ -222,9 +239,10 @@ struct cell_command_rasterizer
*/
struct cell_command_clear_surface
{
uint64_t opcode; /**< CELL_CMD_CLEAR_SURFACE */
opcode_t opcode; /**< CELL_CMD_CLEAR_SURFACE */
uint surface; /**< Temporary: 0=color, 1=Z */
uint value;
uint32_t pad[2];
};
@@ -271,7 +289,7 @@ struct cell_shader_info
#define SPU_VERTS_PER_BATCH 64
struct cell_command_vs
{
uint64_t opcode; /**< CELL_CMD_VS_EXECUTE */
opcode_t opcode; /**< CELL_CMD_VS_EXECUTE */
uint64_t vOut[SPU_VERTS_PER_BATCH];
unsigned num_elts;
unsigned elts[SPU_VERTS_PER_BATCH];
@@ -283,7 +301,7 @@ struct cell_command_vs
struct cell_command_render
{
uint64_t opcode; /**< CELL_CMD_RENDER */
opcode_t opcode; /**< CELL_CMD_RENDER */
uint prim_type; /**< PIPE_PRIM_x */
uint num_verts;
uint vertex_size; /**< bytes per vertex */
@@ -292,27 +310,30 @@ struct cell_command_render
float xmin, ymin, xmax, ymax; /* XXX another dummy field */
uint min_index;
boolean inline_verts;
uint32_t pad_[1];
};
struct cell_command_release_verts
{
uint64_t opcode; /**< CELL_CMD_RELEASE_VERTS */
opcode_t opcode; /**< CELL_CMD_RELEASE_VERTS */
uint vertex_buf; /**< in [0, CELL_NUM_BUFFERS-1] */
uint32_t pad_[3];
};
struct cell_command_sampler
{
uint64_t opcode; /**< CELL_CMD_STATE_SAMPLER */
opcode_t opcode; /**< CELL_CMD_STATE_SAMPLER */
uint unit;
struct pipe_sampler_state state;
uint32_t pad_[1];
};
struct cell_command_texture
{
uint64_t opcode; /**< CELL_CMD_STATE_TEXTURE */
opcode_t opcode; /**< CELL_CMD_STATE_TEXTURE */
uint target; /**< PIPE_TEXTURE_x */
uint unit;
void *start[CELL_MAX_TEXTURE_LEVELS]; /**< Address in main memory */
+11 -66
View File
@@ -108,15 +108,16 @@ emit_fence(struct cell_context *cell)
fence->status[i][0] = CELL_FENCE_EMITTED;
}
STATIC_ASSERT(sizeof(struct cell_command_fence) % 16 == 0);
ASSERT(size % 16 == 0);
ASSERT(size + sizeof(struct cell_command_fence) <= CELL_BUFFER_SIZE);
fence_cmd = (struct cell_command_fence *) (cell->buffer[batch] + size);
fence_cmd->opcode = CELL_CMD_FENCE;
fence_cmd->opcode[0] = CELL_CMD_FENCE;
fence_cmd->fence = fence;
/* update batch buffer size */
cell->buffer_size[batch] = size + sizeof(struct cell_command_fence);
assert(sizeof(struct cell_command_fence) % 8 == 0);
}
@@ -192,16 +193,17 @@ cell_batch_free_space(const struct cell_context *cell)
/**
* Append data to the current batch buffer.
* \param data address of block of bytes to append
* \param bytes size of block of bytes
* Allocate space in the current batch buffer for 'bytes' space.
* Bytes must be a multiple of 16 bytes. Allocation will be 16 byte aligned.
* \return address in batch buffer to put data
*/
void
cell_batch_append(struct cell_context *cell, const void *data, uint bytes)
void *
cell_batch_alloc16(struct cell_context *cell, uint bytes)
{
void *pos;
uint size;
ASSERT(bytes % 8 == 0);
ASSERT(bytes % 16 == 0);
ASSERT(bytes <= CELL_BUFFER_SIZE);
ASSERT(cell->cur_batch >= 0);
@@ -222,64 +224,7 @@ cell_batch_append(struct cell_context *cell, const void *data, uint bytes)
size = 0;
}
ASSERT(size + bytes <= CELL_BUFFER_SIZE);
memcpy(cell->buffer[cell->cur_batch] + size, data, bytes);
cell->buffer_size[cell->cur_batch] = size + bytes;
}
/**
* Allocate space in the current batch buffer for 'bytes' space.
* \return address in batch buffer to put data
*/
void *
cell_batch_alloc(struct cell_context *cell, uint bytes)
{
return cell_batch_alloc_aligned(cell, bytes, 1);
}
/**
* Same as \sa cell_batch_alloc, but return an address at a particular
* alignment.
*/
void *
cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
uint alignment)
{
void *pos;
uint size, padbytes;
ASSERT(bytes % 8 == 0);
ASSERT(bytes <= CELL_BUFFER_SIZE);
ASSERT(alignment > 0);
ASSERT(cell->cur_batch >= 0);
#ifdef ASSERT
{
uint spu;
for (spu = 0; spu < cell->num_spus; spu++) {
ASSERT(cell->buffer_status[spu][cell->cur_batch][0]
== CELL_BUFFER_STATUS_USED);
}
}
#endif
size = cell->buffer_size[cell->cur_batch];
padbytes = (alignment - (size % alignment)) % alignment;
if (padbytes + bytes > cell_batch_free_space(cell)) {
cell_batch_flush(cell);
size = 0;
}
else {
size += padbytes;
}
ASSERT(size % alignment == 0);
ASSERT(size % 16 == 0);
ASSERT(size + bytes <= CELL_BUFFER_SIZE);
pos = (void *) (cell->buffer[cell->cur_batch] + size);
+1 -8
View File
@@ -44,15 +44,8 @@ cell_batch_flush(struct cell_context *cell);
extern uint
cell_batch_free_space(const struct cell_context *cell);
extern void
cell_batch_append(struct cell_context *cell, const void *data, uint bytes);
extern void *
cell_batch_alloc(struct cell_context *cell, uint bytes);
extern void *
cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
uint alignment);
cell_batch_alloc16(struct cell_context *cell, uint bytes);
extern void
cell_init_batch_buffers(struct cell_context *cell);
+3 -2
View File
@@ -99,10 +99,11 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
/* Build a CLEAR command and place it in the current batch buffer */
{
STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0);
struct cell_command_clear_surface *clr
= (struct cell_command_clear_surface *)
cell_batch_alloc(cell, sizeof(*clr));
clr->opcode = CELL_CMD_CLEAR_SURFACE;
cell_batch_alloc16(cell, sizeof(*clr));
clr->opcode[0] = CELL_CMD_CLEAR_SURFACE;
clr->surface = surfIndex;
clr->value = clearValue;
}
+7 -6
View File
@@ -72,8 +72,9 @@ cell_flush_int(struct cell_context *cell, unsigned flags)
flushing = TRUE;
if (flags & CELL_FLUSH_WAIT) {
uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t));
*cmd = CELL_CMD_FINISH;
STATIC_ASSERT(sizeof(opcode_t) % 16 == 0);
opcode_t *cmd = (opcode_t*) cell_batch_alloc16(cell, sizeof(opcode_t));
*cmd[0] = CELL_CMD_FINISH;
}
cell_batch_flush(cell);
@@ -101,11 +102,11 @@ void
cell_flush_buffer_range(struct cell_context *cell, void *ptr,
unsigned size)
{
uint64_t batch[1 + (ROUNDUP8(sizeof(struct cell_buffer_range)) / 8)];
struct cell_buffer_range *br = (struct cell_buffer_range *) & batch[1];
STATIC_ASSERT((sizeof(opcode_t) + sizeof(struct cell_buffer_range)) % 16 == 0);
uint32_t *batch = (uint32_t*)cell_batch_alloc16(cell,
sizeof(opcode_t) + sizeof(struct cell_buffer_range));
struct cell_buffer_range *br = (struct cell_buffer_range *) &batch[4];
batch[0] = CELL_CMD_FLUSH_BUFFER_RANGE;
br->base = (uintptr_t) ptr;
br->size = size;
cell_batch_append(cell, batch, sizeof(batch));
}
File diff suppressed because it is too large Load Diff
+24 -19
View File
@@ -133,7 +133,7 @@ lookup_fragment_ops(struct cell_context *cell)
*/
ops = CALLOC_VARIANT_LENGTH_STRUCT(cell_command_fragment_ops, total_code_size);
/* populate the new cell_command_fragment_ops object */
ops->opcode = CELL_CMD_STATE_FRAGMENT_OPS;
ops->opcode[0] = CELL_CMD_STATE_FRAGMENT_OPS;
ops->total_code_size = total_code_size;
ops->front_code_index = 0;
memcpy(ops->code, spe_code_front.store, front_code_size);
@@ -178,10 +178,10 @@ static void
emit_state_cmd(struct cell_context *cell, uint cmd,
const void *state, uint state_size)
{
uint64_t *dst = (uint64_t *)
cell_batch_alloc(cell, ROUNDUP8(sizeof(uint64_t) + state_size));
uint32_t *dst = (uint32_t *)
cell_batch_alloc16(cell, ROUNDUP16(sizeof(opcode_t) + state_size));
*dst = cmd;
memcpy(dst + 1, state, state_size);
memcpy(dst + 4, state, state_size);
}
@@ -195,9 +195,10 @@ cell_emit_state(struct cell_context *cell)
if (cell->dirty & CELL_NEW_FRAMEBUFFER) {
struct pipe_surface *cbuf = cell->framebuffer.cbufs[0];
struct pipe_surface *zbuf = cell->framebuffer.zsbuf;
STATIC_ASSERT(sizeof(struct cell_command_framebuffer) % 16 == 0);
struct cell_command_framebuffer *fb
= cell_batch_alloc(cell, sizeof(*fb));
fb->opcode = CELL_CMD_STATE_FRAMEBUFFER;
= cell_batch_alloc16(cell, sizeof(*fb));
fb->opcode[0] = CELL_CMD_STATE_FRAMEBUFFER;
fb->color_start = cell->cbuf_map[0];
fb->color_format = cbuf->format;
fb->depth_start = cell->zsbuf_map;
@@ -211,17 +212,19 @@ cell_emit_state(struct cell_context *cell)
}
if (cell->dirty & (CELL_NEW_RASTERIZER)) {
STATIC_ASSERT(sizeof(struct cell_command_rasterizer) % 16 == 0);
struct cell_command_rasterizer *rast =
cell_batch_alloc(cell, sizeof(*rast));
rast->opcode = CELL_CMD_STATE_RASTERIZER;
cell_batch_alloc16(cell, sizeof(*rast));
rast->opcode[0] = CELL_CMD_STATE_RASTERIZER;
rast->rasterizer = *cell->rasterizer;
}
if (cell->dirty & (CELL_NEW_FS)) {
/* Send new fragment program to SPUs */
STATIC_ASSERT(sizeof(struct cell_command_fragment_program) % 16 == 0);
struct cell_command_fragment_program *fp
= cell_batch_alloc(cell, sizeof(*fp));
fp->opcode = CELL_CMD_STATE_FRAGMENT_PROGRAM;
= cell_batch_alloc16(cell, sizeof(*fp));
fp->opcode[0] = CELL_CMD_STATE_FRAGMENT_PROGRAM;
fp->num_inst = cell->fs->code.num_inst;
memcpy(&fp->code, cell->fs->code.store,
SPU_MAX_FRAGMENT_PROGRAM_INSTS * SPE_INST_SIZE);
@@ -238,14 +241,14 @@ cell_emit_state(struct cell_context *cell)
const uint shader = PIPE_SHADER_FRAGMENT;
const uint num_const = cell->constants[shader].size / sizeof(float);
uint i, j;
float *buf = cell_batch_alloc(cell, 16 + num_const * sizeof(float));
uint64_t *ibuf = (uint64_t *) buf;
float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float)));
uint32_t *ibuf = (uint32_t *) buf;
const float *constants = pipe_buffer_map(cell->pipe.screen,
cell->constants[shader].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
ibuf[0] = CELL_CMD_STATE_FS_CONSTANTS;
ibuf[1] = num_const;
j = 4;
ibuf[4] = num_const;
j = 8;
for (i = 0; i < num_const; i++) {
buf[j++] = constants[i];
}
@@ -258,7 +261,7 @@ cell_emit_state(struct cell_context *cell)
struct cell_command_fragment_ops *fops, *fops_cmd;
/* Note that cell_command_fragment_ops is a variant-sized record */
fops = lookup_fragment_ops(cell);
fops_cmd = cell_batch_alloc(cell, sizeof(*fops_cmd) + fops->total_code_size);
fops_cmd = cell_batch_alloc16(cell, ROUNDUP16(sizeof(*fops_cmd) + fops->total_code_size));
memcpy(fops_cmd, fops, sizeof(*fops) + fops->total_code_size);
}
@@ -267,9 +270,10 @@ cell_emit_state(struct cell_context *cell)
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
if (cell->dirty_samplers & (1 << i)) {
if (cell->sampler[i]) {
STATIC_ASSERT(sizeof(struct cell_command_sampler) % 16 == 0);
struct cell_command_sampler *sampler
= cell_batch_alloc(cell, sizeof(*sampler));
sampler->opcode = CELL_CMD_STATE_SAMPLER;
= cell_batch_alloc16(cell, sizeof(*sampler));
sampler->opcode[0] = CELL_CMD_STATE_SAMPLER;
sampler->unit = i;
sampler->state = *cell->sampler[i];
}
@@ -282,9 +286,10 @@ cell_emit_state(struct cell_context *cell)
uint i;
for (i = 0;i < CELL_MAX_SAMPLERS; i++) {
if (cell->dirty_textures & (1 << i)) {
STATIC_ASSERT(sizeof(struct cell_command_texture) % 16 == 0);
struct cell_command_texture *texture
= cell_batch_alloc(cell, sizeof(*texture));
texture->opcode = CELL_CMD_STATE_TEXTURE;
= (struct cell_command_texture *)cell_batch_alloc16(cell, sizeof(*texture));
texture->opcode[0] = CELL_CMD_STATE_TEXTURE;
texture->unit = i;
if (cell->texture[i]) {
uint level;
+9 -7
View File
@@ -116,10 +116,11 @@ cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
/* Tell SPUs they can release the vert buf */
if (cvbr->vertex_buf != ~0U) {
STATIC_ASSERT(sizeof(struct cell_command_release_verts) % 16 == 0);
struct cell_command_release_verts *release
= (struct cell_command_release_verts *)
cell_batch_alloc(cell, sizeof(struct cell_command_release_verts));
release->opcode = CELL_CMD_RELEASE_VERTS;
cell_batch_alloc16(cell, sizeof(struct cell_command_release_verts));
release->opcode[0] = CELL_CMD_RELEASE_VERTS;
release->vertex_buf = cvbr->vertex_buf;
}
@@ -210,15 +211,16 @@ cell_vbuf_draw(struct vbuf_render *vbr,
/* build/insert batch RENDER command */
{
const uint index_bytes = ROUNDUP8(nr_indices * 2);
const uint vertex_bytes = nr_vertices * 4 * cell->vertex_info.size;
const uint index_bytes = ROUNDUP16(nr_indices * 2);
const uint vertex_bytes = ROUNDUP16(nr_vertices * 4 * cell->vertex_info.size);
STATIC_ASSERT(sizeof(struct cell_command_render) % 16 == 0);
const uint batch_size = sizeof(struct cell_command_render) + index_bytes;
struct cell_command_render *render
= (struct cell_command_render *)
cell_batch_alloc(cell, batch_size);
cell_batch_alloc16(cell, batch_size);
render->opcode = CELL_CMD_RENDER;
render->opcode[0] = CELL_CMD_RENDER;
render->prim_type = cvbr->prim;
render->num_indexes = nr_indices;
@@ -236,7 +238,7 @@ cell_vbuf_draw(struct vbuf_render *vbr,
min_index == 0 &&
vertex_bytes + 16 <= cell_batch_free_space(cell)) {
/* vertex data inlined, after indices, at 16-byte boundary */
void *dst = cell_batch_alloc_aligned(cell, vertex_bytes, 16);
void *dst = cell_batch_alloc16(cell, vertex_bytes);
memcpy(dst, vertices, vertex_bytes);
render->inline_verts = TRUE;
render->vertex_buf = ~0;
+26 -26
View File
@@ -292,10 +292,10 @@ cmd_state_fragment_program(const struct cell_command_fragment_program *fp)
static uint
cmd_state_fs_constants(const uint64_t *buffer, uint pos)
cmd_state_fs_constants(const qword *buffer, uint pos)
{
const uint num_const = buffer[pos + 1];
const float *constants = (const float *) &buffer[pos + 2];
const uint num_const = spu_extract((vector unsigned int)buffer[pos+1], 0);
const float *constants = (const float *) &buffer[pos+2];
uint i;
D_PRINTF(CELL_DEBUG_CMD, "CMD_STATE_FS_CONSTANTS (%u)\n", num_const);
@@ -306,8 +306,8 @@ cmd_state_fs_constants(const uint64_t *buffer, uint pos)
spu.constants[i] = spu_splats(constants[i]);
}
/* return new buffer pos (in 8-byte words) */
return pos + 2 + num_const / 2;
/* return new buffer pos (in 16-byte words) */
return pos + 2 + (ROUNDUP16(num_const * sizeof(float)) / 16);
}
@@ -547,8 +547,8 @@ cmd_batch(uint opcode)
{
const uint buf = (opcode >> 8) & 0xff;
uint size = (opcode >> 16);
uint64_t buffer[CELL_BUFFER_SIZE / 8] ALIGN16_ATTRIB;
const unsigned usize = size / sizeof(buffer[0]);
qword buffer[CELL_BUFFER_SIZE / 16] ALIGN16_ATTRIB;
const unsigned usize = ROUNDUP16(size) / sizeof(buffer[0]);
uint pos;
D_PRINTF(CELL_DEBUG_CMD, "BATCH buffer %u, len %u, from %p\n",
@@ -578,7 +578,7 @@ cmd_batch(uint opcode)
* Loop over commands in the batch buffer
*/
for (pos = 0; pos < usize; /* no incr */) {
switch (buffer[pos]) {
switch (si_to_uint(buffer[pos])) {
/*
* rendering commands
*/
@@ -587,7 +587,7 @@ cmd_batch(uint opcode)
struct cell_command_clear_surface *clr
= (struct cell_command_clear_surface *) &buffer[pos];
cmd_clear_surface(clr);
pos += sizeof(*clr) / 8;
pos += sizeof(*clr) / 16;
}
break;
case CELL_CMD_RENDER:
@@ -596,7 +596,7 @@ cmd_batch(uint opcode)
= (struct cell_command_render *) &buffer[pos];
uint pos_incr;
cmd_render(render, &pos_incr);
pos += pos_incr;
pos += ((pos_incr+1)&~1) / 2; // should 'fix' cmd_render return
}
break;
/*
@@ -607,7 +607,7 @@ cmd_batch(uint opcode)
struct cell_command_framebuffer *fb
= (struct cell_command_framebuffer *) &buffer[pos];
cmd_state_framebuffer(fb);
pos += sizeof(*fb) / 8;
pos += sizeof(*fb) / 16;
}
break;
case CELL_CMD_STATE_FRAGMENT_OPS:
@@ -616,7 +616,7 @@ cmd_batch(uint opcode)
= (struct cell_command_fragment_ops *) &buffer[pos];
cmd_state_fragment_ops(fops);
/* This is a variant-sized command */
pos += (sizeof(*fops) + fops->total_code_size)/ 8;
pos += ROUNDUP16(sizeof(*fops) + fops->total_code_size) / 16;
}
break;
case CELL_CMD_STATE_FRAGMENT_PROGRAM:
@@ -624,7 +624,7 @@ cmd_batch(uint opcode)
struct cell_command_fragment_program *fp
= (struct cell_command_fragment_program *) &buffer[pos];
cmd_state_fragment_program(fp);
pos += sizeof(*fp) / 8;
pos += sizeof(*fp) / 16;
}
break;
case CELL_CMD_STATE_FS_CONSTANTS:
@@ -635,7 +635,7 @@ cmd_batch(uint opcode)
struct cell_command_rasterizer *rast =
(struct cell_command_rasterizer *) &buffer[pos];
spu.rasterizer = rast->rasterizer;
pos += sizeof(*rast) / 8;
pos += sizeof(*rast) / 16;
}
break;
case CELL_CMD_STATE_SAMPLER:
@@ -643,7 +643,7 @@ cmd_batch(uint opcode)
struct cell_command_sampler *sampler
= (struct cell_command_sampler *) &buffer[pos];
cmd_state_sampler(sampler);
pos += sizeof(*sampler) / 8;
pos += sizeof(*sampler) / 16;
}
break;
case CELL_CMD_STATE_TEXTURE:
@@ -651,37 +651,37 @@ cmd_batch(uint opcode)
struct cell_command_texture *texture
= (struct cell_command_texture *) &buffer[pos];
cmd_state_texture(texture);
pos += sizeof(*texture) / 8;
pos += sizeof(*texture) / 16;
}
break;
case CELL_CMD_STATE_VERTEX_INFO:
cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct vertex_info)) / 8);
pos += 1 + ROUNDUP16(sizeof(struct vertex_info)) / 16;
break;
case CELL_CMD_STATE_VIEWPORT:
(void) memcpy(& draw.viewport, &buffer[pos+1],
sizeof(struct pipe_viewport_state));
pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8);
pos += 1 + ROUNDUP16(sizeof(struct pipe_viewport_state)) / 16;
break;
case CELL_CMD_STATE_UNIFORMS:
draw.constants = (const float (*)[4]) (uintptr_t) buffer[pos + 1];
draw.constants = (const float (*)[4]) (uintptr_t)spu_extract((vector unsigned int)buffer[pos+1],0);
pos += 2;
break;
case CELL_CMD_STATE_VS_ARRAY_INFO:
cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8);
pos += 1 + ROUNDUP16(sizeof(struct cell_array_info)) / 16;
break;
case CELL_CMD_STATE_BIND_VS:
#if 0
spu_bind_vertex_shader(&draw,
(struct cell_shader_info *) &buffer[pos+1]);
#endif
pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8);
pos += 1 + ROUNDUP16(sizeof(struct cell_shader_info)) / 16;
break;
case CELL_CMD_STATE_ATTRIB_FETCH:
cmd_state_attrib_fetch((struct cell_attribute_fetch_code *)
&buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8);
pos += 1 + ROUNDUP16(sizeof(struct cell_attribute_fetch_code)) / 16;
break;
/*
* misc commands
@@ -695,7 +695,7 @@ cmd_batch(uint opcode)
struct cell_command_fence *fence_cmd =
(struct cell_command_fence *) &buffer[pos];
cmd_fence(fence_cmd);
pos += sizeof(*fence_cmd) / 8;
pos += sizeof(*fence_cmd) / 16;
}
break;
case CELL_CMD_RELEASE_VERTS:
@@ -703,7 +703,7 @@ cmd_batch(uint opcode)
struct cell_command_release_verts *release
= (struct cell_command_release_verts *) &buffer[pos];
cmd_release_verts(release);
pos += sizeof(*release) / 8;
pos += sizeof(*release) / 16;
}
break;
case CELL_CMD_FLUSH_BUFFER_RANGE: {
@@ -711,11 +711,11 @@ cmd_batch(uint opcode)
&buffer[pos+1];
spu_dcache_mark_dirty((unsigned) br->base, br->size);
pos += (1 + ROUNDUP8(sizeof(struct cell_buffer_range)) / 8);
pos += 1 + ROUNDUP16(sizeof(struct cell_buffer_range)) / 16;
break;
}
default:
printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]);
printf("SPU %u: bad opcode: 0x%x\n", spu.init.id, si_to_uint(buffer[pos]));
ASSERT(0);
break;
}
+1 -1
View File
@@ -171,7 +171,7 @@
SHUFFLE_PATTERN_16_##M##__, \
SHUFFLE_PATTERN_16_##N##__, \
SHUFFLE_PATTERN_16_##O##__, \
SHUFFLE_PATTERN_16_##P
SHUFFLE_PATTERN_16_##P##__
#define SHUFFLE16(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) \
((const vector unsigned char){ \
+1 -1
View File
@@ -57,7 +57,7 @@ struct vertex_header {
/* XXX fix this */
#undef CEILF
#define CEILF(X) ((float) (int) ((X) + 0.99999))
#define CEILF(X) ((float) (int) ((X) + 0.99999f))
#define QUAD_TOP_LEFT 0
+12 -2
View File
@@ -67,11 +67,18 @@ struct nv50_rasterizer_stateobj {
struct nouveau_stateobj *so;
};
struct nv50_miptree_level {
struct pipe_buffer **image;
int *image_offset;
unsigned image_dirty_cpu[512/32];
unsigned image_dirty_gpu[512/32];
};
struct nv50_miptree {
struct pipe_texture base;
struct pipe_buffer *buffer;
int *image_offset;
struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
int image_nr;
int total_size;
};
@@ -84,7 +91,6 @@ nv50_miptree(struct pipe_texture *pt)
struct nv50_surface {
struct pipe_surface base;
struct pipe_buffer *untiled;
};
static INLINE struct nv50_surface *
@@ -186,4 +192,8 @@ extern boolean nv50_state_validate(struct nv50_context *nv50);
/* nv50_tex.c */
extern void nv50_tex_validate(struct nv50_context *);
/* nv50_miptree.c */
extern void nv50_miptree_sync(struct pipe_screen *, struct nv50_miptree *,
unsigned level, unsigned image);
#endif
+146 -14
View File
@@ -27,14 +27,16 @@
#include "nv50_context.h"
static struct pipe_texture *
nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
{
struct pipe_winsys *ws = pscreen->winsys;
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
unsigned usage, width = pt->width[0], height = pt->height[0];
int i;
struct pipe_texture *pt = &mt->base;
unsigned usage, width = tmp->width[0], height = tmp->height[0];
unsigned depth = tmp->depth[0];
int i, l;
mt->base = *pt;
mt->base = *tmp;
mt->base.refcount = 1;
mt->base.screen = pscreen;
@@ -59,17 +61,38 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
mt->image_nr = 1;
break;
}
mt->image_offset = CALLOC(mt->image_nr, sizeof(int));
for (l = 0; l <= pt->last_level; l++) {
struct nv50_miptree_level *lvl = &mt->level[l];
pt->width[l] = width;
pt->height[l] = height;
pt->depth[l] = depth;
pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
lvl->image_offset = CALLOC(mt->image_nr, sizeof(int));
lvl->image = CALLOC(mt->image_nr, sizeof(struct pipe_buffer *));
width = MAX2(1, width >> 1);
height = MAX2(1, height >> 1);
depth = MAX2(1, depth >> 1);
}
for (i = 0; i < mt->image_nr; i++) {
int image_size;
for (l = 0; l <= pt->last_level; l++) {
struct nv50_miptree_level *lvl = &mt->level[l];
int size;
image_size = align(width, 8) * pt->block.size;
image_size = align(image_size, 64);
image_size *= align(height, 8) * pt->block.size;
size = align(pt->width[l], 8) * pt->block.size;
size = align(size, 64);
size *= align(pt->height[l], 8) * pt->block.size;
mt->image_offset[i] = mt->total_size;
mt->total_size += image_size;
lvl->image[i] = ws->buffer_create(ws, 256, 0, size);
lvl->image_offset[i] = mt->total_size;
mt->total_size += size;
}
}
mt->buffer = ws->buffer_create(ws, 256, usage, mt->total_size);
@@ -81,6 +104,24 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
return &mt->base;
}
static INLINE void
mark_dirty(uint32_t *flags, unsigned image)
{
flags[image / 32] |= (1 << (image % 32));
}
static INLINE void
mark_clean(uint32_t *flags, unsigned image)
{
flags[image / 32] &= ~(1 << (image % 32));
}
static INLINE int
is_dirty(uint32_t *flags, unsigned image)
{
return !!(flags[image / 32] & (1 << (image % 32)));
}
static void
nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
{
@@ -96,12 +137,86 @@ nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
}
}
void
nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt,
unsigned level, unsigned image)
{
struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
struct nv50_miptree_level *lvl = &mt->level[level];
struct pipe_surface *dst, *src;
unsigned face = 0, zslice = 0;
if (!is_dirty(lvl->image_dirty_cpu, image))
return;
if (mt->base.target == PIPE_TEXTURE_CUBE)
face = image;
else
if (mt->base.target == PIPE_TEXTURE_3D)
zslice = image;
/* Mark as clean already - so we don't continually call this function
* trying to get a GPU_WRITE pipe_surface!
*/
mark_clean(lvl->image_dirty_cpu, image);
/* Pretend we're doing CPU access so we get the backing pipe_surface
* and not a view into the larger miptree.
*/
src = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice,
PIPE_BUFFER_USAGE_CPU_READ);
/* Pretend we're only reading with the GPU so surface doesn't get marked
* as dirtied by the GPU.
*/
dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice,
PIPE_BUFFER_USAGE_GPU_READ);
nvws->surface_copy(nvws, dst, 0, 0, src, 0, 0, dst->width, dst->height);
pscreen->tex_surface_release(pscreen, &dst);
pscreen->tex_surface_release(pscreen, &src);
}
/* The reverse of the above */
void
nv50_miptree_sync_cpu(struct pipe_screen *pscreen, struct nv50_miptree *mt,
unsigned level, unsigned image)
{
struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
struct nv50_miptree_level *lvl = &mt->level[level];
struct pipe_surface *dst, *src;
unsigned face = 0, zslice = 0;
if (!is_dirty(lvl->image_dirty_gpu, image))
return;
if (mt->base.target == PIPE_TEXTURE_CUBE)
face = image;
else
if (mt->base.target == PIPE_TEXTURE_3D)
zslice = image;
mark_clean(lvl->image_dirty_gpu, image);
src = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice,
PIPE_BUFFER_USAGE_GPU_READ);
dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice,
PIPE_BUFFER_USAGE_CPU_READ);
nvws->surface_copy(nvws, dst, 0, 0, src, 0, 0, dst->width, dst->height);
pscreen->tex_surface_release(pscreen, &dst);
pscreen->tex_surface_release(pscreen, &src);
}
static struct pipe_surface *
nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags)
{
struct nv50_miptree *mt = nv50_miptree(pt);
struct nv50_miptree_level *lvl = &mt->level[level];
struct nv50_surface *s;
struct pipe_surface *ps;
int img;
@@ -128,12 +243,29 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
ps->nblocksx = pt->nblocksx[level];
ps->nblocksy = pt->nblocksy[level];
ps->stride = ps->width * ps->block.size;
ps->offset = mt->image_offset[img];
ps->usage = flags;
ps->status = PIPE_SURFACE_STATUS_DEFINED;
pipe_texture_reference(&ps->texture, pt);
pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer);
if (flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE));
nv50_miptree_sync_cpu(pscreen, mt, level, img);
ps->offset = 0;
pipe_texture_reference(&ps->texture, pt);
pipe_buffer_reference(pscreen, &ps->buffer, lvl->image[img]);
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
mark_dirty(lvl->image_dirty_cpu, img);
} else {
nv50_miptree_sync(pscreen, mt, level, img);
ps->offset = lvl->image_offset[img];
pipe_texture_reference(&ps->texture, pt);
pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer);
if (flags & PIPE_BUFFER_USAGE_GPU_WRITE)
mark_dirty(lvl->image_dirty_gpu, img);
}
return ps;
}
+36 -2
View File
@@ -32,7 +32,7 @@
#include "nv50_context.h"
#define NV50_SU_MAX_TEMP 64
#define NV50_PROGRAM_DUMP
//#define NV50_PROGRAM_DUMP
/* ARL - gallium craps itself on progs/vp/arl.txt
*
@@ -841,6 +841,28 @@ emit_neg(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
emit(pc, e);
}
static void
emit_kil(struct nv50_pc *pc, struct nv50_reg *src)
{
struct nv50_program_exec *e;
const int r_pred = 1;
/* Sets predicate reg ? */
e = exec(pc);
e->inst[0] = 0xa00001fd;
e->inst[1] = 0xc4014788;
set_src_0(pc, src, e);
set_pred_wr(pc, 1, r_pred, e);
emit(pc, e);
/* This is probably KILP */
e = exec(pc);
e->inst[0] = 0x000001fe;
set_long(pc, e);
set_pred(pc, 1 /* LT? */, r_pred, e);
emit(pc, e);
}
static struct nv50_reg *
tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst)
{
@@ -1069,6 +1091,12 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
free_temp(pc, temp);
break;
case TGSI_OPCODE_KIL:
emit_kil(pc, src[0][0]);
emit_kil(pc, src[0][1]);
emit_kil(pc, src[0][2]);
emit_kil(pc, src[0][3]);
break;
case TGSI_OPCODE_LIT:
emit_lit(pc, &dst[0], mask, &src[0][0]);
break;
@@ -1602,13 +1630,19 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
if (!upload)
return;
#ifdef NV50_PROGRAM_DUMP
NOUVEAU_ERR("-------\n");
up = ptr = MALLOC(p->exec_size * 4);
for (e = p->exec_head; e; e = e->next) {
NOUVEAU_ERR("0x%08x\n", e->inst[0]);
if (is_long(e))
NOUVEAU_ERR("0x%08x\n", e->inst[1]);
}
#endif
up = ptr = MALLOC(p->exec_size * 4);
for (e = p->exec_head; e; e = e->next) {
*(ptr++) = e->inst[0];
if (is_long(e))
*(ptr++) = e->inst[1];
@@ -1705,7 +1739,7 @@ nv50_fragprog_validate(struct nv50_context *nv50)
so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
NOUVEAU_BO_LOW, 0, 0);
so_method(so, tesla, 0x1904, 4);
so_data (so, 0x01040404); /* p: 0x01000404 */
so_data (so, 0x00040404); /* p: 0x01000404 */
so_data (so, 0x00000004);
so_data (so, 0x00000000);
so_data (so, 0x00000000);
+72 -12
View File
@@ -21,41 +21,101 @@
*/
#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
#include "nv50_context.h"
struct nv50_query {
struct pipe_buffer *buffer;
unsigned type;
boolean ready;
uint64_t result;
};
static INLINE struct nv50_query *
nv50_query(struct pipe_query *pipe)
{
return (struct nv50_query *)pipe;
}
static struct pipe_query *
nv50_query_create(struct pipe_context *pipe, unsigned type)
{
NOUVEAU_ERR("unimplemented\n");
return NULL;
struct pipe_winsys *ws = pipe->winsys;
struct nv50_query *q = CALLOC_STRUCT(nv50_query);
assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER);
q->type = type;
q->buffer = ws->buffer_create(ws, 256, 0, 16);
if (!q->buffer) {
FREE(q);
return NULL;
}
return (struct pipe_query *)q;
}
static void
nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *q)
nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
{
NOUVEAU_ERR("unimplemented\n");
struct nv50_query *q = nv50_query(pq);
if (q) {
pipe_buffer_reference(pipe, &q->buffer, NULL);
FREE(q);
}
}
static void
nv50_query_begin(struct pipe_context *pipe, struct pipe_query *q)
nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
{
NOUVEAU_ERR("unimplemented\n");
struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_query *q = nv50_query(pq);
BEGIN_RING(tesla, 0x1530, 1);
OUT_RING (1);
BEGIN_RING(tesla, 0x1514, 1);
OUT_RING (1);
q->ready = FALSE;
}
static void
nv50_query_end(struct pipe_context *pipe, struct pipe_query *q)
nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
NOUVEAU_ERR("unimplemented\n");
struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_query *q = nv50_query(pq);
BEGIN_RING(tesla, 0x1b00, 4);
OUT_RELOCh(q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
OUT_RELOCl(q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
OUT_RING (0x00000000);
OUT_RING (0x0100f002);
FIRE_RING (NULL);
}
static boolean
nv50_query_result(struct pipe_context *pipe, struct pipe_query *q,
nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
boolean wait, uint64_t *result)
{
NOUVEAU_ERR("unimplemented\n");
*result = 0xdeadcafe;
return TRUE;
struct pipe_winsys *ws = pipe->winsys;
struct nv50_query *q = nv50_query(pq);
/*XXX: Want to be able to return FALSE here instead of blocking
* until the result is available..
*/
if (!q->ready) {
uint32_t *map = ws->buffer_map(ws, q->buffer,
PIPE_BUFFER_USAGE_CPU_READ);
q->result = map[1];
q->ready = TRUE;
ws->buffer_unmap(ws, q->buffer);
}
*result = q->result;
return q->ready;
}
void
+9 -5
View File
@@ -57,6 +57,10 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_A8L8_UNORM:
case PIPE_FORMAT_DXT1_RGB:
case PIPE_FORMAT_DXT1_RGBA:
case PIPE_FORMAT_DXT3_RGBA:
case PIPE_FORMAT_DXT5_RGBA:
return TRUE;
default:
break;
@@ -90,23 +94,23 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return 32;
case PIPE_CAP_NPOT_TEXTURES:
return 0;
return 1;
case PIPE_CAP_TWO_SIDED_STENCIL:
return 1;
case PIPE_CAP_GLSL:
return 0;
case PIPE_CAP_S3TC:
return 0;
return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
return 1;
case PIPE_CAP_POINT_SPRITE:
return 0;
case PIPE_CAP_MAX_RENDER_TARGETS:
return 8;
case PIPE_CAP_OCCLUSION_QUERY:
return 0;
return 1;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 0;
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return 13;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+26
View File
@@ -175,6 +175,32 @@ nv50_sampler_state_create(struct pipe_context *pipe,
break;
}
if (cso->max_anisotropy >= 16.0)
tsc[0] |= (7 << 20);
else
if (cso->max_anisotropy >= 12.0)
tsc[0] |= (6 << 20);
else
if (cso->max_anisotropy >= 10.0)
tsc[0] |= (5 << 20);
else
if (cso->max_anisotropy >= 8.0)
tsc[0] |= (4 << 20);
else
if (cso->max_anisotropy >= 6.0)
tsc[0] |= (3 << 20);
else
if (cso->max_anisotropy >= 4.0)
tsc[0] |= (2 << 20);
else
if (cso->max_anisotropy >= 2.0)
tsc[0] |= (1 << 20);
if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
tsc[0] |= (1 << 8);
tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7);
}
return (void *)tsc;
}
+1 -32
View File
@@ -63,48 +63,17 @@ static void *
nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *ps,
unsigned flags )
{
struct nouveau_winsys *nvws = nv50_screen(screen)->nvws;
struct pipe_winsys *ws = screen->winsys;
struct nv50_surface *s = nv50_surface(ps);
struct nv50_surface m = *s;
void *map;
if (!s->untiled) {
s->untiled = ws->buffer_create(ws, 0, 0, ps->buffer->size);
m.base.buffer = s->untiled;
nvws->surface_copy(nvws, &m.base, 0, 0, &s->base, 0, 0,
ps->width, ps->height);
}
/* Map original tiled surface to disallow it being validated while
* untiled mirror is mapped.
*/
ws->buffer_map(ws, ps->buffer, flags);
map = ws->buffer_map(ws, s->untiled, flags);
if (!map)
return NULL;
return map;
return ws->buffer_map(ws, ps->buffer, flags);
}
static void
nv50_surface_unmap(struct pipe_screen *pscreen, struct pipe_surface *ps)
{
struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
struct pipe_winsys *ws = pscreen->winsys;
struct nv50_surface *s = nv50_surface(ps);
struct nv50_surface m = *s;
ws->buffer_unmap(ws, s->untiled);
ws->buffer_unmap(ws, ps->buffer);
m.base.buffer = s->untiled;
nvws->surface_copy(nvws, &s->base, 0, 0, &m.base, 0, 0,
ps->width, ps->height);
pipe_buffer_reference(pscreen, &s->untiled, NULL);
}
void
+40 -3
View File
@@ -85,6 +85,34 @@ nv50_tex_construct(struct nouveau_stateobj *so, struct nv50_miptree *mt)
NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_8_8);
break;
case PIPE_FORMAT_DXT1_RGB:
so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM |
NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_DXT1);
break;
case PIPE_FORMAT_DXT1_RGBA:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_DXT1);
break;
case PIPE_FORMAT_DXT3_RGBA:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_DXT3);
break;
case PIPE_FORMAT_DXT5_RGBA:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_DXT5);
break;
default:
return 1;
}
@@ -105,14 +133,23 @@ nv50_tex_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so;
int i;
int unit, level, image;
so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2);
so_method(so, tesla, 0x0f00, 1);
so_data (so, NV50_CB_TIC);
so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8);
for (i = 0; i < nv50->miptree_nr; i++) {
if (nv50_tex_construct(so, nv50->miptree[i])) {
for (unit = 0; unit < nv50->miptree_nr; unit++) {
struct nv50_miptree *mt = nv50->miptree[unit];
for (level = 0; level <= mt->base.last_level; level++) {
for (image = 0; image < mt->image_nr; image++) {
nv50_miptree_sync(&nv50->screen->pipe, mt,
level, image);
}
}
if (nv50_tex_construct(so, mt)) {
NOUVEAU_ERR("failed tex validate\n");
so_ref(NULL, &so);
return;
+3
View File
@@ -50,6 +50,9 @@
#define NV50TIC_0_0_FMT_5_6_5 0x00000015
#define NV50TIC_0_0_FMT_8_8 0x00000018
#define NV50TIC_0_0_FMT_8 0x0000001d
#define NV50TIC_0_0_FMT_DXT1 0x00000024
#define NV50TIC_0_0_FMT_DXT3 0x00000025
#define NV50TIC_0_0_FMT_DXT5 0x00000026
#define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff
#define NV50TIC_0_1_OFFSET_LOW_SHIFT 0
+4
View File
@@ -60,6 +60,10 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
OUT_RING (0);
BEGIN_RING(tesla, 0x142c, 1);
OUT_RING (0);
BEGIN_RING(tesla, 0x1440, 1);
OUT_RING (0);
BEGIN_RING(tesla, 0x1334, 1);
OUT_RING (0);
BEGIN_RING(tesla, NV50TCL_VERTEX_BEGIN, 1);
OUT_RING (nv50_prim(mode));
+1
View File
@@ -204,6 +204,7 @@ enum pipe_texture_target {
#define PIPE_BUFFER_USAGE_VERTEX (1 << 5)
#define PIPE_BUFFER_USAGE_INDEX (1 << 6)
#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7)
#define PIPE_BUFFER_USAGE_DISCARD (1 << 8)
/** Pipe driver custom usage flags should be greater or equal to this value */
#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16)
@@ -0,0 +1,33 @@
#ifndef _DRM_API_H_
#define _DRM_API_H_
struct pipe_screen;
struct pipe_winsys;
struct pipe_context;
struct drm_api
{
/**
* Special buffer function
*/
/*@{*/
struct pipe_screen* (*create_screen)(int drmFB, int pciID);
struct pipe_context* (*create_context)(struct pipe_screen *screen);
/*@}*/
/**
* Special buffer function
*/
/*@{*/
struct pipe_buffer* (*buffer_from_handle)(struct pipe_winsys *winsys, const char *name, unsigned handle);
unsigned (*handle_from_buffer)(struct pipe_winsys *winsys, struct pipe_buffer *buffer);
/*@}*/
};
/**
* A driver needs to export this symbol
*/
extern struct drm_api drm_api_hocks;
#endif
+29
View File
@@ -0,0 +1,29 @@
TARGET = libegldrm.a
CFILES = $(wildcard ./*.c)
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
GALLIUMDIR = ../..
TOP = ../../../..
include ${TOP}/configs/current
CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \
$(shell pkg-config --cflags pixman-1 xorg-server) \
-I${GALLIUMDIR}/include \
-I${GALLIUMDIR}/auxiliary \
-I${TOP}/src/mesa/drivers/dri/common \
-I${TOP}/src/mesa \
-I$(TOP)/include \
-I$(TOP)/src/egl/main \
${LIBDRM_CFLAGS}
#############################################
.PHONY = all clean
all: ${TARGET}
${TARGET}: ${OBJECTS}
ar rcs $@ $^
clean:
rm -rf ${OBJECTS} ${TARGET}
@@ -0,0 +1,194 @@
#include "utils.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "egl_tracker.h"
#include "egllog.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_winsys.h"
#include "state_tracker/st_public.h"
#include "state_tracker/drm_api.h"
#include "GL/internal/glcore.h"
#define need_GL_ARB_multisample
#define need_GL_ARB_point_parameters
#define need_GL_ARB_texture_compression
#define need_GL_ARB_vertex_buffer_object
#define need_GL_ARB_vertex_program
#define need_GL_ARB_window_pos
#define need_GL_EXT_blend_color
#define need_GL_EXT_blend_equation_separate
#define need_GL_EXT_blend_func_separate
#define need_GL_EXT_blend_minmax
#define need_GL_EXT_cull_vertex
#define need_GL_EXT_fog_coord
#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_NV_vertex_program
#include "extension_helper.h"
/**
* TODO HACK! FUGLY!
* Copied for intel extentions.
*/
const struct dri_extension card_extensions[] = {
{"GL_ARB_multisample", GL_ARB_multisample_functions},
{"GL_ARB_multitexture", NULL},
{"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
{"GL_ARB_texture_border_clamp", NULL},
{"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
{"GL_ARB_texture_cube_map", NULL},
{"GL_ARB_texture_env_add", NULL},
{"GL_ARB_texture_env_combine", NULL},
{"GL_ARB_texture_env_dot3", NULL},
{"GL_ARB_texture_mirrored_repeat", NULL},
{"GL_ARB_texture_rectangle", NULL},
{"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
{"GL_ARB_pixel_buffer_object", NULL},
{"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
{"GL_ARB_window_pos", GL_ARB_window_pos_functions},
{"GL_EXT_blend_color", GL_EXT_blend_color_functions},
{"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
{"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
{"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
{"GL_EXT_blend_subtract", NULL},
{"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
{"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
{"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
{"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
{"GL_EXT_packed_depth_stencil", NULL},
{"GL_EXT_pixel_buffer_object", NULL},
{"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
{"GL_EXT_stencil_wrap", NULL},
{"GL_EXT_texture_edge_clamp", NULL},
{"GL_EXT_texture_env_combine", NULL},
{"GL_EXT_texture_env_dot3", NULL},
{"GL_EXT_texture_filter_anisotropic", NULL},
{"GL_EXT_texture_lod_bias", NULL},
{"GL_3DFX_texture_compression_FXT1", NULL},
{"GL_APPLE_client_storage", NULL},
{"GL_MESA_pack_invert", NULL},
{"GL_MESA_ycbcr_texture", NULL},
{"GL_NV_blend_square", NULL},
{"GL_NV_vertex_program", GL_NV_vertex_program_functions},
{"GL_NV_vertex_program1_1", NULL},
{"GL_SGIS_generate_mipmap", NULL },
{NULL, NULL}
};
EGLContext
drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
{
struct drm_device *dev = (struct drm_device *)drv;
struct drm_context *ctx;
struct drm_context *share = NULL;
struct st_context *st_share = NULL;
_EGLConfig *conf;
int i;
__GLcontextModes *visual;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return EGL_NO_CONTEXT;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs defined for now */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
return EGL_NO_CONTEXT;
}
}
ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context));
if (!ctx)
goto err_c;
_eglInitContext(drv, dpy, &ctx->base, config, attrib_list);
ctx->pipe = drm_api_hocks.create_context(dev->screen);
if (!ctx->pipe)
goto err_pipe;
if (share)
st_share = share->st;
visual = drm_visual_from_config(conf);
ctx->st = st_create_context(ctx->pipe, visual, st_share);
drm_visual_modes_destroy(visual);
if (!ctx->st)
goto err_gl;
/* generate handle and insert into hash table */
_eglSaveContext(&ctx->base);
assert(_eglGetContextHandle(&ctx->base));
return _eglGetContextHandle(&ctx->base);
err_gl:
ctx->pipe->destroy(ctx->pipe);
err_pipe:
free(ctx);
err_c:
return EGL_NO_CONTEXT;
}
EGLBoolean
drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
struct drm_context *c = lookup_drm_context(context);
_eglRemoveContext(&c->base);
if (c->base.IsBound) {
c->base.DeletePending = EGL_TRUE;
} else {
st_destroy_context(c->st);
c->pipe->destroy(c->pipe);
free(c);
}
return EGL_TRUE;
}
EGLBoolean
drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
{
struct drm_surface *readSurf = lookup_drm_surface(read);
struct drm_surface *drawSurf = lookup_drm_surface(draw);
struct drm_context *ctx = lookup_drm_context(context);
EGLBoolean b;
b = _eglMakeCurrent(drv, dpy, draw, read, context);
if (!b)
return EGL_FALSE;
if (ctx) {
if (!drawSurf || !readSurf)
return EGL_FALSE;
drawSurf->user = ctx;
readSurf->user = ctx;
st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb);
/* st_resize_framebuffer needs a bound context to work */
st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h);
st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h);
} else {
drawSurf->user = NULL;
readSurf->user = NULL;
st_make_current(NULL, NULL, NULL);
}
return EGL_TRUE;
}
@@ -0,0 +1,418 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "egl_tracker.h"
#include "egllog.h"
#include "pipe/p_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "state_tracker/drm_api.h"
/*
* Util functions
*/
static struct drm_mode_modeinfo *
drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode)
{
int i;
struct drm_mode_modeinfo *m = NULL;
for (i = 0; i < connector->count_modes; i++) {
m = &connector->modes[i];
if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
break;
m = &connector->modes[0]; /* if we can't find one, return first */
}
return m;
}
static struct st_framebuffer *
drm_create_framebuffer(const __GLcontextModes *visual,
unsigned width,
unsigned height,
void *priv)
{
enum pipe_format colorFormat, depthFormat, stencilFormat;
if (visual->redBits == 5)
colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
else
colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
if (visual->depthBits == 16)
depthFormat = PIPE_FORMAT_Z16_UNORM;
else if (visual->depthBits == 24)
depthFormat = PIPE_FORMAT_S8Z24_UNORM;
else
depthFormat = PIPE_FORMAT_NONE;
if (visual->stencilBits == 8)
stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
else
stencilFormat = PIPE_FORMAT_NONE;
return st_create_framebuffer(visual,
colorFormat,
depthFormat,
stencilFormat,
width,
height,
priv);
}
static void
drm_create_texture(_EGLDriver *drv,
struct drm_screen *scrn,
unsigned w, unsigned h)
{
struct drm_device *dev = (struct drm_device *)drv;
struct pipe_screen *screen = dev->screen;
struct pipe_surface *surface;
struct pipe_texture *texture;
struct pipe_texture templat;
struct pipe_buffer *buf;
unsigned stride = 1024;
unsigned pitch = 0;
unsigned size = 0;
void *ptr;
/* ugly */
if (stride < w)
stride = 2048;
pitch = stride * 4;
size = h * 2 * pitch;
buf = pipe_buffer_create(screen,
0, /* alignment */
PIPE_BUFFER_USAGE_GPU_READ_WRITE |
PIPE_BUFFER_USAGE_CPU_READ_WRITE,
size);
if (!buf)
goto err_buf;
#if DEBUG
ptr = pipe_buffer_map(screen, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
memset(ptr, 0xFF, size);
pipe_buffer_unmap(screen, buf);
#else
(void)ptr;
#endif
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth[0] = 1;
templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
templat.width[0] = w;
templat.height[0] = h;
pf_get_block(templat.format, &templat.block);
texture = screen->texture_blanket(dev->screen,
&templat,
&pitch,
buf);
if (!texture)
goto err_tex;
surface = screen->get_tex_surface(screen,
texture,
0,
0,
0,
PIPE_BUFFER_USAGE_GPU_WRITE);
if (!surface)
goto err_surf;
scrn->tex = texture;
scrn->surface = surface;
scrn->buffer = buf;
scrn->front.width = w;
scrn->front.height = h;
scrn->front.pitch = pitch;
scrn->front.handle = drm_api_hocks.handle_from_buffer(dev->winsys, scrn->buffer);
if (0)
goto err_handle;
return;
err_handle:
pipe_surface_reference(&surface, NULL);
err_surf:
pipe_texture_reference(&texture, NULL);
err_tex:
pipe_buffer_reference(screen, &buf, NULL);
err_buf:
return;
}
/*
* Exported functions
*/
void
drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
{
struct drm_device *dev = (struct drm_device *)drv;
screen->surf = NULL;
drmModeSetCrtc(
dev->drmFD,
screen->crtcID,
0, // FD
0, 0,
NULL, 0, // List of output ids
NULL);
drmModeRmFB(dev->drmFD, screen->fbID);
drmModeFreeFB(screen->fb);
screen->fb = NULL;
pipe_surface_reference(&screen->surface, NULL);
pipe_texture_reference(&screen->tex, NULL);
pipe_buffer_reference(dev->screen, &screen->buffer, NULL);
screen->shown = 0;
}
EGLSurface
drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
{
return EGL_NO_SURFACE;
}
EGLSurface
drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
{
return EGL_NO_SURFACE;
}
EGLSurface
drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
int i;
int width = -1;
int height = -1;
struct drm_surface *surf = NULL;
__GLcontextModes *visual;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
return EGL_NO_CONTEXT;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_WIDTH:
width = attrib_list[++i];
break;
case EGL_HEIGHT:
height = attrib_list[++i];
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
return EGL_NO_SURFACE;
}
}
if (width < 1 || height < 1) {
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
return EGL_NO_SURFACE;
}
surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
if (!surf)
goto err;
if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list))
goto err_surf;
surf->w = width;
surf->h = height;
visual = drm_visual_from_config(conf);
surf->stfb = drm_create_framebuffer(visual,
width,
height,
(void*)surf);
drm_visual_modes_destroy(visual);
_eglSaveSurface(&surf->base);
return surf->base.Handle;
err_surf:
free(surf);
err:
return EGL_NO_SURFACE;
}
EGLSurface
drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
const EGLint *attrib_list)
{
EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
return surf;
}
EGLBoolean
drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
EGLScreenMESA screen,
EGLSurface surface, EGLModeMESA m)
{
struct drm_device *dev = (struct drm_device *)drv;
struct drm_surface *surf = lookup_drm_surface(surface);
struct drm_screen *scrn = lookup_drm_screen(dpy, screen);
_EGLMode *mode = _eglLookupMode(dpy, m);
int ret;
unsigned int i, k;
if (scrn->shown)
drm_takedown_shown_screen(drv, scrn);
drm_create_texture(drv, scrn, mode->Width, mode->Height);
if (!scrn->buffer)
return EGL_FALSE;
ret = drmModeAddFB(dev->drmFD,
scrn->front.width, scrn->front.height,
32, 32, scrn->front.pitch,
scrn->front.handle,
&scrn->fbID);
if (ret)
goto err_bo;
scrn->fb = drmModeGetFB(dev->drmFD, scrn->fbID);
if (!scrn->fb)
goto err_bo;
/* find a fitting crtc */
{
drmModeConnector *con = scrn->connector;
scrn->mode = drm_find_mode(con, mode);
if (!scrn->mode)
goto err_fb;
for (k = 0; k < con->count_encoders; k++) {
drmModeEncoder *enc = drmModeGetEncoder(dev->drmFD, con->encoders[k]);
for (i = 0; i < dev->res->count_crtcs; i++) {
if (enc->possible_crtcs & (1<<i)) {
/* save the ID */
scrn->crtcID = dev->res->crtcs[i];
/* skip the rest */
i = dev->res->count_crtcs;
k = dev->res->count_encoders;
}
}
drmModeFreeEncoder(enc);
}
}
ret = drmModeSetCrtc(dev->drmFD,
scrn->crtcID,
scrn->fbID,
0, 0,
&scrn->connectorID, 1,
scrn->mode);
if (ret)
goto err_crtc;
surf->screen = scrn;
scrn->surf = surf;
scrn->shown = 1;
return EGL_TRUE;
err_crtc:
scrn->crtcID = 0;
err_fb:
drmModeRmFB(dev->drmFD, scrn->fbID);
drmModeFreeFB(scrn->fb);
scrn->fb = NULL;
err_bo:
pipe_surface_reference(&scrn->surface, NULL);
pipe_texture_reference(&scrn->tex, NULL);
pipe_buffer_reference(dev->screen, &scrn->buffer, NULL);
return EGL_FALSE;
}
EGLBoolean
drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
struct drm_surface *surf = lookup_drm_surface(surface);
_eglRemoveSurface(&surf->base);
if (surf->base.IsBound) {
surf->base.DeletePending = EGL_TRUE;
} else {
if (surf->screen)
drm_takedown_shown_screen(drv, surf->screen);
st_unreference_framebuffer(surf->stfb);
free(surf);
}
return EGL_TRUE;
}
EGLBoolean
drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
struct drm_surface *surf = lookup_drm_surface(draw);
struct pipe_surface *back_surf;
if (!surf)
return EGL_FALSE;
/* error checking */
if (!_eglSwapBuffers(drv, dpy, draw))
return EGL_FALSE;
back_surf = st_get_framebuffer_surface(surf->stfb,
ST_SURFACE_BACK_LEFT);
if (back_surf) {
st_notify_swapbuffers(surf->stfb);
if (surf->screen) {
surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
surf->user->pipe->surface_copy(surf->user->pipe,
0,
surf->screen->surface,
0, 0,
back_surf,
0, 0,
surf->w, surf->h);
surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
/* TODO stuff here */
}
st_notify_swapbuffers_complete(surf->stfb);
}
return EGL_TRUE;
}
@@ -0,0 +1,217 @@
#include "utils.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "egl_tracker.h"
#include "egllog.h"
#include "state_tracker/drm_api.h"
#include "pipe/p_screen.h"
#include "pipe/p_winsys.h"
/** HACK */
void* driDriverAPI;
extern const struct dri_extension card_extensions[];
/*
* Exported functions
*/
/**
* The bootstrap function. Return a new drm_driver object and
* plug in API functions.
*/
_EGLDriver *
_eglMain(_EGLDisplay *dpy, const char *args)
{
struct drm_device *drm;
drm = (struct drm_device *) calloc(1, sizeof(struct drm_device));
if (!drm) {
return NULL;
}
/* First fill in the dispatch table with defaults */
_eglInitDriverFallbacks(&drm->base);
/* then plug in our Drm-specific functions */
drm->base.API.Initialize = drm_initialize;
drm->base.API.Terminate = drm_terminate;
drm->base.API.CreateContext = drm_create_context;
drm->base.API.MakeCurrent = drm_make_current;
drm->base.API.CreateWindowSurface = drm_create_window_surface;
drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface;
drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface;
drm->base.API.DestroySurface = drm_destroy_surface;
drm->base.API.DestroyContext = drm_destroy_context;
drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
drm->base.API.SwapBuffers = drm_swap_buffers;
drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
drm->base.Name = "DRM/Gallium/Win";
/* enable supported extensions */
drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
drm->base.Extensions.MESA_copy_context = EGL_TRUE;
return &drm->base;
}
static void
drm_get_device_id(struct drm_device *device)
{
char path[512];
FILE *file;
/* TODO get the real minor */
int minor = 0;
snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
file = fopen(path, "r");
if (!file) {
_eglLog(_EGL_WARNING, "Could not retrive device ID\n");
return;
}
fgets(path, sizeof( path ), file);
sscanf(path, "%x", &device->deviceID);
fclose(file);
}
static void
drm_update_res(struct drm_device *dev)
{
drmModeFreeResources(dev->res);
dev->res = drmModeGetResources(dev->drmFD);
}
static void
drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
{
struct drm_mode_modeinfo *m;
int i;
for (i = 0; i < connector->count_modes; i++) {
m = &connector->modes[i];
_eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
}
}
EGLBoolean
drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct drm_device *dev = (struct drm_device *)drv;
struct drm_screen *screen = NULL;
drmModeConnectorPtr connector = NULL;
drmModeResPtr res = NULL;
unsigned count_connectors = 0;
int num_screens = 0;
EGLint i;
int fd;
fd = drmOpen("i915", NULL);
if (fd < 0)
goto err_fd;
dev->drmFD = fd;
drm_get_device_id(dev);
dev->screen = drm_api_hocks.create_screen(dev->drmFD, dev->deviceID);
if (!dev->screen)
goto err_screen;
dev->winsys = dev->screen->winsys;
/* TODO HACK */
driInitExtensions(NULL, card_extensions, GL_FALSE);
drm_update_res(dev);
res = dev->res;
if (res)
count_connectors = res->count_connectors;
else
_eglLog(_EGL_WARNING, "Could not retrive kms information\n");
for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
connector = drmModeGetConnector(fd, res->connectors[i]);
if (!connector)
continue;
if (connector->connection != DRM_MODE_CONNECTED) {
drmModeFreeConnector(connector);
continue;
}
screen = malloc(sizeof(struct drm_screen));
memset(screen, 0, sizeof(*screen));
screen->connector = connector;
screen->connectorID = connector->connector_id;
_eglInitScreen(&screen->base);
_eglAddScreen(disp, &screen->base);
drm_add_modes_from_connector(&screen->base, connector);
dev->screens[num_screens++] = screen;
}
dev->count_screens = num_screens;
/* for now we only have one config */
_EGLConfig *config = calloc(1, sizeof(*config));
memset(config, 1, sizeof(*config));
_eglInitConfig(config, 1);
_eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
_eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
_eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
_eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
_eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
_eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
_eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
_eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
_eglAddConfig(disp, config);
drv->Initialized = EGL_TRUE;
*major = 1;
*minor = 4;
return EGL_TRUE;
err_screen:
drmClose(fd);
err_fd:
return EGL_FALSE;
}
EGLBoolean
drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
{
struct drm_device *dev = (struct drm_device *)drv;
struct drm_screen *screen;
int i = 0;
drmFreeVersion(dev->version);
for (i = 0; i < dev->count_screens; i++) {
screen = dev->screens[i];
if (screen->shown)
drm_takedown_shown_screen(drv, screen);
drmModeFreeConnector(screen->connector);
_eglDestroyScreen(&screen->base);
dev->screens[i] = NULL;
}
dev->screen->destroy(dev->screen);
dev->winsys = NULL;
drmClose(dev->drmFD);
_eglCleanupDisplay(_eglLookupDisplay(dpy));
free(dev);
return EGL_TRUE;
}
@@ -0,0 +1,191 @@
#ifndef _EGL_TRACKER_H_
#define _EGL_TRACKER_H_
#include <stdint.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglmode.h"
#include "eglscreen.h"
#include "eglsurface.h"
#include "xf86drm.h"
#include "xf86drmMode.h"
#include "pipe/p_compiler.h"
#include "state_tracker/st_public.h"
#define MAX_SCREENS 16
struct pipe_winsys;
struct pipe_screen;
struct pipe_context;
struct state_tracker;
struct drm_screen;
struct drm_context;
struct drm_device
{
_EGLDriver base; /* base class/object */
/*
* pipe
*/
struct pipe_winsys *winsys;
struct pipe_screen *screen;
/*
* drm
*/
int drmFD;
drmVersionPtr version;
int deviceID;
drmModeResPtr res;
struct drm_screen *screens[MAX_SCREENS];
size_t count_screens;
};
struct drm_surface
{
_EGLSurface base; /* base class/object */
/*
* pipe
*/
struct st_framebuffer *stfb;
/*
* drm
*/
struct drm_context *user;
struct drm_screen *screen;
int w;
int h;
};
struct drm_context
{
_EGLContext base; /* base class/object */
/* pipe */
struct pipe_context *pipe;
struct st_context *st;
};
struct drm_screen
{
_EGLScreen base;
/*
* pipe
*/
struct pipe_buffer *buffer;
struct pipe_texture *tex;
struct pipe_surface *surface;
/*
* drm
*/
struct {
unsigned height;
unsigned width;
unsigned pitch;
unsigned handle;
} front;
/* currently only support one connector */
drmModeConnectorPtr connector;
uint32_t connectorID;
/* Has this screen been shown */
int shown;
/* Surface that is currently attached to this screen */
struct drm_surface *surf;
/* framebuffer */
drmModeFBPtr fb;
uint32_t fbID;
/* crtc and mode used */
/*drmModeCrtcPtr crtc;*/
uint32_t crtcID;
struct drm_mode_modeinfo *mode;
};
static INLINE struct drm_context *
lookup_drm_context(EGLContext context)
{
_EGLContext *c = _eglLookupContext(context);
return (struct drm_context *) c;
}
static INLINE struct drm_surface *
lookup_drm_surface(EGLSurface surface)
{
_EGLSurface *s = _eglLookupSurface(surface);
return (struct drm_surface *) s;
}
static INLINE struct drm_screen *
lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen)
{
_EGLScreen *s = _eglLookupScreen(dpy, screen);
return (struct drm_screen *) s;
}
/**
* egl_visual.h
*/
/*@{*/
void drm_visual_modes_destroy(__GLcontextModes *modes);
__GLcontextModes* drm_visual_modes_create(unsigned count, size_t minimum_size);
__GLcontextModes* drm_visual_from_config(_EGLConfig *conf);
/*@}*/
/**
* egl_surface.h
*/
/*@{*/
void drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen);
/*@}*/
/**
* All function exported to the egl side.
*/
/*@{*/
EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor);
EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy);
EGLContext drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
EGLBoolean drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context);
EGLSurface drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
EGLSurface drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
EGLSurface drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, const EGLint *attrib_list);
EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA m);
EGLBoolean drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context);
EGLBoolean drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
/*@}*/
#endif
@@ -0,0 +1,85 @@
#include "egl_tracker.h"
#include "egllog.h"
void
drm_visual_modes_destroy(__GLcontextModes *modes)
{
_eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
while (modes) {
__GLcontextModes * const next = modes->next;
free(modes);
modes = next;
}
}
__GLcontextModes *
drm_visual_modes_create(unsigned count, size_t minimum_size)
{
/* This code copied from libGLX, and modified */
const size_t size = (minimum_size > sizeof(__GLcontextModes))
? minimum_size : sizeof(__GLcontextModes);
__GLcontextModes * head = NULL;
__GLcontextModes ** next;
unsigned i;
_eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size);
next = & head;
for (i = 0 ; i < count ; i++) {
*next = (__GLcontextModes *) calloc(1, size);
if (*next == NULL) {
drm_visual_modes_destroy(head);
head = NULL;
break;
}
(*next)->doubleBufferMode = 1;
(*next)->visualID = GLX_DONT_CARE;
(*next)->visualType = GLX_DONT_CARE;
(*next)->visualRating = GLX_NONE;
(*next)->transparentPixel = GLX_NONE;
(*next)->transparentRed = GLX_DONT_CARE;
(*next)->transparentGreen = GLX_DONT_CARE;
(*next)->transparentBlue = GLX_DONT_CARE;
(*next)->transparentAlpha = GLX_DONT_CARE;
(*next)->transparentIndex = GLX_DONT_CARE;
(*next)->xRenderable = GLX_DONT_CARE;
(*next)->fbconfigID = GLX_DONT_CARE;
(*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
(*next)->bindToTextureRgb = GLX_DONT_CARE;
(*next)->bindToTextureRgba = GLX_DONT_CARE;
(*next)->bindToMipmapTexture = GLX_DONT_CARE;
(*next)->bindToTextureTargets = 0;
(*next)->yInverted = GLX_DONT_CARE;
next = & ((*next)->next);
}
return head;
}
__GLcontextModes *
drm_visual_from_config(_EGLConfig *conf)
{
__GLcontextModes *visual;
(void)conf;
visual = drm_visual_modes_create(1, sizeof(*visual));
visual->redBits = 8;
visual->greenBits = 8;
visual->blueBits = 8;
visual->alphaBits = 8;
visual->rgbBits = 32;
visual->doubleBufferMode = 1;
visual->depthBits = 24;
visual->haveDepthBuffer = visual->depthBits > 0;
visual->stencilBits = 8;
visual->haveStencilBuffer = visual->stencilBits > 0;
return visual;
}
+30 -24
View File
@@ -71,7 +71,10 @@ static int vlResizeFrameBuffer
basic_csc->viewport.translate[3] = 0;
if (basic_csc->framebuffer_tex)
pipe_texture_release(&basic_csc->framebuffer_tex);
{
pipe_surface_reference(&basic_csc->framebuffer.cbufs[0], NULL);
pipe_texture_reference(&basic_csc->framebuffer_tex, NULL);
}
memset(&template, 0, sizeof(struct pipe_texture));
template.target = PIPE_TEXTURE_2D;
@@ -153,11 +156,11 @@ static int vlPutPictureCSC
basic_csc = (struct vlBasicCSC*)csc;
pipe = basic_csc->pipe;
vs_consts = pipe->winsys->buffer_map
vs_consts = pipe_buffer_map
(
pipe->winsys,
pipe->screen,
basic_csc->vs_const_buf.buffer,
PIPE_BUFFER_USAGE_CPU_WRITE
PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
vs_consts->dst_scale.x = destw / (float)basic_csc->framebuffer.cbufs[0]->width;
@@ -178,7 +181,7 @@ static int vlPutPictureCSC
vs_consts->src_trans.z = 0;
vs_consts->src_trans.w = 0;
pipe->winsys->buffer_unmap(pipe->winsys, basic_csc->vs_const_buf.buffer);
pipe_buffer_unmap(pipe->screen, basic_csc->vs_const_buf.buffer);
pipe->set_sampler_textures(pipe, 1, &surface->texture);
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
@@ -225,17 +228,20 @@ static int vlDestroy
pipe = basic_csc->pipe;
if (basic_csc->framebuffer_tex)
pipe_texture_release(&basic_csc->framebuffer_tex);
{
pipe_surface_reference(&basic_csc->framebuffer.cbufs[0], NULL);
pipe_texture_reference(&basic_csc->framebuffer_tex, NULL);
}
pipe->delete_sampler_state(pipe, basic_csc->sampler);
pipe->delete_vs_state(pipe, basic_csc->vertex_shader);
pipe->delete_fs_state(pipe, basic_csc->fragment_shader);
for (i = 0; i < 2; ++i)
pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vertex_bufs[i].buffer);
pipe_buffer_reference(pipe->screen, &basic_csc->vertex_bufs[i].buffer, NULL);
pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vs_const_buf.buffer);
pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->fs_const_buf.buffer);
pipe_buffer_reference(pipe->screen, &basic_csc->vs_const_buf.buffer, NULL);
pipe_buffer_reference(pipe->screen, &basic_csc->fs_const_buf.buffer, NULL);
FREE(basic_csc);
@@ -542,9 +548,9 @@ static int vlCreateDataBufs
csc->vertex_bufs[0].pitch = sizeof(struct vlVertex2f);
csc->vertex_bufs[0].max_index = 3;
csc->vertex_bufs[0].buffer_offset = 0;
csc->vertex_bufs[0].buffer = pipe->winsys->buffer_create
csc->vertex_bufs[0].buffer = pipe_buffer_create
(
pipe->winsys,
pipe->screen,
1,
PIPE_BUFFER_USAGE_VERTEX,
sizeof(struct vlVertex2f) * 4
@@ -552,12 +558,12 @@ static int vlCreateDataBufs
memcpy
(
pipe->winsys->buffer_map(pipe->winsys, csc->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
pipe_buffer_map(pipe->screen, csc->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
surface_verts,
sizeof(struct vlVertex2f) * 4
);
pipe->winsys->buffer_unmap(pipe->winsys, csc->vertex_bufs[0].buffer);
pipe_buffer_unmap(pipe->screen, csc->vertex_bufs[0].buffer);
csc->vertex_elems[0].src_offset = 0;
csc->vertex_elems[0].vertex_buffer_index = 0;
@@ -571,9 +577,9 @@ static int vlCreateDataBufs
csc->vertex_bufs[1].pitch = sizeof(struct vlVertex2f);
csc->vertex_bufs[1].max_index = 3;
csc->vertex_bufs[1].buffer_offset = 0;
csc->vertex_bufs[1].buffer = pipe->winsys->buffer_create
csc->vertex_bufs[1].buffer = pipe_buffer_create
(
pipe->winsys,
pipe->screen,
1,
PIPE_BUFFER_USAGE_VERTEX,
sizeof(struct vlVertex2f) * 4
@@ -581,12 +587,12 @@ static int vlCreateDataBufs
memcpy
(
pipe->winsys->buffer_map(pipe->winsys, csc->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
pipe_buffer_map(pipe->screen, csc->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
surface_texcoords,
sizeof(struct vlVertex2f) * 4
);
pipe->winsys->buffer_unmap(pipe->winsys, csc->vertex_bufs[1].buffer);
pipe_buffer_unmap(pipe->screen, csc->vertex_bufs[1].buffer);
csc->vertex_elems[1].src_offset = 0;
csc->vertex_elems[1].vertex_buffer_index = 1;
@@ -598,11 +604,11 @@ static int vlCreateDataBufs
* Const buffer contains scaling and translation vectors
*/
csc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts);
csc->vs_const_buf.buffer = pipe->winsys->buffer_create
csc->vs_const_buf.buffer = pipe_buffer_create
(
pipe->winsys,
pipe->screen,
1,
PIPE_BUFFER_USAGE_CONSTANT,
PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD,
csc->vs_const_buf.size
);
@@ -611,9 +617,9 @@ static int vlCreateDataBufs
* Const buffer contains the color conversion matrix and bias vectors
*/
csc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts);
csc->fs_const_buf.buffer = pipe->winsys->buffer_create
csc->fs_const_buf.buffer = pipe_buffer_create
(
pipe->winsys,
pipe->screen,
1,
PIPE_BUFFER_USAGE_CONSTANT,
csc->fs_const_buf.size
@@ -625,12 +631,12 @@ static int vlCreateDataBufs
*/
memcpy
(
pipe->winsys->buffer_map(pipe->winsys, csc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
pipe_buffer_map(pipe->screen, csc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
&bt_601_full,
sizeof(struct vlFragmentShaderConsts)
);
pipe->winsys->buffer_unmap(pipe->winsys, csc->fs_const_buf.buffer);
pipe_buffer_unmap(pipe->screen, csc->fs_const_buf.buffer);
return 0;
}
@@ -297,6 +297,7 @@ static inline int vlGrabMacroBlock
{
assert(mc);
assert(macroblock);
assert(mc->num_macroblocks < mc->macroblocks_per_picture);
mc->macroblocks[mc->num_macroblocks].mbx = macroblock->mbx;
mc->macroblocks[mc->num_macroblocks].mby = macroblock->mby;
@@ -330,6 +331,7 @@ static inline int vlGrabMacroBlock
}
#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb) \
do { \
(vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \
(vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \
(vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \
@@ -392,7 +394,8 @@ static inline int vlGrabMacroBlock
(vb)[3].cr_tc.x = (zb)[2].x + (hx); (vb)[3].cr_tc.y = (zb)[2].y; \
(vb)[4].cr_tc.x = (zb)[2].x; (vb)[4].cr_tc.y = (zb)[2].y + (hy); \
(vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \
}
} \
} while (0)
static inline int vlGenMacroblockVerts
(
@@ -409,6 +412,7 @@ static inline int vlGenMacroblockVerts
assert(mc);
assert(macroblock);
assert(ycbcr_vb);
assert(pos < mc->macroblocks_per_picture);
switch (macroblock->mb_type)
{
@@ -581,6 +585,8 @@ static int vlFlush
if (mc->num_macroblocks < mc->macroblocks_per_picture)
return 0;
assert(mc->num_macroblocks <= mc->macroblocks_per_picture);
pipe = mc->pipe;
for (i = 0; i < mc->num_macroblocks; ++i)
@@ -599,19 +605,19 @@ static int vlFlush
struct vlMacroBlockVertexStream0 *ycbcr_vb;
struct vlVertex2f *ref_vb[2];
ycbcr_vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
ycbcr_vb = (struct vlMacroBlockVertexStream0*)pipe_buffer_map
(
mc->pipe->winsys,
pipe->screen,
mc->vertex_bufs.ycbcr.buffer,
PIPE_BUFFER_USAGE_CPU_WRITE
PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
for (i = 0; i < 2; ++i)
ref_vb[i] = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
ref_vb[i] = (struct vlVertex2f*)pipe_buffer_map
(
mc->pipe->winsys,
pipe->screen,
mc->vertex_bufs.ref[i].buffer,
PIPE_BUFFER_USAGE_CPU_WRITE
PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
for (i = 0; i < mc->num_macroblocks; ++i)
@@ -623,15 +629,15 @@ static int vlFlush
offset[mb_type_ex]++;
}
mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ycbcr.buffer);
pipe_buffer_unmap(pipe->screen, 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);
pipe_buffer_unmap(pipe->screen, mc->vertex_bufs.ref[i].buffer);
}
for (i = 0; i < 3; ++i)
{
pipe_surface_unmap(mc->tex_surface[i]);
mc->pipe->screen->tex_surface_release(mc->pipe->screen, &mc->tex_surface[i]);
pipe_surface_reference(&mc->tex_surface[i], NULL);
}
mc->render_target.cbufs[0] = pipe->screen->get_tex_surface
@@ -647,13 +653,13 @@ static int vlFlush
(
pipe->winsys,
mc->vs_const_buf.buffer,
PIPE_BUFFER_USAGE_CPU_WRITE
PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
vs_consts->denorm.x = mc->buffered_surface->texture->width[0];
vs_consts->denorm.y = mc->buffered_surface->texture->height[0];
pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer);
pipe_buffer_unmap(pipe->screen, mc->vs_const_buf.buffer);
pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &mc->vs_const_buf);
pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &mc->fs_const_buf);
@@ -757,7 +763,7 @@ 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]);
pipe_surface_reference(&mc->render_target.cbufs[0], NULL);
for (i = 0; i < 3; ++i)
mc->zero_block[i].x = -1.0f;
@@ -808,10 +814,10 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
(
mc->pipe->screen,
mc->textures.all[i],
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE);
mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD);
}
}
@@ -849,11 +855,11 @@ static int vlDestroy
pipe->delete_sampler_state(pipe, mc->samplers.all[i]);
for (i = 0; i < 3; ++i)
pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs.all[i].buffer);
pipe_buffer_reference(pipe->screen, &mc->vertex_bufs.all[i].buffer, NULL);
/* Textures 3 & 4 are not created directly, no need to release them here */
for (i = 0; i < 3; ++i)
pipe_texture_release(&mc->textures.all[i]);
pipe_texture_reference(&mc->textures.all[i], NULL);
pipe->delete_vs_state(pipe, mc->i_vs);
pipe->delete_fs_state(pipe, mc->i_fs);
@@ -866,8 +872,8 @@ static int vlDestroy
pipe->delete_fs_state(pipe, mc->b_fs[i]);
}
pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer);
pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer);
pipe_buffer_reference(pipe->screen, &mc->vs_const_buf.buffer, NULL);
pipe_buffer_reference(pipe->screen, &mc->fs_const_buf.buffer, NULL);
FREE(mc->macroblocks);
FREE(mc);
@@ -909,11 +915,11 @@ static int vlCreateDataBufs
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
mc->vertex_bufs.ycbcr.buffer = pipe_buffer_create
(
pipe->winsys,
pipe->screen,
DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_VERTEX,
PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
sizeof(struct vlVertex2f) * 4 * 24 * mc->macroblocks_per_picture
);
@@ -922,11 +928,11 @@ static int vlCreateDataBufs
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
mc->vertex_bufs.all[i].buffer = pipe_buffer_create
(
pipe->winsys,
pipe->screen,
DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_VERTEX,
PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
sizeof(struct vlVertex2f) * 2 * 24 * mc->macroblocks_per_picture
);
}
@@ -981,18 +987,18 @@ static int vlCreateDataBufs
/* Create our constant buffer */
mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts);
mc->vs_const_buf.buffer = pipe->winsys->buffer_create
mc->vs_const_buf.buffer = pipe_buffer_create
(
pipe->winsys,
pipe->screen,
DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_CONSTANT,
PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD,
mc->vs_const_buf.size
);
mc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts);
mc->fs_const_buf.buffer = pipe->winsys->buffer_create
mc->fs_const_buf.buffer = pipe_buffer_create
(
pipe->winsys,
pipe->screen,
DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_CONSTANT,
mc->fs_const_buf.size
@@ -1000,12 +1006,12 @@ static int vlCreateDataBufs
memcpy
(
pipe->winsys->buffer_map(pipe->winsys, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
pipe_buffer_map(pipe->screen, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
&fs_consts,
sizeof(struct vlFragmentShaderConsts)
);
pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer);
pipe_buffer_unmap(pipe->screen, mc->fs_const_buf.buffer);
mc->macroblocks = MALLOC(sizeof(struct vlMpeg2MacroBlock) * mc->macroblocks_per_picture);
@@ -51,6 +51,12 @@ int vlCreateSurface
sfc->texture = vlGetPipeScreen(screen)->texture_create(vlGetPipeScreen(screen), &template);
if (!sfc->texture)
{
FREE(sfc);
return 1;
}
*surface = sfc;
return 0;
@@ -63,7 +69,7 @@ int vlDestroySurface
{
assert(surface);
pipe_texture_release(&surface->texture);
pipe_texture_reference(&surface->texture, NULL);
FREE(surface);
return 0;
+2 -2
View File
@@ -84,14 +84,14 @@ default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
$(TOP)/bin/mklib -noprefix -o $@ \
$(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS)
$(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS)
$(TOP)/bin/mklib -o $(LIBNAME_EGL) \
-linker "$(CC)" \
-noprefix \
$(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \
--whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive
--whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(DRIVER_EXTRAS)
$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME)
$(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR)
+1 -1
View File
@@ -2,7 +2,7 @@ TOP = ../../../../..
include $(TOP)/configs/current
SUBDIRS = common dri egl
SUBDIRS = gem egl
default: subdirs
+6 -4
View File
@@ -6,21 +6,23 @@ LIBNAME = EGL_i915.so
PIPE_DRIVERS = \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \
../common/libinteldrm.a
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
../gem/libinteldrm.a
DRIVER_SOURCES = \
intel_swapbuffers.c \
intel_context.c \
intel_device.c \
intel_egl.c
intel_api.c
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
DRIVER_EXTRAS = -ldrm_intel
ASM_SOURCES =
DRIVER_DEFINES = -I../common $(shell pkg-config libdrm --atleast-version=2.3.1 \
DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \
&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
include ../../Makefile.template
@@ -1,39 +0,0 @@
Import('*')
env = drienv.Clone()
env.Append(CPPPATH = [
'../intel',
'server'
])
#MINIGLX_SOURCES = server/intel_dri.c
DRIVER_SOURCES = [
'intel_winsys_pipe.c',
'intel_winsys_softpipe.c',
'intel_winsys_i915.c',
'intel_batchbuffer.c',
'intel_swapbuffers.c',
'intel_context.c',
'intel_lock.c',
'intel_screen.c',
'intel_batchpool.c',
]
sources = \
COMMON_GALLIUM_SOURCES + \
COMMON_BM_SOURCES + \
DRIVER_SOURCES
drivers = [
softpipe,
i915simple
]
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
env.SharedLibrary(
target ='i915tex_dri.so',
source = sources,
LIBS = drivers + mesa + auxiliaries + env['LIBS'],
)
@@ -0,0 +1,10 @@
#include "intel_api.h"
struct drm_api drm_api_hocks =
{
.create_screen = intel_create_screen,
.create_context = intel_create_context,
.buffer_from_handle = intel_be_buffer_from_handle,
.handle_from_buffer = intel_be_handle_from_buffer,
};
@@ -0,0 +1,14 @@
#ifndef _INTEL_API_H_
#define _INTEL_API_H_
#include "pipe/p_compiler.h"
#include "state_tracker/drm_api.h"
#include "intel_be_device.h"
struct pipe_screen *intel_create_screen(int drmFD, int pciID);
struct pipe_context *intel_create_context(struct pipe_screen *screen);
#endif
@@ -1,24 +0,0 @@
#ifndef INTEL_BATCHBUFFER_H
#define INTEL_BATCHBUFFER_H
#include "intel_be_batchbuffer.h"
/*
* Need to redefine the BATCH defines
*/
#undef BEGIN_BATCH
#define BEGIN_BATCH(dwords, relocs) \
(i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs))
#undef OUT_BATCH
#define OUT_BATCH(d) \
i915_batchbuffer_dword(&intel->base.batch->base, d)
#undef OUT_RELOC
#define OUT_RELOC(buf,flags,mask,delta) do { \
assert((delta) >= 0); \
intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \
} while (0)
#endif
+27 -186
View File
@@ -1,119 +1,21 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "i915simple/i915_screen.h"
#include "intel_device.h"
#include "intel_context.h"
#include "intel_batchbuffer.h"
#include "intel_be_device.h"
#include "intel_be_context.h"
#include "state_tracker/st_public.h"
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
#include "intel_egl.h"
#include "utils.h"
#ifdef DEBUG
int __intel_debug = 0;
#endif
#include "intel_api.h"
struct intel_context
{
struct intel_be_context base;
#define need_GL_ARB_multisample
#define need_GL_ARB_point_parameters
#define need_GL_ARB_texture_compression
#define need_GL_ARB_vertex_buffer_object
#define need_GL_ARB_vertex_program
#define need_GL_ARB_window_pos
#define need_GL_EXT_blend_color
#define need_GL_EXT_blend_equation_separate
#define need_GL_EXT_blend_func_separate
#define need_GL_EXT_blend_minmax
#define need_GL_EXT_cull_vertex
#define need_GL_EXT_fog_coord
#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_NV_vertex_program
#include "extension_helper.h"
/**
* Extension strings exported by the intel driver.
*
* \note
* It appears that ARB_texture_env_crossbar has "disappeared" compared to the
* old i830-specific driver.
*/
const struct dri_extension card_extensions[] = {
{"GL_ARB_multisample", GL_ARB_multisample_functions},
{"GL_ARB_multitexture", NULL},
{"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
{"GL_ARB_texture_border_clamp", NULL},
{"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
{"GL_ARB_texture_cube_map", NULL},
{"GL_ARB_texture_env_add", NULL},
{"GL_ARB_texture_env_combine", NULL},
{"GL_ARB_texture_env_dot3", NULL},
{"GL_ARB_texture_mirrored_repeat", NULL},
{"GL_ARB_texture_rectangle", NULL},
{"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
{"GL_ARB_pixel_buffer_object", NULL},
{"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
{"GL_ARB_window_pos", GL_ARB_window_pos_functions},
{"GL_EXT_blend_color", GL_EXT_blend_color_functions},
{"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
{"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
{"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
{"GL_EXT_blend_subtract", NULL},
{"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
{"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
{"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
{"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
{"GL_EXT_packed_depth_stencil", NULL},
{"GL_EXT_pixel_buffer_object", NULL},
{"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
{"GL_EXT_stencil_wrap", NULL},
{"GL_EXT_texture_edge_clamp", NULL},
{"GL_EXT_texture_env_combine", NULL},
{"GL_EXT_texture_env_dot3", NULL},
{"GL_EXT_texture_filter_anisotropic", NULL},
{"GL_EXT_texture_lod_bias", NULL},
{"GL_3DFX_texture_compression_FXT1", NULL},
{"GL_APPLE_client_storage", NULL},
{"GL_MESA_pack_invert", NULL},
{"GL_MESA_ycbcr_texture", NULL},
{"GL_NV_blend_square", NULL},
{"GL_NV_vertex_program", GL_NV_vertex_program_functions},
{"GL_NV_vertex_program1_1", NULL},
{"GL_SGIS_generate_mipmap", NULL },
{NULL, NULL}
/* stuff */
};
/*
* Hardware lock functions.
* Doesn't do anything in EGL
@@ -142,101 +44,40 @@ intel_locked_hardware(struct intel_be_context *context)
/*
* Misc functions.
*/
int
intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate)
static void
intel_destroy_be_context(struct i915_winsys *winsys)
{
struct intel_context *intel = CALLOC_STRUCT(intel_context);
struct intel_device *device = (struct intel_device *)egl_context->device->priv;
struct intel_context *intel = (struct intel_context *)winsys;
intel_be_destroy_context(&intel->base);
free(intel);
}
struct pipe_context *
intel_create_context(struct pipe_screen *screen)
{
struct intel_context *intel;
struct pipe_context *pipe;
struct st_context *st_share = NULL;
struct intel_be_device *device = (struct intel_be_device *)screen->winsys;
egl_context->priv = intel;
intel->intel_device = device;
intel->egl_context = egl_context;
intel->egl_device = egl_context->device;
intel = (struct intel_context *)malloc(sizeof(*intel));
memset(intel, 0, sizeof(*intel));
intel->base.hardware_lock = intel_lock_hardware;
intel->base.hardware_unlock = intel_unlock_hardware;
intel->base.hardware_locked = intel_locked_hardware;
intel_be_init_context(&intel->base, &device->base);
intel_be_init_context(&intel->base, device);
intel->base.base.destroy = intel_destroy_be_context;
#if 0
pipe = intel_create_softpipe(intel, screen->winsys);
#else
pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base);
pipe = i915_create_context(screen, &device->base, &intel->base.base);
#endif
pipe->priv = intel;
intel->st = st_create_context(pipe, visual, st_share);
device->dummy = intel;
return TRUE;
}
int
intel_destroy_context(struct egl_drm_context *egl_context)
{
struct intel_context *intel = egl_context->priv;
if (intel->intel_device->dummy == intel)
intel->intel_device->dummy = NULL;
st_destroy_context(intel->st);
intel_be_destroy_context(&intel->base);
free(intel);
return TRUE;
}
void
intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read)
{
if (context) {
struct intel_context *intel = (struct intel_context *)context->priv;
struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv;
assert(draw_fb->stfb);
assert(read_fb->stfb);
st_make_current(intel->st, draw_fb->stfb, read_fb->stfb);
intel->egl_drawable = draw;
st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h);
if (draw != read)
st_resize_framebuffer(read_fb->stfb, read->w, read->h);
} else {
st_make_current(NULL, NULL, NULL);
}
}
void
intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front)
{
struct intel_device *device = (struct intel_device *)draw->device->priv;
struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
if (draw_fb->front_buffer)
driBOUnReference(draw_fb->front_buffer);
draw_fb->front_buffer = NULL;
draw_fb->front = NULL;
/* to unbind just call this function with front == NULL */
if (!front)
return;
draw_fb->front = front;
driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0);
driBOSetReferenced(draw_fb->front_buffer, front->handle);
st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h);
return pipe;
}
@@ -1,118 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTEL_CONTEXT_H
#define INTEL_CONTEXT_H
#include "pipe/p_debug.h"
#include "intel_be_context.h"
struct st_context;
struct egl_drm_device;
struct egl_drm_context;
struct egl_drm_frontbuffer;
/**
* Intel rendering context, contains a state tracker and intel-specific info.
*/
struct intel_context
{
struct intel_be_context base;
struct st_context *st;
struct intel_device *intel_device;
/* new egl stuff */
struct egl_drm_device *egl_device;
struct egl_drm_context *egl_context;
struct egl_drm_drawable *egl_drawable;
};
/**
* Intel framebuffer.
*/
struct intel_framebuffer
{
struct st_framebuffer *stfb;
struct intel_device *device;
struct _DriBufferObject *front_buffer;
struct egl_drm_frontbuffer *front;
};
/* These are functions now:
*/
void LOCK_HARDWARE( struct intel_context *intel );
void UNLOCK_HARDWARE( struct intel_context *intel );
extern char *__progname;
/* ================================================================
* Debugging:
*/
#ifdef DEBUG
extern int __intel_debug;
#define DEBUG_SWAP 0x1
#define DEBUG_LOCK 0x2
#define DEBUG_IOCTL 0x4
#define DEBUG_BATCH 0x8
#define DBG(flag, ...) do { \
if (__intel_debug & (DEBUG_##flag)) \
printf(__VA_ARGS__); \
} while(0)
#else
#define DBG(flag, ...)
#endif
#define PCI_CHIP_845_G 0x2562
#define PCI_CHIP_I830_M 0x3577
#define PCI_CHIP_I855_GM 0x3582
#define PCI_CHIP_I865_G 0x2572
#define PCI_CHIP_I915_G 0x2582
#define PCI_CHIP_I915_GM 0x2592
#define PCI_CHIP_I945_G 0x2772
#define PCI_CHIP_I945_GM 0x27A2
#define PCI_CHIP_I945_GME 0x27AE
#define PCI_CHIP_G33_G 0x29C2
#define PCI_CHIP_Q35_G 0x29B2
#define PCI_CHIP_Q33_G 0x29D2
#endif
+35 -124
View File
@@ -1,137 +1,48 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "utils.h"
#include "state_tracker/st_public.h"
#include <stdio.h>
#include "pipe/p_defines.h"
#include "intel_be_device.h"
#include "i915simple/i915_screen.h"
#include "intel_context.h"
#include "intel_device.h"
#include "intel_batchbuffer.h"
#include "intel_egl.h"
#include "intel_api.h"
extern const struct dri_extension card_extensions[];
int
intel_create_device(struct egl_drm_device *device)
struct intel_device
{
struct intel_device *intel_device;
struct intel_be_device base;
int deviceID;
};
static void
intel_destroy_winsys(struct pipe_winsys *winsys)
{
struct intel_device *dev = (struct intel_device *)winsys;
intel_be_destroy_device(&dev->base);
free(dev);
}
struct pipe_screen *
intel_create_screen(int drmFD, int deviceID)
{
struct intel_device *dev;
struct pipe_screen *screen;
/* Allocate the private area */
intel_device = CALLOC_STRUCT(intel_device);
if (!intel_device)
return FALSE;
dev = malloc(sizeof(*dev));
if (!dev)
return NULL;
memset(dev, 0, sizeof(*dev));
device->priv = (void *)intel_device;
intel_device->device = device;
dev->deviceID = deviceID;
intel_device->deviceID = device->deviceID;
intel_be_init_device(&dev->base, drmFD, deviceID);
intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID);
/* we need to hock our own destroy function in here */
dev->base.base.destroy = intel_destroy_winsys;
intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID);
screen = i915_create_screen(&dev->base.base, deviceID);
/* hack */
driInitExtensions(NULL, card_extensions, GL_FALSE);
return TRUE;
}
int
intel_destroy_device(struct egl_drm_device *device)
{
struct intel_device *intel_device = (struct intel_device *)device->priv;
intel_be_destroy_device(&intel_device->base);
free(intel_device);
device->priv = NULL;
return TRUE;
}
int
intel_create_drawable(struct egl_drm_drawable *drawable,
const __GLcontextModes * visual)
{
enum pipe_format colorFormat, depthFormat, stencilFormat;
struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer);
if (!intelfb)
return GL_FALSE;
intelfb->device = drawable->device->priv;
if (visual->redBits == 5)
colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
else
colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
if (visual->depthBits == 16)
depthFormat = PIPE_FORMAT_Z16_UNORM;
else if (visual->depthBits == 24)
depthFormat = PIPE_FORMAT_S8Z24_UNORM;
else
depthFormat = PIPE_FORMAT_NONE;
if (visual->stencilBits == 8)
stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
else
stencilFormat = PIPE_FORMAT_NONE;
intelfb->stfb = st_create_framebuffer(visual,
colorFormat,
depthFormat,
stencilFormat,
drawable->w,
drawable->h,
(void*) intelfb);
if (!intelfb->stfb) {
free(intelfb);
return GL_FALSE;
}
drawable->priv = (void *) intelfb;
return GL_TRUE;
}
int
intel_destroy_drawable(struct egl_drm_drawable *drawable)
{
struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv;
drawable->priv = NULL;
assert(intelfb->stfb);
st_unreference_framebuffer(intelfb->stfb);
free(intelfb);
return TRUE;
return screen;
}
@@ -1,50 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _INTEL_SCREEN_H_
#define _INTEL_SCREEN_H_
#include "intel_be_device.h"
#include "pipe/p_compiler.h"
struct pipe_screen;
struct egl_drm_device;
struct intel_context;
struct intel_device
{
struct intel_be_device base;
struct pipe_screen *pipe;
int deviceID;
struct egl_drm_device *device;
struct intel_context *dummy;
};
#endif
@@ -1,796 +0,0 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglmode.h"
#include "eglscreen.h"
#include "eglsurface.h"
#include "egllog.h"
#include "intel_egl.h"
#include "xf86drm.h"
#include "xf86drmMode.h"
#include "intel_context.h"
#include "state_tracker/st_public.h"
#define MAX_SCREENS 16
static void
drm_get_device_id(struct egl_drm_device *device)
{
char path[512];
FILE *file;
/* TODO get the real minor */
int minor = 0;
snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
file = fopen(path, "r");
if (!file) {
_eglLog(_EGL_WARNING, "Could not retrive device ID\n");
return;
}
fgets(path, sizeof( path ), file);
sscanf(path, "%x", &device->deviceID);
fclose(file);
}
static struct egl_drm_device*
egl_drm_create_device(int drmFD)
{
struct egl_drm_device *device = malloc(sizeof(*device));
memset(device, 0, sizeof(*device));
device->drmFD = drmFD;
device->version = drmGetVersion(device->drmFD);
drm_get_device_id(device);
if (!intel_create_device(device)) {
free(device);
return NULL;
}
return device;
}
static void
_egl_context_modes_destroy(__GLcontextModes *modes)
{
_eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
while (modes) {
__GLcontextModes * const next = modes->next;
free(modes);
modes = next;
}
}
/**
* Create a linked list of 'count' GLcontextModes.
* These are used during the client/server visual negotiation phase,
* then discarded.
*/
static __GLcontextModes *
_egl_context_modes_create(unsigned count, size_t minimum_size)
{
/* This code copied from libGLX, and modified */
const size_t size = (minimum_size > sizeof(__GLcontextModes))
? minimum_size : sizeof(__GLcontextModes);
__GLcontextModes * head = NULL;
__GLcontextModes ** next;
unsigned i;
_eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size);
next = & head;
for (i = 0 ; i < count ; i++) {
*next = (__GLcontextModes *) calloc(1, size);
if (*next == NULL) {
_egl_context_modes_destroy(head);
head = NULL;
break;
}
(*next)->doubleBufferMode = 1;
(*next)->visualID = GLX_DONT_CARE;
(*next)->visualType = GLX_DONT_CARE;
(*next)->visualRating = GLX_NONE;
(*next)->transparentPixel = GLX_NONE;
(*next)->transparentRed = GLX_DONT_CARE;
(*next)->transparentGreen = GLX_DONT_CARE;
(*next)->transparentBlue = GLX_DONT_CARE;
(*next)->transparentAlpha = GLX_DONT_CARE;
(*next)->transparentIndex = GLX_DONT_CARE;
(*next)->xRenderable = GLX_DONT_CARE;
(*next)->fbconfigID = GLX_DONT_CARE;
(*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
(*next)->bindToTextureRgb = GLX_DONT_CARE;
(*next)->bindToTextureRgba = GLX_DONT_CARE;
(*next)->bindToMipmapTexture = GLX_DONT_CARE;
(*next)->bindToTextureTargets = 0;
(*next)->yInverted = GLX_DONT_CARE;
next = & ((*next)->next);
}
return head;
}
struct drm_screen;
struct drm_driver
{
_EGLDriver base; /* base class/object */
drmModeResPtr res;
struct drm_screen *screens[MAX_SCREENS];
size_t count_screens;
struct egl_drm_device *device;
};
struct drm_surface
{
_EGLSurface base; /* base class/object */
struct egl_drm_drawable *drawable;
};
struct drm_context
{
_EGLContext base; /* base class/object */
struct egl_drm_context *context;
};
struct drm_screen
{
_EGLScreen base;
/* currently only support one connector */
drmModeConnectorPtr connector;
/* Has this screen been shown */
int shown;
/* Surface that is currently attached to this screen */
struct drm_surface *surf;
/* backing buffer */
drmBO buffer;
/* framebuffer */
drmModeFBPtr fb;
uint32_t fbID;
/* crtc and mode used */
drmModeCrtcPtr crtc;
uint32_t crtcID;
struct drm_mode_modeinfo *mode;
/* geometry of the screen */
struct egl_drm_frontbuffer front;
};
static void
drm_update_res(struct drm_driver *drm_drv)
{
drmModeFreeResources(drm_drv->res);
drm_drv->res = drmModeGetResources(drm_drv->device->drmFD);
}
static void
drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
{
struct drm_mode_modeinfo *m;
int i;
for (i = 0; i < connector->count_modes; i++) {
m = &connector->modes[i];
_eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
}
}
static EGLBoolean
drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct drm_driver *drm_drv = (struct drm_driver *)drv;
struct drm_screen *screen = NULL;
drmModeConnectorPtr connector = NULL;
drmModeResPtr res = NULL;
unsigned count_connectors = 0;
int num_screens = 0;
EGLint i;
int fd;
fd = drmOpen("i915", NULL);
if (fd < 0) {
return EGL_FALSE;
}
drm_drv->device = egl_drm_create_device(fd);
if (!drm_drv->device) {
drmClose(fd);
return EGL_FALSE;
}
drm_update_res(drm_drv);
res = drm_drv->res;
if (res)
count_connectors = res->count_connectors;
for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
connector = drmModeGetConnector(fd, res->connectors[i]);
if (!connector)
continue;
if (connector->connection != DRM_MODE_CONNECTED) {
drmModeFreeConnector(connector);
continue;
}
screen = malloc(sizeof(struct drm_screen));
memset(screen, 0, sizeof(*screen));
screen->connector = connector;
_eglInitScreen(&screen->base);
_eglAddScreen(disp, &screen->base);
drm_add_modes_from_connector(&screen->base, connector);
drm_drv->screens[num_screens++] = screen;
}
drm_drv->count_screens = num_screens;
/* for now we only have one config */
_EGLConfig *config = calloc(1, sizeof(*config));
memset(config, 1, sizeof(*config));
_eglInitConfig(config, 1);
_eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
_eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
_eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
_eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
_eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
_eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
_eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
_eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
_eglAddConfig(disp, config);
drv->Initialized = EGL_TRUE;
*major = 1;
*minor = 4;
return EGL_TRUE;
}
static void
drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
{
struct drm_driver *drm_drv = (struct drm_driver *)drv;
unsigned int i;
intel_bind_frontbuffer(screen->surf->drawable, NULL);
screen->surf = NULL;
for (i = 0; i < drm_drv->res->count_crtcs; i++) {
drmModeSetCrtc(
drm_drv->device->drmFD,
drm_drv->res->crtcs[i],
0, // FD
0, 0,
NULL, 0, // List of output ids
NULL);
}
drmModeRmFB(drm_drv->device->drmFD, screen->fbID);
drmModeFreeFB(screen->fb);
screen->fb = NULL;
drmBOUnreference(drm_drv->device->drmFD, &screen->buffer);
screen->shown = 0;
}
static EGLBoolean
drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
{
struct drm_driver *drm_drv = (struct drm_driver *)drv;
struct drm_screen *screen;
int i = 0;
intel_destroy_device(drm_drv->device);
drmFreeVersion(drm_drv->device->version);
for (i = 0; i < drm_drv->count_screens; i++) {
screen = drm_drv->screens[i];
if (screen->shown)
drm_takedown_shown_screen(drv, screen);
drmModeFreeConnector(screen->connector);
_eglDestroyScreen(&screen->base);
drm_drv->screens[i] = NULL;
}
drmClose(drm_drv->device->drmFD);
free(drm_drv->device);
_eglCleanupDisplay(_eglLookupDisplay(dpy));
free(drm_drv);
return EGL_TRUE;
}
static struct drm_context *
lookup_drm_context(EGLContext context)
{
_EGLContext *c = _eglLookupContext(context);
return (struct drm_context *) c;
}
static struct drm_surface *
lookup_drm_surface(EGLSurface surface)
{
_EGLSurface *s = _eglLookupSurface(surface);
return (struct drm_surface *) s;
}
static struct drm_screen *
lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen)
{
_EGLScreen *s = _eglLookupScreen(dpy, screen);
return (struct drm_screen *) s;
}
static __GLcontextModes*
visual_from_config(_EGLConfig *conf)
{
__GLcontextModes *visual;
(void)conf;
visual = _egl_context_modes_create(1, sizeof(*visual));
visual->redBits = 8;
visual->greenBits = 8;
visual->blueBits = 8;
visual->alphaBits = 8;
visual->rgbBits = 32;
visual->doubleBufferMode = 1;
visual->depthBits = 24;
visual->haveDepthBuffer = visual->depthBits > 0;
visual->stencilBits = 8;
visual->haveStencilBuffer = visual->stencilBits > 0;
return visual;
}
static EGLContext
drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
{
struct drm_driver *drm_drv = (struct drm_driver *)drv;
struct drm_context *c;
struct drm_egl_context *share = NULL;
_EGLConfig *conf;
int i;
int ret;
__GLcontextModes *visual;
struct egl_drm_context *context;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return EGL_NO_CONTEXT;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs defined for now */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
return EGL_NO_CONTEXT;
}
}
c = (struct drm_context *) calloc(1, sizeof(struct drm_context));
if (!c)
return EGL_NO_CONTEXT;
_eglInitContext(drv, dpy, &c->base, config, attrib_list);
context = malloc(sizeof(*context));
memset(context, 0, sizeof(*context));
if (!context)
goto err_c;
context->device = drm_drv->device;
visual = visual_from_config(conf);
ret = intel_create_context(context, visual, share);
free(visual);
if (!ret)
goto err_gl;
c->context = context;
/* generate handle and insert into hash table */
_eglSaveContext(&c->base);
assert(_eglGetContextHandle(&c->base));
return _eglGetContextHandle(&c->base);
err_gl:
free(context);
err_c:
free(c);
return EGL_NO_CONTEXT;
}
static EGLBoolean
drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
struct drm_context *fc = lookup_drm_context(context);
_eglRemoveContext(&fc->base);
if (fc->base.IsBound) {
fc->base.DeletePending = EGL_TRUE;
} else {
intel_destroy_context(fc->context);
free(fc->context);
free(fc);
}
return EGL_TRUE;
}
static EGLSurface
drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
{
return EGL_NO_SURFACE;
}
static EGLSurface
drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
{
return EGL_NO_SURFACE;
}
static EGLSurface
drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
struct drm_driver *drm_drv = (struct drm_driver *)drv;
int i;
int ret;
int width = -1;
int height = -1;
struct drm_surface *surf = NULL;
struct egl_drm_drawable *drawable = NULL;
__GLcontextModes *visual;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
return EGL_NO_CONTEXT;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_WIDTH:
width = attrib_list[++i];
break;
case EGL_HEIGHT:
height = attrib_list[++i];
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
return EGL_NO_SURFACE;
}
}
if (width < 1 || height < 1) {
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
return EGL_NO_SURFACE;
}
surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
if (!surf)
goto err;
if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list))
goto err_surf;
drawable = malloc(sizeof(*drawable));
memset(drawable, 0, sizeof(*drawable));
drawable->w = width;
drawable->h = height;
visual = visual_from_config(conf);
drawable->device = drm_drv->device;
ret = intel_create_drawable(drawable, visual);
free(visual);
if (!ret)
goto err_draw;
surf->drawable = drawable;
_eglSaveSurface(&surf->base);
return surf->base.Handle;
err_draw:
free(drawable);
err_surf:
free(surf);
err:
return EGL_NO_SURFACE;
}
static EGLSurface
drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
const EGLint *attrib_list)
{
EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
return surf;
}
static struct drm_mode_modeinfo *
drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode)
{
int i;
struct drm_mode_modeinfo *m = NULL;
for (i = 0; i < connector->count_modes; i++) {
m = &connector->modes[i];
if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
break;
m = &connector->modes[0]; /* if we can't find one, return first */
}
return m;
}
static void
draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr)
{
int i, j;
for (i = x; i < x + w; i++)
for(j = y; j < y + h; j++)
ptr[(i * pitch / 4) + j] = v;
}
static void
prettyColors(int fd, unsigned int handle, size_t pitch)
{
drmBO bo;
unsigned int *ptr;
void *p;
int i;
drmBOReference(fd, handle, &bo);
drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p);
ptr = (unsigned int*)p;
for (i = 0; i < (bo.size / 4); i++)
ptr[i] = 0xFFFFFFFF;
for (i = 0; i < 4; i++)
draw(i * 40, i * 40, 40, 40, pitch, 0, ptr);
draw(200, 100, 40, 40, pitch, 0xff00ff, ptr);
draw(100, 200, 40, 40, pitch, 0xff00ff, ptr);
drmBOUnmap(fd, &bo);
}
static EGLBoolean
drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
EGLScreenMESA screen,
EGLSurface surface, EGLModeMESA m)
{
struct drm_driver *drm_drv = (struct drm_driver *)drv;
struct drm_surface *surf = lookup_drm_surface(surface);
struct drm_screen *scrn = lookup_drm_screen(dpy, screen);
_EGLMode *mode = _eglLookupMode(dpy, m);
size_t pitch = mode->Width * 4;
size_t size = mode->Height * pitch;
int ret;
unsigned int i,j,k;
if (scrn->shown)
drm_takedown_shown_screen(drv, scrn);
ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0,
DRM_BO_FLAG_READ |
DRM_BO_FLAG_WRITE |
DRM_BO_FLAG_MEM_TT |
DRM_BO_FLAG_MEM_VRAM |
DRM_BO_FLAG_NO_EVICT,
DRM_BO_HINT_DONT_FENCE, &scrn->buffer);
if (ret)
return EGL_FALSE;
prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch);
ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height,
32, 32, pitch,
scrn->buffer.handle,
&scrn->fbID);
if (ret)
goto err_bo;
scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID);
if (!scrn->fb)
goto err_bo;
for (j = 0; j < drm_drv->res->count_connectors; j++) {
drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]);
scrn->mode = drm_find_mode(con, mode);
if (!scrn->mode)
goto err_fb;
for (k = 0; k < con->count_encoders; k++) {
drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]);
for (i = 0; i < drm_drv->res->count_crtcs; i++) {
if (enc->possible_crtcs & (1<<i)) {
ret = drmModeSetCrtc(
drm_drv->device->drmFD,
drm_drv->res->crtcs[i],
scrn->fbID,
0, 0,
&drm_drv->res->connectors[j], 1,
scrn->mode);
/* skip the other crtcs now */
i = drm_drv->res->count_crtcs;
}
}
}
}
scrn->front.handle = scrn->buffer.handle;
scrn->front.pitch = pitch;
scrn->front.width = mode->Width;
scrn->front.height = mode->Height;
scrn->surf = surf;
intel_bind_frontbuffer(surf->drawable, &scrn->front);
scrn->shown = 1;
return EGL_TRUE;
err_fb:
/* TODO remove fb */
err_bo:
drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer);
return EGL_FALSE;
}
static EGLBoolean
drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
struct drm_surface *fs = lookup_drm_surface(surface);
_eglRemoveSurface(&fs->base);
if (fs->base.IsBound) {
fs->base.DeletePending = EGL_TRUE;
} else {
intel_bind_frontbuffer(fs->drawable, NULL);
intel_destroy_drawable(fs->drawable);
free(fs->drawable);
free(fs);
}
return EGL_TRUE;
}
static EGLBoolean
drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
{
struct drm_surface *readSurf = lookup_drm_surface(read);
struct drm_surface *drawSurf = lookup_drm_surface(draw);
struct drm_context *ctx = lookup_drm_context(context);
EGLBoolean b;
b = _eglMakeCurrent(drv, dpy, draw, read, context);
if (!b)
return EGL_FALSE;
if (ctx) {
if (!drawSurf || !readSurf)
return EGL_FALSE;
intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
} else {
intel_make_current(NULL, NULL, NULL);
}
return EGL_TRUE;
}
static EGLBoolean
drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
struct drm_surface *surf = lookup_drm_surface(draw);
if (!surf)
return EGL_FALSE;
/* error checking */
if (!_eglSwapBuffers(drv, dpy, draw))
return EGL_FALSE;
intel_swap_buffers(surf->drawable);
return EGL_TRUE;
}
/**
* The bootstrap function. Return a new drm_driver object and
* plug in API functions.
*/
_EGLDriver *
_eglMain(_EGLDisplay *dpy, const char *args)
{
struct drm_driver *drm;
drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver));
if (!drm) {
return NULL;
}
/* First fill in the dispatch table with defaults */
_eglInitDriverFallbacks(&drm->base);
/* then plug in our Drm-specific functions */
drm->base.API.Initialize = drm_initialize;
drm->base.API.Terminate = drm_terminate;
drm->base.API.CreateContext = drm_create_context;
drm->base.API.MakeCurrent = drm_make_current;
drm->base.API.CreateWindowSurface = drm_create_window_surface;
drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface;
drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface;
drm->base.API.DestroySurface = drm_destroy_surface;
drm->base.API.DestroyContext = drm_destroy_context;
drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
drm->base.API.SwapBuffers = drm_swap_buffers;
drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
drm->base.Name = "DRM/Gallium";
/* enable supported extensions */
drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
drm->base.Extensions.MESA_copy_context = EGL_TRUE;
return &drm->base;
}
@@ -1,53 +0,0 @@
#ifndef _INTEL_EGL_H_
#define _INTEL_EGL_H_
#include <xf86drm.h>
struct egl_drm_device
{
void *priv;
int drmFD;
drmVersionPtr version;
int deviceID;
};
struct egl_drm_context
{
void *priv;
struct egl_drm_device *device;
};
struct egl_drm_drawable
{
void *priv;
struct egl_drm_device *device;
size_t h;
size_t w;
};
struct egl_drm_frontbuffer
{
uint32_t handle;
uint32_t pitch;
uint32_t width;
uint32_t height;
};
#include "GL/internal/glcore.h"
int intel_create_device(struct egl_drm_device *device);
int intel_destroy_device(struct egl_drm_device *device);
int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate);
int intel_destroy_context(struct egl_drm_context *context);
int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual);
int intel_destroy_drawable(struct egl_drm_drawable *drawable);
void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read);
void intel_swap_buffers(struct egl_drm_drawable *draw);
void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front);
#endif
@@ -1,53 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _INTEL_REG_H_
#define _INTEL_REG_H_
#define BR00_BITBLT_CLIENT 0x40000000
#define BR00_OP_COLOR_BLT 0x10000000
#define BR00_OP_SRC_COPY_BLT 0x10C00000
#define BR13_SOLID_PATTERN 0x80000000
#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4)
#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
#define XY_COLOR_BLT_WRITE_RGB (1<<20)
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
#define MI_WAIT_FOR_EVENT ((0x3<<23))
#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
#define MI_BATCH_BUFFER_END (0xA<<23)
#endif
@@ -1,111 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "intel_device.h"
#include "intel_context.h"
#include "intel_batchbuffer.h"
#include "intel_reg.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 "intel_egl.h"
static void
intel_display_surface(struct egl_drm_drawable *draw,
struct pipe_surface *surf);
void intel_swap_buffers(struct egl_drm_drawable *draw)
{
struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv;
struct pipe_surface *back_surf;
assert(intel_fb);
assert(intel_fb->stfb);
back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT);
if (back_surf) {
st_notify_swapbuffers(intel_fb->stfb);
if (intel_fb->front)
intel_display_surface(draw, back_surf);
st_notify_swapbuffers_complete(intel_fb->stfb);
}
}
static void
intel_display_surface(struct egl_drm_drawable *draw,
struct pipe_surface *surf)
{
struct intel_context *intel = NULL;
struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv;
struct _DriFenceObject *fence;
//const int srcWidth = surf->width;
//const int srcHeight = surf->height;
intel = intel_fb->device->dummy;
if (!intel) {
printf("No dummy context\n");
return;
}
const int dstWidth = intel_fb->front->width;
const int dstHeight = intel_fb->front->height;
const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp;
const int cpp = 4;//intel_fb->front->cpp;
const int srcPitch = surf->stride / cpp;
int BR13, CMD;
//int i;
BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
BEGIN_BATCH(8, 2);
OUT_BATCH(CMD);
OUT_BATCH(BR13);
OUT_BATCH((0 << 16) | 0);
OUT_BATCH((dstHeight << 16) | dstWidth);
OUT_RELOC(intel_fb->front_buffer,
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
OUT_BATCH((0 << 16) | 0);
OUT_BATCH((srcPitch * cpp) & 0xffff);
OUT_RELOC(dri_bo(surf->buffer),
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
fence = intel_be_batchbuffer_flush(intel->base.batch);
driFenceUnReference(&fence);
intel_be_batchbuffer_finish(intel->base.batch);
}
+18
View File
@@ -0,0 +1,18 @@
TOP = ../../../../../..
include $(TOP)/configs/current
LIBNAME = inteldrm
C_SOURCES = \
intel_be_batchbuffer.c \
intel_be_context.c \
intel_be_device.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:
@@ -0,0 +1,64 @@
# -*-makefile-*-
# We still have a dependency on the "dri" buffer manager. Most likely
# the interface can be reused in non-dri environments, and also as a
# frontend to simpler memory managers.
#
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 *.a *~ server/*.o $(SYMLINKS)
-rm -f depend depend.bak
include depend
@@ -0,0 +1,139 @@
#include "intel_be_batchbuffer.h"
#include "intel_be_context.h"
#include "intel_be_device.h"
#include "intel_be_fence.h"
#include <errno.h>
#include "util/u_memory.h"
struct intel_be_batchbuffer *
intel_be_batchbuffer_alloc(struct intel_be_context *intel)
{
struct intel_be_batchbuffer *batch = CALLOC_STRUCT(intel_be_batchbuffer);
batch->base.buffer = NULL;
batch->base.winsys = &intel->base;
batch->base.map = NULL;
batch->base.ptr = NULL;
batch->base.size = 0;
batch->base.actual_size = intel->device->max_batch_size;
batch->base.relocs = 0;
batch->base.max_relocs = INTEL_DEFAULT_RELOCS;
batch->base.map = malloc(batch->base.actual_size);
memset(batch->base.map, 0, batch->base.actual_size);
batch->base.ptr = batch->base.map;
intel_be_batchbuffer_reset(batch);
return batch;
}
void
intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
{
struct intel_be_context *intel = intel_be_context(batch->base.winsys);
struct intel_be_device *dev = intel->device;
if (batch->bo)
drm_intel_bo_unreference(batch->bo);
memset(batch->base.map, 0, batch->base.actual_size);
batch->base.ptr = batch->base.map;
batch->base.size = batch->base.actual_size - BATCH_RESERVED;
batch->base.relocs = 0;
batch->base.max_relocs = INTEL_DEFAULT_RELOCS;
batch->bo = drm_intel_bo_alloc(dev->pools.gem,
"gallium3d_batch_buffer",
batch->base.actual_size, 0);
}
int
intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
unsigned pre_add,
drm_intel_bo *bo,
uint32_t read_domains,
uint32_t write_domain)
{
unsigned offset;
int ret = 0;
assert(batch->base.relocs < batch->base.max_relocs);
offset = (unsigned)(batch->base.ptr - batch->base.map);
batch->base.ptr += 4;
ret = drm_intel_bo_emit_reloc(bo, pre_add,
batch->bo, offset,
read_domains,
write_domain);
if (!ret)
batch->base.relocs++;
return ret;
}
void
intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
struct intel_be_fence **fence)
{
struct i915_batchbuffer *i915 = &batch->base;
unsigned used = 0;
int ret = 0;
assert(i915_batchbuffer_space(i915) >= 0);
used = batch->base.ptr - batch->base.map;
assert((used & 3) == 0);
if (used & 4) {
((uint32_t *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
((uint32_t *) batch->base.ptr)[1] = 0;
((uint32_t *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END;
batch->base.ptr += 12;
} else {
((uint32_t *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
((uint32_t *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END;
batch->base.ptr += 8;
}
used = batch->base.ptr - batch->base.map;
drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
assert(ret == 0);
intel_be_batchbuffer_reset(batch);
if (fence) {
if (*fence)
intel_be_fence_unreference(*fence);
(*fence) = CALLOC_STRUCT(intel_be_fence);
(*fence)->refcount = 1;
(*fence)->bo = NULL;
}
}
void
intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch)
{
}
void
intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch)
{
if (batch->bo)
drm_intel_bo_unreference(batch->bo);
free(batch->base.map);
free(batch);
}
@@ -0,0 +1,55 @@
#ifndef INTEL_BE_BATCHBUFFER_H
#define INTEL_BE_BATCHBUFFER_H
#include "i915simple/i915_batch.h"
#include "drm.h"
#include "intel_bufmgr.h"
#define BATCH_RESERVED 16
#define INTEL_DEFAULT_RELOCS 100
#define INTEL_MAX_RELOCS 400
#define INTEL_BATCH_NO_CLIPRECTS 0x1
#define INTEL_BATCH_CLIPRECTS 0x2
struct intel_be_context;
struct intel_be_device;
struct intel_be_fence;
struct intel_be_batchbuffer
{
struct i915_batchbuffer base;
struct intel_be_context *intel;
struct intel_be_device *device;
drm_intel_bo *bo;
};
struct intel_be_batchbuffer *
intel_be_batchbuffer_alloc(struct intel_be_context *intel);
void
intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch);
void
intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch);
void
intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
struct intel_be_fence **fence);
void
intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch);
int
intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
unsigned pre_add,
drm_intel_bo *bo,
uint32_t read_domains,
uint32_t write_doman);
#endif
@@ -0,0 +1,78 @@
#include "intel_be_device.h"
#include "intel_be_context.h"
#include "intel_be_batchbuffer.h"
#include "i915_drm.h"
static struct i915_batchbuffer *
intel_be_batch_get(struct i915_winsys *sws)
{
struct intel_be_context *intel = intel_be_context(sws);
return &intel->batch->base;
}
static void
intel_be_batch_reloc(struct i915_winsys *sws,
struct pipe_buffer *buf,
unsigned access_flags,
unsigned delta)
{
struct intel_be_context *intel = intel_be_context(sws);
drm_intel_bo *bo = intel_bo(buf);
int ret;
uint32_t read = 0;
uint32_t write = 0;
if (access_flags & I915_BUFFER_ACCESS_WRITE) {
write = I915_GEM_DOMAIN_RENDER;
}
if (access_flags & I915_BUFFER_ACCESS_READ) {
read = I915_GEM_DOMAIN_SAMPLER |
I915_GEM_DOMAIN_VERTEX;
}
ret = intel_be_offset_relocation(intel->batch,
delta,
bo,
read,
write);
/* TODO change return type */
/* return ret; */
}
static void
intel_be_batch_flush(struct i915_winsys *sws,
struct pipe_fence_handle **fence)
{
struct intel_be_context *intel = intel_be_context(sws);
struct intel_be_fence **f = (struct intel_be_fence **)fence;
if (fence && *fence)
assert(0);
intel_be_batchbuffer_flush(intel->batch, f);
}
boolean
intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device)
{
assert(intel);
assert(device);
intel->device = device;
intel->base.batch_get = intel_be_batch_get;
intel->base.batch_reloc = intel_be_batch_reloc;
intel->base.batch_flush = intel_be_batch_flush;
intel->batch = intel_be_batchbuffer_alloc(intel);
return true;
}
void
intel_be_destroy_context(struct intel_be_context *intel)
{
intel_be_batchbuffer_free(intel->batch);
}
@@ -0,0 +1,48 @@
#ifndef INTEL_BE_CONTEXT_H
#define INTEL_BE_CONTEXT_H
#include "i915simple/i915_winsys.h"
struct intel_be_context
{
/** Interface to i915simple driver */
struct i915_winsys base;
struct intel_be_device *device;
struct intel_be_batchbuffer *batch;
/*
* Hardware lock functions.
*
* Needs to be filled in by the winsys.
*/
void (*hardware_lock)(struct intel_be_context *context);
void (*hardware_unlock)(struct intel_be_context *context);
boolean (*hardware_locked)(struct intel_be_context *context);
};
static INLINE struct intel_be_context *
intel_be_context(struct i915_winsys *sws)
{
return (struct intel_be_context *)sws;
}
/**
* Intialize a allocated intel_be_context struct.
*
* Remember to set the hardware_* functions.
*/
boolean
intel_be_init_context(struct intel_be_context *intel,
struct intel_be_device *device);
/**
* Destroy a intel_be_context.
*
* Does not free the struct that is up to the winsys.
*/
void
intel_be_destroy_context(struct intel_be_context *intel);
#endif
@@ -0,0 +1,267 @@
#include "intel_be_device.h"
#include "pipe/p_winsys.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
#include "util/u_memory.h"
#include "intel_be_fence.h"
#include "i915simple/i915_screen.h"
/**
* Turn a pipe winsys into an intel/pipe winsys:
*/
static INLINE struct intel_be_device *
intel_be_device(struct pipe_winsys *winsys)
{
return (struct intel_be_device *)winsys;
}
/*
* Buffer
*/
static void *
intel_be_buffer_map(struct pipe_winsys *winsys,
struct pipe_buffer *buf,
unsigned flags)
{
drm_intel_bo *bo = intel_bo(buf);
int write = 0;
int ret;
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
write = 1;
ret = drm_intel_bo_map(bo, write);
if (ret)
return NULL;
return bo->virtual;
}
static void
intel_be_buffer_unmap(struct pipe_winsys *winsys,
struct pipe_buffer *buf)
{
drm_intel_bo_unmap(intel_bo(buf));
}
static void
intel_be_buffer_destroy(struct pipe_winsys *winsys,
struct pipe_buffer *buf)
{
drm_intel_bo_unreference(intel_bo(buf));
free(buf);
}
static struct pipe_buffer *
intel_be_buffer_create(struct pipe_winsys *winsys,
unsigned alignment,
unsigned usage,
unsigned size)
{
struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
struct intel_be_device *dev = intel_be_device(winsys);
drm_intel_bufmgr *pool;
char *name;
if (!buffer)
return NULL;
buffer->base.refcount = 1;
buffer->base.alignment = alignment;
buffer->base.usage = usage;
buffer->base.size = size;
if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
/* Local buffer */
name = "gallium3d_local";
pool = dev->pools.gem;
} else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
/* For vertex buffers */
name = "gallium3d_internal_vertex";
pool = dev->pools.gem;
} else {
/* Regular buffers */
name = "gallium3d_regular";
pool = dev->pools.gem;
}
buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
if (!buffer->bo)
goto err;
return &buffer->base;
err:
free(buffer);
return NULL;
}
static struct pipe_buffer *
intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
{
struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
struct intel_be_device *dev = intel_be_device(winsys);
int ret;
if (!buffer)
return NULL;
buffer->base.refcount = 1;
buffer->base.alignment = 0;
buffer->base.usage = 0;
buffer->base.size = bytes;
buffer->bo = drm_intel_bo_alloc(dev->pools.gem,
"gallium3d_user_buffer",
bytes, 0);
if (!buffer->bo)
goto err;
ret = drm_intel_bo_subdata(buffer->bo,
0, bytes, ptr);
if (ret)
goto err;
return &buffer->base;
err:
free(buffer);
return NULL;
}
struct pipe_buffer *
intel_be_buffer_from_handle(struct pipe_winsys *winsys,
const char* name, unsigned handle)
{
struct intel_be_device *dev = intel_be_device(winsys);
struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
if (!buffer)
return NULL;
buffer->bo = drm_intel_bo_gem_create_from_name(dev->pools.gem, name, handle);
if (!buffer->bo)
goto err;
buffer->base.refcount = 1;
buffer->base.alignment = buffer->bo->align;
buffer->base.usage = PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE |
PIPE_BUFFER_USAGE_CPU_READ |
PIPE_BUFFER_USAGE_CPU_WRITE;
buffer->base.size = buffer->bo->size;
return &buffer->base;
err:
free(buffer);
return NULL;
}
unsigned
intel_be_handle_from_buffer(struct pipe_winsys *winsys,
struct pipe_buffer *buf)
{
drm_intel_bo *bo = intel_bo(buf);
return bo->handle;
}
/*
* Fence
*/
static void
intel_be_fence_refunref(struct pipe_winsys *sws,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
struct intel_be_fence **p = (struct intel_be_fence **)ptr;
struct intel_be_fence *f = (struct intel_be_fence *)fence;
assert(p);
if (f)
intel_be_fence_reference(f);
if (*p)
intel_be_fence_unreference(*p);
*p = f;
}
static int
intel_be_fence_signalled(struct pipe_winsys *sws,
struct pipe_fence_handle *fence,
unsigned flag)
{
assert(0);
return 0;
}
static int
intel_be_fence_finish(struct pipe_winsys *sws,
struct pipe_fence_handle *fence,
unsigned flag)
{
struct intel_be_fence *f = (struct intel_be_fence *)fence;
/* fence already expired */
if (!f->bo)
return 0;
drm_intel_bo_wait_rendering(f->bo);
drm_intel_bo_unreference(f->bo);
f->bo = NULL;
return 0;
}
/*
* Misc functions
*/
boolean
intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
{
dev->fd = fd;
dev->max_batch_size = 16 * 4096;
dev->max_vertex_size = 128 * 4096;
dev->base.buffer_create = intel_be_buffer_create;
dev->base.user_buffer_create = intel_be_user_buffer_create;
dev->base.buffer_map = intel_be_buffer_map;
dev->base.buffer_unmap = intel_be_buffer_unmap;
dev->base.buffer_destroy = intel_be_buffer_destroy;
/* Not used anymore */
dev->base.surface_alloc = NULL;
dev->base.surface_alloc_storage = NULL;
dev->base.surface_release = NULL;
dev->base.fence_reference = intel_be_fence_refunref;
dev->base.fence_signalled = intel_be_fence_signalled;
dev->base.fence_finish = intel_be_fence_finish;
dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
return true;
}
void
intel_be_destroy_device(struct intel_be_device *dev)
{
drm_intel_bufmgr_destroy(dev->pools.gem);
}
@@ -0,0 +1,74 @@
#ifndef INTEL_DRM_DEVICE_H
#define INTEL_DRM_DEVICE_H
#include "pipe/p_winsys.h"
#include "pipe/p_context.h"
#include "drm.h"
#include "intel_bufmgr.h"
/*
* Device
*/
struct intel_be_device
{
struct pipe_winsys base;
int fd; /**< Drm file discriptor */
size_t max_batch_size;
size_t max_vertex_size;
struct {
drm_intel_bufmgr *gem;
} pools;
};
boolean
intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
void
intel_be_destroy_device(struct intel_be_device *dev);
/*
* Buffer
*/
struct intel_be_buffer {
struct pipe_buffer base;
drm_intel_bo *bo;
};
/**
* Create a be buffer from a drm bo handle.
*
* Takes a reference.
*/
struct pipe_buffer *
intel_be_buffer_from_handle(struct pipe_winsys *winsys,
const char* name, unsigned handle);
/**
* Gets a handle from a buffer.
*
* If buffer is destroyed handle may become invalid.
*/
unsigned
intel_be_handle_from_buffer(struct pipe_winsys *winsys,
struct pipe_buffer *buffer);
static INLINE struct intel_be_buffer *
intel_be_buffer(struct pipe_buffer *buf)
{
return (struct intel_be_buffer *)buf;
}
static INLINE drm_intel_bo *
intel_bo(struct pipe_buffer *buf)
{
return intel_be_buffer(buf)->bo;
}
#endif
@@ -0,0 +1,38 @@
#ifndef INTEL_BE_FENCE_H
#define INTEL_BE_FENCE_H
#include "pipe/p_defines.h"
#include "drm.h"
#include "intel_bufmgr.h"
/**
* Because gem does not have fence's we have to create our own fences.
*
* They work by keeping the batchbuffer around and checking if that has
* been idled. If bo is NULL fence has expired.
*/
struct intel_be_fence
{
uint32_t refcount;
drm_intel_bo *bo;
};
static INLINE void
intel_be_fence_reference(struct intel_be_fence *f)
{
f->refcount++;
}
static INLINE void
intel_be_fence_unreference(struct intel_be_fence *f)
{
if (!--f->refcount) {
if (f->bo)
drm_intel_bo_unreference(f->bo);
free(f);
}
}
#endif
@@ -69,7 +69,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
nvbuf->base.usage = usage;
nvbuf->base.size = size;
flags = nouveau_flags_from_usage(nv, flags);
flags = nouveau_flags_from_usage(nv, usage);
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
FREE(nvbuf);
@@ -121,14 +121,9 @@ 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)) {
if (flags & PIPE_BUFFER_USAGE_DISCARD &&
!(flags & PIPE_BUFFER_USAGE_CPU_READ) &&
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;
@@ -42,7 +42,7 @@ nouveau_context_create(const __GLcontextModes *glVis,
if (nouveau_context_init(&nv_screen->base, driContextPriv->hHWContext,
(drmLock *)&driScrnPriv->pSAREA->lock,
nv_share, &nv->base)) {
&nv_share->base, &nv->base)) {
return GL_FALSE;
}
+3 -3
View File
@@ -113,7 +113,7 @@ swrastGetDrawableInfo(__DRIdrawable * draw,
int *x, int *y, int *w, int *h, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
__GLXDRIdrawable *pdraw = &(pdp->base);
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
@@ -141,7 +141,7 @@ swrastPutImage(__DRIdrawable * draw, int op,
int x, int y, int w, int h, char *data, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
__GLXDRIdrawable *pdraw = &(pdp->base);
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
XImage *ximage;
@@ -176,7 +176,7 @@ swrastGetImage(__DRIdrawable * draw,
int x, int y, int w, int h, char *data, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
__GLXDRIdrawable *pdraw = &(pdp->base);
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
XImage *ximage;
+2 -2
View File
@@ -220,14 +220,14 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
unsigned int length;
unsigned int i;
unsigned int num_attributes;
GLboolean use_glx_1_3;
if ((dpy == NULL) || (drawable == 0)) {
return 0;
}
priv = __glXInitialize(dpy);
GLboolean use_glx_1_3 = ((priv->majorVersion > 1)
|| (priv->minorVersion >= 3));
use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3));
*value = 0;
+2 -3
View File
@@ -365,7 +365,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
? opcode : __glXSetupForCommand(oldGC->currentDpy);
Bool bindReturnValue;
__GLXattribute *state;
if (!opcode || !oldOpcode) {
return GL_FALSE;
@@ -489,8 +489,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
} while (0);
#endif
__GLXattribute *state =
(__GLXattribute *) (gc->client_state_private);
state = (__GLXattribute *) (gc->client_state_private);
gc->currentContextTag = reply.contextTag;
if (state->array_state == NULL) {
+1 -1
View File
@@ -26,7 +26,7 @@
#include "main/imports.h"
#include "main/matrix.h"
#include "main/mtypes.h"
#include "GL/amesa.h"
#include "amesa.h"
struct amesa_visual
+3
View File
@@ -143,6 +143,9 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
ctx->Const.MaxCubeTextureLevels = 12;
ctx->Const.MaxTextureRectSize = (1<<11);
/* if conformance mode is set, swrast can handle any size AA point */
ctx->Const.MaxPointSizeAA = 255.0;
/* ctx->Const.MaxNativeVertexProgramTemps = 32; */
brw_init_attribs( brw );
+6
View File
@@ -111,9 +111,15 @@ static void brwProgramStringNotify( GLcontext *ctx,
struct gl_program *prog )
{
if (target == GL_FRAGMENT_PROGRAM_ARB) {
struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
struct brw_context *brw = brw_context(ctx);
struct brw_fragment_program *p = (struct brw_fragment_program *)prog;
struct brw_fragment_program *fp = (struct brw_fragment_program *)brw->fragment_program;
if (fprog->FogOption) {
_mesa_append_fog_code(ctx, fprog);
fprog->FogOption = GL_NONE;
}
if (p == fp)
brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
p->id = brw->program_id++;
+6 -5
View File
@@ -73,10 +73,12 @@ static void compile_sf_prog( struct brw_context *brw,
c.attr_to_idx[i] = idx;
c.idx_to_attr[idx] = i;
if (i >= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) {
c.point_attrs[i].CoordReplace =
brw->attribs.Point->CoordReplace[i - VERT_RESULT_TEX0];
} else
c.point_attrs[i].CoordReplace = GL_FALSE;
c.point_attrs[i].CoordReplace =
brw->attribs.Point->CoordReplace[i - VERT_RESULT_TEX0];
}
else {
c.point_attrs[i].CoordReplace = GL_FALSE;
}
idx++;
}
@@ -106,7 +108,6 @@ static void compile_sf_prog( struct brw_context *brw,
assert(0);
return;
}
/* get the program
*/
+1 -1
View File
@@ -229,7 +229,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
/* XXX clamp max depends on AA vs. non-AA */
sf.sf7.sprite_point = key->point_sprite;
sf.sf7.point_size = CLAMP(nearbyint(key->point_size), 1, 255) * (1<<3);
sf.sf7.point_size = CLAMP(rint(key->point_size), 1, 255) * (1<<3);
sf.sf7.use_point_size_state = !key->point_attenuated;
sf.sf7.aa_line_distance_mode = 0;
-52
View File
@@ -811,57 +811,6 @@ static void precalc_txp( struct brw_wm_compile *c,
/***********************************************************************
* Add instructions to perform fog blending
*/
static void fog_blend( struct brw_wm_compile *c,
struct prog_src_register fog_factor )
{
struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 );
/* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */
emit_op(c,
OPCODE_LRP,
dst_mask(outcolor, WRITEMASK_XYZ),
0, 0, 0,
fog_factor,
src_reg_from_dst(outcolor),
fogcolor);
}
/* This one is simple - just take the interpolated fog coordinate and
* use it as the fog blend factor.
*/
static void fog_interpolated( struct brw_wm_compile *c )
{
struct prog_src_register fogc = src_reg(PROGRAM_INPUT, FRAG_ATTRIB_FOGC);
if (!(c->fp_interp_emitted & (1<<FRAG_ATTRIB_FOGC)))
emit_interp(c, FRAG_ATTRIB_FOGC);
fog_blend( c, src_swizzle1(fogc, GET_SWZ(fogc.Swizzle,X)));
}
static void emit_fog( struct brw_wm_compile *c )
{
if (!c->fp->program.FogOption)
return;
if (1)
fog_interpolated( c );
else {
/* TODO: per-pixel fog */
assert(0);
}
}
static void emit_fb_write( struct brw_wm_compile *c )
{
struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
@@ -1059,7 +1008,6 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
emit_ddy(c, inst);
break;
case OPCODE_END:
emit_fog(c);
emit_fb_write(c);
break;
case OPCODE_PRINT:
+11 -7
View File
@@ -892,15 +892,19 @@ static void emit_lrp(struct brw_wm_compile *c,
}
}
/**
* For GLSL shaders, this KIL will be unconditional.
* It may be contained inside an IF/ENDIF structure of course.
*/
static void emit_kil(struct brw_wm_compile *c)
{
struct brw_compile *p = &c->func;
struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
brw_push_insn_state(p);
brw_set_mask_control(p, BRW_MASK_DISABLE);
brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
brw_AND(p, depth, c->emit_mask_reg, depth);
brw_pop_insn_state(p);
struct brw_compile *p = &c->func;
struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
brw_push_insn_state(p);
brw_set_mask_control(p, BRW_MASK_DISABLE);
brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
brw_AND(p, depth, c->emit_mask_reg, depth);
brw_pop_insn_state(p);
}
static void emit_mad(struct brw_wm_compile *c,

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