Merge branch 'master' into glsl2

This commit is contained in:
Ian Romanick 2010-08-13 20:22:46 -07:00
commit 443a7e4e9a
431 changed files with 10452 additions and 7673 deletions

View File

@ -123,7 +123,7 @@ GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) @GLUT_MESA_DEPS@ \
GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) @GLW_MESA_DEPS@ \
$(EXTRA_LIB_PATH) @GLW_LIB_DEPS@
APP_LIB_DEPS = $(EXTRA_LIB_PATH) @APP_LIB_DEPS@
GLESv1_CM_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv1_LIB_DEPS@
GLESv1_CM_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv1_CM_LIB_DEPS@
GLESv2_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv2_LIB_DEPS@
VG_LIB_DEPS = $(EXTRA_LIB_PATH) @VG_LIB_DEPS@

View File

@ -645,7 +645,7 @@ AC_SUBST([GL_PC_REQ_PRIV])
AC_SUBST([GL_PC_LIB_PRIV])
AC_SUBST([GL_PC_CFLAGS])
AC_SUBST([DRI_PC_REQ_PRIV])
AC_SUBST([GLESv1_LIB_DEPS])
AC_SUBST([GLESv1_CM_LIB_DEPS])
AC_SUBST([GLESv1_CM_PC_LIB_PRIV])
AC_SUBST([GLESv2_LIB_DEPS])
AC_SUBST([GLESv2_PC_LIB_PRIV])

View File

@ -177,9 +177,9 @@ EGLint dri2_to_egl_attribute_map[] = {
EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */
};
static void
static struct dri2_egl_config *
dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
int depth, xcb_visualtype_t *visual)
int depth, EGLint surface_type)
{
struct dri2_egl_config *conf;
struct dri2_egl_display *dri2_dpy;
@ -192,6 +192,10 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
_eglInitConfig(&base, disp, id);
i = 0;
double_buffer = 0;
bind_to_texture_rgb = 0;
bind_to_texture_rgba = 0;
while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) {
switch (attrib) {
case __DRI_ATTRIB_RENDER_TYPE:
@ -242,35 +246,27 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
* return in the getBuffer callback to get the behaviour we want. */
if (double_buffer)
return;
return NULL;
if (visual != NULL) {
if (depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE))
return;
_eglSetConfigKey(&base, EGL_SURFACE_TYPE,
EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_BIT);
_eglSetConfigKey(&base, EGL_NATIVE_VISUAL_ID, visual->visual_id);
_eglSetConfigKey(&base, EGL_NATIVE_VISUAL_TYPE, visual->_class);
} else {
_eglSetConfigKey(&base, EGL_SURFACE_TYPE,
EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
}
if (depth > 0 && depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE))
return NULL;
_eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE);
_eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb);
if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0)
_eglSetConfigKey(&base,
EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba);
_eglSetConfigKey(&base, EGL_SURFACE_TYPE, surface_type);
if (surface_type & (EGL_PIXMAP_BIT | EGL_PBUFFER_BIT)) {
_eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb);
if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0)
_eglSetConfigKey(&base,
EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba);
}
_eglSetConfigKey(&base, EGL_RENDERABLE_TYPE, disp->ClientAPIsMask);
_eglSetConfigKey(&base, EGL_CONFORMANT, disp->ClientAPIsMask);
if (!_eglValidateConfig(&base, EGL_FALSE)) {
_eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id);
return;
return NULL;
}
conf = malloc(sizeof *conf);
@ -279,6 +275,8 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
conf->dri_config = dri_config;
_eglAddConfig(disp, &conf->base);
}
return conf;
}
/**
@ -613,10 +611,19 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
xcb_depth_iterator_t d;
xcb_visualtype_t *visuals;
int i, j, id;
struct dri2_egl_config *conf;
EGLint surface_type;
s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
d = xcb_screen_allowed_depths_iterator(s.data);
id = 1;
surface_type =
EGL_WINDOW_BIT |
EGL_PIXMAP_BIT |
EGL_PBUFFER_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
while (d.rem > 0) {
EGLBoolean class_added[6] = { 0, };
@ -626,9 +633,16 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
continue;
class_added[visuals[i]._class] = EGL_TRUE;
for (j = 0; dri2_dpy->driver_configs[j]; j++)
dri2_add_config(disp, dri2_dpy->driver_configs[j],
id++, d.data->depth, &visuals[i]);
for (j = 0; dri2_dpy->driver_configs[j]; j++) {
conf = dri2_add_config(disp, dri2_dpy->driver_configs[j],
id++, d.data->depth, surface_type);
if (conf == NULL)
continue;
_eglSetConfigKey(&conf->base,
EGL_NATIVE_VISUAL_ID, visuals[i].visual_id);
_eglSetConfigKey(&conf->base,
EGL_NATIVE_VISUAL_TYPE, visuals[i]._class);
}
}
xcb_depth_next(&d);
@ -738,6 +752,12 @@ dri2_create_screen(_EGLDisplay *disp)
if (api_mask & (1 << __DRI_API_GLES2))
disp->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
if (dri2_dpy->dri2->base.version >= 2) {
disp->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
disp->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
disp->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
}
return EGL_TRUE;
cleanup_dri_screen:
@ -948,6 +968,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp,
EGLint *major, EGLint *minor)
{
struct dri2_egl_display *dri2_dpy;
int i;
dri2_dpy = malloc(sizeof *dri2_dpy);
if (!dri2_dpy)
@ -970,10 +991,17 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp,
if (!dri2_create_screen(disp))
goto cleanup_driver;
for (i = 0; dri2_dpy->driver_configs[i]; i++)
dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, 0);
disp->Extensions.KHR_image_base = EGL_TRUE;
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
/* we're supporting EGL 1.4 */
*major = 1;
*minor = 4;
return EGL_TRUE;
cleanup_driver:
@ -1041,6 +1069,7 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list);
struct dri2_egl_config *dri2_config = dri2_egl_config(conf);
const __DRIconfig *dri_config;
int api;
dri2_ctx = malloc(sizeof *dri2_ctx);
@ -1074,11 +1103,16 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
if (conf != NULL)
dri_config = dri2_config->dri_config;
else
dri_config = NULL;
if (dri2_dpy->dri2->base.version >= 2) {
dri2_ctx->dri_context =
dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen,
api,
dri2_config->dri_config,
dri_config,
dri2_ctx_shared ?
dri2_ctx_shared->dri_context : NULL,
dri2_ctx);

View File

@ -379,7 +379,11 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
_EGLContext *context;
EGLContext ret;
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
if (config)
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
else
drv = _eglCheckDisplay(disp, __FUNCTION__);
if (!share && share_list != EGL_NO_CONTEXT)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);

View File

@ -314,8 +314,10 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
EGL_VG_ALPHA_FORMAT_PRE_BIT |
EGL_MULTISAMPLE_RESOLVE_BOX_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
#ifdef EGL_MESA_screen_surface
if (conf->Display->Extensions.MESA_screen_surface)
mask |= EGL_SCREEN_BIT_MESA;
#endif
break;
case EGL_RENDERABLE_TYPE:
case EGL_CONFORMANT:

View File

@ -83,7 +83,7 @@ _eglParseContextAttribList(_EGLContext *ctx, const EGLint *attrib_list)
}
}
if (err == EGL_SUCCESS) {
if (err == EGL_SUCCESS && ctx->Config) {
EGLint renderable_type, api_bit;
renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE);
@ -220,45 +220,49 @@ _eglBindContextToSurfaces(_EGLContext *newCtx,
* surface (oldDraw), the old bindings are broken first and the new one is
* created.
*/
oldCtx = newDraw->CurrentContext;
if (newCtx != oldCtx) {
if (oldCtx) {
assert(oldCtx->DrawSurface == newDraw);
oldCtx->DrawSurface = NULL;
if (newDraw) {
oldCtx = newDraw->CurrentContext;
if (newCtx != oldCtx) {
if (oldCtx) {
assert(oldCtx->DrawSurface == newDraw);
oldCtx->DrawSurface = NULL;
}
newDraw->CurrentContext = newCtx;
}
}
if (newCtx) {
_EGLSurface *oldDraw = newCtx->DrawSurface;
if (oldDraw)
oldDraw->CurrentContext = NULL;
if (newCtx) {
_EGLSurface *oldDraw = newCtx->DrawSurface;
if (oldDraw)
oldDraw->CurrentContext = NULL;
newCtx->DrawSurface = newDraw;
*draw = oldDraw;
}
newDraw->CurrentContext = newCtx;
newCtx->DrawSurface = newDraw;
*draw = oldDraw;
}
/* likewise */
if (newRead != newDraw)
if (newRead && newRead != newDraw) {
oldCtx = newRead->CurrentContext;
if (newCtx != oldCtx) {
if (oldCtx) {
assert(oldCtx->ReadSurface == newRead);
oldCtx->ReadSurface = NULL;
if (newCtx != oldCtx) {
if (oldCtx) {
assert(oldCtx->ReadSurface == newRead);
oldCtx->ReadSurface = NULL;
}
newRead->CurrentContext = newCtx;
}
if (newCtx) {
_EGLSurface *oldRead = newCtx->ReadSurface;
if (oldRead)
oldRead->CurrentContext = NULL;
newCtx->ReadSurface = newRead;
*read = oldRead;
}
newRead->CurrentContext = newCtx;
}
if (newCtx) {
_EGLSurface *oldRead = newCtx->ReadSurface;
if (oldRead)
oldRead->CurrentContext = NULL;
newCtx->ReadSurface = newRead;
*read = oldRead;
}
}
@ -297,7 +301,9 @@ static EGLBoolean
_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
_EGLDisplay *dpy;
EGLint conflict_api;
EGLBoolean surfaceless;
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
@ -309,8 +315,23 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
return EGL_TRUE;
}
/* ctx/draw/read must be all given */
if (draw == NULL || read == NULL)
dpy = ctx->Resource.Display;
switch (_eglGetContextAPIBit(ctx)) {
case EGL_OPENGL_ES_BIT:
surfaceless = dpy->Extensions.KHR_surfaceless_gles1;
break;
case EGL_OPENGL_ES2_BIT:
surfaceless = dpy->Extensions.KHR_surfaceless_gles2;
break;
case EGL_OPENGL_BIT:
surfaceless = dpy->Extensions.KHR_surfaceless_opengl;
break;
default:
surfaceless = EGL_FALSE;
break;
}
if (!surfaceless && (draw == NULL || read == NULL))
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
/* context stealing from another thread is not allowed */
@ -331,12 +352,13 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
*
* The latter is more restrictive so we can check only the latter case.
*/
if ((draw->CurrentContext && draw->CurrentContext != ctx) ||
(read->CurrentContext && read->CurrentContext != ctx))
if ((draw && draw->CurrentContext && draw->CurrentContext != ctx) ||
(read && read->CurrentContext && read->CurrentContext != ctx))
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
/* simply require the configs to be equal */
if (draw->Config != ctx->Config || read->Config != ctx->Config)
if ((draw && draw->Config != ctx->Config) ||
(read && read->Config != ctx->Config))
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
switch (ctx->ClientAPI) {
@ -387,7 +409,6 @@ _eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read)
*draw = oldCtx->DrawSurface;
*read = oldCtx->ReadSurface;
assert(*draw && *read);
_eglBindContextToSurfaces(NULL, draw, read);
}

View File

@ -1,9 +1,9 @@
#include <stdlib.h>
#include <string.h>
#include "eglglobals.h"
#include "egllog.h"
#include "eglmutex.h"
#include "eglcurrent.h"
#include "eglglobals.h"
/* This should be kept in sync with _eglInitThreadInfo() */
@ -300,12 +300,14 @@ _eglError(EGLint errCode, const char *msg)
case EGL_BAD_SURFACE:
s = "EGL_BAD_SURFACE";
break;
#ifdef EGL_MESA_screen_surface
case EGL_BAD_SCREEN_MESA:
s = "EGL_BAD_SCREEN_MESA";
break;
case EGL_BAD_MODE_MESA:
s = "EGL_BAD_MODE_MESA";
break;
#endif
default:
s = "other";
}

View File

@ -60,6 +60,9 @@ struct _egl_extensions
EGLBoolean KHR_gl_texture_cubemap_image;
EGLBoolean KHR_gl_texture_3D_image;
EGLBoolean KHR_gl_renderbuffer_image;
EGLBoolean KHR_surfaceless_gles1;
EGLBoolean KHR_surfaceless_gles2;
EGLBoolean KHR_surfaceless_opengl;
EGLBoolean NOK_swap_region;
EGLBoolean NOK_texture_from_pixmap;

View File

@ -14,7 +14,6 @@
#include "egldefines.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "egllog.h"
#include "eglmisc.h"
#include "eglmode.h"

View File

@ -11,7 +11,6 @@ struct _egl_global _eglGlobal =
{
&_eglGlobalMutex, /* Mutex */
NULL, /* DisplayList */
1, /* FreeScreenHandle */
2, /* NumAtExitCalls */
{
/* default AtExitCalls, called in reverse order */

View File

@ -16,8 +16,6 @@ struct _egl_global
/* the list of all displays */
_EGLDisplay *DisplayList;
EGLScreenMESA FreeScreenHandle;
EGLint NumAtExitCalls;
void (*AtExitCalls[10])(void);
};

View File

@ -97,6 +97,10 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
_EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
_EGL_CHECK_EXTENSION(KHR_surfaceless_gles1);
_EGL_CHECK_EXTENSION(KHR_surfaceless_gles2);
_EGL_CHECK_EXTENSION(KHR_surfaceless_opengl);
_EGL_CHECK_EXTENSION(NOK_swap_region);
_EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
#undef _EGL_CHECK_EXTENSION

View File

@ -10,6 +10,9 @@
#include "eglstring.h"
#ifdef EGL_MESA_screen_surface
#define MIN2(A, B) (((A) < (B)) ? (A) : (B))
@ -353,3 +356,6 @@ _eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m)
{
return m->Name;
}
#endif /* EGL_MESA_screen_surface */

View File

@ -4,6 +4,9 @@
#include "egltypedefs.h"
#ifdef EGL_MESA_screen_surface
#define EGL_NO_MODE_MESA 0
@ -54,4 +57,7 @@ extern const char *
_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m);
#endif /* EGL_MESA_screen_surface */
#endif /* EGLMODE_INCLUDED */

View File

@ -16,7 +16,6 @@
#include <string.h>
#include "egldisplay.h"
#include "eglglobals.h"
#include "eglcurrent.h"
#include "eglmode.h"
#include "eglconfig.h"
@ -25,6 +24,14 @@
#include "eglmutex.h"
#ifdef EGL_MESA_screen_surface
/* ugh, no atomic op? */
static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex);
static EGLScreenMESA _eglNextScreenHandle = 1;
/**
* Return a new screen handle/ID.
* NOTE: we never reuse these!
@ -33,10 +40,10 @@ static EGLScreenMESA
_eglAllocScreenHandle(void)
{
EGLScreenMESA s;
_eglLockMutex(_eglGlobal.Mutex);
s = _eglGlobal.FreeScreenHandle++;
_eglUnlockMutex(_eglGlobal.Mutex);
_eglLockMutex(&_eglNextScreenHandleMutex);
s = _eglNextScreenHandle++;
_eglUnlockMutex(&_eglNextScreenHandleMutex);
return s;
}
@ -263,3 +270,5 @@ _eglDestroyScreen(_EGLScreen *scrn)
free(scrn);
}
#endif /* EGL_MESA_screen_surface */

View File

@ -5,6 +5,9 @@
#include "egltypedefs.h"
#ifdef EGL_MESA_screen_surface
/**
* Per-screen information.
* Note that an EGL screen doesn't have a size. A screen may be set to
@ -86,4 +89,7 @@ PUBLIC void
_eglDestroyScreen(_EGLScreen *scrn);
#endif /* EGL_MESA_screen_surface */
#endif /* EGLSCREEN_INCLUDED */

View File

