Merge commit 'origin/gallium-0.2' into gallium-xlib-rework
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ demo2
|
||||
demo3
|
||||
eglgears
|
||||
eglinfo
|
||||
eglscreen
|
||||
egltri
|
||||
peglgears
|
||||
xeglgears
|
||||
|
||||
@@ -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
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ progs = [
|
||||
'tri-blend-sub',
|
||||
'tri-blend',
|
||||
'tri-clip',
|
||||
'tri-clear',
|
||||
'tri-cull-both',
|
||||
'tri-cull',
|
||||
'tri-dlist',
|
||||
|
||||
+4
-6
@@ -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
@@ -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
|
||||
]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(PIPE_OS_WINDOWS) && defined(DEBUG)
|
||||
#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG)
|
||||
|
||||
/* memory debugging */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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){ \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -2,7 +2,7 @@ TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
SUBDIRS = common dri egl
|
||||
SUBDIRS = gem egl
|
||||
|
||||
|
||||
default: subdirs
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user