@ -30,6 +30,50 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
}
#ifdef EGL_MESA_screen_surface
static EGLint
_eglParseScreenSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
{
EGLint i, err = EGL_SUCCESS;
if (!attrib_list)
return EGL_SUCCESS;
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
EGLint attr = attrib_list[i++];
EGLint val = attrib_list[i];
switch (attr) {
case EGL_WIDTH:
if (val < 0) {
err = EGL_BAD_PARAMETER;
break;
}
surf->Width = val;
break;
case EGL_HEIGHT:
if (val < 0) {
err = EGL_BAD_PARAMETER;
break;
}
surf->Height = val;
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
if (err != EGL_SUCCESS) {
_eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
break;
}
}
return err;
}
#endif /* EGL_MESA_screen_surface */
/**
* Parse the list of surface attributes and return the proper error code.
*/
@ -44,6 +88,11 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
if (!attrib_list)
return EGL_SUCCESS;
#ifdef EGL_MESA_screen_surface
if (type == EGL_SCREEN_BIT_MESA)
return _eglParseScreenSurfaceAttribList(surf, attrib_list);
#endif
if (dpy->Extensions.NOK_texture_from_pixmap)
texture_type |= EGL_PIXMAP_BIT;
@ -52,12 +101,8 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
EGLint val = attrib_list[i];
switch (attr) {
/* common (except for screen surfaces) attributes */
/* common attributes */
case EGL_VG_COLORSPACE:
if (type == EGL_SCREEN_BIT_MESA) {
err = EGL_BAD_ATTRIBUTE;
break;
}
switch (val) {
case EGL_VG_COLORSPACE_sRGB:
case EGL_VG_COLORSPACE_LINEAR:
@ -71,10 +116,6 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
surf->VGColorspace = val;
break;
case EGL_VG_ALPHA_FORMAT:
if (type == EGL_SCREEN_BIT_MESA) {
err = EGL_BAD_ATTRIBUTE;
break;
}
switch (val) {
case EGL_VG_ALPHA_FORMAT_NONPRE:
case EGL_VG_ALPHA_FORMAT_PRE:
@ -101,7 +142,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
break;
/* pbuffer surface attributes */
case EGL_WIDTH:
if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) {
if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
@ -112,7 +153,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
surf->Width = val;
break;
case EGL_HEIGHT:
if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) {
if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
@ -129,6 +170,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
}
surf->LargestPbuffer = !!val;
break;
/* for eglBindTexImage */
case EGL_TEXTURE_FORMAT:
if (!(type & texture_type)) {
err = EGL_BAD_ATTRIBUTE;
@ -210,10 +252,12 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
case EGL_PBUFFER_BIT:
func = "eglCreatePBufferSurface";
break;
#ifdef EGL_MESA_screen_surface
case EGL_SCREEN_BIT_MESA:
func = "eglCreateScreenSurface";
renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
break;
#endif
default:
_eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
return EGL_FALSE;

View File

@ -149,6 +149,7 @@ C_SOURCES = \
GALLIVM_SOURCES = \
gallivm/lp_bld_arit.c \
gallivm/lp_bld_assert.c \
gallivm/lp_bld_const.c \
gallivm/lp_bld_conv.c \
gallivm/lp_bld_debug.c \

View File

@ -34,14 +34,14 @@ env.CodeGenerate(
target = 'util/u_format_table.c',
script = '#src/gallium/auxiliary/util/u_format_table.py',
source = ['#src/gallium/auxiliary/util/u_format.csv'],
command = 'python $SCRIPT $SOURCE > $TARGET'
command = python_cmd + ' $SCRIPT $SOURCE > $TARGET'
)
env.CodeGenerate(
target = 'util/u_half.c',
script = 'util/u_half.py',
source = [],
command = 'python $SCRIPT > $TARGET'
command = python_cmd + ' $SCRIPT > $TARGET'
)
env.Depends('util/u_format_table.c', [
@ -198,6 +198,7 @@ source = [
if env['llvm']:
source += [
'gallivm/lp_bld_arit.c',
'gallivm/lp_bld_assert.c',
'gallivm/lp_bld_const.c',
'gallivm/lp_bld_conv.c',
'gallivm/lp_bld_debug.c',

View File

@ -288,12 +288,19 @@ draw_set_mapped_constant_buffer(struct draw_context *draw,
shader_type == PIPE_SHADER_GEOMETRY);
debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS);
if (shader_type == PIPE_SHADER_VERTEX) {
switch (shader_type) {
case PIPE_SHADER_VERTEX:
draw->pt.user.vs_constants[slot] = buffer;
draw->pt.user.vs_constants_size[slot] = size;
draw_vs_set_constants(draw, slot, buffer, size);
} else if (shader_type == PIPE_SHADER_GEOMETRY) {
break;
case PIPE_SHADER_GEOMETRY:
draw->pt.user.gs_constants[slot] = buffer;
draw->pt.user.gs_constants_size[slot] = size;
draw_gs_set_constants(draw, slot, buffer, size);
break;
default:
assert(0 && "invalid shader type in draw_set_mapped_constant_buffer");
}
}

View File

@ -0,0 +1,425 @@
/*
* Mesa 3-D graphics library
* Version: 7.9
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* Copyright (C) 2010 LunarG Inc.
*
* 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 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
* Chia-I Wu <olv@lunarg.com>
*/
/* these macros are optional */
#ifndef LOCAL_VARS
#define LOCAL_VARS
#endif
#ifndef FUNC_ENTER
#define FUNC_ENTER do {} while (0)
#endif
#ifndef FUNC_EXIT
#define FUNC_EXIT do {} while (0)
#endif
#ifndef LINE_ADJ
#define LINE_ADJ(flags, a0, i0, i1, a1) LINE(flags, i0, i1)
#endif
#ifndef TRIANGLE_ADJ
#define TRIANGLE_ADJ(flags, i0, a0, i1, a1, i2, a2) TRIANGLE(flags, i0, i1, i2)
#endif
static void
FUNC(FUNC_VARS)
{
unsigned idx[6], i;
ushort flags;
LOCAL_VARS
FUNC_ENTER;
/* prim, count, and last_vertex_last should have been defined */
if (0) {
debug_printf("%s: prim 0x%x, count %d, last_vertex_last %d\n",
__FUNCTION__, prim, count, last_vertex_last);
}
switch (prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i++) {
idx[0] = GET_ELT(i);
POINT(idx[0]);
}
break;
case PIPE_PRIM_LINES:
flags = DRAW_PIPE_RESET_STIPPLE;
for (i = 0; i + 1 < count; i += 2) {
idx[0] = GET_ELT(i);
idx[1] = GET_ELT(i + 1);
LINE(flags, idx[0], idx[1]);
}
break;
case PIPE_PRIM_LINE_LOOP:
case PIPE_PRIM_LINE_STRIP:
if (count >= 2) {
flags = DRAW_PIPE_RESET_STIPPLE;
idx[1] = GET_ELT(0);
idx[2] = idx[1];
for (i = 1; i < count; i++, flags = 0) {
idx[0] = idx[1];
idx[1] = GET_ELT(i);
LINE(flags, idx[0], idx[1]);
}
/* close the loop */
if (prim == PIPE_PRIM_LINE_LOOP)
LINE(flags, idx[1], idx[2]);
}
break;
case PIPE_PRIM_TRIANGLES:
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
for (i = 0; i + 2 < count; i += 3) {
idx[0] = GET_ELT(i);
idx[1] = GET_ELT(i + 1);
idx[2] = GET_ELT(i + 2);
TRIANGLE(flags, idx[0], idx[1], idx[2]);
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
if (count >= 3) {
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
idx[1] = GET_ELT(0);
idx[2] = GET_ELT(1);
if (last_vertex_last) {
for (i = 0; i + 2 < count; i++) {
idx[0] = idx[1];
idx[1] = idx[2];
idx[2] = GET_ELT(i + 2);
/* always emit idx[2] last */
if (i & 1)
TRIANGLE(flags, idx[1], idx[0], idx[2]);
else
TRIANGLE(flags, idx[0], idx[1], idx[2]);
}
}
else {
for (i = 0; i + 2 < count; i++) {
idx[0] = idx[1];
idx[1] = idx[2];
idx[2] = GET_ELT(i + 2);
/* always emit idx[0] first */
if (i & 1)
TRIANGLE(flags, idx[0], idx[2], idx[1]);
else
TRIANGLE(flags, idx[0], idx[1], idx[2]);
}
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
idx[0] = GET_ELT(0);
idx[2] = GET_ELT(1);
/* idx[0] is neither the first nor the last vertex */
if (last_vertex_last) {
for (i = 0; i + 2 < count; i++) {
idx[1] = idx[2];
idx[2] = GET_ELT(i + 2);
/* always emit idx[2] last */
TRIANGLE(flags, idx[0], idx[1], idx[2]);
}
}
else {
for (i = 0; i + 2 < count; i++) {
idx[1] = idx[2];
idx[2] = GET_ELT(i + 2);
/* always emit idx[1] first */
TRIANGLE(flags, idx[1], idx[2], idx[0]);
}
}
}
break;
case PIPE_PRIM_QUADS:
if (last_vertex_last) {
for (i = 0; i + 3 < count; i += 4) {
idx[0] = GET_ELT(i);
idx[1] = GET_ELT(i + 1);
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_2;
/* always emit idx[3] last */
TRIANGLE(flags, idx[0], idx[1], idx[3]);
flags = DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
TRIANGLE(flags, idx[1], idx[2], idx[3]);
}
}
else {
for (i = 0; i + 3 < count; i += 4) {
idx[0] = GET_ELT(i);
idx[1] = GET_ELT(i + 1);
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
/* XXX should always emit idx[0] first */
/* always emit idx[3] first */
TRIANGLE(flags, idx[3], idx[0], idx[1]);
flags = DRAW_PIPE_EDGE_FLAG_1 |
DRAW_PIPE_EDGE_FLAG_2;
TRIANGLE(flags, idx[3], idx[1], idx[2]);
}
}
break;
case PIPE_PRIM_QUAD_STRIP:
if (count >= 4) {
idx[2] = GET_ELT(0);
idx[3] = GET_ELT(1);
if (last_vertex_last) {
for (i = 0; i + 3 < count; i += 2) {
idx[0] = idx[2];
idx[1] = idx[3];
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
/* always emit idx[3] last */
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_2;
TRIANGLE(flags, idx[2], idx[0], idx[3]);
flags = DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
TRIANGLE(flags, idx[0], idx[1], idx[3]);
}
}
else {
for (i = 0; i + 3 < count; i += 2) {
idx[0] = idx[2];
idx[1] = idx[3];
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
/* XXX should always emit idx[0] first */
/* always emit idx[3] first */
TRIANGLE(flags, idx[3], idx[2], idx[0]);
flags = DRAW_PIPE_EDGE_FLAG_1 |
DRAW_PIPE_EDGE_FLAG_2;
TRIANGLE(flags, idx[3], idx[0], idx[1]);
}
}
}
break;
case PIPE_PRIM_POLYGON:
if (count >= 3) {
ushort edge_next, edge_finish;
if (last_vertex_last) {
flags = (DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_2 |
DRAW_PIPE_EDGE_FLAG_0);
edge_next = DRAW_PIPE_EDGE_FLAG_0;
edge_finish = DRAW_PIPE_EDGE_FLAG_1;
}
else {
flags = (DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1);
edge_next = DRAW_PIPE_EDGE_FLAG_1;
edge_finish = DRAW_PIPE_EDGE_FLAG_2;
}
idx[0] = GET_ELT(0);
idx[2] = GET_ELT(1);
for (i = 0; i + 2 < count; i++, flags = edge_next) {
idx[1] = idx[2];
idx[2] = GET_ELT(i + 2);
if (i + 3 == count)
flags |= edge_finish;
/* idx[0] is both the first and the last vertex */
if (last_vertex_last)
TRIANGLE(flags, idx[1], idx[2], idx[0]);
else
TRIANGLE(flags, idx[0], idx[1], idx[2]);
}
}
break;
case PIPE_PRIM_LINES_ADJACENCY:
flags = DRAW_PIPE_RESET_STIPPLE;
for (i = 0; i + 3 < count; i += 4) {
idx[0] = GET_ELT(i);
idx[1] = GET_ELT(i + 1);
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);
}
break;
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
if (count >= 4) {
flags = DRAW_PIPE_RESET_STIPPLE;
idx[1] = GET_ELT(0);
idx[2] = GET_ELT(1);
idx[3] = GET_ELT(2);
for (i = 1; i + 2 < count; i++, flags = 0) {
idx[0] = idx[1];
idx[1] = idx[2];
idx[2] = idx[3];
idx[3] = GET_ELT(i + 2);
LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);
}
}
break;
case PIPE_PRIM_TRIANGLES_ADJACENCY:
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
for (i = 0; i + 5 < count; i += 6) {
idx[0] = GET_ELT(i);
idx[1] = GET_ELT(i + 1);
idx[2] = GET_ELT(i + 2);
idx[3] = GET_ELT(i + 3);
idx[4] = GET_ELT(i + 4);
idx[5] = GET_ELT(i + 5);
TRIANGLE_ADJ(flags, idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
}
break;
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
if (count >= 6) {
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
idx[0] = GET_ELT(1);
idx[2] = GET_ELT(0);
idx[4] = GET_ELT(2);
idx[3] = GET_ELT(4);
/*
* The vertices of the i-th triangle are stored in
* idx[0,2,4] = { 2*i, 2*i+2, 2*i+4 };
*
* The adjacent vertices are stored in
* idx[1,3,5] = { 2*i-2, 2*i+6, 2*i+3 }.
*
* However, there are two exceptions:
*
* For the first triangle, idx[1] = 1;
* For the last triangle, idx[3] = 2*i+5.
*/
if (last_vertex_last) {
for (i = 0; i + 5 < count; i += 2) {
idx[1] = idx[0];
idx[0] = idx[2];
idx[2] = idx[4];
idx[4] = idx[3];
idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));
idx[5] = GET_ELT(i + 3);
/*
* alternate the first two vertices (idx[0] and idx[2]) and the
* corresponding adjacent vertices (idx[3] and idx[5]) to have
* the correct orientation
*/
if (i & 2) {
TRIANGLE_ADJ(flags,
idx[2], idx[1], idx[0], idx[5], idx[4], idx[3]);
}
else {
TRIANGLE_ADJ(flags,
idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
}
}
}
else {
for (i = 0; i + 5 < count; i += 2) {
idx[1] = idx[0];
idx[0] = idx[2];
idx[2] = idx[4];
idx[4] = idx[3];
idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));
idx[5] = GET_ELT(i + 3);
/*
* alternate the last two vertices (idx[2] and idx[4]) and the
* corresponding adjacent vertices (idx[1] and idx[5]) to have
* the correct orientation
*/
if (i & 2) {
TRIANGLE_ADJ(flags,
idx[0], idx[5], idx[4], idx[3], idx[2], idx[1]);
}
else {
TRIANGLE_ADJ(flags,
idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
}
}
}
}
break;
default:
assert(0);
break;
}
FUNC_EXIT;
}
#undef LOCAL_VARS
#undef FUNC_ENTER
#undef FUNC_EXIT
#undef LINE_ADJ
#undef TRIANGLE_ADJ
#undef FUNC
#undef FUNC_VARS
#undef GET_ELT
#undef POINT
#undef LINE
#undef TRIANGLE

View File

@ -1,6 +1,6 @@
/**************************************************************************
*
* Copyright 2009 VMWare Inc.
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -75,7 +75,10 @@ draw_gs_set_constants(struct draw_context *draw,
const void *constants,
unsigned size)
{
/* noop */
/* noop. added here for symmetry with the VS
* code and in case we'll ever want to allign
* the constants, e.g. when we'll change to a
* different interpreter */
}
@ -370,32 +373,23 @@ static void gs_tri_adj(struct draw_geometry_shader *shader,
gs_flush(shader, 1);
}
#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,i0,i1,i2)
#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5)
#define LINE(gs,i0,i1) gs_line(gs,i0,i1)
#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3)
#define POINT(gs,i0) gs_point(gs,i0)
#define FUNC gs_run
#define LOCAL_VARS
#define FUNC gs_run
#define GET_ELT(idx) (idx)
#include "draw_gs_tmp.h"
#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,elts[i0],elts[i1],elts[i2])
#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) \
gs_tri_adj(gs,elts[i0],elts[i1],elts[i2],elts[i3], \
elts[i4],elts[i5])
#define LINE(gs,i0,i1) gs_line(gs,elts[i0],elts[i1])
#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,elts[i0], \
elts[i1], \
elts[i2],elts[i3])
#define POINT(gs,i0) gs_point(gs,elts[i0])
#define FUNC gs_run_elts
#define LOCAL_VARS \
const ushort *elts = input_prims->elts;
#define FUNC gs_run_elts
#define LOCAL_VARS const ushort *elts = input_prims->elts;
#define GET_ELT(idx) (elts[idx] & ~DRAW_PIPE_FLAG_MASK)
#include "draw_gs_tmp.h"
/**
* Execute geometry shader using TGSI interpreter.
*/
int draw_geometry_shader_run(struct draw_geometry_shader *shader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts,
const struct draw_prim_info *input_prim,
struct draw_vertex_info *output_verts,
@ -405,7 +399,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
unsigned input_stride = input_verts->vertex_size;
unsigned vertex_size = input_verts->vertex_size;
struct tgsi_exec_machine *machine = shader->machine;
unsigned int i;
unsigned num_input_verts = input_prim->linear ?
input_verts->count :
input_prim->count;
@ -447,9 +440,8 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
}
shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));
for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
machine->Consts[i] = constants[i];
}
tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
constants, constants_size);
if (input_prim->linear)
gs_run(shader, input_prim, input_verts,

View File

@ -1,6 +1,6 @@
/**************************************************************************
*
* Copyright 2009 VMWare Inc.
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -73,6 +73,7 @@ struct draw_geometry_shader {
*/
int draw_geometry_shader_run(struct draw_geometry_shader *shader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts,
const struct draw_prim_info *input_prim,
struct draw_vertex_info *output_verts,

View File

@ -1,152 +1,34 @@
#define FUNC_VARS struct draw_geometry_shader *gs, \
const struct draw_prim_info *input_prims, \
const struct draw_vertex_info *input_verts, \
struct draw_prim_info *output_prims, \
struct draw_vertex_info *output_verts
static void FUNC( struct draw_geometry_shader *shader,
const struct draw_prim_info *input_prims,
const struct draw_vertex_info *input_verts,
struct draw_prim_info *output_prims,
struct draw_vertex_info *output_verts)
{
struct draw_context *draw = shader->draw;
#define FUNC_ENTER \
/* declare more local vars */ \
struct draw_context *draw = gs->draw; \
const unsigned prim = input_prims->prim; \
const unsigned count = input_prims->count; \
const boolean last_vertex_last = \
!(draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
do { \
debug_assert(input_prims->primitive_count == 1); \
switch (prim) { \
case PIPE_PRIM_QUADS: \
case PIPE_PRIM_QUAD_STRIP: \
case PIPE_PRIM_POLYGON: \
debug_assert(!"unexpected primitive type in GS"); \
return; \
default: \
break; \
} \
} while (0) \
boolean flatfirst = (draw->rasterizer->flatshade &&
draw->rasterizer->flatshade_first);
unsigned i, j;
unsigned count = input_prims->count;
LOCAL_VARS
#define POINT(i0) gs_point(gs,i0)
#define LINE(flags,i0,i1) gs_line(gs,i0,i1)
#define TRIANGLE(flags,i0,i1,i2) gs_tri(gs,i0,i1,i2)
#define LINE_ADJ(flags,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3)
#define TRIANGLE_ADJ(flags,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5)
if (0) debug_printf("%s %d\n", __FUNCTION__, count);
debug_assert(input_prims->primitive_count == 1);
switch (input_prims->prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i++) {
POINT( shader, i + 0 );
}
break;
case PIPE_PRIM_LINES:
for (i = 0; i+1 < count; i += 2) {
LINE( shader , i + 0 , i + 1 );
}
break;
case PIPE_PRIM_LINE_LOOP:
if (count >= 2) {
for (i = 1; i < count; i++) {
LINE( shader, i - 1, i );
}
LINE( shader, i - 1, 0 );
}
break;
case PIPE_PRIM_LINE_STRIP:
for (i = 1; i < count; i++) {
LINE( shader, i - 1, i );
}
break;
case PIPE_PRIM_TRIANGLES:
for (i = 0; i+2 < count; i += 3) {
TRIANGLE( shader, i + 0, i + 1, i + 2 );
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( shader,
i + 0,
i + 1 + (i&1),
i + 2 - (i&1) );
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( shader,
i + 0 + (i&1),
i + 1 - (i&1),
i + 2 );
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( shader,
i + 1,
i + 2,
0 );
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( shader,
0,
i + 1,
i + 2 );
}
}
}
break;
case PIPE_PRIM_POLYGON:
{
for (i = 0; i+2 < count; i++) {
if (flatfirst) {
TRIANGLE( shader, 0, i + 1, i + 2 );
}
else {
TRIANGLE( shader, i + 1, i + 2, 0 );
}
}
}
break;
case PIPE_PRIM_LINES_ADJACENCY:
for (i = 0; i+3 < count; i += 4) {
LINE_ADJ( shader , i + 0 , i + 1, i + 2, i + 3 );
}
break;
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
for (i = 1; i + 2 < count; i++) {
LINE_ADJ( shader, i - 1, i, i + 1, i + 2 );
}
break;
case PIPE_PRIM_TRIANGLES_ADJACENCY:
for (i = 0; i+5 < count; i += 5) {
TRI_ADJ( shader, i + 0, i + 1, i + 2,
i + 3, i + 4, i + 5);
}
break;
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
for (i = 0, j = 0; i+5 < count; i += 2, ++j) {
TRI_ADJ( shader,
i + 0,
i + 1 + 2*(j&1),
i + 2 + 2*(j&1),
i + 3 - 2*(j&1),
i + 4 - 2*(j&1),
i + 5);
}
break;
default:
debug_assert(!"Unsupported primitive in geometry shader");
break;
}
}
#undef TRIANGLE
#undef TRI_ADJ
#undef POINT
#undef LINE
#undef LINE_ADJ
#undef FUNC
#undef LOCAL_VARS
#include "draw_decompose_tmp.h"

View File

@ -37,6 +37,8 @@
#include "gallivm/lp_bld_debug.h"
#include "gallivm/lp_bld_tgsi.h"
#include "gallivm/lp_bld_printf.h"
#include "gallivm/lp_bld_intr.h"
#include "gallivm/lp_bld_init.h"
#include "tgsi/tgsi_exec.h"
#include "tgsi/tgsi_dump.h"
@ -793,6 +795,11 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
sampler->destroy(sampler);
#ifdef PIPE_ARCH_X86
/* Avoid corrupting the FPU stack on 32bit OSes. */
lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0);
#endif
LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(builder);
@ -820,6 +827,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(code);
}
lp_func_delete_body(variant->function);
}
@ -963,6 +971,11 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
sampler->destroy(sampler);
#ifdef PIPE_ARCH_X86
/* Avoid corrupting the FPU stack on 32bit OSes. */
lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0);
#endif
LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(builder);
@ -990,6 +1003,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(code);
}
lp_func_delete_body(variant->function_elts);
}
void

View File

@ -169,77 +169,40 @@ static void do_triangle( struct draw_context *draw,
/*
* Set up macros for draw_pt_decompose.h template code.
* This code uses vertex indexes / elements.
*
* Flags are needed by the stipple and unfilled stages. When the two stages
* are active, vcache_run_extras is called and the flags are stored in the
* higher bits of i0. Otherwise, flags do not matter.
*/
/* emit first quad vertex as first vertex in triangles */
#define QUAD_FIRST_PV(i0,i1,i2,i3) \
do_triangle( draw, \
( DRAW_PIPE_RESET_STIPPLE | \
DRAW_PIPE_EDGE_FLAG_0 | \
DRAW_PIPE_EDGE_FLAG_1 ), \
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK)); \
do_triangle( draw, \
( DRAW_PIPE_EDGE_FLAG_1 | \
DRAW_PIPE_EDGE_FLAG_2 ), \
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK))
#define TRIANGLE(flags,i0,i1,i2) \
do_triangle( draw, \
i0, /* flags */ \
verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (i1), \
verts + stride * (i2) )
/* emit last quad vertex as last vertex in triangles */
#define QUAD_LAST_PV(i0,i1,i2,i3) \
do_triangle( draw, \
( DRAW_PIPE_RESET_STIPPLE | \
DRAW_PIPE_EDGE_FLAG_0 | \
DRAW_PIPE_EDGE_FLAG_2 ), \
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK)); \
do_triangle( draw, \
( DRAW_PIPE_EDGE_FLAG_0 | \
DRAW_PIPE_EDGE_FLAG_1 ), \
verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK))
#define TRIANGLE(flags,i0,i1,i2) \
do_triangle( draw, \
elts[i0], /* flags */ \
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK) );
#define LINE(flags,i0,i1) \
do_line( draw, \
elts[i0], \
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK) );
#define LINE(flags,i0,i1) \
do_line( draw, \
i0, /* flags */ \
verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (i1) )
#define POINT(i0) \
do_point( draw, \
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK) )
do_point( draw, verts + stride * (i0) )
#define FUNC pipe_run
#define ARGS \
#define GET_ELT(idx) (elts[idx])
#define FUNC pipe_run_elts
#define FUNC_VARS \
struct draw_context *draw, \
unsigned prim, \
struct vertex_header *vertices, \
unsigned stride, \
const ushort *elts
#define LOCAL_VARS \
char *verts = (char *)vertices; \
boolean flatfirst = (draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
unsigned i; \
ushort flags
#define FLUSH
const ushort *elts, \
unsigned count
#include "draw_pt_decompose.h"
#undef ARGS
#undef LOCAL_VARS
@ -269,14 +232,29 @@ void draw_pipeline_run( struct draw_context *draw,
i < prim_info->primitive_count;
start += prim_info->primitive_lengths[i], i++)
{
unsigned count = prim_info->primitive_lengths[i];
const unsigned count = prim_info->primitive_lengths[i];
pipe_run(draw,
prim_info->prim,
vert_info->verts,
vert_info->stride,
prim_info->elts + start,
count);
#if DEBUG
/* make sure none of the element indexes go outside the vertex buffer */
{
unsigned max_index = 0x0, i;
/* find the largest element index */
for (i = 0; i < count; i++) {
unsigned int index = (prim_info->elts[start + i]
& ~DRAW_PIPE_FLAG_MASK);
if (index > max_index)
max_index = index;
}
assert(max_index <= vert_info->count);
}
#endif
pipe_run_elts(draw,
prim_info->prim,
vert_info->verts,
vert_info->stride,
prim_info->elts + start,
count);
}
draw->pipeline.verts = NULL;
@ -289,70 +267,30 @@ void draw_pipeline_run( struct draw_context *draw,
* This code is for non-indexed (aka linear) rendering (no elts).
*/
/* emit first quad vertex as first vertex in triangles */
#define QUAD_FIRST_PV(i0,i1,i2,i3) \
do_triangle( draw, \
( DRAW_PIPE_RESET_STIPPLE | \
DRAW_PIPE_EDGE_FLAG_0 | \
DRAW_PIPE_EDGE_FLAG_1 ), \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK)); \
do_triangle( draw, \
( DRAW_PIPE_EDGE_FLAG_1 | \
DRAW_PIPE_EDGE_FLAG_2 ), \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK))
#define TRIANGLE(flags,i0,i1,i2) \
do_triangle( draw, flags, \
verts + stride * (i0), \
verts + stride * (i1), \
verts + stride * (i2) )
/* emit last quad vertex as last vertex in triangles */
#define QUAD_LAST_PV(i0,i1,i2,i3) \
do_triangle( draw, \
( DRAW_PIPE_RESET_STIPPLE | \
DRAW_PIPE_EDGE_FLAG_0 | \
DRAW_PIPE_EDGE_FLAG_2 ), \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)); \
do_triangle( draw, \
( DRAW_PIPE_EDGE_FLAG_0 | \
DRAW_PIPE_EDGE_FLAG_1 ), \
verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK))
#define LINE(flags,i0,i1) \
do_line( draw, flags, \
verts + stride * (i0), \
verts + stride * (i1) )
#define TRIANGLE(flags,i0,i1,i2) \
do_triangle( draw, \
flags, /* flags */ \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK))
#define POINT(i0) \
do_point( draw, verts + stride * (i0) )
#define LINE(flags,i0,i1) \
do_line( draw, \
flags, \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK))
#define POINT(i0) \
do_point( draw, \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK) )
#define GET_ELT(idx) (idx)
#define FUNC pipe_run_linear
#define ARGS \
struct draw_context *draw, \
unsigned prim, \
struct vertex_header *vertices, \
unsigned stride
#define LOCAL_VARS \
char *verts = (char *)vertices; \
boolean flatfirst = (draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
unsigned i; \
ushort flags
#define FLUSH
#define FUNC_VARS \
struct draw_context *draw, \
unsigned prim, \
struct vertex_header *vertices, \
unsigned stride, \
unsigned count
#include "draw_pt_decompose.h"
@ -378,6 +316,8 @@ void draw_pipeline_run_linear( struct draw_context *draw,
draw->pipeline.vertex_stride = vert_info->stride;
draw->pipeline.vertex_count = count;
assert(count <= vert_info->count);
pipe_run_linear(draw,
prim_info->prim,
(struct vertex_header*)verts,

View File

@ -68,8 +68,7 @@ struct clip_stage {
};
/* This is a bit confusing:
*/
/** Cast wrapper */
static INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
{
return (struct clip_stage *)stage;
@ -81,18 +80,22 @@ static INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
/* All attributes are float[4], so this is easy:
*/
static void interp_attr( float *fdst,
static void interp_attr( float dst[4],
float t,
const float *fin,
const float *fout )
const float in[4],
const float out[4] )
{
fdst[0] = LINTERP( t, fout[0], fin[0] );
fdst[1] = LINTERP( t, fout[1], fin[1] );
fdst[2] = LINTERP( t, fout[2], fin[2] );
fdst[3] = LINTERP( t, fout[3], fin[3] );
dst[0] = LINTERP( t, out[0], in[0] );
dst[1] = LINTERP( t, out[1], in[1] );
dst[2] = LINTERP( t, out[2], in[2] );
dst[3] = LINTERP( t, out[3], in[3] );
}
/**
* Copy front/back, primary/secondary colors from src vertex to dst vertex.
* Used when flat shading.
*/
static void copy_colors( struct draw_stage *stage,
struct vertex_header *dst,
const struct vertex_header *src )
@ -121,20 +124,17 @@ static void interp( const struct clip_stage *clip,
/* Vertex header.
*/
{
dst->clipmask = 0;
dst->edgeflag = 0; /* will get overwritten later */
dst->pad = 0;
dst->vertex_id = UNDEFINED_VERTEX_ID;
}
dst->clipmask = 0;
dst->edgeflag = 0; /* will get overwritten later */
dst->pad = 0;
dst->vertex_id = UNDEFINED_VERTEX_ID;
/* Clip coordinates: interpolate normally
/* Interpolate the clip-space coords.
*/
{
interp_attr(dst->clip, t, in->clip, out->clip);
}
interp_attr(dst->clip, t, in->clip, out->clip);
/* Do the projective divide and insert window coordinates:
/* Do the projective divide and viewport transformation to get
* new window coordinates:
*/
{
const float *pos = dst->clip;

View File

@ -163,9 +163,11 @@ struct draw_context
/** vertex arrays */
const void *vbuffer[PIPE_MAX_ATTRIBS];
/** constant buffer (for vertex/geometry shader) */
/** constant buffers (for vertex/geometry shader) */
const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS];
unsigned vs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS];
unsigned gs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
} user;
boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */
@ -198,6 +200,7 @@ struct draw_context
struct pipe_viewport_state viewport;
boolean identity_viewport;
/** Vertex shader state */
struct {
struct draw_vertex_shader *vertex_shader;
uint num_vs_outputs; /**< convenience, from vertex_shader */
@ -227,6 +230,7 @@ struct draw_context
struct translate_cache *emit_cache;
} vs;
/** Geometry shader state */
struct {
struct draw_geometry_shader *geometry_shader;
uint num_gs_outputs; /**< convenience, from geometry_shader */
@ -239,6 +243,7 @@ struct draw_context
struct tgsi_sampler **samplers;
} gs;
/** Stream output (vertex feedback) state */
struct {
struct pipe_stream_output_state state;
void *buffers[PIPE_MAX_SO_BUFFERS];

View File

@ -259,6 +259,12 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
for (j = 0; j < draw->pt.nr_vertex_elements; j++) {
uint buf = draw->pt.vertex_element[j].vertex_buffer_index;
ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf];
if (draw->pt.vertex_element[j].instance_divisor) {
ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor;
}
ptr += draw->pt.vertex_buffer[buf].buffer_offset;
ptr += draw->pt.vertex_buffer[buf].stride * ii;
ptr += draw->pt.vertex_element[j].src_offset;
@ -341,19 +347,22 @@ draw_arrays_instanced(struct draw_context *draw,
unsigned reduced_prim = u_reduced_prim(mode);
unsigned instance;
assert(instanceCount > 0);
if (reduced_prim != draw->reduced_prim) {
draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
draw->reduced_prim = reduced_prim;
}
if (0)
draw_print_arrays(draw, mode, start, MIN2(count, 20));
debug_printf("draw_arrays(mode=%u start=%u count=%u):\n",
mode, start, count);
if (0)
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
if (0) {
unsigned int i;
debug_printf("draw_arrays(mode=%u start=%u count=%u):\n",
mode, start, count);
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
debug_printf("Elements:\n");
for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
debug_printf(" %u: src_offset=%u inst_div=%u vbuf=%u format=%s\n",
@ -374,6 +383,9 @@ draw_arrays_instanced(struct draw_context *draw,
}
}
if (0)
draw_print_arrays(draw, mode, start, MIN2(count, 20));
for (instance = 0; instance < instanceCount; instance++) {
draw->instance_id = instance + startInstance;
draw_pt_arrays(draw, mode, start, count);

View File

@ -1,194 +1,7 @@
#define LOCAL_VARS \
char *verts = (char *) vertices; \
const boolean last_vertex_last = \
!(draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first);
static void FUNC( ARGS,
unsigned count )
{
LOCAL_VARS;
switch (prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
POINT( (i + 0) );
}
break;
case PIPE_PRIM_LINES:
for (i = 0; i+1 < count; i += 2) {
LINE( DRAW_PIPE_RESET_STIPPLE,
(i + 0),
(i + 1));
}
break;
case PIPE_PRIM_LINE_LOOP:
if (count >= 2) {
flags = DRAW_PIPE_RESET_STIPPLE;
for (i = 1; i < count; i++, flags = 0) {
LINE( flags,
(i - 1),
(i ));
}
LINE( flags,
(i - 1),
(0 ));
}
break;
case PIPE_PRIM_LINE_STRIP:
flags = DRAW_PIPE_RESET_STIPPLE;
for (i = 1; i < count; i++, flags = 0) {
LINE( flags,
(i - 1),
(i ));
}
break;
case PIPE_PRIM_TRIANGLES:
for (i = 0; i+2 < count; i += 3) {
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(i + 0),
(i + 1),
(i + 2 ));
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
/* Emit first triangle vertex as first triangle vertex */
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(i + 0),
(i + 1 + (i&1)),
(i + 2 - (i&1)) );
}
}
else {
for (i = 0; i+2 < count; i++) {
/* Emit last triangle vertex as last triangle vertex */
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(i + 0 + (i&1)),
(i + 1 - (i&1)),
(i + 2 ));
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(i + 1),
(i + 2),
0 );
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(0),
(i + 1),
(i + 2 ));
}
}
}
break;
case PIPE_PRIM_QUADS:
/* GL quads don't follow provoking vertex convention */
if (flatfirst) {
for (i = 0; i+3 < count; i += 4) {
/* emit last quad vertex as first triangle vertex */
QUAD_FIRST_PV( (i + 3),
(i + 0),
(i + 1),
(i + 2) );
}
}
else {
for (i = 0; i+3 < count; i += 4) {
/* emit last quad vertex as last triangle vertex */
QUAD_LAST_PV( (i + 0),
(i + 1),
(i + 2),
(i + 3) );
}
}
break;
case PIPE_PRIM_QUAD_STRIP:
/* GL quad strips don't follow provoking vertex convention */
if (flatfirst) {
for (i = 0; i+3 < count; i += 2) {
/* emit last quad vertex as first triangle vertex */
QUAD_FIRST_PV( (i + 3),
(i + 2),
(i + 0),
(i + 1) );
}
}
else {
for (i = 0; i+3 < count; i += 2) {
/* emit last quad vertex as last triangle vertex */
QUAD_LAST_PV( (i + 2),
(i + 0),
(i + 1),
(i + 3) );
}
}
break;
case PIPE_PRIM_POLYGON:
/* GL polygons don't follow provoking vertex convention */
{
/* These bitflags look a little odd because we submit the
* vertices as (1,2,0) to satisfy flatshade requirements.
*/
const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2;
const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0;
const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1;
flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
for (i = 0; i+2 < count; i++, flags = edge_middle) {
if (i + 3 == count)
flags |= edge_last;
if (flatfirst) {
/* emit first polygon vertex as first triangle vertex */
TRIANGLE( flags,
(0),
(i + 1),
(i + 2) );
}
else {
/* emit first polygon vertex as last triangle vertex */
TRIANGLE( flags,
(i + 1),
(i + 2),
(0));
}
}
}
break;
default:
assert(0);
break;
}
FLUSH;
}
#undef TRIANGLE
#undef QUAD_FIRST_PV
#undef QUAD_LAST_PV
#undef POINT
#undef LINE
#undef FUNC
#include "draw_decompose_tmp.h"

View File

@ -182,6 +182,7 @@ void draw_pt_emit( struct pt_emit *emit,
0,
~0);
/* fetch/translate vertex attribs to fill hw_verts[] */
translate->run( translate,
0,
vertex_count,

View File

@ -176,6 +176,7 @@ static void emit(struct pt_emit *emit,
static void draw_vertex_shader_run(struct draw_vertex_shader *vshader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts,
struct draw_vertex_info *output_verts )
{
@ -190,6 +191,7 @@ static void draw_vertex_shader_run(struct draw_vertex_shader *vshader,
(const float (*)[4])input_verts->verts->data,
( float (*)[4])output_verts->verts->data,
constants,
const_size,
input_verts->count,
input_verts->vertex_size,
input_verts->vertex_size);
@ -236,6 +238,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
if (fpme->opt & PT_SHADE) {
draw_vertex_shader_run(vshader,
draw->pt.user.vs_constants,
draw->pt.user.vs_constants_size,
vert_info,
&vs_vert_info);
@ -246,6 +249,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
if ((fpme->opt & PT_SHADE) && gshader) {
draw_geometry_shader_run(gshader,
draw->pt.user.gs_constants,
draw->pt.user.gs_constants_size,
vert_info,
prim_info,
&gs_vert_info,

View File

@ -1,6 +1,6 @@
/**************************************************************************
*
* Copyright 2010 VMWare, Inc.
* Copyright 2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -254,6 +254,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
if ((opt & PT_SHADE) && gshader) {
draw_geometry_shader_run(gshader,
draw->pt.user.gs_constants,
draw->pt.user.gs_constants_size,
vert_info,
prim_info,
&gs_vert_info,

View File

@ -218,25 +218,15 @@ static void so_tri(struct pt_so_emit *so, int i0, int i1, int i2)
}
#define TRIANGLE(gs,i0,i1,i2) so_tri(so,i0,i1,i2)
#define LINE(gs,i0,i1) so_line(so,i0,i1)
#define POINT(gs,i0) so_point(so,i0)
#define FUNC so_run_linear
#define LOCAL_VARS
#define FUNC so_run_linear
#define GET_ELT(idx) (start + (idx))
#include "draw_so_emit_tmp.h"
#undef LOCAL_VARS
#undef FUNC
#define TRIANGLE(gs,i0,i1,i2) so_tri(gs,elts[i0],elts[i1],elts[i2])
#define LINE(gs,i0,i1) so_line(gs,elts[i0],elts[i1])
#define POINT(gs,i0) so_point(gs,elts[i0])
#define FUNC so_run_elts
#define LOCAL_VARS \
const ushort *elts = input_prims->elts;
#define FUNC so_run_elts
#define LOCAL_VARS const ushort *elts = input_prims->elts;
#define GET_ELT(idx) (elts[start + (idx)] & ~DRAW_PIPE_FLAG_MASK)
#include "draw_so_emit_tmp.h"
#undef LOCAL_VARS
#undef FUNC
void draw_pt_so_emit( struct pt_so_emit *emit,

View File

@ -95,7 +95,7 @@ static INLINE void
vcache_check_flush( struct vcache_frontend *vcache )
{
if (vcache->draw_count + 6 >= DRAW_MAX ||
vcache->fetch_count + 4 >= FETCH_MAX) {
vcache->fetch_count + 6 >= FETCH_MAX) {
vcache_flush( vcache );
}
}
@ -180,59 +180,61 @@ vcache_point( struct vcache_frontend *vcache,
}
static INLINE void
vcache_quad( struct vcache_frontend *vcache,
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3 )
static INLINE void
vcache_line_adj_flags( struct vcache_frontend *vcache,
unsigned flags,
unsigned a0, unsigned i0, unsigned i1, unsigned a1 )
{
if (vcache->draw->rasterizer->flatshade_first) {
/* pass last quad vertex as first triangle vertex */
vcache_triangle( vcache, i3, i0, i1 );
vcache_triangle( vcache, i3, i1, i2 );
}
else {
/* pass last quad vertex as last triangle vertex */
vcache_triangle( vcache, i0, i1, i3 );
vcache_triangle( vcache, i1, i2, i3 );
}
vcache_elt(vcache, a0, 0);
vcache_elt(vcache, i0, flags);
vcache_elt(vcache, i1, 0);
vcache_elt(vcache, a1, 0);
vcache_check_flush(vcache);
}
static INLINE void
vcache_ef_quad( struct vcache_frontend *vcache,
unsigned i0,
unsigned i1,
unsigned i2,
unsigned i3 )
static INLINE void
vcache_line_adj( struct vcache_frontend *vcache,
unsigned a0, unsigned i0, unsigned i1, unsigned a1 )
{
if (vcache->draw->rasterizer->flatshade_first) {
/* pass last quad vertex as first triangle vertex */
vcache_triangle_flags( vcache,
( DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1 ),
i3, i0, i1 );
vcache_elt(vcache, a0, 0);
vcache_elt(vcache, i0, 0);
vcache_elt(vcache, i1, 0);
vcache_elt(vcache, a1, 0);
vcache_check_flush(vcache);
}
vcache_triangle_flags( vcache,
( DRAW_PIPE_EDGE_FLAG_1 |
DRAW_PIPE_EDGE_FLAG_2 ),
i3, i1, i2 );
}
else {
/* pass last quad vertex as last triangle vertex */
vcache_triangle_flags( vcache,
( DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_2 ),
i0, i1, i3 );
vcache_triangle_flags( vcache,
( DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1 ),
i1, i2, i3 );
}
static INLINE void
vcache_triangle_adj_flags( struct vcache_frontend *vcache,
unsigned flags,
unsigned i0, unsigned a0,
unsigned i1, unsigned a1,
unsigned i2, unsigned a2 )
{
vcache_elt(vcache, i0, flags);
vcache_elt(vcache, a0, 0);
vcache_elt(vcache, i1, 0);
vcache_elt(vcache, a1, 0);
vcache_elt(vcache, i2, 0);
vcache_elt(vcache, a2, 0);
vcache_check_flush(vcache);
}
static INLINE void
vcache_triangle_adj( struct vcache_frontend *vcache,
unsigned i0, unsigned a0,
unsigned i1, unsigned a1,
unsigned i2, unsigned a2 )
{
vcache_elt(vcache, i0, 0);
vcache_elt(vcache, a0, 0);
vcache_elt(vcache, i1, 0);
vcache_elt(vcache, a1, 0);
vcache_elt(vcache, i2, 0);
vcache_elt(vcache, a2, 0);
vcache_check_flush(vcache);
}
@ -240,17 +242,23 @@ vcache_ef_quad( struct vcache_frontend *vcache,
* this. The two paths aren't too different though - it may be
* possible to reunify them.
*/
#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2)
#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3)
#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1)
#define POINT(vc,i0) vcache_point(vc,i0)
#define TRIANGLE(flags,i0,i1,i2) vcache_triangle_flags(vcache,flags,i0,i1,i2)
#define LINE(flags,i0,i1) vcache_line_flags(vcache,flags,i0,i1)
#define POINT(i0) vcache_point(vcache,i0)
#define LINE_ADJ(flags,a0,i0,i1,a1) \
vcache_line_adj_flags(vcache,flags,a0,i0,i1,a1)
#define TRIANGLE_ADJ(flags,i0,a0,i1,a1,i2,a2) \
vcache_triangle_adj_flags(vcache,flags,i0,a0,i1,a1,i2,a2)
#define FUNC vcache_run_extras
#include "draw_pt_vcache_tmp.h"
#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2)
#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3)
#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1)
#define POINT(vc,i0) vcache_point(vc,i0)
#define TRIANGLE(flags,i0,i1,i2) vcache_triangle(vcache,i0,i1,i2)
#define LINE(flags,i0,i1) vcache_line(vcache,i0,i1)
#define POINT(i0) vcache_point(vcache,i0)
#define LINE_ADJ(flags,a0,i0,i1,a1) \
vcache_line_adj(vcache,a0,i0,i1,a1)
#define TRIANGLE_ADJ(flags,i0,a0,i1,a1,i2,a2) \
vcache_triangle_adj(vcache,i0,a0,i1,a1,i2,a2)
#define FUNC vcache_run
#include "draw_pt_vcache_tmp.h"
@ -339,6 +347,25 @@ format_from_get_elt( pt_elt_func get_elt )
#endif
/**
* Check if any vertex attributes use instance divisors.
* Note that instance divisors complicate vertex fetching so we need
* to take the vcache path when they're in use.
*/
static boolean
any_instance_divisors(const struct draw_context *draw)
{
uint i;
for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
uint div = draw->pt.vertex_element[i].instance_divisor;
if (div)
return TRUE;
}
return FALSE;
}
static INLINE void
vcache_check_run( struct draw_pt_front_end *frontend,
pt_elt_func get_elt,
@ -382,6 +409,9 @@ vcache_check_run( struct draw_pt_front_end *frontend,
if (max_index >= (unsigned) DRAW_PIPE_MAX_VERTICES)
goto fail;
if (any_instance_divisors(draw))
goto fail;
fetch_count = max_index + 1 - min_index;
if (0)
@ -518,7 +548,18 @@ vcache_prepare( struct draw_pt_front_end *frontend,
* which is a separate issue.
*/
vcache->input_prim = in_prim;
vcache->output_prim = u_reduced_prim(in_prim);
switch (in_prim) {
case PIPE_PRIM_LINES_ADJACENCY:
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
vcache->output_prim = PIPE_PRIM_LINES_ADJACENCY;
break;
case PIPE_PRIM_TRIANGLES_ADJACENCY:
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
vcache->output_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
break;
default:
vcache->output_prim = u_reduced_prim(in_prim);
}
vcache->middle = middle;
vcache->opt = opt;

View File

@ -1,198 +1,19 @@
#define FUNC_VARS \
struct draw_pt_front_end *frontend, \
pt_elt_func get_elt, \
const void *elts, \
int elt_bias, \
unsigned count
#define LOCAL_VARS \
struct vcache_frontend *vcache = (struct vcache_frontend *) frontend; \
struct draw_context *draw = vcache->draw; \
const unsigned prim = vcache->input_prim; \
const boolean last_vertex_last = !(draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first);
static void FUNC( struct draw_pt_front_end *frontend,
pt_elt_func get_elt,
const void *elts,
int elt_bias,
unsigned count )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
struct draw_context *draw = vcache->draw;
#define GET_ELT(idx) (get_elt(elts, idx) + elt_bias)
boolean flatfirst = (draw->rasterizer->flatshade &&
draw->rasterizer->flatshade_first);
unsigned i;
ushort flags;
#define FUNC_EXIT do { vcache_flush(vcache); } while (0)
if (0) debug_printf("%s %d\n", __FUNCTION__, count);
switch (vcache->input_prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
POINT( vcache,
get_elt(elts, i + 0) + elt_bias );
}
break;
case PIPE_PRIM_LINES:
for (i = 0; i+1 < count; i += 2) {
LINE( vcache,
DRAW_PIPE_RESET_STIPPLE,
get_elt(elts, i + 0) + elt_bias,
get_elt(elts, i + 1) + elt_bias);
}
break;
case PIPE_PRIM_LINE_LOOP:
if (count >= 2) {
flags = DRAW_PIPE_RESET_STIPPLE;
for (i = 1; i < count; i++, flags = 0) {
LINE( vcache,
flags,
get_elt(elts, i - 1) + elt_bias,
get_elt(elts, i ) + elt_bias);
}
LINE( vcache,
flags,
get_elt(elts, i - 1) + elt_bias,
get_elt(elts, 0 ) + elt_bias);
}
break;
case PIPE_PRIM_LINE_STRIP:
flags = DRAW_PIPE_RESET_STIPPLE;
for (i = 1; i < count; i++, flags = 0) {
LINE( vcache,
flags,
get_elt(elts, i - 1) + elt_bias,
get_elt(elts, i ) + elt_bias);
}
break;
case PIPE_PRIM_TRIANGLES:
for (i = 0; i+2 < count; i += 3) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 0) + elt_bias,
get_elt(elts, i + 1) + elt_bias,
get_elt(elts, i + 2 ) + elt_bias);
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 0) + elt_bias,
get_elt(elts, i + 1 + (i&1)) + elt_bias,
get_elt(elts, i + 2 - (i&1)) + elt_bias);
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 0 + (i&1)) + elt_bias,
get_elt(elts, i + 1 - (i&1)) + elt_bias,
get_elt(elts, i + 2 ) + elt_bias);
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, i + 1) + elt_bias,
get_elt(elts, i + 2) + elt_bias,
get_elt(elts, 0 ) + elt_bias);
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( vcache,
DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
get_elt(elts, 0) + elt_bias,
get_elt(elts, i + 1) + elt_bias,
get_elt(elts, i + 2 ) + elt_bias);
}
}
}
break;
case PIPE_PRIM_QUADS:
for (i = 0; i+3 < count; i += 4) {
QUAD( vcache,
get_elt(elts, i + 0) + elt_bias,
get_elt(elts, i + 1) + elt_bias,
get_elt(elts, i + 2) + elt_bias,
get_elt(elts, i + 3) + elt_bias );
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (i = 0; i+3 < count; i += 2) {
QUAD( vcache,
get_elt(elts, i + 2) + elt_bias,
get_elt(elts, i + 0) + elt_bias,
get_elt(elts, i + 1) + elt_bias,
get_elt(elts, i + 3) + elt_bias );
}
break;
case PIPE_PRIM_POLYGON:
{
/* These bitflags look a little odd because we submit the
* vertices as (1,2,0) to satisfy flatshade requirements.
*/
ushort edge_next, edge_finish;
if (flatfirst) {
flags = (DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_1 |
DRAW_PIPE_EDGE_FLAG_2);
edge_next = DRAW_PIPE_EDGE_FLAG_2;
edge_finish = DRAW_PIPE_EDGE_FLAG_0;
}
else {
flags = (DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_2 |
DRAW_PIPE_EDGE_FLAG_0);
edge_next = DRAW_PIPE_EDGE_FLAG_0;
edge_finish = DRAW_PIPE_EDGE_FLAG_1;
}
for (i = 0; i+2 < count; i++, flags = edge_next) {
if (i + 3 == count)
flags |= edge_finish;
if (flatfirst) {
TRIANGLE( vcache,
flags,
get_elt(elts, 0) + elt_bias,
get_elt(elts, i + 1) + elt_bias,
get_elt(elts, i + 2) + elt_bias );
}
else {
TRIANGLE( vcache,
flags,
get_elt(elts, i + 1) + elt_bias,
get_elt(elts, i + 2) + elt_bias,
get_elt(elts, 0) + elt_bias);
}
}
}
break;
default:
assert(0);
break;
}
vcache_flush( vcache );
}
#undef TRIANGLE
#undef QUAD
#undef POINT
#undef LINE
#undef FUNC
#include "draw_decompose_tmp.h"

View File

@ -1,123 +1,33 @@
#define FUNC_VARS \
struct pt_so_emit *so, \
const struct draw_prim_info *input_prims, \
const struct draw_vertex_info *input_verts, \
unsigned start, \
unsigned count
static void FUNC( struct pt_so_emit *so,
const struct draw_prim_info *input_prims,
const struct draw_vertex_info *input_verts,
unsigned start,
unsigned count)
{
struct draw_context *draw = so->draw;
#define FUNC_ENTER \
/* declare more local vars */ \
struct draw_context *draw = so->draw; \
const unsigned prim = input_prims->prim; \
const boolean last_vertex_last = \
!(draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
do { \
debug_assert(input_prims->primitive_count == 1); \
switch (prim) { \
case PIPE_PRIM_LINES_ADJACENCY: \
case PIPE_PRIM_LINE_STRIP_ADJACENCY: \
case PIPE_PRIM_TRIANGLES_ADJACENCY: \
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: \
debug_assert(!"unexpected primitive type in stream output"); \
return; \
default: \
break; \
} \
} while (0) \
boolean flatfirst = (draw->rasterizer->flatshade &&
draw->rasterizer->flatshade_first);
unsigned i;
LOCAL_VARS
#define POINT(i0) so_point(so,i0)
#define LINE(flags,i0,i1) so_line(so,i0,i1)
#define TRIANGLE(flags,i0,i1,i2) so_tri(so,i0,i1,i2)
if (0) debug_printf("%s %d\n", __FUNCTION__, count);
debug_assert(input_prims->primitive_count == 1);
switch (input_prims->prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i++) {
POINT( so, start + i + 0 );
}
break;
case PIPE_PRIM_LINES:
for (i = 0; i+1 < count; i += 2) {
LINE( so , start + i + 0 , start + i + 1 );
}
break;
case PIPE_PRIM_LINE_LOOP:
if (count >= 2) {
for (i = 1; i < count; i++) {
LINE( so, start + i - 1, start + i );
}
LINE( so, start + i - 1, start );
}
break;
case PIPE_PRIM_LINE_STRIP:
for (i = 1; i < count; i++) {
LINE( so, start + i - 1, start + i );
}
break;
case PIPE_PRIM_TRIANGLES:
for (i = 0; i+2 < count; i += 3) {
TRIANGLE( so, start + i + 0, start + i + 1, start + i + 2 );
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( so,
start + i + 0,
start + i + 1 + (i&1),
start + i + 2 - (i&1) );
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( so,
start + i + 0 + (i&1),
start + i + 1 - (i&1),
start + i + 2 );
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( so,
start + i + 1,
start + i + 2,
start );
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( so,
start,
start + i + 1,
start + i + 2 );
}
}
}
break;
case PIPE_PRIM_POLYGON:
{
/* These bitflags look a little odd because we submit the
* vertices as (1,2,0) to satisfy flatshade requirements.
*/
for (i = 0; i+2 < count; i++) {
if (flatfirst) {
TRIANGLE( so, start + 0, start + i + 1, start + i + 2 );
}
else {
TRIANGLE( so, start + i + 1, start + i + 2, start + 0 );
}
}
}
break;
default:
debug_assert(!"Unsupported primitive in stream output");
break;
}
}
#undef TRIANGLE
#undef POINT
#undef LINE
#undef FUNC
#include "draw_decompose_tmp.h"

View File

@ -166,7 +166,7 @@ static INLINE enum pipe_format draw_translate_vinfo_format(enum attrib_emit emit
}
}
static INLINE enum attrib_emit draw_translate_vinfo_size(enum attrib_emit emit)
static INLINE unsigned draw_translate_vinfo_size(enum attrib_emit emit)
{
switch (emit) {
case EMIT_OMIT:

View File

@ -48,18 +48,30 @@
DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE)
/**
* Set a vertex shader constant buffer.
* \param slot which constant buffer in [0, PIPE_MAX_CONSTANT_BUFFERS-1]
* \param constants the mapped buffer
* \param size size of buffer in bytes
*/
void
draw_vs_set_constants(struct draw_context *draw,
unsigned slot,
const void *constants,
unsigned size)
{
if (((uintptr_t)constants) & 0xf) {
const int alignment = 16;
/* check if buffer is 16-byte aligned */
if (((uintptr_t)constants) & (alignment - 1)) {
/* if not, copy the constants into a new, 16-byte aligned buffer */
if (size > draw->vs.const_storage_size[slot]) {
if (draw->vs.aligned_constant_storage[slot]) {
align_free((void *)draw->vs.aligned_constant_storage[slot]);
}
draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16);
draw->vs.aligned_constant_storage[slot] =
align_malloc(size, alignment);
}
assert(constants);
memcpy((void *)draw->vs.aligned_constant_storage[slot],

View File

@ -133,7 +133,8 @@ struct draw_vertex_shader {
void (*run_linear)( struct draw_vertex_shader *shader,
const float (*input)[4],
float (*output)[4],
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride );

View File

@ -85,7 +85,8 @@ static void
vs_exec_run_linear( struct draw_vertex_shader *shader,
const float (*input)[4],
float (*output)[4],
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )
@ -95,9 +96,8 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,
unsigned int i, j;
unsigned slot;
for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
machine->Consts[i] = constants[i];
}
tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
constants, const_size);
for (i = 0; i < count; i += MAX_TGSI_VERTICES) {
unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i);

View File

@ -49,6 +49,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *shader,
const float (*input)[4],
float (*output)[4],
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )

View File

@ -84,6 +84,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base,
const float (*input)[4],
float (*output)[4],
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )

View File

@ -149,7 +149,8 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient,
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
vsvg->base.vs->draw->pt.user.vs_constants,
vsvg->base.vs->draw->pt.user.vs_constants,
vsvg->base.vs->draw->pt.user.vs_constants_size,
count,
temp_vertex_stride,
temp_vertex_stride);
@ -214,7 +215,8 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient,
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
vsvg->base.vs->draw->pt.user.vs_constants,
vsvg->base.vs->draw->pt.user.vs_constants,
vsvg->base.vs->draw->pt.user.vs_constants_size,
count,
temp_vertex_stride,
temp_vertex_stride);

View File

@ -0,0 +1,101 @@
/**************************************************************************
*
* Copyright 2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "lp_bld_assert.h"
#include "lp_bld_init.h"
#include "lp_bld_printf.h"
/**
* A call to lp_build_assert() will build a function call to this function.
*/
static void
lp_assert(int condition, const char *msg)
{
if (!condition) {
debug_printf("LLVM assertion '%s' failed!\n", msg);
assert(condition);
}
}
/**
* lp_build_assert.
*
* Build an assertion in LLVM IR by building a function call to the
* lp_assert() function above.
*
* \param condition should be an 'i1' or 'i32' value
* \param msg a string to print if the assertion fails.
*/
LLVMValueRef
lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition,
const char *msg)
{
LLVMModuleRef module;
LLVMTypeRef arg_types[2];
LLVMValueRef msg_string, assert_func, params[2], r;
module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(
LLVMGetInsertBlock(builder)));
msg_string = lp_build_const_string_variable(module, msg, strlen(msg) + 1);
arg_types[0] = LLVMInt32Type();
arg_types[1] = LLVMPointerType(LLVMInt8Type(), 0);
/* lookup the lp_assert function */
assert_func = LLVMGetNamedFunction(module, "lp_assert");
/* Create the assertion function if not found */
if (!assert_func) {
LLVMTypeRef func_type =
LLVMFunctionType(LLVMVoidType(), arg_types, 2, 0);
assert_func = LLVMAddFunction(module, "lp_assert", func_type);
LLVMSetFunctionCallConv(assert_func, LLVMCCallConv);
LLVMSetLinkage(assert_func, LLVMExternalLinkage);
LLVMAddGlobalMapping(lp_build_engine, assert_func,
func_to_pointer((func_pointer)lp_assert));
}
assert(assert_func);
/* build function call param list */
params[0] = LLVMBuildZExt(builder, condition, arg_types[0], "");
params[1] = LLVMBuildBitCast(builder, msg_string, arg_types[1], "");
/* check arg types */
assert(LLVMTypeOf(params[0]) == arg_types[0]);
assert(LLVMTypeOf(params[1]) == arg_types[1]);
r = LLVMBuildCall(builder, assert_func, params, 2, "");
return r;
}

View File

@ -1,6 +1,6 @@
/**************************************************************************
*
* Copyright 2009, VMware, Inc.
* Copyright 2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -25,13 +25,17 @@
*
**************************************************************************/
#ifndef DRI2_H
#define DRI2_H
#ifndef LP_BLD_ASSERT_H
#define LP_BLD_ASSERT_H
#include "dri_drawable.h"
#include "dri_wrapper.h"
const __DRIconfig **
dri2_init_screen(__DRIscreen * sPriv);
#include "lp_bld.h"
LLVMValueRef
lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition,
const char *msg);
#endif
#endif /* DRI2_H */

View File

@ -45,6 +45,8 @@ static const struct debug_named_value lp_bld_debug_flags[] = {
{ "nopt", GALLIVM_DEBUG_NO_OPT, NULL },
DEBUG_NAMED_VALUE_END
};
DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags, 0);
#endif
@ -89,7 +91,7 @@ void
lp_build_init(void)
{
#ifdef DEBUG
gallivm_debug = debug_get_flags_option("GALLIVM_DEBUG", lp_bld_debug_flags, 0 );
gallivm_debug = debug_get_option_gallivm_debug();
#endif
lp_set_target_options();

View File

@ -44,5 +44,7 @@ extern LLVMPassManagerRef lp_build_pass;
void
lp_build_init(void);
extern void
lp_func_delete_body(LLVMValueRef func);
#endif /* !LP_BLD_INIT_H */

View File

@ -362,10 +362,53 @@ lp_build_cmp(struct lp_build_context *bld,
}
/**
* Return (mask & a) | (~mask & b);
*/
LLVMValueRef
lp_build_select_bitwise(struct lp_build_context *bld,
LLVMValueRef mask,
LLVMValueRef a,
LLVMValueRef b)
{
struct lp_type type = bld->type;
LLVMValueRef res;
if (a == b) {
return a;
}
if(type.floating) {
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
}
a = LLVMBuildAnd(bld->builder, a, mask, "");
/* This often gets translated to PANDN, but sometimes the NOT is
* pre-computed and stored in another constant. The best strategy depends
* on available registers, so it is not a big deal -- hopefully LLVM does
* the right decision attending the rest of the program.
*/
b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
res = LLVMBuildOr(bld->builder, a, b, "");
if(type.floating) {
LLVMTypeRef vec_type = lp_build_vec_type(type);
res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
}
return res;
}
/**
* Return mask ? a : b;
*
* mask is a bitwise mask, composed of 0 or ~0 for each element.
* mask is a bitwise mask, composed of 0 or ~0 for each element. Any other value
* will yield unpredictable results.
*/
LLVMValueRef
lp_build_select(struct lp_build_context *bld,
@ -424,27 +467,7 @@ lp_build_select(struct lp_build_context *bld,
}
}
else {
if(type.floating) {
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
}
a = LLVMBuildAnd(bld->builder, a, mask, "");
/* This often gets translated to PANDN, but sometimes the NOT is
* pre-computed and stored in another constant. The best strategy depends
* on available registers, so it is not a big deal -- hopefully LLVM does
* the right decision attending the rest of the program.
*/
b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
res = LLVMBuildOr(bld->builder, a, b, "");
if(type.floating) {
LLVMTypeRef vec_type = lp_build_vec_type(type);
res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
}
res = lp_build_select_bitwise(bld, mask, a, b);
}
return res;

View File

@ -63,6 +63,11 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b);
LLVMValueRef
lp_build_select_bitwise(struct lp_build_context *bld,
LLVMValueRef mask,
LLVMValueRef a,
LLVMValueRef b);
LLVMValueRef
lp_build_select(struct lp_build_context *bld,

View File

@ -39,6 +39,7 @@
#include <llvm/Target/TargetOptions.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/Support/CommandLine.h>
#include "pipe/p_config.h"
#include "util/u_debug.h"
@ -141,4 +142,35 @@ lp_set_target_options(void)
#if 0
llvm::UnsafeFPMath = true;
#endif
#if 0
/*
* LLVM will generate MMX instructions for vectors <= 64 bits, leading to
* innefficient code, and in 32bit systems, to the corruption of the FPU
* stack given that it expects the user to generate the EMMS instructions.
*
* See also:
* - http://llvm.org/bugs/show_bug.cgi?id=3287
* - http://l4.me.uk/post/2009/06/07/llvm-wrinkle-3-configuration-what-configuration/
*
* XXX: Unfortunately this is not working.
*/
static boolean first = FALSE;
if (first) {
static const char* options[] = {
"prog",
"-disable-mmx"
};
llvm::cl::ParseCommandLineOptions(2, const_cast<char**>(options));
first = FALSE;
}
#endif
}
extern "C" void
lp_func_delete_body(LLVMValueRef FF)
{
llvm::Function *func = llvm::unwrap<llvm::Function>(FF);
func->deleteBody();
}

View File

@ -557,6 +557,23 @@ print_temp(const struct tgsi_exec_machine *mach, uint index)
#endif
void
tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach,
unsigned num_bufs,
const void **bufs,
const unsigned *buf_sizes)
{
unsigned i;
for (i = 0; i < num_bufs; i++) {
mach->Consts[i] = bufs[i];
mach->ConstsSize[i] = buf_sizes[i];
}
}
/**
* Check if there's a potential src/dst register data dependency when
* using SOA execution.
@ -632,6 +649,10 @@ tgsi_exec_machine_bind_shader(
util_init_math();
if (numSamplers) {
assert(samplers);
}
mach->Tokens = tokens;
mach->Samplers = samplers;
@ -1040,6 +1061,8 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,
{
uint i;
assert(swizzle < 4);
switch (file) {
case TGSI_FILE_CONSTANT:
for (i = 0; i < QUAD_SIZE; i++) {
@ -1049,9 +1072,23 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,
if (index->i[i] < 0) {
chan->u[i] = 0;
} else {
const uint *p = (const uint *)mach->Consts[index2D->i[i]];
chan->u[i] = p[index->i[i] * 4 + swizzle];
/* NOTE: copying the const value as a uint instead of float */
const uint constbuf = index2D->i[i];
const uint *buf = (const uint *)mach->Consts[constbuf];
const int pos = index->i[i] * 4 + swizzle;
/* const buffer bounds check */
if (pos < 0 || pos >= mach->ConstsSize[constbuf]) {
if (0) {
/* Debug: print warning */
static int count = 0;
if (count++ < 100)
debug_printf("TGSI Exec: const buffer index %d"
" out of bounds\n", pos);
}
chan->u[i] = 0;
}
else
chan->u[i] = buf[pos];
}
}
break;
@ -1065,9 +1102,10 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,
index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i],
index2D->i[i], index->i[i]);
}*/
chan->u[i] = mach->Inputs[index2D->i[i] *
TGSI_EXEC_MAX_INPUT_ATTRIBS +
index->i[i]].xyzw[swizzle].u[i];
int pos = index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i];
assert(pos >= 0);
assert(pos < Elements(mach->Inputs));
chan->u[i] = mach->Inputs[pos].xyzw[swizzle].u[i];
}
break;
@ -1187,7 +1225,7 @@ fetch_source(const struct tgsi_exec_machine *mach,
index2.i[1] =
index2.i[2] =
index2.i[3] = reg->Indirect.Index;
assert(reg->Indirect.File == TGSI_FILE_ADDRESS);
/* get current value of address register[swizzle] */
swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, CHAN_X );
fetch_src_file_channel(mach,

View File

@ -253,7 +253,10 @@ struct tgsi_exec_machine
struct tgsi_sampler **Samplers;
unsigned ImmLimit;
const void *Consts[PIPE_MAX_CONSTANT_BUFFERS];
unsigned ConstsSize[PIPE_MAX_CONSTANT_BUFFERS];
const struct tgsi_token *Tokens; /**< Declarations, instructions */
unsigned Processor; /**< TGSI_PROCESSOR_x */
@ -367,6 +370,13 @@ tgsi_set_exec_mask(struct tgsi_exec_machine *mach,
}
extern void
tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach,
unsigned num_bufs,
const void **bufs,
const unsigned *buf_sizes);
#if defined __cplusplus
} /* extern "C" */
#endif

View File

@ -33,6 +33,10 @@
#include "tgsi_info.h"
#include "tgsi_iterate.h"
DEBUG_GET_ONCE_BOOL_OPTION(print_sanity, "TGSI_PRINT_SANITY", TRUE);
typedef struct {
uint file : 28;
/* max 2 dimensions */
@ -54,6 +58,8 @@ struct sanity_check_ctx
uint errors;
uint warnings;
uint implied_array_size;
boolean print;
};
static INLINE unsigned
@ -148,6 +154,9 @@ report_error(
{
va_list args;
if (!ctx->print)
return;
debug_printf( "Error : " );
va_start( args, format );
_debug_vprintf( format, args );
@ -164,6 +173,9 @@ report_warning(
{
va_list args;
if (!ctx->print)
return;
debug_printf( "Warning: " );
va_start( args, format );
_debug_vprintf( format, args );
@ -539,6 +551,7 @@ tgsi_sanity_check(
ctx.errors = 0;
ctx.warnings = 0;
ctx.implied_array_size = 0;
ctx.print = debug_get_option_print_sanity();
if (!tgsi_iterate_shader( tokens, &ctx.iter ))
return FALSE;

View File

@ -35,7 +35,8 @@ extern "C" {
#endif
/* Check the given token stream for errors and common mistakes.
* Diagnostic messages are printed out to the debug output.
* Diagnostic messages are printed out to the debug output, and is
* controlled by the debug option TGSI_PRINT_SANITY (default true).
* Returns TRUE if there are no errors, even though there could be some warnings.
*/
boolean

View File

@ -368,23 +368,23 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
/* loop over vertex attributes (vertex shader inputs)
*/
for (i = 0; i < count; i++) {
unsigned elt = *elts++;
const unsigned elt = *elts++;
for (attr = 0; attr < nr_attrs; attr++) {
float data[4];
const uint8_t *src;
unsigned index;
char *dst = (vert +
tg->attrib[attr].output_offset);
char *dst = vert + tg->attrib[attr].output_offset;
if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
const uint8_t *src;
unsigned index;
if (tg->attrib[attr].instance_divisor) {
index = instance_id / tg->attrib[attr].instance_divisor;
} else {
index = elt;
}
/* clamp to void going out of bounds */
index = MIN2(index, tg->attrib[attr].max_index);
src = tg->attrib[attr].input_ptr +
@ -392,11 +392,23 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
tg->attrib[attr].fetch( data, src, 0, 0 );
if (0)
debug_printf("Fetch elt attr %d from %p stride %d div %u max %u index %d: "
" %f, %f, %f, %f \n",
attr,
tg->attrib[attr].input_ptr,
tg->attrib[attr].input_stride,
tg->attrib[attr].instance_divisor,
tg->attrib[attr].max_index,
index,
data[0], data[1],data[2], data[3]);
} else {
data[0] = (float)instance_id;
}
if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n",
i, elt, attr, data[0], data[1], data[2], data[3]);
if (0)
debug_printf("vert %d/%d attr %d: %f %f %f %f\n",
i, elt, attr, data[0], data[1], data[2], data[3]);
tg->attrib[attr].emit( data, dst );
}
@ -425,29 +437,42 @@ static void PIPE_CDECL generic_run( struct translate *translate,
for (attr = 0; attr < nr_attrs; attr++) {
float data[4];
char *dst = (vert +
tg->attrib[attr].output_offset);
char *dst = vert + tg->attrib[attr].output_offset;
if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
const uint8_t *src;
unsigned index;
if (tg->attrib[attr].instance_divisor) {
src = tg->attrib[attr].input_ptr +
tg->attrib[attr].input_stride *
(instance_id / tg->attrib[attr].instance_divisor);
} else {
src = tg->attrib[attr].input_ptr +
tg->attrib[attr].input_stride * elt;
index = instance_id / tg->attrib[attr].instance_divisor;
}
else {
index = elt;
}
/* clamp to void going out of bounds */
index = MIN2(index, tg->attrib[attr].max_index);
src = tg->attrib[attr].input_ptr +
tg->attrib[attr].input_stride * index;
tg->attrib[attr].fetch( data, src, 0, 0 );
if (0)
debug_printf("Fetch linear attr %d from %p stride %d index %d: "
" %f, %f, %f, %f \n",
attr,
tg->attrib[attr].input_ptr,
tg->attrib[attr].input_stride,
index,
data[0], data[1],data[2], data[3]);
} else {
data[0] = (float)instance_id;
}
if (0) debug_printf("vert %d attr %d: %f %f %f %f\n",
i, attr, data[0], data[1], data[2], data[3]);
if (0)
debug_printf("vert %d attr %d: %f %f %f %f\n",
i, attr, data[0], data[1], data[2], data[3]);
tg->attrib[attr].emit( data, dst );
}

View File

@ -87,6 +87,7 @@ struct blitter_context_priv
void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil;
void *dsa_keep_depth_write_stencil;
void *dsa_flush_depth_stencil;
void *velem_state;
@ -156,6 +157,10 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->dsa_keep_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
dsa.depth.writemask = 1;
ctx->dsa_flush_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
dsa.depth.enabled = 1;
dsa.depth.writemask = 1;
dsa.depth.func = PIPE_FUNC_ALWAYS;
@ -940,3 +945,42 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
UTIL_BLITTER_ATTRIB_NONE, NULL);
blitter_restore_CSOs(ctx);
}
/* Clear a region of a depth stencil surface. */
void util_blitter_flush_depth_stencil(struct blitter_context *blitter,
struct pipe_surface *dstsurf)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_framebuffer_state fb_state;
assert(dstsurf->texture);
if (!dstsurf->texture)
return;
/* check the saved state */
blitter_check_saved_CSOs(ctx);
assert(blitter->saved_fb_state.nr_cbufs != ~0);
/* bind CSOs */
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_flush_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0));
pipe->bind_vs_state(pipe, ctx->vs_col);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
/* set a framebuffer state */
fb_state.width = dstsurf->width;
fb_state.height = dstsurf->height;
fb_state.nr_cbufs = 0;
fb_state.cbufs[0] = 0;
fb_state.zsbuf = dstsurf;
pipe->set_framebuffer_state(pipe, &fb_state);
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height, 0,
UTIL_BLITTER_ATTRIB_NONE, NULL);
blitter_restore_CSOs(ctx);
}

View File

@ -200,6 +200,8 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height);
void util_blitter_flush_depth_stencil(struct blitter_context *blitter,
struct pipe_surface *dstsurf);
/* The functions below should be used to save currently bound constant state
* objects inside a driver. The objects are automatically restored at the end
* of the util_blitter_{clear, copy_region, fill_region} functions and then

View File

@ -73,9 +73,15 @@
#endif
DEBUG_GET_ONCE_BOOL_OPTION(dump_cpu, "GALLIUM_DUMP_CPU", TRUE);
struct util_cpu_caps util_cpu_caps;
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
static int has_cpuid(void);
#endif
#if defined(PIPE_ARCH_X86)
@ -497,23 +503,25 @@ util_cpu_detect(void)
#endif /* PIPE_ARCH_PPC */
#ifdef DEBUG
debug_printf("util_cpu_caps.arch = %i\n", util_cpu_caps.arch);
debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus);
if (debug_get_option_dump_cpu()) {
debug_printf("util_cpu_caps.arch = %i\n", util_cpu_caps.arch);
debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus);
debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type);
debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline);
debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type);
debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline);
debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc);
debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx);
debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2);
debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse);
debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2);
debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3);
debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3);
debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1);
debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow);
debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext);
debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec);
debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc);
debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx);
debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2);
debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse);
debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2);
debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3);
debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3);
debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1);
debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow);
debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext);
debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec);
}
#endif
util_cpu_detect_initialized = TRUE;

View File

@ -0,0 +1,138 @@
/**************************************************************************
*
* Copyright 2008 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 U_DRAW_H
#define U_DRAW_H
#include "pipe/p_compiler.h"
#include "pipe/p_context.h"
static INLINE void
util_draw_init_info(struct pipe_draw_info *info)
{
memset(info, 0, sizeof(*info));
info->instance_count = 1;
info->max_index = 0xffffffff;
}
static INLINE void
util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count)
{
struct pipe_draw_info info;
util_draw_init_info(&info);
info.mode = mode;
info.start = start;
info.count = count;
info.min_index = start;
info.max_index = start + count - 1;
pipe->draw_vbo(pipe, &info);
}
static INLINE void
util_draw_elements(struct pipe_context *pipe, int index_bias,
uint mode, uint start, uint count)
{
struct pipe_draw_info info;
util_draw_init_info(&info);
info.indexed = TRUE;
info.mode = mode;
info.start = start;
info.count = count;
info.index_bias = index_bias;
pipe->draw_vbo(pipe, &info);
}
static INLINE void
util_draw_arrays_instanced(struct pipe_context *pipe,
uint mode, uint start, uint count,
uint start_instance,
uint instance_count)
{
struct pipe_draw_info info;
util_draw_init_info(&info);
info.mode = mode;
info.start = start;
info.count = count;
info.start_instance = start_instance;
info.instance_count = instance_count;
info.min_index = start;
info.max_index = start + count - 1;
pipe->draw_vbo(pipe, &info);
}
static INLINE void
util_draw_elements_instanced(struct pipe_context *pipe,
int index_bias,
uint mode, uint start, uint count,
uint start_instance,
uint instance_count)
{
struct pipe_draw_info info;
util_draw_init_info(&info);
info.indexed = TRUE;
info.mode = mode;
info.start = start;
info.count = count;
info.index_bias = index_bias;
info.start_instance = start_instance;
info.instance_count = instance_count;
pipe->draw_vbo(pipe, &info);
}
static INLINE void
util_draw_range_elements(struct pipe_context *pipe,
int index_bias,
uint min_index,
uint max_index,
uint mode, uint start, uint count)
{
struct pipe_draw_info info;
util_draw_init_info(&info);
info.indexed = TRUE;
info.mode = mode;
info.start = start;
info.count = count;
info.index_bias = index_bias;
info.min_index = min_index;
info.max_index = max_index;
pipe->draw_vbo(pipe, &info);
}
#endif

View File

@ -60,7 +60,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
/* note: vertex elements already set by caller */
/* draw */
pipe->draw_arrays(pipe, prim_type, 0, num_verts);
util_draw_arrays(pipe, prim_type, 0, num_verts);
}

View File

@ -29,12 +29,18 @@
#define U_DRAWQUAD_H
#include "pipe/p_compiler.h"
#include "pipe/p_context.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pipe_resource;
#include "util/u_draw.h"
extern void
util_draw_vertex_buffer(struct pipe_context *pipe,
struct pipe_resource *vbuf, uint offset,

View File

@ -121,6 +121,15 @@ util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
* A.k.a. D3DFMT_CxV8U8
*/
static uint8_t
r8g8bx_derive(int16_t r, int16_t g)
{
/* Derive blue from red and green components.
* Apparently, we must always use integers to perform calculations,
* otherwise the results won't match D3D's CxV8U8 definition.
*/
return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f;
}
void
util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
@ -145,7 +154,7 @@ util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
dst[0] = (float)(r * (1.0f/0x7f)); /* r */
dst[1] = (float)(g * (1.0f/0x7f)); /* g */
dst[2] = sqrtf(1.0f - dst[0] * dst[0] - dst[1] * dst[1]); /* b */
dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */
dst[3] = 1.0f; /* a */
dst += 4;
}
@ -177,7 +186,7 @@ util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid
dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */
dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */
dst[2] = (uint8_t)sqrtf(0x7f*0x7f - r * r - g * g) * 0xff / 0x7f; /* b */
dst[2] = r8g8bx_derive(r, g); /* b */
dst[3] = 255; /* a */
dst += 4;
}
@ -262,6 +271,6 @@ util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src,
dst[0] = r * (1.0f/0x7f); /* r */
dst[1] = g * (1.0f/0x7f); /* g */
dst[2] = sqrtf(1.0f - dst[0] * dst[0] - dst[1] * dst[1]); /* b */
dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */
dst[3] = 1.0f; /* a */
}

View File

@ -425,6 +425,53 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color *
}
}
/* Integer versions of util_pack_z and util_pack_z_stencil - useful for
* constructing clear masks.
*/
static INLINE uint
util_pack_uint_z(enum pipe_format format, unsigned z)
{
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
return z & 0xffff;
case PIPE_FORMAT_Z32_UNORM:
case PIPE_FORMAT_Z32_FLOAT:
return z;
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
case PIPE_FORMAT_Z24X8_UNORM:
return z & 0xffffff;
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
return (z & 0xffffff) << 8;
case PIPE_FORMAT_S8_USCALED:
return 0;
default:
debug_print_format("gallium: unhandled format in util_pack_z()", format);
assert(0);
return 0;
}
}
static INLINE uint
util_pack_uint_z_stencil(enum pipe_format format, double z, uint s)
{
unsigned packed = util_pack_uint_z(format, z);
s &= 0xff;
switch (format) {
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return packed | (s << 24);
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return packed | s;
case PIPE_FORMAT_S8_USCALED:
return packed | s;
default:
return packed;
}
}
/**
* Note: it's assumed that z is in [0,1]

View File

@ -108,6 +108,20 @@ static INLINE boolean u_trim_pipe_prim( unsigned pipe_prim, unsigned *nr )
ok = (*nr >= 4);
*nr -= (*nr % 2);
break;
case PIPE_PRIM_LINES_ADJACENCY:
ok = (*nr >= 4);
*nr -= (*nr % 4);
break;
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
ok = (*nr >= 4);
break;
case PIPE_PRIM_TRIANGLES_ADJACENCY:
ok = (*nr >= 6);
*nr -= (*nr % 5);
break;
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
ok = (*nr >= 4);
break;
default:
ok = 0;
break;

View File

@ -41,7 +41,6 @@
#if defined(PIPE_ARCH_SSE)
#include <xmmintrin.h>
#include <emmintrin.h>

View File

@ -66,9 +66,6 @@ Unordered access view: view supporting random read/write access (usually from co
clear
+ Gallium supports clearing both render targets and depth/stencil with a single call
draw_range_elements
+ Gallium supports indexed draw with explicit range
fence_signalled
fence_finish
+ D3D10/D3D11 don't appear to support explicit fencing; queries can often substitute though, and flushing is supported
@ -271,31 +268,27 @@ Dispatch (D3D11 only)
DispatchIndirect (D3D11 only)
- Gallium does not support compute shaders
Draw -> draw_arrays
Draw -> draw_vbo
! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
DrawAuto -> draw_auto
DrawIndexed -> draw_elements
DrawIndexed -> draw_vbo
! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
* may want to add a separate set_index_buffer
- Gallium lacks base vertex for indexed draw calls
+ D3D11 lacks draw_range_elements functionality, which is required for OpenGL
+ D3D11 lacks explicit range, which is required for OpenGL
DrawIndexedInstanced -> draw_elements_instanced
DrawIndexedInstanced -> draw_vbo
! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
* may want to add a separate set_index_buffer
- Gallium lacks base vertex for indexed draw calls
DrawIndexedInstancedIndirect (D3D11 only) -> call draw_elements_instanced multiple times in software
# this allows to use an hardware buffer to specify the parameters for multiple draw_elements_instanced calls
DrawIndexedInstancedIndirect (D3D11 only)
# this allows to use an hardware buffer to specify the parameters for multiple draw_vbo calls
- Gallium does not support draw call parameter buffers and indirect draw
DrawInstanced -> draw_arrays_instanced
DrawInstanced -> draw_vbo
! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
DrawInstancedIndirect (D3D11 only) -> call draw_arrays_instanced multiple times in software
# this allows to use an hardware buffer to specify the parameters for multiple draw_arrays_instanced calls
DrawInstancedIndirect (D3D11 only)
# this allows to use an hardware buffer to specify the parameters for multiple draw_vbo calls
- Gallium does not support draw call parameter buffers and indirect draws
DsSetConstantBuffers (D3D11 only)
@ -332,10 +325,9 @@ HsSetShaderResources (D3D11 only)
HsSetShaderWithIfaces (D3D11 only)
- Gallium does not support hull shaders
IaSetIndexBuffer
! Gallium passes this to the draw_elements or draw_elements_instanced calls
IaSetIndexBuffer -> set_index_buffer
+ Gallium supports 8-bit indices
! the D3D11 interface allows index-size-unaligned byte offsets into index buffers; it's not clear whether they actually work
# the D3D11 interface allows index-size-unaligned byte offsets into the index buffer; most drivers will abort with an assertion
IaSetInputLayout -> bind_vertex_elements_state

View File

@ -38,7 +38,7 @@ master_doc = 'index'
# General information about the project.
project = u'Gallium'
copyright = u'2009, VMWare, X.org, Nouveau'
copyright = u'2009, VMware, X.org, Nouveau'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@ -176,7 +176,7 @@ htmlhelp_basename = 'Galliumdoc'
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'Gallium.tex', u'Gallium Documentation',
u'VMWare, X.org, Nouveau', 'manual'),
u'VMware, X.org, Nouveau', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of

View File

@ -45,6 +45,7 @@ buffers, surfaces) are bound to the driver.
* ``set_vertex_buffers``
* ``set_index_buffer``
Non-CSO State
^^^^^^^^^^^^^
@ -132,50 +133,26 @@ this surface need not be bound to the framebuffer.
Drawing
^^^^^^^
``draw_arrays`` draws a specified primitive.
``draw_vbo`` draws a specified primitive. The primitive mode and other
properties are described by ``pipe_draw_info``.
This command is equivalent to calling ``draw_arrays_instanced``
with ``startInstance`` set to 0 and ``instanceCount`` set to 1.
The ``mode``, ``start``, and ``count`` fields of ``pipe_draw_info`` specify the
the mode of the primitive and the vertices to be fetched, in the range between
``start`` to ``start``+``count``-1, inclusive.
``draw_elements`` draws a specified primitive using an optional
index buffer.
Every instance with instanceID in the range between ``start_instance`` and
``start_instance``+``instance_count``-1, inclusive, will be drawn.
This command is equivalent to calling ``draw_elements_instanced``
with ``startInstance`` set to 0 and ``instanceCount`` set to 1.
All vertex indices must fall inside the range given by ``min_index`` and
``max_index``. In case non-indexed draw, ``min_index`` should be set to
``start`` and ``max_index`` should be set to ``start``+``count``-1.
``draw_range_elements``
``index_bias`` is a value added to every vertex index before fetching vertex
attributes. It does not affect ``min_index`` and ``max_index``.
XXX: this is (probably) a temporary entrypoint, as the range
information should be available from the vertex_buffer state.
Using this to quickly evaluate a specialized path in the draw
module.
``draw_arrays_instanced`` draws multiple instances of the same primitive.
This command is equivalent to calling ``draw_elements_instanced``
with ``indexBuffer`` set to NULL and ``indexSize`` set to 0.
``draw_elements_instanced`` draws multiple instances of the same primitive
using an optional index buffer.
For instanceID in the range between ``startInstance``
and ``startInstance``+``instanceCount``-1, inclusive, draw a primitive
specified by ``mode`` and sequential numbers in the range between ``start``
and ``start``+``count``-1, inclusive.
If ``indexBuffer`` is not NULL, it specifies an index buffer with index
byte size of ``indexSize``. The sequential numbers are used to lookup
the index buffer and the resulting indices in turn are used to fetch
vertex attributes.
If ``indexBuffer`` is NULL, the sequential numbers are used directly
as indices to fetch vertex attributes.
``indexBias`` is a value which is added to every index read from the index
buffer before fetching vertex attributes.
``minIndex`` and ``maxIndex`` describe minimum and maximum index contained in
the index buffer.
If there is an index buffer bound, and ``indexed`` field is true, all vertex
indices will be looked up in the index buffer. ``min_index``, ``max_index``,
and ``index_bias`` apply after index lookup.
If a given vertex element has ``instance_divisor`` set to 0, it is said
it contains per-vertex data and effective vertex attribute address needs

View File

@ -126,11 +126,15 @@ sprite_coord_enable
Specifies if a texture unit has its texture coordinates replaced or not. This
is a packed bitfield containing the enable for all texcoords -- if all bits
are zero, point sprites are effectively disabled. If any bit is set, then
point_smooth and point_quad_rasterization are ignored; point smoothing is
disabled and points are always rasterized as quads. If enabled, the four
vertices of the resulting quad will be assigned texture coordinates,
according to sprite_coord_mode.
are zero, point sprites are effectively disabled.
If any bit is set, then point_smooth MUST be disabled (there are no
round sprites) and point_quad_rasterization MUST be true (sprites are
always rasterized as quads). Any mismatch between these states should
be considered a bug in the state-tracker.
If enabled, the four vertices of the resulting quad will be assigned
texture coordinates, according to sprite_coord_mode.
sprite_coord_mode
^^^^^^^^^^^^^^^^^
@ -141,20 +145,23 @@ have coordinates (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left
vertex will have coordinates (0,0,0,1).
This state is used by :ref:`Draw` to generate texcoords.
.. note::
When geometry shaders are available, a special geometry shader could be
used instead of this functionality, to convert incoming points into quads
with the proper texture coordinates.
point_quad_rasterization
^^^^^^^^^^^^^^^^^^^^^^^^
Determines if points should be rasterized as quads or points. Certain APIs,
like Direct3D, always use quad rasterization for points, regardless of
whether point sprites are enabled or not. If this state is enabled, point
smoothing and antialiasing are disabled. If it is disabled, point sprite
coordinates are not generated.
Determines if points should be rasterized according to quad or point
rasterization rules.
OpenGL actually has quite different rasterization rules for points and
point sprites - hence this indicates if points should be rasterized as
points or according to point sprite (which decomposes them into quads,
basically) rules.
Additionally Direct3D will always use quad rasterization rules for
points, regardless of whether point sprites are enabled or not.
If this state is enabled, point smoothing and antialiasing are
disabled. If it is disabled, point sprite coordinates are not
generated.
.. note::

View File

@ -51,10 +51,10 @@ nVidia nv50
Driver for the nVidia nv50 family of GPUs.
VMWare SVGA
VMware SVGA
^^^^^^^^^^^
Driver for VMWare virtualized guest operating system graphics processing.
Driver for VMware virtualized guest operating system graphics processing.
ATI r300
^^^^^^^^

View File

@ -230,7 +230,7 @@ struct cell_command_rasterizer
{
opcode_t opcode; /**< CELL_CMD_STATE_RASTERIZER */
struct pipe_rasterizer_state rasterizer;
uint32_t pad[1];
/*uint32_t pad[1];*/
};

View File

@ -132,6 +132,7 @@ struct cell_context
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers;
struct pipe_index_buffer index_buffer;
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map;
@ -154,7 +155,7 @@ struct cell_context
struct vertex_info vertex_info;
/** Mapped constant buffers */
void *mapped_constants[PIPE_SHADER_TYPES];
const void *mapped_constants[PIPE_SHADER_TYPES];
PIPE_ALIGN_VAR(16) struct cell_spu_function_info spu_functions;

View File

@ -56,16 +56,11 @@
* XXX should the element buffer be specified/bound with a separate function?
*/
static void
cell_draw_range_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
int indexBias,
unsigned min_index,
unsigned max_index,
unsigned mode, unsigned start, unsigned count)
cell_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct cell_context *cell = cell_context(pipe);
struct draw_context *draw = cell->draw;
void *mapped_indices = NULL;
unsigned i;
if (cell->dirty)
@ -83,18 +78,20 @@ cell_draw_range_elements(struct pipe_context *pipe,
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
void *mapped_indexes = cell_resource(indexBuffer)->data;
draw_set_mapped_element_buffer(draw, indexSize, indexBias, mapped_indexes);
}
else {
/* no index/element buffer */
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
if (info->indexed && cell->index_buffer.buffer) {
mapped_indices = cell_resource(cell->index_buffer.buffer)->data;
mapped_indices += cell->index_buffer.offset;
}
draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
lp->index_buffer.index_size : 0,
info->index_bias,
info->min_index,
info->max_index,
mapped_indices);
/* draw! */
draw_arrays(draw, mode, start, count);
draw_arrays(draw, info->mode, info->start, info->count);
/*
* unmap vertex/index buffers - will cause draw module to flush
@ -102,7 +99,7 @@ cell_draw_range_elements(struct pipe_context *pipe,
for (i = 0; i < cell->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
if (indexBuffer) {
if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
@ -115,32 +112,9 @@ cell_draw_range_elements(struct pipe_context *pipe,
}
static void
cell_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize, int indexBias,
unsigned mode, unsigned start, unsigned count)
{
cell_draw_range_elements( pipe, indexBuffer,
indexSize, indexBias,
0, 0xffffffff,
mode, start, count );
}
static void
cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count)
{
cell_draw_elements(pipe, NULL, 0, 0, mode, start, count);
}
void
cell_init_draw_functions(struct cell_context *cell)
{
cell->pipe.draw_arrays = cell_draw_arrays;
cell->pipe.draw_elements = cell_draw_elements;
cell->pipe.draw_range_elements = cell_draw_range_elements;
cell->pipe.draw_vbo = cell_draw_vbo;
}

View File

@ -87,6 +87,7 @@ struct cell_buffer_node
};
#if 0
static void
cell_add_buffer_to_list(struct cell_context *cell,
struct cell_buffer_list *list,
@ -100,6 +101,7 @@ cell_add_buffer_to_list(struct cell_context *cell,
list->head = node;
}
}
#endif
/**
@ -113,7 +115,7 @@ cell_free_fenced_buffers(struct cell_context *cell,
struct cell_buffer_list *list)
{
if (list->head) {
struct pipe_screen *ps = cell->pipe.screen;
/*struct pipe_screen *ps = cell->pipe.screen;*/
struct cell_buffer_node *node;
cell_fence_finish(cell, &list->fence);
@ -146,7 +148,7 @@ cell_free_fenced_buffers(struct cell_context *cell,
void
cell_add_fenced_textures(struct cell_context *cell)
{
struct cell_buffer_list *list = &cell->fenced_buffers[cell->cur_batch];
/*struct cell_buffer_list *list = &cell->fenced_buffers[cell->cur_batch];*/
uint i;
for (i = 0; i < cell->num_textures; i++) {

View File

@ -281,7 +281,7 @@ cell_set_fragment_sampler_views(struct pipe_context *pipe,
struct pipe_resource *new_tex = new_view ? new_view->texture : NULL;
pipe_sampler_view_reference(&cell->fragment_sampler_views[i],
views[i]);
new_view);
pipe_resource_reference((struct pipe_resource **) &cell->texture[i],
(struct pipe_resource *) new_tex);

View File

@ -36,7 +36,7 @@
#include "draw/draw_context.h"
void *
static void *
cell_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *attribs)
@ -51,7 +51,7 @@ cell_create_vertex_elements_state(struct pipe_context *pipe,
return velems;
}
void
static void
cell_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{
@ -66,7 +66,7 @@ cell_bind_vertex_elements_state(struct pipe_context *pipe,
draw_set_vertex_elements(cell->draw, cell_velems->count, cell_velems->velem);
}
void
static void
cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
@ -91,10 +91,26 @@ cell_set_vertex_buffers(struct pipe_context *pipe,
}
static void
cell_set_index_buffer(struct pipe_context *pipe,
const struct pipe_index_buffer *ib)
{
struct cell_context *cell = cell_context(pipe);
if (ib)
memcpy(&cell->index_buffer, ib, sizeof(cell->index_buffer));
else
memset(&cell->index_buffer, 0, sizeof(cell->index_buffer));
/* TODO make this more like a state */
}
void
cell_init_vertex_functions(struct cell_context *cell)
{
cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
cell->pipe.set_index_buffer = cell_set_index_buffer;
cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state;
cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state;
cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state;

View File

@ -50,13 +50,8 @@ void failover_fail_over( struct failover_context *failover )
}
static void failover_draw_elements( struct pipe_context *pipe,
struct pipe_resource *indexResource,
unsigned indexSize,
int indexBias,
unsigned prim,
unsigned start,
unsigned count)
static void failover_draw_vbo( struct pipe_context *pipe,
const struct pipe_draw_info *info)
{
struct failover_context *failover = failover_context( pipe );
@ -70,13 +65,7 @@ static void failover_draw_elements( struct pipe_context *pipe,
/* Try hardware:
*/
if (failover->mode == FO_HW) {
failover->hw->draw_elements( failover->hw,
indexResource,
indexSize,
indexBias,
prim,
start,
count );
failover->hw->draw_vbo( failover->hw, info );
}
/* Possibly try software:
@ -88,13 +77,7 @@ static void failover_draw_elements( struct pipe_context *pipe,
failover_state_emit( failover );
}
failover->sw->draw_elements( failover->sw,
indexResource,
indexSize,
indexBias,
prim,
start,
count );
failover->sw->draw_vbo( failover->sw, info );
/* Be ready to switch back to hardware rendering without an
* intervening flush. Unlikely to be much performance impact to
@ -104,13 +87,6 @@ static void failover_draw_elements( struct pipe_context *pipe,
}
}
static void failover_draw_arrays( struct pipe_context *pipe,
unsigned prim, unsigned start, unsigned count)
{
failover_draw_elements(pipe, NULL, 0, 0, prim, start, count);
}
static unsigned int
failover_is_resource_referenced( struct pipe_context *_pipe,
struct pipe_resource *resource,
@ -143,8 +119,7 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover->pipe.get_paramf = hw->get_paramf;
#endif
failover->pipe.draw_arrays = failover_draw_arrays;
failover->pipe.draw_elements = failover_draw_elements;
failover->pipe.draw_vbo = failover_draw_vbo;
failover->pipe.clear = hw->clear;
failover->pipe.clear_render_target = hw->clear_render_target;
failover->pipe.clear_depth_stencil = hw->clear_depth_stencil;

View File

@ -56,6 +56,7 @@
#define FO_NEW_VERTEX_BUFFER 0x40000
#define FO_NEW_VERTEX_ELEMENT 0x80000
#define FO_NEW_SAMPLE_MASK 0x100000
#define FO_NEW_INDEX_BUFFER 0x200000
@ -97,6 +98,7 @@ struct failover_context {
struct pipe_scissor_state scissor;
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer index_buffer;
uint num_vertex_buffers;

View File

@ -583,6 +583,23 @@ failover_set_vertex_buffers(struct pipe_context *pipe,
}
static void
failover_set_index_buffer(struct pipe_context *pipe,
const struct pipe_index_buffer *ib)
{
struct failover_context *failover = failover_context(pipe);
if (ib)
memcpy(&failover->index_buffer, ib, sizeof(failover->index_buffer));
else
memset(&failover->index_buffer, 0, sizeof(failover->index_buffer));
failover->dirty |= FO_NEW_INDEX_BUFFER;
failover->sw->set_index_buffer( failover->sw, ib );
failover->hw->set_index_buffer( failover->hw, ib );
}
void
failover_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
@ -635,6 +652,7 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views;
failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
failover->pipe.set_index_buffer = failover_set_index_buffer;
failover->pipe.set_constant_buffer = failover_set_constant_buffer;
failover->pipe.create_sampler_view = failover_create_sampler_view;
failover->pipe.sampler_view_destroy = failover_sampler_view_destroy;

View File

@ -135,5 +135,10 @@ failover_state_emit( struct failover_context *failover )
failover->vertex_buffers );
}
if (failover->dirty & FO_NEW_INDEX_BUFFER) {
failover->sw->set_index_buffer( failover->sw,
&failover->index_buffer );
}
failover->dirty = 0;
}

View File

@ -48,68 +48,13 @@ galahad_destroy(struct pipe_context *_pipe)
}
static void
galahad_draw_arrays(struct pipe_context *_pipe,
unsigned prim,
unsigned start,
unsigned count)
galahad_draw_vbo(struct pipe_context *_pipe,
const struct pipe_draw_info *info)
{
struct galahad_context *glhd_pipe = galahad_context(_pipe);
struct pipe_context *pipe = glhd_pipe->pipe;
pipe->draw_arrays(pipe,
prim,
start,
count);
}
static void
galahad_draw_elements(struct pipe_context *_pipe,
struct pipe_resource *_indexResource,
unsigned indexSize,
int indexBias,
unsigned prim,
unsigned start,
unsigned count)
{
struct galahad_context *glhd_pipe = galahad_context(_pipe);
struct galahad_resource *glhd_resource = galahad_resource(_indexResource);
struct pipe_context *pipe = glhd_pipe->pipe;
struct pipe_resource *indexResource = glhd_resource->resource;
pipe->draw_elements(pipe,
indexResource,
indexSize,
indexBias,
prim,
start,
count);
}
static void
galahad_draw_range_elements(struct pipe_context *_pipe,
struct pipe_resource *_indexResource,
unsigned indexSize,
int indexBias,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
unsigned start,
unsigned count)
{
struct galahad_context *glhd_pipe = galahad_context(_pipe);
struct galahad_resource *glhd_resource = galahad_resource(_indexResource);
struct pipe_context *pipe = glhd_pipe->pipe;
struct pipe_resource *indexResource = glhd_resource->resource;
pipe->draw_range_elements(pipe,
indexResource,
indexSize,
indexBias,
minIndex,
maxIndex,
mode,
start,
count);
pipe->draw_vbo(pipe, info);
}
static struct pipe_query *
@ -650,6 +595,41 @@ galahad_set_vertex_buffers(struct pipe_context *_pipe,
num_buffers,
buffers);
}
static void
galahad_set_index_buffer(struct pipe_context *_pipe,
const struct pipe_index_buffer *_ib)
{
struct galahad_context *glhd_pipe = galahad_context(_pipe);
struct pipe_context *pipe = glhd_pipe->pipe;
struct pipe_index_buffer unwrapped_ib, *ib = NULL;
if (_ib->buffer) {
switch (_ib->index_size) {
case 1:
case 2:
case 4:
break;
default:
glhd_warn("index buffer %p has unrecognized index size %d",
_ib->buffer, _ib->index_size);
break;
}
}
else if (_ib->offset || _ib->index_size) {
glhd_warn("non-indexed state with index offset %d and index size %d",
_ib->offset, _ib->index_size);
}
if (_ib) {
unwrapped_ib = *_ib;
unwrapped_ib.buffer = galahad_resource_unwrap(_ib->buffer);
ib = &unwrapped_ib;
}
pipe->set_index_buffer(pipe, ib);
}
static void
galahad_resource_copy_region(struct pipe_context *_pipe,
struct pipe_resource *_dst,
@ -934,9 +914,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
glhd_pipe->base.draw = NULL;
glhd_pipe->base.destroy = galahad_destroy;
glhd_pipe->base.draw_arrays = galahad_draw_arrays;
glhd_pipe->base.draw_elements = galahad_draw_elements;
glhd_pipe->base.draw_range_elements = galahad_draw_range_elements;
glhd_pipe->base.draw_vbo = galahad_draw_vbo;
glhd_pipe->base.create_query = galahad_create_query;
glhd_pipe->base.destroy_query = galahad_destroy_query;
glhd_pipe->base.begin_query = galahad_begin_query;
@ -976,6 +954,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
glhd_pipe->base.set_fragment_sampler_views = galahad_set_fragment_sampler_views;
glhd_pipe->base.set_vertex_sampler_views = galahad_set_vertex_sampler_views;
glhd_pipe->base.set_vertex_buffers = galahad_set_vertex_buffers;
glhd_pipe->base.set_index_buffer = galahad_set_index_buffer;
glhd_pipe->base.resource_copy_region = galahad_resource_copy_region;
glhd_pipe->base.clear = galahad_clear;
glhd_pipe->base.clear_render_target = galahad_clear_render_target;

View File

@ -45,16 +45,11 @@
static void
i915_draw_range_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
int indexBias,
unsigned min_index,
unsigned max_index,
unsigned prim, unsigned start, unsigned count)
i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct i915_context *i915 = i915_context(pipe);
struct draw_context *draw = i915->draw;
void *mapped_indices = NULL;
unsigned i;
if (i915->dirty)
@ -71,16 +66,18 @@ i915_draw_range_elements(struct pipe_context *pipe,
/*
* Map index buffer, if present
*/
if (indexBuffer) {
void *mapped_indexes = i915_buffer(indexBuffer)->data;
draw_set_mapped_element_buffer_range(draw, indexSize, indexBias,
min_index,
max_index,
mapped_indexes);
} else {
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
if (info->indexed && i915->index_buffer.buffer) {
char *indices = (char *) i915_buffer(i915->index_buffer.buffer)->data;
mapped_indices = (void *) (indices + i915->index_buffer.offset);
}
draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
i915->index_buffer.index_size : 0,
info->index_bias,
info->min_index,
info->max_index,
mapped_indices);
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
i915->current.constants[PIPE_SHADER_VERTEX],
@ -90,7 +87,7 @@ i915_draw_range_elements(struct pipe_context *pipe,
/*
* Do the drawing
*/
draw_arrays(i915->draw, prim, start, count);
draw_arrays(i915->draw, info->mode, info->start, info->count);
/*
* unmap vertex/index buffers
@ -99,32 +96,11 @@ i915_draw_range_elements(struct pipe_context *pipe,
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
if (indexBuffer) {
if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
}
static void
i915_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize, int indexBias,
unsigned prim, unsigned start, unsigned count)
{
i915_draw_range_elements(pipe, indexBuffer,
indexSize, indexBias,
0, 0xffffffff,
prim, start, count);
}
static void
i915_draw_arrays(struct pipe_context *pipe,
unsigned prim, unsigned start, unsigned count)
{
i915_draw_elements(pipe, NULL, 0, 0, prim, start, count);
}
/*
* Generic context functions
@ -168,9 +144,7 @@ i915_create_context(struct pipe_screen *screen, void *priv)
i915->base.clear = i915_clear;
i915->base.draw_arrays = i915_draw_arrays;
i915->base.draw_elements = i915_draw_elements;
i915->base.draw_range_elements = i915_draw_range_elements;
i915->base.draw_vbo = i915_draw_vbo;
/*
* Create drawing context and plug our rendering stage into it.

View File

@ -221,6 +221,7 @@ struct i915_context
struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer index_buffer;
unsigned dirty;

View File

@ -812,6 +812,19 @@ i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
FREE( velems );
}
static void i915_set_index_buffer(struct pipe_context *pipe,
const struct pipe_index_buffer *ib)
{
struct i915_context *i915 = i915_context(pipe);
if (ib)
memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer));
else
memset(&i915->index_buffer, 0, sizeof(i915->index_buffer));
/* TODO make this more like a state */
}
static void
i915_set_sample_mask(struct pipe_context *pipe,
unsigned sample_mask)
@ -860,4 +873,5 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.sampler_view_destroy = i915_sampler_view_destroy;
i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers;
i915->base.set_index_buffer = i915_set_index_buffer;
}

View File

@ -576,6 +576,7 @@ struct brw_context
*/
struct pipe_resource *index_buffer;
unsigned index_size;
unsigned index_offset;
/* Updates are signalled by PIPE_NEW_INDEX_RANGE:
*/

View File

@ -142,7 +142,7 @@ static int brw_emit_prim(struct brw_context *brw,
*/
static int
try_draw_range_elements(struct brw_context *brw,
struct pipe_resource *index_buffer,
boolean indexed,
unsigned hw_prim,
unsigned start, unsigned count)
{
@ -165,7 +165,7 @@ try_draw_range_elements(struct brw_context *brw,
if (ret)
return ret;
ret = brw_emit_prim(brw, start, count, index_buffer != NULL, hw_prim);
ret = brw_emit_prim(brw, start, count, indexed, hw_prim);
if (ret)
return ret;
@ -177,91 +177,54 @@ try_draw_range_elements(struct brw_context *brw,
static void
brw_draw_range_elements(struct pipe_context *pipe,
struct pipe_resource *index_buffer,
unsigned index_size, int index_bias,
unsigned min_index,
unsigned max_index,
unsigned mode, unsigned start, unsigned count)
brw_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct brw_context *brw = brw_context(pipe);
int ret;
uint32_t hw_prim;
hw_prim = brw_set_prim(brw, mode);
hw_prim = brw_set_prim(brw, info->mode);
if (BRW_DEBUG & DEBUG_PRIMS)
debug_printf("PRIM: %s start %d count %d index_buffer %p\n",
u_prim_name(mode), start, count, (void *)index_buffer);
u_prim_name(info->mode), info->start, info->count,
(void *) brw->curr.index_buffer);
assert(index_bias == 0);
assert(info->index_bias == 0);
/* Potentially trigger upload of new index buffer.
*
* XXX: do we need to go through state validation to achieve this?
* Could just call upload code directly.
/* Potentially trigger upload of new index buffer range.
* XXX: do we really care?
*/
if (brw->curr.index_buffer != index_buffer ||
brw->curr.index_size != index_size) {
pipe_resource_reference( &brw->curr.index_buffer, index_buffer );
brw->curr.index_size = index_size;
brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
}
/* XXX: do we really care?
*/
if (brw->curr.min_index != min_index ||
brw->curr.max_index != max_index)
if (brw->curr.min_index != info->min_index ||
brw->curr.max_index != info->max_index)
{
brw->curr.min_index = min_index;
brw->curr.max_index = max_index;
brw->curr.min_index = info->min_index;
brw->curr.max_index = info->max_index;
brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE;
}
/* Make a first attempt at drawing:
*/
ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
ret = try_draw_range_elements(brw, info->indexed,
hw_prim, info->start, info->count);
/* Otherwise, flush and retry:
*/
if (ret != 0) {
brw_context_flush( brw );
ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
ret = try_draw_range_elements(brw, info->indexed,
hw_prim, info->start, info->count);
assert(ret == 0);
}
}
static void
brw_draw_elements(struct pipe_context *pipe,
struct pipe_resource *index_buffer,
unsigned index_size, int index_bias,
unsigned mode,
unsigned start, unsigned count)
{
brw_draw_range_elements( pipe, index_buffer,
index_size, index_bias,
0, 0xffffffff,
mode,
start, count );
}
static void
brw_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count)
{
brw_draw_elements(pipe, NULL, 0, 0, mode, start, count);
}
boolean brw_draw_init( struct brw_context *brw )
{
/* Register our drawing function:
*/
brw->base.draw_arrays = brw_draw_arrays;
brw->base.draw_elements = brw_draw_elements;
brw->base.draw_range_elements = brw_draw_range_elements;
brw->base.draw_vbo = brw_draw_vbo;
/* Create helpers for uploading data in user buffers:
*/

View File

@ -231,7 +231,7 @@ static int brw_prepare_indices(struct brw_context *brw)
struct pipe_resource *upload_buf = NULL;
struct brw_winsys_buffer *bo = NULL;
GLuint offset;
GLuint index_size;
GLuint index_size, index_offset;
GLuint ib_size;
int ret;
@ -246,13 +246,14 @@ static int brw_prepare_indices(struct brw_context *brw)
ib_size = index_buffer->width0;
index_size = brw->curr.index_size;
index_offset = brw->curr.index_offset;
/* Turn userbuffer into a proper hardware buffer?
*/
if (brw_buffer_is_user_buffer(index_buffer)) {
ret = u_upload_buffer( brw->vb.upload_index,
0,
index_offset,
ib_size,
index_buffer,
&offset,
@ -269,7 +270,7 @@ static int brw_prepare_indices(struct brw_context *brw)
else {
bo = brw_buffer(index_buffer)->bo;
ib_size = bo->size;
offset = 0;
offset = index_offset;
}
/* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the

View File

@ -274,10 +274,41 @@ static void brw_set_vertex_buffers(struct pipe_context *pipe,
}
static void brw_set_index_buffer(struct pipe_context *pipe,
const struct pipe_index_buffer *ib)
{
struct brw_context *brw = brw_context(pipe);
if (ib) {
if (brw->curr.index_buffer == ib->buffer &&
brw->curr.index_offset == ib->offset &&
brw->curr.index_size == ib->index_size)
return;
pipe_resource_reference(&brw->curr.index_buffer, ib->buffer);
brw->curr.index_offset = ib->offset;
brw->curr.index_size = ib->index_size;
}
else {
if (!brw->curr.index_buffer &&
!brw->curr.index_offset &&
!brw->curr.index_size)
return;
pipe_resource_reference(&brw->curr.index_buffer, NULL);
brw->curr.index_offset = 0;
brw->curr.index_size = 0;
}
brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
}
void
brw_pipe_vertex_init( struct brw_context *brw )
{
brw->base.set_vertex_buffers = brw_set_vertex_buffers;
brw->base.set_index_buffer = brw_set_index_buffer;
brw->base.create_vertex_elements_state = brw_create_vertex_elements_state;
brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state;
brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state;

View File

@ -46,68 +46,13 @@ identity_destroy(struct pipe_context *_pipe)
}
static void
identity_draw_arrays(struct pipe_context *_pipe,
unsigned prim,
unsigned start,
unsigned count)
identity_draw_vbo(struct pipe_context *_pipe,
const struct pipe_draw_info *info)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
pipe->draw_arrays(pipe,
prim,
start,
count);
}
static void
identity_draw_elements(struct pipe_context *_pipe,
struct pipe_resource *_indexResource,
unsigned indexSize,
int indexBias,
unsigned prim,
unsigned start,
unsigned count)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct identity_resource *id_resource = identity_resource(_indexResource);
struct pipe_context *pipe = id_pipe->pipe;
struct pipe_resource *indexResource = id_resource->resource;
pipe->draw_elements(pipe,
indexResource,
indexSize,
indexBias,
prim,
start,
count);
}
static void
identity_draw_range_elements(struct pipe_context *_pipe,
struct pipe_resource *_indexResource,
unsigned indexSize,
int indexBias,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
unsigned start,
unsigned count)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct identity_resource *id_resource = identity_resource(_indexResource);
struct pipe_context *pipe = id_pipe->pipe;
struct pipe_resource *indexResource = id_resource->resource;
pipe->draw_range_elements(pipe,
indexResource,
indexSize,
indexBias,
minIndex,
maxIndex,
mode,
start,
count);
pipe->draw_vbo(pipe, info);
}
static struct pipe_query *
@ -611,6 +556,24 @@ identity_set_vertex_buffers(struct pipe_context *_pipe,
num_buffers,
buffers);
}
static void
identity_set_index_buffer(struct pipe_context *_pipe,
const struct pipe_index_buffer *_ib)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
struct pipe_index_buffer unwrapped_ib, *ib = NULL;
if (_ib) {
unwrapped_ib = *_ib;
unwrapped_ib.buffer = identity_resource_unwrap(_ib->buffer);
ib = &unwrapped_ib;
}
pipe->set_index_buffer(pipe, ib);
}
static void
identity_resource_copy_region(struct pipe_context *_pipe,
struct pipe_resource *_dst,
@ -889,9 +852,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.draw = NULL;
id_pipe->base.destroy = identity_destroy;
id_pipe->base.draw_arrays = identity_draw_arrays;
id_pipe->base.draw_elements = identity_draw_elements;
id_pipe->base.draw_range_elements = identity_draw_range_elements;
id_pipe->base.draw_vbo = identity_draw_vbo;
id_pipe->base.create_query = identity_create_query;
id_pipe->base.destroy_query = identity_destroy_query;
id_pipe->base.begin_query = identity_begin_query;
@ -931,6 +892,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views;
id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
id_pipe->base.set_index_buffer = identity_set_index_buffer;
id_pipe->base.resource_copy_region = identity_resource_copy_region;
id_pipe->base.clear = identity_clear;
id_pipe->base.clear_render_target = identity_clear_render_target;

View File

@ -1,3 +1,4 @@
from sys import executable as python_cmd
import distutils.version
Import('*')
@ -16,7 +17,7 @@ env.CodeGenerate(
target = 'lp_tile_soa.c',
script = 'lp_tile_soa.py',
source = ['#src/gallium/auxiliary/util/u_format.csv'],
command = 'python $SCRIPT $SOURCE > $TARGET'
command = python_cmd + ' $SCRIPT $SOURCE > $TARGET'
)
# XXX: Our dependency scanner only finds depended modules in relative dirs.

View File

@ -258,16 +258,16 @@ lp_build_stencil_op_single(struct lp_build_context *bld,
}
if (stencil->writemask != stencilMax) {
/* compute res = (res & mask) | (stencilVals & ~mask) */
LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask);
LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask");
LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1");
LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2");
res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2");
/* mask &= stencil->writemask */
LLVMValueRef writemask = lp_build_const_int_vec(type, stencil->writemask);
mask = LLVMBuildAnd(bld->builder, mask, writemask, "");
/* res = (res & mask) | (stencilVals & ~mask) */
res = lp_build_select_bitwise(bld, writemask, res, stencilVals);
}
else {
/* res = mask ? res : stencilVals */
res = lp_build_select(bld, mask, res, stencilVals);
}
/* only the update the vector elements enabled by 'mask' */
res = lp_build_select(bld, mask, res, stencilVals);
return res;
}
@ -662,9 +662,9 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
}
/* Mix the old and new Z buffer values.
* z_dst[i] = zselectmask[i] ? z_src[i] : z_dst[i]
* z_dst[i] = (zselectmask[i] & z_src[i]) | (~zselectmask[i] & z_dst[i])
*/
z_dst = lp_build_select(&bld, zselectmask, z_src, z_dst);
z_dst = lp_build_select_bitwise(&bld, zselectmask, z_src, z_dst);
}
if (stencil[0].enabled) {

View File

@ -46,6 +46,10 @@
#include "lp_query.h"
#include "lp_setup.h"
DEBUG_GET_ONCE_BOOL_OPTION(lp_no_rast, "LP_NO_RAST", FALSE);
static void llvmpipe_destroy( struct pipe_context *pipe )
{
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
@ -130,7 +134,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
/* FIXME: devise alternative to draw_texture_samplers */
if (debug_get_bool_option( "LP_NO_RAST", FALSE ))
if (debug_get_option_lp_no_rast())
llvmpipe->no_rast = TRUE;
llvmpipe->setup = lp_setup_create( &llvmpipe->pipe,

View File

@ -77,6 +77,7 @@ struct llvmpipe_context {
struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer index_buffer;
struct {
struct llvmpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
int offset[PIPE_MAX_SO_BUFFERS];

View File

@ -49,20 +49,11 @@
* the drawing to the 'draw' module.
*/
static void
llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
int indexBias,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
unsigned start,
unsigned count,
unsigned startInstance,
unsigned instanceCount)
llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct llvmpipe_context *lp = llvmpipe_context(pipe);
struct draw_context *draw = lp->draw;
void *mapped_indices = NULL;
unsigned i;
if (lp->dirty)
@ -77,27 +68,25 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
}
/* Map index buffer, if present */
if (indexBuffer) {
void *mapped_indexes = llvmpipe_resource_data(indexBuffer);
draw_set_mapped_element_buffer_range(draw,
indexSize,
indexBias,
minIndex,
maxIndex,
mapped_indexes);
}
else {
/* no index/element buffer */
draw_set_mapped_element_buffer_range(draw, 0, 0, start,
start + count - 1, NULL);
if (info->indexed && lp->index_buffer.buffer) {
char *indices = (char *) llvmpipe_resource_data(lp->index_buffer.buffer);
mapped_indices = (void *) (indices + lp->index_buffer.offset);
}
draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
lp->index_buffer.index_size : 0,
info->index_bias,
info->min_index,
info->max_index,
mapped_indices);
llvmpipe_prepare_vertex_sampling(lp,
lp->num_vertex_sampler_views,
lp->vertex_sampler_views);
/* draw! */
draw_arrays_instanced(draw, mode, start, count,
startInstance, instanceCount);
draw_arrays_instanced(draw, info->mode, info->start, info->count,
info->start_instance, info->instance_count);
/*
* unmap vertex/index buffers
@ -105,7 +94,7 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
for (i = 0; i < lp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
if (indexBuffer) {
if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
llvmpipe_cleanup_vertex_sampling(lp);
@ -119,112 +108,8 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
}
static void
llvmpipe_draw_arrays_instanced(struct pipe_context *pipe,
unsigned mode,
unsigned start,
unsigned count,
unsigned startInstance,
unsigned instanceCount)
{
llvmpipe_draw_range_elements_instanced(pipe,
NULL, /* no indexBuffer */
0, 0, /* indexSize, indexBias */
0, ~0, /* minIndex, maxIndex */
mode,
start,
count,
startInstance,
instanceCount);
}
static void
llvmpipe_draw_elements_instanced(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
int indexBias,
unsigned mode,
unsigned start,
unsigned count,
unsigned startInstance,
unsigned instanceCount)
{
llvmpipe_draw_range_elements_instanced(pipe,
indexBuffer,
indexSize, indexBias,
0, ~0, /* minIndex, maxIndex */
mode,
start,
count,
startInstance,
instanceCount);
}
static void
llvmpipe_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
int indexBias,
unsigned mode,
unsigned start,
unsigned count)
{
llvmpipe_draw_range_elements_instanced(pipe,
indexBuffer,
indexSize, indexBias,
0, 0xffffffff, /* min, maxIndex */
mode, start, count,
0, /* startInstance */
1); /* instanceCount */
}
static void
llvmpipe_draw_range_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
int indexBias,
unsigned min_index,
unsigned max_index,
unsigned mode,
unsigned start,
unsigned count)
{
llvmpipe_draw_range_elements_instanced(pipe,
indexBuffer,
indexSize, indexBias,
min_index, max_index,
mode, start, count,
0, /* startInstance */
1); /* instanceCount */
}
static void
llvmpipe_draw_arrays(struct pipe_context *pipe,
unsigned mode,
unsigned start,
unsigned count)
{
llvmpipe_draw_range_elements_instanced(pipe,
NULL, /* indexBuffer */
0, /* indexSize */
0, /* indexBias */
0, ~0, /* min, maxIndex */
mode, start, count,
0, /* startInstance */
1); /* instanceCount */
}
void
llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
llvmpipe->pipe.draw_arrays_instanced = llvmpipe_draw_arrays_instanced;
llvmpipe->pipe.draw_elements_instanced = llvmpipe_draw_elements_instanced;
llvmpipe->pipe.draw_vbo = llvmpipe_draw_vbo;
}

View File

@ -43,6 +43,12 @@
#include "lp_scene.h"
#ifdef DEBUG
int jit_line = 0;
const struct lp_rast_state *jit_state = NULL;
#endif
/**
* Begin rasterizing a scene.
* Called once per scene by one thread.
@ -368,14 +374,15 @@ lp_rast_store_linear_color( struct lp_rasterizer_task *task,
for (buf = 0; buf < rast->state.nr_cbufs; buf++) {
struct pipe_surface *cbuf = scene->fb.cbufs[buf];
const unsigned face = cbuf->face, level = cbuf->level;
const unsigned face_slice = cbuf->face + cbuf->zslice;
const unsigned level = cbuf->level;
struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture);
if (!task->color_tiles[buf])
continue;
llvmpipe_unswizzle_cbuf_tile(lpt,
face,
face_slice,
level,
task->x, task->y,
task->color_tiles[buf]);
@ -418,6 +425,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y);
/* run shader on 4x4 block */
BEGIN_JIT_CALL(state);
variant->jit_function[RAST_WHOLE]( &state->jit_context,
tile_x + x, tile_y + y,
inputs->facing,
@ -428,6 +436,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
depth,
0xffff,
&task->vis_counter);
END_JIT_CALL();
}
}
}
@ -497,6 +506,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
assert(lp_check_alignment(state->jit_context.blend_color, 16));
/* run shader on 4x4 block */
BEGIN_JIT_CALL(state);
variant->jit_function[RAST_EDGE_TEST](&state->jit_context,
x, y,
inputs->facing,
@ -507,6 +517,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
depth,
mask,
&task->vis_counter);
END_JIT_CALL();
}

View File

@ -40,6 +40,34 @@
#include "lp_limits.h"
/* If we crash in a jitted function, we can examine jit_line and jit_state
* to get some info. This is not thread-safe, however.
*/
#ifdef DEBUG
extern int jit_line;
extern const struct lp_rast_state *jit_state;
#define BEGIN_JIT_CALL(state) \
do { \
jit_line = __LINE__; \
jit_state = state; \
} while (0)
#define END_JIT_CALL() \
do { \
jit_line = 0; \
jit_state = NULL; \
} while (0)
#else
#define BEGIN_JIT_CALL(X)
#define END_JIT_CALL()
#endif
struct lp_rasterizer;
@ -249,6 +277,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
depth = lp_rast_get_depth_block_pointer(task, x, y);
/* run shader on 4x4 block */
BEGIN_JIT_CALL(state);
variant->jit_function[RAST_WHOLE]( &state->jit_context,
x, y,
inputs->facing,
@ -259,6 +288,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
depth,
0xffff,
&task->vis_counter );
END_JIT_CALL();
}

View File

@ -75,6 +75,7 @@
#include "gallivm/lp_bld_type.h"
#include "gallivm/lp_bld_const.h"
#include "gallivm/lp_bld_conv.h"
#include "gallivm/lp_bld_init.h"
#include "gallivm/lp_bld_intr.h"
#include "gallivm/lp_bld_logic.h"
#include "gallivm/lp_bld_tgsi.h"
@ -676,6 +677,11 @@ generate_fragment(struct llvmpipe_context *lp,
color_ptr);
}
#ifdef PIPE_ARCH_X86
/* Avoid corrupting the FPU stack on 32bit OSes. */
lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0);
#endif
LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(builder);
@ -710,6 +716,7 @@ generate_fragment(struct llvmpipe_context *lp,
if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(f);
}
lp_func_delete_body(function);
}
}

View File

@ -89,6 +89,19 @@ llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
}
static void
llvmpipe_set_index_buffer(struct pipe_context *pipe,
const struct pipe_index_buffer *ib)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
if (ib)
memcpy(&llvmpipe->index_buffer, ib, sizeof(llvmpipe->index_buffer));
else
memset(&llvmpipe->index_buffer, 0, sizeof(llvmpipe->index_buffer));
/* TODO make this more like a state */
}
void
llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe)
@ -98,4 +111,5 @@ llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe)
llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
llvmpipe->pipe.set_index_buffer = llvmpipe_set_index_buffer;
}

View File

@ -37,6 +37,7 @@
*/
#include "gallivm/lp_bld_init.h"
#include "gallivm/lp_bld_type.h"
#include "gallivm/lp_bld_debug.h"
#include "lp_bld_blend.h"
@ -485,8 +486,7 @@ test_one(unsigned verbose,
{
LLVMModuleRef module = NULL;
LLVMValueRef func = NULL;
LLVMExecutionEngineRef engine = NULL;
LLVMModuleProviderRef provider = NULL;
LLVMExecutionEngineRef engine = lp_build_engine;
LLVMPassManagerRef pass = NULL;
char *error = NULL;
blend_test_ptr_t blend_test_ptr;
@ -510,15 +510,6 @@ test_one(unsigned verbose,
}
LLVMDisposeMessage(error);
provider = LLVMCreateModuleProviderForExistingModule(module);
if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
if(verbose < 1)
dump_blend_type(stderr, blend, mode, type);
fprintf(stderr, "%s\n", error);
LLVMDisposeMessage(error);
abort();
}
#if 0
pass = LLVMCreatePassManager();
LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
@ -735,7 +726,6 @@ test_one(unsigned verbose,
LLVMFreeMachineCodeForFunction(engine, func);
LLVMDisposeExecutionEngine(engine);
if(pass)
LLVMDisposePassManager(pass);

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