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@ \ GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) @GLW_MESA_DEPS@ \
$(EXTRA_LIB_PATH) @GLW_LIB_DEPS@ $(EXTRA_LIB_PATH) @GLW_LIB_DEPS@
APP_LIB_DEPS = $(EXTRA_LIB_PATH) @APP_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@ GLESv2_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv2_LIB_DEPS@
VG_LIB_DEPS = $(EXTRA_LIB_PATH) @VG_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_LIB_PRIV])
AC_SUBST([GL_PC_CFLAGS]) AC_SUBST([GL_PC_CFLAGS])
AC_SUBST([DRI_PC_REQ_PRIV]) 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([GLESv1_CM_PC_LIB_PRIV])
AC_SUBST([GLESv2_LIB_DEPS]) AC_SUBST([GLESv2_LIB_DEPS])
AC_SUBST([GLESv2_PC_LIB_PRIV]) 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 */ 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, 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_config *conf;
struct dri2_egl_display *dri2_dpy; 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); _eglInitConfig(&base, disp, id);
i = 0; 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)) { while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) {
switch (attrib) { switch (attrib) {
case __DRI_ATTRIB_RENDER_TYPE: 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. */ * return in the getBuffer callback to get the behaviour we want. */
if (double_buffer) if (double_buffer)
return; return NULL;
if (visual != NULL) { if (depth > 0 && depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE))
if (depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE)) return NULL;
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);
}
_eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE); _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_SURFACE_TYPE, surface_type);
_eglSetConfigKey(&base, if (surface_type & (EGL_PIXMAP_BIT | EGL_PBUFFER_BIT)) {
EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba); _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_RENDERABLE_TYPE, disp->ClientAPIsMask);
_eglSetConfigKey(&base, EGL_CONFORMANT, disp->ClientAPIsMask); _eglSetConfigKey(&base, EGL_CONFORMANT, disp->ClientAPIsMask);
if (!_eglValidateConfig(&base, EGL_FALSE)) { if (!_eglValidateConfig(&base, EGL_FALSE)) {
_eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id);
return; return NULL;
} }
conf = malloc(sizeof *conf); conf = malloc(sizeof *conf);
@ -279,6 +275,8 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
conf->dri_config = dri_config; conf->dri_config = dri_config;
_eglAddConfig(disp, &conf->base); _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_depth_iterator_t d;
xcb_visualtype_t *visuals; xcb_visualtype_t *visuals;
int i, j, id; int i, j, id;
struct dri2_egl_config *conf;
EGLint surface_type;
s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
d = xcb_screen_allowed_depths_iterator(s.data); d = xcb_screen_allowed_depths_iterator(s.data);
id = 1; id = 1;
surface_type =
EGL_WINDOW_BIT |
EGL_PIXMAP_BIT |
EGL_PBUFFER_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
while (d.rem > 0) { while (d.rem > 0) {
EGLBoolean class_added[6] = { 0, }; EGLBoolean class_added[6] = { 0, };
@ -626,9 +633,16 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
continue; continue;
class_added[visuals[i]._class] = EGL_TRUE; class_added[visuals[i]._class] = EGL_TRUE;
for (j = 0; dri2_dpy->driver_configs[j]; j++) for (j = 0; dri2_dpy->driver_configs[j]; j++) {
dri2_add_config(disp, dri2_dpy->driver_configs[j], conf = dri2_add_config(disp, dri2_dpy->driver_configs[j],
id++, d.data->depth, &visuals[i]); 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); xcb_depth_next(&d);
@ -738,6 +752,12 @@ dri2_create_screen(_EGLDisplay *disp)
if (api_mask & (1 << __DRI_API_GLES2)) if (api_mask & (1 << __DRI_API_GLES2))
disp->ClientAPIsMask |= EGL_OPENGL_ES2_BIT; 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; return EGL_TRUE;
cleanup_dri_screen: cleanup_dri_screen:
@ -948,6 +968,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp,
EGLint *major, EGLint *minor) EGLint *major, EGLint *minor)
{ {
struct dri2_egl_display *dri2_dpy; struct dri2_egl_display *dri2_dpy;
int i;
dri2_dpy = malloc(sizeof *dri2_dpy); dri2_dpy = malloc(sizeof *dri2_dpy);
if (!dri2_dpy) if (!dri2_dpy)
@ -970,10 +991,17 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp,
if (!dri2_create_screen(disp)) if (!dri2_create_screen(disp))
goto cleanup_driver; 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_image_base = EGL_TRUE;
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
disp->Extensions.KHR_gl_texture_2D_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; return EGL_TRUE;
cleanup_driver: 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_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list); struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list);
struct dri2_egl_config *dri2_config = dri2_egl_config(conf); struct dri2_egl_config *dri2_config = dri2_egl_config(conf);
const __DRIconfig *dri_config;
int api; int api;
dri2_ctx = malloc(sizeof *dri2_ctx); dri2_ctx = malloc(sizeof *dri2_ctx);
@ -1074,11 +1103,16 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL; return NULL;
} }
if (conf != NULL)
dri_config = dri2_config->dri_config;
else
dri_config = NULL;
if (dri2_dpy->dri2->base.version >= 2) { if (dri2_dpy->dri2->base.version >= 2) {
dri2_ctx->dri_context = dri2_ctx->dri_context =
dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen, dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen,
api, api,
dri2_config->dri_config, dri_config,
dri2_ctx_shared ? dri2_ctx_shared ?
dri2_ctx_shared->dri_context : NULL, dri2_ctx_shared->dri_context : NULL,
dri2_ctx); dri2_ctx);

View File

@ -379,7 +379,11 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
_EGLContext *context; _EGLContext *context;
EGLContext ret; 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) if (!share && share_list != EGL_NO_CONTEXT)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, 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_VG_ALPHA_FORMAT_PRE_BIT |
EGL_MULTISAMPLE_RESOLVE_BOX_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_BIT; EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
#ifdef EGL_MESA_screen_surface
if (conf->Display->Extensions.MESA_screen_surface) if (conf->Display->Extensions.MESA_screen_surface)
mask |= EGL_SCREEN_BIT_MESA; mask |= EGL_SCREEN_BIT_MESA;
#endif
break; break;
case EGL_RENDERABLE_TYPE: case EGL_RENDERABLE_TYPE:
case EGL_CONFORMANT: 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; EGLint renderable_type, api_bit;
renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE); 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 * surface (oldDraw), the old bindings are broken first and the new one is
* created. * created.
*/ */
oldCtx = newDraw->CurrentContext; if (newDraw) {
if (newCtx != oldCtx) { oldCtx = newDraw->CurrentContext;
if (oldCtx) { if (newCtx != oldCtx) {
assert(oldCtx->DrawSurface == newDraw); if (oldCtx) {
oldCtx->DrawSurface = NULL; assert(oldCtx->DrawSurface == newDraw);
oldCtx->DrawSurface = NULL;
}
newDraw->CurrentContext = newCtx;
} }
}
if (newCtx) { if (newCtx) {
_EGLSurface *oldDraw = newCtx->DrawSurface; _EGLSurface *oldDraw = newCtx->DrawSurface;
if (oldDraw) if (oldDraw)
oldDraw->CurrentContext = NULL; oldDraw->CurrentContext = NULL;
newCtx->DrawSurface = newDraw; newCtx->DrawSurface = newDraw;
*draw = oldDraw; *draw = oldDraw;
}
newDraw->CurrentContext = newCtx;
} }
/* likewise */ /* likewise */
if (newRead != newDraw) if (newRead && newRead != newDraw) {
oldCtx = newRead->CurrentContext; oldCtx = newRead->CurrentContext;
if (newCtx != oldCtx) { if (newCtx != oldCtx) {
if (oldCtx) { if (oldCtx) {
assert(oldCtx->ReadSurface == newRead); assert(oldCtx->ReadSurface == newRead);
oldCtx->ReadSurface = NULL; 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) _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
{ {
_EGLThreadInfo *t = _eglGetCurrentThread(); _EGLThreadInfo *t = _eglGetCurrentThread();
_EGLDisplay *dpy;
EGLint conflict_api; EGLint conflict_api;
EGLBoolean surfaceless;
if (_eglIsCurrentThreadDummy()) if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
@ -309,8 +315,23 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
return EGL_TRUE; return EGL_TRUE;
} }
/* ctx/draw/read must be all given */ dpy = ctx->Resource.Display;
if (draw == NULL || read == NULL) 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"); return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
/* context stealing from another thread is not allowed */ /* 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. * The latter is more restrictive so we can check only the latter case.
*/ */
if ((draw->CurrentContext && draw->CurrentContext != ctx) || if ((draw && draw->CurrentContext && draw->CurrentContext != ctx) ||
(read->CurrentContext && read->CurrentContext != ctx)) (read && read->CurrentContext && read->CurrentContext != ctx))
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
/* simply require the configs to be equal */ /* 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"); return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
switch (ctx->ClientAPI) { switch (ctx->ClientAPI) {
@ -387,7 +409,6 @@ _eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read)
*draw = oldCtx->DrawSurface; *draw = oldCtx->DrawSurface;
*read = oldCtx->ReadSurface; *read = oldCtx->ReadSurface;
assert(*draw && *read);
_eglBindContextToSurfaces(NULL, draw, read); _eglBindContextToSurfaces(NULL, draw, read);
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -16,8 +16,6 @@ struct _egl_global
/* the list of all displays */ /* the list of all displays */
_EGLDisplay *DisplayList; _EGLDisplay *DisplayList;
EGLScreenMESA FreeScreenHandle;
EGLint NumAtExitCalls; EGLint NumAtExitCalls;
void (*AtExitCalls[10])(void); 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_texture_3D_image);
_EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_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_swap_region);
_EGL_CHECK_EXTENSION(NOK_texture_from_pixmap); _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
#undef _EGL_CHECK_EXTENSION #undef _EGL_CHECK_EXTENSION

View File

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

View File

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

View File

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

View File

@ -5,6 +5,9 @@
#include "egltypedefs.h" #include "egltypedefs.h"
#ifdef EGL_MESA_screen_surface
/** /**
* Per-screen information. * Per-screen information.
* Note that an EGL screen doesn't have a size. A screen may be set to * 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); _eglDestroyScreen(_EGLScreen *scrn);
#endif /* EGL_MESA_screen_surface */
#endif /* EGLSCREEN_INCLUDED */ #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. * 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) if (!attrib_list)
return EGL_SUCCESS; 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) if (dpy->Extensions.NOK_texture_from_pixmap)
texture_type |= EGL_PIXMAP_BIT; texture_type |= EGL_PIXMAP_BIT;
@ -52,12 +101,8 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
EGLint val = attrib_list[i]; EGLint val = attrib_list[i];
switch (attr) { switch (attr) {
/* common (except for screen surfaces) attributes */ /* common attributes */
case EGL_VG_COLORSPACE: case EGL_VG_COLORSPACE:
if (type == EGL_SCREEN_BIT_MESA) {
err = EGL_BAD_ATTRIBUTE;
break;
}
switch (val) { switch (val) {
case EGL_VG_COLORSPACE_sRGB: case EGL_VG_COLORSPACE_sRGB:
case EGL_VG_COLORSPACE_LINEAR: case EGL_VG_COLORSPACE_LINEAR:
@ -71,10 +116,6 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
surf->VGColorspace = val; surf->VGColorspace = val;
break; break;
case EGL_VG_ALPHA_FORMAT: case EGL_VG_ALPHA_FORMAT:
if (type == EGL_SCREEN_BIT_MESA) {
err = EGL_BAD_ATTRIBUTE;
break;
}
switch (val) { switch (val) {
case EGL_VG_ALPHA_FORMAT_NONPRE: case EGL_VG_ALPHA_FORMAT_NONPRE:
case EGL_VG_ALPHA_FORMAT_PRE: case EGL_VG_ALPHA_FORMAT_PRE:
@ -101,7 +142,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
break; break;
/* pbuffer surface attributes */ /* pbuffer surface attributes */
case EGL_WIDTH: case EGL_WIDTH:
if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) { if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE; err = EGL_BAD_ATTRIBUTE;
break; break;
} }
@ -112,7 +153,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
surf->Width = val; surf->Width = val;
break; break;
case EGL_HEIGHT: case EGL_HEIGHT:
if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) { if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE; err = EGL_BAD_ATTRIBUTE;
break; break;
} }
@ -129,6 +170,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
} }
surf->LargestPbuffer = !!val; surf->LargestPbuffer = !!val;
break; break;
/* for eglBindTexImage */
case EGL_TEXTURE_FORMAT: case EGL_TEXTURE_FORMAT:
if (!(type & texture_type)) { if (!(type & texture_type)) {
err = EGL_BAD_ATTRIBUTE; err = EGL_BAD_ATTRIBUTE;
@ -210,10 +252,12 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
case EGL_PBUFFER_BIT: case EGL_PBUFFER_BIT:
func = "eglCreatePBufferSurface"; func = "eglCreatePBufferSurface";
break; break;
#ifdef EGL_MESA_screen_surface
case EGL_SCREEN_BIT_MESA: case EGL_SCREEN_BIT_MESA:
func = "eglCreateScreenSurface"; func = "eglCreateScreenSurface";
renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */ renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
break; break;
#endif
default: default:
_eglLog(_EGL_WARNING, "Bad type in _eglInitSurface"); _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
return EGL_FALSE; return EGL_FALSE;

View File

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

View File

@ -34,14 +34,14 @@ env.CodeGenerate(
target = 'util/u_format_table.c', target = 'util/u_format_table.c',
script = '#src/gallium/auxiliary/util/u_format_table.py', script = '#src/gallium/auxiliary/util/u_format_table.py',
source = ['#src/gallium/auxiliary/util/u_format.csv'], source = ['#src/gallium/auxiliary/util/u_format.csv'],
command = 'python $SCRIPT $SOURCE > $TARGET' command = python_cmd + ' $SCRIPT $SOURCE > $TARGET'
) )
env.CodeGenerate( env.CodeGenerate(
target = 'util/u_half.c', target = 'util/u_half.c',
script = 'util/u_half.py', script = 'util/u_half.py',
source = [], source = [],
command = 'python $SCRIPT > $TARGET' command = python_cmd + ' $SCRIPT > $TARGET'
) )
env.Depends('util/u_format_table.c', [ env.Depends('util/u_format_table.c', [
@ -198,6 +198,7 @@ source = [
if env['llvm']: if env['llvm']:
source += [ source += [
'gallivm/lp_bld_arit.c', 'gallivm/lp_bld_arit.c',
'gallivm/lp_bld_assert.c',
'gallivm/lp_bld_const.c', 'gallivm/lp_bld_const.c',
'gallivm/lp_bld_conv.c', 'gallivm/lp_bld_conv.c',
'gallivm/lp_bld_debug.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); shader_type == PIPE_SHADER_GEOMETRY);
debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS); 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[slot] = buffer;
draw->pt.user.vs_constants_size[slot] = size;
draw_vs_set_constants(draw, slot, buffer, 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[slot] = buffer;
draw->pt.user.gs_constants_size[slot] = size;
draw_gs_set_constants(draw, slot, buffer, 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. * All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * 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, const void *constants,
unsigned size) 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); gs_flush(shader, 1);
} }
#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,i0,i1,i2) #define FUNC gs_run
#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5) #define GET_ELT(idx) (idx)
#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
#include "draw_gs_tmp.h" #include "draw_gs_tmp.h"
#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,elts[i0],elts[i1],elts[i2]) #define FUNC gs_run_elts
#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) \ #define LOCAL_VARS const ushort *elts = input_prims->elts;
gs_tri_adj(gs,elts[i0],elts[i1],elts[i2],elts[i3], \ #define GET_ELT(idx) (elts[idx] & ~DRAW_PIPE_FLAG_MASK)
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;
#include "draw_gs_tmp.h" #include "draw_gs_tmp.h"
/**
* Execute geometry shader using TGSI interpreter.
*/
int draw_geometry_shader_run(struct draw_geometry_shader *shader, int draw_geometry_shader_run(struct draw_geometry_shader *shader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS], 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_vertex_info *input_verts,
const struct draw_prim_info *input_prim, const struct draw_prim_info *input_prim,
struct draw_vertex_info *output_verts, 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 input_stride = input_verts->vertex_size;
unsigned vertex_size = input_verts->vertex_size; unsigned vertex_size = input_verts->vertex_size;
struct tgsi_exec_machine *machine = shader->machine; struct tgsi_exec_machine *machine = shader->machine;
unsigned int i;
unsigned num_input_verts = input_prim->linear ? unsigned num_input_verts = input_prim->linear ?
input_verts->count : input_verts->count :
input_prim->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)); shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));
for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
machine->Consts[i] = constants[i]; constants, constants_size);
}
if (input_prim->linear) if (input_prim->linear)
gs_run(shader, input_prim, input_verts, gs_run(shader, input_prim, input_verts,

View File

@ -1,6 +1,6 @@
/************************************************************************** /**************************************************************************
* *
* Copyright 2009 VMWare Inc. * Copyright 2009 VMware, Inc.
* All Rights Reserved. * All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * 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, int draw_geometry_shader_run(struct draw_geometry_shader *shader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS], 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_vertex_info *input_verts,
const struct draw_prim_info *input_prim, const struct draw_prim_info *input_prim,
struct draw_vertex_info *output_verts, 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, #define FUNC_ENTER \
const struct draw_prim_info *input_prims, /* declare more local vars */ \
const struct draw_vertex_info *input_verts, struct draw_context *draw = gs->draw; \
struct draw_prim_info *output_prims, const unsigned prim = input_prims->prim; \
struct draw_vertex_info *output_verts) const unsigned count = input_prims->count; \
{ const boolean last_vertex_last = \
struct draw_context *draw = shader->draw; !(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 && #define POINT(i0) gs_point(gs,i0)
draw->rasterizer->flatshade_first); #define LINE(flags,i0,i1) gs_line(gs,i0,i1)
unsigned i, j; #define TRIANGLE(flags,i0,i1,i2) gs_tri(gs,i0,i1,i2)
unsigned count = input_prims->count; #define LINE_ADJ(flags,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3)
LOCAL_VARS #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); #include "draw_decompose_tmp.h"
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

View File

@ -37,6 +37,8 @@
#include "gallivm/lp_bld_debug.h" #include "gallivm/lp_bld_debug.h"
#include "gallivm/lp_bld_tgsi.h" #include "gallivm/lp_bld_tgsi.h"
#include "gallivm/lp_bld_printf.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_exec.h"
#include "tgsi/tgsi_dump.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); 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); LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(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) { if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(code); 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); 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); LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(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) { if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(code); lp_disassemble(code);
} }
lp_func_delete_body(variant->function_elts);
} }
void 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. * Set up macros for draw_pt_decompose.h template code.
* This code uses vertex indexes / elements. * 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 TRIANGLE(flags,i0,i1,i2) \
#define QUAD_FIRST_PV(i0,i1,i2,i3) \ do_triangle( draw, \
do_triangle( draw, \ i0, /* flags */ \
( DRAW_PIPE_RESET_STIPPLE | \ verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \
DRAW_PIPE_EDGE_FLAG_0 | \ verts + stride * (i1), \
DRAW_PIPE_EDGE_FLAG_1 ), \ verts + stride * (i2) )
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))
/* emit last quad vertex as last vertex in triangles */ #define LINE(flags,i0,i1) \
#define QUAD_LAST_PV(i0,i1,i2,i3) \ do_line( draw, \
do_triangle( draw, \ i0, /* flags */ \
( DRAW_PIPE_RESET_STIPPLE | \ verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \
DRAW_PIPE_EDGE_FLAG_0 | \ verts + stride * (i1) )
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 POINT(i0) \ #define POINT(i0) \
do_point( draw, \ do_point( draw, verts + stride * (i0) )
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK) )
#define FUNC pipe_run #define GET_ELT(idx) (elts[idx])
#define ARGS \
#define FUNC pipe_run_elts
#define FUNC_VARS \
struct draw_context *draw, \ struct draw_context *draw, \
unsigned prim, \ unsigned prim, \
struct vertex_header *vertices, \ struct vertex_header *vertices, \
unsigned stride, \ unsigned stride, \
const ushort *elts const ushort *elts, \
unsigned count
#define LOCAL_VARS \
char *verts = (char *)vertices; \
boolean flatfirst = (draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
unsigned i; \
ushort flags
#define FLUSH
#include "draw_pt_decompose.h" #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; i < prim_info->primitive_count;
start += prim_info->primitive_lengths[i], i++) 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, #if DEBUG
prim_info->prim, /* make sure none of the element indexes go outside the vertex buffer */
vert_info->verts, {
vert_info->stride, unsigned max_index = 0x0, i;
prim_info->elts + start, /* find the largest element index */
count); 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; 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). * This code is for non-indexed (aka linear) rendering (no elts).
*/ */
/* emit first quad vertex as first vertex in triangles */ #define TRIANGLE(flags,i0,i1,i2) \
#define QUAD_FIRST_PV(i0,i1,i2,i3) \ do_triangle( draw, flags, \
do_triangle( draw, \ verts + stride * (i0), \
( DRAW_PIPE_RESET_STIPPLE | \ verts + stride * (i1), \
DRAW_PIPE_EDGE_FLAG_0 | \ verts + stride * (i2) )
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))
/* emit last quad vertex as last vertex in triangles */ #define LINE(flags,i0,i1) \
#define QUAD_LAST_PV(i0,i1,i2,i3) \ do_line( draw, flags, \
do_triangle( draw, \ verts + stride * (i0), \
( DRAW_PIPE_RESET_STIPPLE | \ verts + stride * (i1) )
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 TRIANGLE(flags,i0,i1,i2) \ #define POINT(i0) \
do_triangle( draw, \ do_point( draw, verts + stride * (i0) )
flags, /* flags */ \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK))
#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) \ #define GET_ELT(idx) (idx)
do_point( draw, \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK) )
#define FUNC pipe_run_linear #define FUNC pipe_run_linear
#define ARGS \ #define FUNC_VARS \
struct draw_context *draw, \ struct draw_context *draw, \
unsigned prim, \ unsigned prim, \
struct vertex_header *vertices, \ struct vertex_header *vertices, \
unsigned stride unsigned stride, \
unsigned count
#define LOCAL_VARS \
char *verts = (char *)vertices; \
boolean flatfirst = (draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
unsigned i; \
ushort flags
#define FLUSH
#include "draw_pt_decompose.h" #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_stride = vert_info->stride;
draw->pipeline.vertex_count = count; draw->pipeline.vertex_count = count;
assert(count <= vert_info->count);
pipe_run_linear(draw, pipe_run_linear(draw,
prim_info->prim, prim_info->prim,
(struct vertex_header*)verts, (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 ) static INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
{ {
return (struct clip_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: /* All attributes are float[4], so this is easy:
*/ */
static void interp_attr( float *fdst, static void interp_attr( float dst[4],
float t, float t,
const float *fin, const float in[4],
const float *fout ) const float out[4] )
{ {
fdst[0] = LINTERP( t, fout[0], fin[0] ); dst[0] = LINTERP( t, out[0], in[0] );
fdst[1] = LINTERP( t, fout[1], fin[1] ); dst[1] = LINTERP( t, out[1], in[1] );
fdst[2] = LINTERP( t, fout[2], fin[2] ); dst[2] = LINTERP( t, out[2], in[2] );
fdst[3] = LINTERP( t, fout[3], fin[3] ); 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, static void copy_colors( struct draw_stage *stage,
struct vertex_header *dst, struct vertex_header *dst,
const struct vertex_header *src ) const struct vertex_header *src )
@ -121,20 +124,17 @@ static void interp( const struct clip_stage *clip,
/* Vertex header. /* Vertex header.
*/ */
{ dst->clipmask = 0;
dst->clipmask = 0; dst->edgeflag = 0; /* will get overwritten later */
dst->edgeflag = 0; /* will get overwritten later */ dst->pad = 0;
dst->pad = 0; dst->vertex_id = UNDEFINED_VERTEX_ID;
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; const float *pos = dst->clip;

View File

@ -163,9 +163,11 @@ struct draw_context
/** vertex arrays */ /** vertex arrays */
const void *vbuffer[PIPE_MAX_ATTRIBS]; 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]; const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS];
unsigned vs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS]; const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS];
unsigned gs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
} user; } user;
boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */ 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; struct pipe_viewport_state viewport;
boolean identity_viewport; boolean identity_viewport;
/** Vertex shader state */
struct { struct {
struct draw_vertex_shader *vertex_shader; struct draw_vertex_shader *vertex_shader;
uint num_vs_outputs; /**< convenience, from vertex_shader */ uint num_vs_outputs; /**< convenience, from vertex_shader */
@ -227,6 +230,7 @@ struct draw_context
struct translate_cache *emit_cache; struct translate_cache *emit_cache;
} vs; } vs;
/** Geometry shader state */
struct { struct {
struct draw_geometry_shader *geometry_shader; struct draw_geometry_shader *geometry_shader;
uint num_gs_outputs; /**< convenience, from geometry_shader */ uint num_gs_outputs; /**< convenience, from geometry_shader */
@ -239,6 +243,7 @@ struct draw_context
struct tgsi_sampler **samplers; struct tgsi_sampler **samplers;
} gs; } gs;
/** Stream output (vertex feedback) state */
struct { struct {
struct pipe_stream_output_state state; struct pipe_stream_output_state state;
void *buffers[PIPE_MAX_SO_BUFFERS]; 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++) { for (j = 0; j < draw->pt.nr_vertex_elements; j++) {
uint buf = draw->pt.vertex_element[j].vertex_buffer_index; uint buf = draw->pt.vertex_element[j].vertex_buffer_index;
ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf]; 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_buffer[buf].stride * ii;
ptr += draw->pt.vertex_element[j].src_offset; 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 reduced_prim = u_reduced_prim(mode);
unsigned instance; unsigned instance;
assert(instanceCount > 0);
if (reduced_prim != draw->reduced_prim) { if (reduced_prim != draw->reduced_prim) {
draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE); draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
draw->reduced_prim = reduced_prim; draw->reduced_prim = reduced_prim;
} }
if (0) 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) { if (0) {
unsigned int i; 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"); debug_printf("Elements:\n");
for (i = 0; i < draw->pt.nr_vertex_elements; i++) { for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
debug_printf(" %u: src_offset=%u inst_div=%u vbuf=%u format=%s\n", 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++) { for (instance = 0; instance < instanceCount; instance++) {
draw->instance_id = instance + startInstance; draw->instance_id = instance + startInstance;
draw_pt_arrays(draw, mode, start, count); 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);
#include "draw_decompose_tmp.h"
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

View File

@ -182,6 +182,7 @@ void draw_pt_emit( struct pt_emit *emit,
0, 0,
~0); ~0);
/* fetch/translate vertex attribs to fill hw_verts[] */
translate->run( translate, translate->run( translate,
0, 0,
vertex_count, 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, static void draw_vertex_shader_run(struct draw_vertex_shader *vshader,
const void *constants[PIPE_MAX_CONSTANT_BUFFERS], const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts, const struct draw_vertex_info *input_verts,
struct draw_vertex_info *output_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, (const float (*)[4])input_verts->verts->data,
( float (*)[4])output_verts->verts->data, ( float (*)[4])output_verts->verts->data,
constants, constants,
const_size,
input_verts->count, input_verts->count,
input_verts->vertex_size, input_verts->vertex_size,
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) { if (fpme->opt & PT_SHADE) {
draw_vertex_shader_run(vshader, draw_vertex_shader_run(vshader,
draw->pt.user.vs_constants, draw->pt.user.vs_constants,
draw->pt.user.vs_constants_size,
vert_info, vert_info,
&vs_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) { if ((fpme->opt & PT_SHADE) && gshader) {
draw_geometry_shader_run(gshader, draw_geometry_shader_run(gshader,
draw->pt.user.gs_constants, draw->pt.user.gs_constants,
draw->pt.user.gs_constants_size,
vert_info, vert_info,
prim_info, prim_info,
&gs_vert_info, &gs_vert_info,

View File

@ -1,6 +1,6 @@
/************************************************************************** /**************************************************************************
* *
* Copyright 2010 VMWare, Inc. * Copyright 2010 VMware, Inc.
* All Rights Reserved. * All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * 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) { if ((opt & PT_SHADE) && gshader) {
draw_geometry_shader_run(gshader, draw_geometry_shader_run(gshader,
draw->pt.user.gs_constants, draw->pt.user.gs_constants,
draw->pt.user.gs_constants_size,
vert_info, vert_info,
prim_info, prim_info,
&gs_vert_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 FUNC so_run_linear
#define LINE(gs,i0,i1) so_line(so,i0,i1) #define GET_ELT(idx) (start + (idx))
#define POINT(gs,i0) so_point(so,i0)
#define FUNC so_run_linear
#define LOCAL_VARS
#include "draw_so_emit_tmp.h" #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 FUNC so_run_elts
#define LINE(gs,i0,i1) so_line(gs,elts[i0],elts[i1]) #define LOCAL_VARS const ushort *elts = input_prims->elts;
#define POINT(gs,i0) so_point(gs,elts[i0]) #define GET_ELT(idx) (elts[start + (idx)] & ~DRAW_PIPE_FLAG_MASK)
#define FUNC so_run_elts
#define LOCAL_VARS \
const ushort *elts = input_prims->elts;
#include "draw_so_emit_tmp.h" #include "draw_so_emit_tmp.h"
#undef LOCAL_VARS
#undef FUNC
void draw_pt_so_emit( struct pt_so_emit *emit, 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 ) vcache_check_flush( struct vcache_frontend *vcache )
{ {
if (vcache->draw_count + 6 >= DRAW_MAX || if (vcache->draw_count + 6 >= DRAW_MAX ||
vcache->fetch_count + 4 >= FETCH_MAX) { vcache->fetch_count + 6 >= FETCH_MAX) {
vcache_flush( vcache ); vcache_flush( vcache );
} }
} }
@ -180,59 +180,61 @@ vcache_point( struct vcache_frontend *vcache,
} }
static INLINE void static INLINE void
vcache_quad( struct vcache_frontend *vcache, vcache_line_adj_flags( struct vcache_frontend *vcache,
unsigned i0, unsigned flags,
unsigned i1, unsigned a0, unsigned i0, unsigned i1, unsigned a1 )
unsigned i2,
unsigned i3 )
{ {
if (vcache->draw->rasterizer->flatshade_first) { vcache_elt(vcache, a0, 0);
/* pass last quad vertex as first triangle vertex */ vcache_elt(vcache, i0, flags);
vcache_triangle( vcache, i3, i0, i1 ); vcache_elt(vcache, i1, 0);
vcache_triangle( vcache, i3, i1, i2 ); vcache_elt(vcache, a1, 0);
} vcache_check_flush(vcache);
else {
/* pass last quad vertex as last triangle vertex */
vcache_triangle( vcache, i0, i1, i3 );
vcache_triangle( vcache, i1, i2, i3 );
}
} }
static INLINE void static INLINE void
vcache_ef_quad( struct vcache_frontend *vcache, vcache_line_adj( struct vcache_frontend *vcache,
unsigned i0, unsigned a0, unsigned i0, unsigned i1, unsigned a1 )
unsigned i1,
unsigned i2,
unsigned i3 )
{ {
if (vcache->draw->rasterizer->flatshade_first) { vcache_elt(vcache, a0, 0);
/* pass last quad vertex as first triangle vertex */ vcache_elt(vcache, i0, 0);
vcache_triangle_flags( vcache, vcache_elt(vcache, i1, 0);
( DRAW_PIPE_RESET_STIPPLE | vcache_elt(vcache, a1, 0);
DRAW_PIPE_EDGE_FLAG_0 | vcache_check_flush(vcache);
DRAW_PIPE_EDGE_FLAG_1 ), }
i3, i0, i1 );
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, static INLINE void
( DRAW_PIPE_EDGE_FLAG_0 | vcache_triangle_adj_flags( struct vcache_frontend *vcache,
DRAW_PIPE_EDGE_FLAG_1 ), unsigned flags,
i1, i2, i3 ); 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 * this. The two paths aren't too different though - it may be
* possible to reunify them. * possible to reunify them.
*/ */
#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2) #define TRIANGLE(flags,i0,i1,i2) vcache_triangle_flags(vcache,flags,i0,i1,i2)
#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3) #define LINE(flags,i0,i1) vcache_line_flags(vcache,flags,i0,i1)
#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1) #define POINT(i0) vcache_point(vcache,i0)
#define POINT(vc,i0) vcache_point(vc,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 #define FUNC vcache_run_extras
#include "draw_pt_vcache_tmp.h" #include "draw_pt_vcache_tmp.h"
#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2) #define TRIANGLE(flags,i0,i1,i2) vcache_triangle(vcache,i0,i1,i2)
#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3) #define LINE(flags,i0,i1) vcache_line(vcache,i0,i1)
#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1) #define POINT(i0) vcache_point(vcache,i0)
#define POINT(vc,i0) vcache_point(vc,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 #define FUNC vcache_run
#include "draw_pt_vcache_tmp.h" #include "draw_pt_vcache_tmp.h"
@ -339,6 +347,25 @@ format_from_get_elt( pt_elt_func get_elt )
#endif #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 static INLINE void
vcache_check_run( struct draw_pt_front_end *frontend, vcache_check_run( struct draw_pt_front_end *frontend,
pt_elt_func get_elt, 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) if (max_index >= (unsigned) DRAW_PIPE_MAX_VERTICES)
goto fail; goto fail;
if (any_instance_divisors(draw))
goto fail;
fetch_count = max_index + 1 - min_index; fetch_count = max_index + 1 - min_index;
if (0) if (0)
@ -518,7 +548,18 @@ vcache_prepare( struct draw_pt_front_end *frontend,
* which is a separate issue. * which is a separate issue.
*/ */
vcache->input_prim = in_prim; 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->middle = middle;
vcache->opt = opt; 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, #define GET_ELT(idx) (get_elt(elts, idx) + elt_bias)
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;
boolean flatfirst = (draw->rasterizer->flatshade && #define FUNC_EXIT do { vcache_flush(vcache); } while (0)
draw->rasterizer->flatshade_first);
unsigned i;
ushort flags;
if (0) debug_printf("%s %d\n", __FUNCTION__, count); #include "draw_decompose_tmp.h"
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

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, #define FUNC_ENTER \
const struct draw_prim_info *input_prims, /* declare more local vars */ \
const struct draw_vertex_info *input_verts, struct draw_context *draw = so->draw; \
unsigned start, const unsigned prim = input_prims->prim; \
unsigned count) const boolean last_vertex_last = \
{ !(draw->rasterizer->flatshade && \
struct draw_context *draw = so->draw; 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 && #define POINT(i0) so_point(so,i0)
draw->rasterizer->flatshade_first); #define LINE(flags,i0,i1) so_line(so,i0,i1)
unsigned i; #define TRIANGLE(flags,i0,i1,i2) so_tri(so,i0,i1,i2)
LOCAL_VARS
if (0) debug_printf("%s %d\n", __FUNCTION__, count); #include "draw_decompose_tmp.h"
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

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) { switch (emit) {
case EMIT_OMIT: case EMIT_OMIT:

View File

@ -48,18 +48,30 @@
DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE) 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 void
draw_vs_set_constants(struct draw_context *draw, draw_vs_set_constants(struct draw_context *draw,
unsigned slot, unsigned slot,
const void *constants, const void *constants,
unsigned size) 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 (size > draw->vs.const_storage_size[slot]) {
if (draw->vs.aligned_constant_storage[slot]) { if (draw->vs.aligned_constant_storage[slot]) {
align_free((void *)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); assert(constants);
memcpy((void *)draw->vs.aligned_constant_storage[slot], 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, void (*run_linear)( struct draw_vertex_shader *shader,
const float (*input)[4], const float (*input)[4],
float (*output)[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 count,
unsigned input_stride, unsigned input_stride,
unsigned output_stride ); unsigned output_stride );

View File

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

View File

@ -84,6 +84,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base,
const float (*input)[4], const float (*input)[4],
float (*output)[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 count,
unsigned input_stride, unsigned input_stride,
unsigned output_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, vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer, temp_buffer,
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, count,
temp_vertex_stride, temp_vertex_stride,
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, vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer, temp_buffer,
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, count,
temp_vertex_stride, temp_vertex_stride,
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. * All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
@ -25,13 +25,17 @@
* *
**************************************************************************/ **************************************************************************/
#ifndef DRI2_H #ifndef LP_BLD_ASSERT_H
#define DRI2_H #define LP_BLD_ASSERT_H
#include "dri_drawable.h"
#include "dri_wrapper.h"
const __DRIconfig ** #include "lp_bld.h"
dri2_init_screen(__DRIscreen * sPriv);
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 }, { "nopt", GALLIVM_DEBUG_NO_OPT, NULL },
DEBUG_NAMED_VALUE_END DEBUG_NAMED_VALUE_END
}; };
DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags, 0);
#endif #endif
@ -89,7 +91,7 @@ void
lp_build_init(void) lp_build_init(void)
{ {
#ifdef DEBUG #ifdef DEBUG
gallivm_debug = debug_get_flags_option("GALLIVM_DEBUG", lp_bld_debug_flags, 0 ); gallivm_debug = debug_get_option_gallivm_debug();
#endif #endif
lp_set_target_options(); lp_set_target_options();

View File

@ -44,5 +44,7 @@ extern LLVMPassManagerRef lp_build_pass;
void void
lp_build_init(void); lp_build_init(void);
extern void
lp_func_delete_body(LLVMValueRef func);
#endif /* !LP_BLD_INIT_H */ #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; * 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 LLVMValueRef
lp_build_select(struct lp_build_context *bld, lp_build_select(struct lp_build_context *bld,
@ -424,27 +467,7 @@ lp_build_select(struct lp_build_context *bld,
} }
} }
else { else {
if(type.floating) { res = lp_build_select_bitwise(bld, mask, a, b);
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 res;

View File

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

View File

@ -39,6 +39,7 @@
#include <llvm/Target/TargetOptions.h> #include <llvm/Target/TargetOptions.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/JITEventListener.h> #include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/Support/CommandLine.h>
#include "pipe/p_config.h" #include "pipe/p_config.h"
#include "util/u_debug.h" #include "util/u_debug.h"
@ -141,4 +142,35 @@ lp_set_target_options(void)
#if 0 #if 0
llvm::UnsafeFPMath = true; llvm::UnsafeFPMath = true;
#endif #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 #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 * Check if there's a potential src/dst register data dependency when
* using SOA execution. * using SOA execution.
@ -632,6 +649,10 @@ tgsi_exec_machine_bind_shader(
util_init_math(); util_init_math();
if (numSamplers) {
assert(samplers);
}
mach->Tokens = tokens; mach->Tokens = tokens;
mach->Samplers = samplers; mach->Samplers = samplers;
@ -1040,6 +1061,8 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,
{ {
uint i; uint i;
assert(swizzle < 4);
switch (file) { switch (file) {
case TGSI_FILE_CONSTANT: case TGSI_FILE_CONSTANT:
for (i = 0; i < QUAD_SIZE; i++) { 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) { if (index->i[i] < 0) {
chan->u[i] = 0; chan->u[i] = 0;
} else { } else {
const uint *p = (const uint *)mach->Consts[index2D->i[i]]; /* NOTE: copying the const value as a uint instead of float */
const uint constbuf = index2D->i[i];
chan->u[i] = p[index->i[i] * 4 + swizzle]; 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; 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] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i],
index2D->i[i], index->i[i]); index2D->i[i], index->i[i]);
}*/ }*/
chan->u[i] = mach->Inputs[index2D->i[i] * int pos = index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i];
TGSI_EXEC_MAX_INPUT_ATTRIBS + assert(pos >= 0);
index->i[i]].xyzw[swizzle].u[i]; assert(pos < Elements(mach->Inputs));
chan->u[i] = mach->Inputs[pos].xyzw[swizzle].u[i];
} }
break; break;
@ -1187,7 +1225,7 @@ fetch_source(const struct tgsi_exec_machine *mach,
index2.i[1] = index2.i[1] =
index2.i[2] = index2.i[2] =
index2.i[3] = reg->Indirect.Index; index2.i[3] = reg->Indirect.Index;
assert(reg->Indirect.File == TGSI_FILE_ADDRESS);
/* get current value of address register[swizzle] */ /* get current value of address register[swizzle] */
swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, CHAN_X ); swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, CHAN_X );
fetch_src_file_channel(mach, fetch_src_file_channel(mach,

View File

@ -253,7 +253,10 @@ struct tgsi_exec_machine
struct tgsi_sampler **Samplers; struct tgsi_sampler **Samplers;
unsigned ImmLimit; unsigned ImmLimit;
const void *Consts[PIPE_MAX_CONSTANT_BUFFERS]; const void *Consts[PIPE_MAX_CONSTANT_BUFFERS];
unsigned ConstsSize[PIPE_MAX_CONSTANT_BUFFERS];
const struct tgsi_token *Tokens; /**< Declarations, instructions */ const struct tgsi_token *Tokens; /**< Declarations, instructions */
unsigned Processor; /**< TGSI_PROCESSOR_x */ 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 #if defined __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif

View File

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

View File

@ -35,7 +35,8 @@ extern "C" {
#endif #endif
/* Check the given token stream for errors and common mistakes. /* 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. * Returns TRUE if there are no errors, even though there could be some warnings.
*/ */
boolean boolean

View File

@ -368,23 +368,23 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
/* loop over vertex attributes (vertex shader inputs) /* loop over vertex attributes (vertex shader inputs)
*/ */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
unsigned elt = *elts++; const unsigned elt = *elts++;
for (attr = 0; attr < nr_attrs; attr++) { for (attr = 0; attr < nr_attrs; attr++) {
float data[4]; float data[4];
const uint8_t *src; char *dst = vert + tg->attrib[attr].output_offset;
unsigned index;
char *dst = (vert +
tg->attrib[attr].output_offset);
if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
const uint8_t *src;
unsigned index;
if (tg->attrib[attr].instance_divisor) { if (tg->attrib[attr].instance_divisor) {
index = instance_id / tg->attrib[attr].instance_divisor; index = instance_id / tg->attrib[attr].instance_divisor;
} else { } else {
index = elt; index = elt;
} }
/* clamp to void going out of bounds */
index = MIN2(index, tg->attrib[attr].max_index); index = MIN2(index, tg->attrib[attr].max_index);
src = tg->attrib[attr].input_ptr + 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 ); 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 { } else {
data[0] = (float)instance_id; 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 ); 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++) { for (attr = 0; attr < nr_attrs; attr++) {
float data[4]; 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) { if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
const uint8_t *src; const uint8_t *src;
unsigned index;
if (tg->attrib[attr].instance_divisor) { if (tg->attrib[attr].instance_divisor) {
src = tg->attrib[attr].input_ptr + index = instance_id / tg->attrib[attr].instance_divisor;
tg->attrib[attr].input_stride * }
(instance_id / tg->attrib[attr].instance_divisor); else {
} else { index = elt;
src = tg->attrib[attr].input_ptr +
tg->attrib[attr].input_stride * 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 ); 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 { } else {
data[0] = (float)instance_id; data[0] = (float)instance_id;
} }
if (0) debug_printf("vert %d attr %d: %f %f %f %f\n", if (0)
i, attr, data[0], data[1], data[2], data[3]); 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 ); tg->attrib[attr].emit( data, dst );
} }

View File

@ -87,6 +87,7 @@ struct blitter_context_priv
void *dsa_write_depth_keep_stencil; void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil; void *dsa_keep_depth_stencil;
void *dsa_keep_depth_write_stencil; void *dsa_keep_depth_write_stencil;
void *dsa_flush_depth_stencil;
void *velem_state; void *velem_state;
@ -156,6 +157,10 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->dsa_keep_depth_stencil = ctx->dsa_keep_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa); 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.enabled = 1;
dsa.depth.writemask = 1; dsa.depth.writemask = 1;
dsa.depth.func = PIPE_FUNC_ALWAYS; 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); UTIL_BLITTER_ATTRIB_NONE, NULL);
blitter_restore_CSOs(ctx); 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 dstx, unsigned dsty,
unsigned width, unsigned height); 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 /* The functions below should be used to save currently bound constant state
* objects inside a driver. The objects are automatically restored at the end * objects inside a driver. The objects are automatically restored at the end
* of the util_blitter_{clear, copy_region, fill_region} functions and then * of the util_blitter_{clear, copy_region, fill_region} functions and then

View File

@ -73,9 +73,15 @@
#endif #endif
DEBUG_GET_ONCE_BOOL_OPTION(dump_cpu, "GALLIUM_DUMP_CPU", TRUE);
struct util_cpu_caps util_cpu_caps; struct util_cpu_caps util_cpu_caps;
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
static int has_cpuid(void); static int has_cpuid(void);
#endif
#if defined(PIPE_ARCH_X86) #if defined(PIPE_ARCH_X86)
@ -497,23 +503,25 @@ util_cpu_detect(void)
#endif /* PIPE_ARCH_PPC */ #endif /* PIPE_ARCH_PPC */
#ifdef DEBUG #ifdef DEBUG
debug_printf("util_cpu_caps.arch = %i\n", util_cpu_caps.arch); if (debug_get_option_dump_cpu()) {
debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus); 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.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.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_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_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_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_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_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_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_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_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 = %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_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_altivec = %u\n", util_cpu_caps.has_altivec);
}
#endif #endif
util_cpu_detect_initialized = TRUE; 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 */ /* note: vertex elements already set by caller */
/* draw */ /* 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 #define U_DRAWQUAD_H
#include "pipe/p_compiler.h"
#include "pipe/p_context.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct pipe_resource; struct pipe_resource;
#include "util/u_draw.h"
extern void extern void
util_draw_vertex_buffer(struct pipe_context *pipe, util_draw_vertex_buffer(struct pipe_context *pipe,
struct pipe_resource *vbuf, uint offset, 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 * 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 void
util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, 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[0] = (float)(r * (1.0f/0x7f)); /* r */
dst[1] = (float)(g * (1.0f/0x7f)); /* g */ 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[3] = 1.0f; /* a */
dst += 4; 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[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */
dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */ 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[3] = 255; /* a */
dst += 4; 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[0] = r * (1.0f/0x7f); /* r */
dst[1] = g * (1.0f/0x7f); /* g */ 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 */ 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] * 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); ok = (*nr >= 4);
*nr -= (*nr % 2); *nr -= (*nr % 2);
break; 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: default:
ok = 0; ok = 0;
break; break;

View File

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

View File

@ -66,9 +66,6 @@ Unordered access view: view supporting random read/write access (usually from co
clear clear
+ Gallium supports clearing both render targets and depth/stencil with a single call + 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_signalled
fence_finish fence_finish
+ D3D10/D3D11 don't appear to support explicit fencing; queries can often substitute though, and flushing is supported + 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) DispatchIndirect (D3D11 only)
- Gallium does not support compute shaders - 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 ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
DrawAuto -> draw_auto DrawAuto -> draw_auto
DrawIndexed -> draw_elements DrawIndexed -> draw_vbo
! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
* may want to add a separate set_index_buffer + D3D11 lacks explicit range, which is required for OpenGL
- Gallium lacks base vertex for indexed draw calls
+ D3D11 lacks draw_range_elements functionality, 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 ! 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 DrawIndexedInstancedIndirect (D3D11 only)
# this allows to use an hardware buffer to specify the parameters for multiple draw_elements_instanced calls # 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 - 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 ! 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 DrawInstancedIndirect (D3D11 only)
# this allows to use an hardware buffer to specify the parameters for multiple draw_arrays_instanced calls # 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 - Gallium does not support draw call parameter buffers and indirect draws
DsSetConstantBuffers (D3D11 only) DsSetConstantBuffers (D3D11 only)
@ -332,10 +325,9 @@ HsSetShaderResources (D3D11 only)
HsSetShaderWithIfaces (D3D11 only) HsSetShaderWithIfaces (D3D11 only)
- Gallium does not support hull shaders - Gallium does not support hull shaders
IaSetIndexBuffer IaSetIndexBuffer -> set_index_buffer
! Gallium passes this to the draw_elements or draw_elements_instanced calls
+ Gallium supports 8-bit indices + 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 IaSetInputLayout -> bind_vertex_elements_state

View File

@ -38,7 +38,7 @@ master_doc = 'index'
# General information about the project. # General information about the project.
project = u'Gallium' 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 # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |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]). # (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [ latex_documents = [
('index', 'Gallium.tex', u'Gallium Documentation', ('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 # 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_vertex_buffers``
* ``set_index_buffer``
Non-CSO State Non-CSO State
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
@ -132,50 +133,26 @@ this surface need not be bound to the framebuffer.
Drawing 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`` The ``mode``, ``start``, and ``count`` fields of ``pipe_draw_info`` specify the
with ``startInstance`` set to 0 and ``instanceCount`` set to 1. 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 Every instance with instanceID in the range between ``start_instance`` and
index buffer. ``start_instance``+``instance_count``-1, inclusive, will be drawn.
This command is equivalent to calling ``draw_elements_instanced`` All vertex indices must fall inside the range given by ``min_index`` and
with ``startInstance`` set to 0 and ``instanceCount`` set to 1. ``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 If there is an index buffer bound, and ``indexed`` field is true, all vertex
information should be available from the vertex_buffer state. indices will be looked up in the index buffer. ``min_index``, ``max_index``,
Using this to quickly evaluate a specialized path in the draw and ``index_bias`` apply after index lookup.
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 a given vertex element has ``instance_divisor`` set to 0, it is said 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 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 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 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 are zero, point sprites are effectively disabled.
point_smooth and point_quad_rasterization are ignored; point smoothing is
disabled and points are always rasterized as quads. If enabled, the four If any bit is set, then point_smooth MUST be disabled (there are no
vertices of the resulting quad will be assigned texture coordinates, round sprites) and point_quad_rasterization MUST be true (sprites are
according to sprite_coord_mode. 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 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). vertex will have coordinates (0,0,0,1).
This state is used by :ref:`Draw` to generate texcoords. 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 point_quad_rasterization
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
Determines if points should be rasterized as quads or points. Certain APIs, Determines if points should be rasterized according to quad or point
like Direct3D, always use quad rasterization for points, regardless of rasterization rules.
whether point sprites are enabled or not. If this state is enabled, point
smoothing and antialiasing are disabled. If it is disabled, point sprite OpenGL actually has quite different rasterization rules for points and
coordinates are not generated. 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:: .. note::

View File

@ -51,10 +51,10 @@ nVidia nv50
Driver for the nVidia nv50 family of GPUs. 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 ATI r300
^^^^^^^^ ^^^^^^^^

View File

@ -230,7 +230,7 @@ struct cell_command_rasterizer
{ {
opcode_t opcode; /**< CELL_CMD_STATE_RASTERIZER */ opcode_t opcode; /**< CELL_CMD_STATE_RASTERIZER */
struct pipe_rasterizer_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_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers; uint num_vertex_buffers;
struct pipe_index_buffer index_buffer;
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS]; ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map; ubyte *zsbuf_map;
@ -154,7 +155,7 @@ struct cell_context
struct vertex_info vertex_info; struct vertex_info vertex_info;
/** Mapped constant buffers */ /** 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; 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? * XXX should the element buffer be specified/bound with a separate function?
*/ */
static void static void
cell_draw_range_elements(struct pipe_context *pipe, cell_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
struct pipe_resource *indexBuffer,
unsigned indexSize,
int indexBias,
unsigned min_index,
unsigned max_index,
unsigned mode, unsigned start, unsigned count)
{ {
struct cell_context *cell = cell_context(pipe); struct cell_context *cell = cell_context(pipe);
struct draw_context *draw = cell->draw; struct draw_context *draw = cell->draw;
void *mapped_indices = NULL;
unsigned i; unsigned i;
if (cell->dirty) if (cell->dirty)
@ -83,18 +78,20 @@ cell_draw_range_elements(struct pipe_context *pipe,
draw_set_mapped_vertex_buffer(draw, i, buf); draw_set_mapped_vertex_buffer(draw, i, buf);
} }
/* Map index buffer, if present */ /* Map index buffer, if present */
if (indexBuffer) { if (info->indexed && cell->index_buffer.buffer) {
void *mapped_indexes = cell_resource(indexBuffer)->data; mapped_indices = cell_resource(cell->index_buffer.buffer)->data;
draw_set_mapped_element_buffer(draw, indexSize, indexBias, mapped_indexes); mapped_indices += cell->index_buffer.offset;
}
else {
/* no index/element buffer */
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
} }
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! */
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 * 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++) { for (i = 0; i < cell->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL); draw_set_mapped_vertex_buffer(draw, i, NULL);
} }
if (indexBuffer) { if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL); 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 void
cell_init_draw_functions(struct cell_context *cell) cell_init_draw_functions(struct cell_context *cell)
{ {
cell->pipe.draw_arrays = cell_draw_arrays; cell->pipe.draw_vbo = cell_draw_vbo;
cell->pipe.draw_elements = cell_draw_elements;
cell->pipe.draw_range_elements = cell_draw_range_elements;
} }

View File

@ -87,6 +87,7 @@ struct cell_buffer_node
}; };
#if 0
static void static void
cell_add_buffer_to_list(struct cell_context *cell, cell_add_buffer_to_list(struct cell_context *cell,
struct cell_buffer_list *list, struct cell_buffer_list *list,
@ -100,6 +101,7 @@ cell_add_buffer_to_list(struct cell_context *cell,
list->head = node; list->head = node;
} }
} }
#endif
/** /**
@ -113,7 +115,7 @@ cell_free_fenced_buffers(struct cell_context *cell,
struct cell_buffer_list *list) struct cell_buffer_list *list)
{ {
if (list->head) { if (list->head) {
struct pipe_screen *ps = cell->pipe.screen; /*struct pipe_screen *ps = cell->pipe.screen;*/
struct cell_buffer_node *node; struct cell_buffer_node *node;
cell_fence_finish(cell, &list->fence); cell_fence_finish(cell, &list->fence);
@ -146,7 +148,7 @@ cell_free_fenced_buffers(struct cell_context *cell,
void void
cell_add_fenced_textures(struct cell_context *cell) 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; uint i;
for (i = 0; i < cell->num_textures; 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; struct pipe_resource *new_tex = new_view ? new_view->texture : NULL;
pipe_sampler_view_reference(&cell->fragment_sampler_views[i], pipe_sampler_view_reference(&cell->fragment_sampler_views[i],
views[i]); new_view);
pipe_resource_reference((struct pipe_resource **) &cell->texture[i], pipe_resource_reference((struct pipe_resource **) &cell->texture[i],
(struct pipe_resource *) new_tex); (struct pipe_resource *) new_tex);

View File

@ -36,7 +36,7 @@
#include "draw/draw_context.h" #include "draw/draw_context.h"
void * static void *
cell_create_vertex_elements_state(struct pipe_context *pipe, cell_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count, unsigned count,
const struct pipe_vertex_element *attribs) const struct pipe_vertex_element *attribs)
@ -51,7 +51,7 @@ cell_create_vertex_elements_state(struct pipe_context *pipe,
return velems; return velems;
} }
void static void
cell_bind_vertex_elements_state(struct pipe_context *pipe, cell_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems) 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); 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) cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{ {
FREE( 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 void
cell_init_vertex_functions(struct cell_context *cell) cell_init_vertex_functions(struct cell_context *cell)
{ {
cell->pipe.set_vertex_buffers = cell_set_vertex_buffers; 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.create_vertex_elements_state = cell_create_vertex_elements_state;
cell->pipe.bind_vertex_elements_state = cell_bind_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; 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, static void failover_draw_vbo( struct pipe_context *pipe,
struct pipe_resource *indexResource, const struct pipe_draw_info *info)
unsigned indexSize,
int indexBias,
unsigned prim,
unsigned start,
unsigned count)
{ {
struct failover_context *failover = failover_context( pipe ); struct failover_context *failover = failover_context( pipe );
@ -70,13 +65,7 @@ static void failover_draw_elements( struct pipe_context *pipe,
/* Try hardware: /* Try hardware:
*/ */
if (failover->mode == FO_HW) { if (failover->mode == FO_HW) {
failover->hw->draw_elements( failover->hw, failover->hw->draw_vbo( failover->hw, info );
indexResource,
indexSize,
indexBias,
prim,
start,
count );
} }
/* Possibly try software: /* Possibly try software:
@ -88,13 +77,7 @@ static void failover_draw_elements( struct pipe_context *pipe,
failover_state_emit( failover ); failover_state_emit( failover );
} }
failover->sw->draw_elements( failover->sw, failover->sw->draw_vbo( failover->sw, info );
indexResource,
indexSize,
indexBias,
prim,
start,
count );
/* Be ready to switch back to hardware rendering without an /* Be ready to switch back to hardware rendering without an
* intervening flush. Unlikely to be much performance impact to * 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 static unsigned int
failover_is_resource_referenced( struct pipe_context *_pipe, failover_is_resource_referenced( struct pipe_context *_pipe,
struct pipe_resource *resource, struct pipe_resource *resource,
@ -143,8 +119,7 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover->pipe.get_paramf = hw->get_paramf; failover->pipe.get_paramf = hw->get_paramf;
#endif #endif
failover->pipe.draw_arrays = failover_draw_arrays; failover->pipe.draw_vbo = failover_draw_vbo;
failover->pipe.draw_elements = failover_draw_elements;
failover->pipe.clear = hw->clear; failover->pipe.clear = hw->clear;
failover->pipe.clear_render_target = hw->clear_render_target; failover->pipe.clear_render_target = hw->clear_render_target;
failover->pipe.clear_depth_stencil = hw->clear_depth_stencil; 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_BUFFER 0x40000
#define FO_NEW_VERTEX_ELEMENT 0x80000 #define FO_NEW_VERTEX_ELEMENT 0x80000
#define FO_NEW_SAMPLE_MASK 0x100000 #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_scissor_state scissor;
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer index_buffer;
uint num_vertex_buffers; 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 void
failover_set_constant_buffer(struct pipe_context *pipe, failover_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index, 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_vertex_sampler_views = failover_set_vertex_sampler_views;
failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffers = failover_set_vertex_buffers; 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.set_constant_buffer = failover_set_constant_buffer;
failover->pipe.create_sampler_view = failover_create_sampler_view; failover->pipe.create_sampler_view = failover_create_sampler_view;
failover->pipe.sampler_view_destroy = failover_sampler_view_destroy; 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 ); failover->vertex_buffers );
} }
if (failover->dirty & FO_NEW_INDEX_BUFFER) {
failover->sw->set_index_buffer( failover->sw,
&failover->index_buffer );
}
failover->dirty = 0; failover->dirty = 0;
} }

View File

@ -48,68 +48,13 @@ galahad_destroy(struct pipe_context *_pipe)
} }
static void static void
galahad_draw_arrays(struct pipe_context *_pipe, galahad_draw_vbo(struct pipe_context *_pipe,
unsigned prim, const struct pipe_draw_info *info)
unsigned start,
unsigned count)
{ {
struct galahad_context *glhd_pipe = galahad_context(_pipe); struct galahad_context *glhd_pipe = galahad_context(_pipe);
struct pipe_context *pipe = glhd_pipe->pipe; struct pipe_context *pipe = glhd_pipe->pipe;
pipe->draw_arrays(pipe, pipe->draw_vbo(pipe, info);
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);
} }
static struct pipe_query * static struct pipe_query *
@ -650,6 +595,41 @@ galahad_set_vertex_buffers(struct pipe_context *_pipe,
num_buffers, num_buffers,
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 static void
galahad_resource_copy_region(struct pipe_context *_pipe, galahad_resource_copy_region(struct pipe_context *_pipe,
struct pipe_resource *_dst, 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.draw = NULL;
glhd_pipe->base.destroy = galahad_destroy; glhd_pipe->base.destroy = galahad_destroy;
glhd_pipe->base.draw_arrays = galahad_draw_arrays; glhd_pipe->base.draw_vbo = galahad_draw_vbo;
glhd_pipe->base.draw_elements = galahad_draw_elements;
glhd_pipe->base.draw_range_elements = galahad_draw_range_elements;
glhd_pipe->base.create_query = galahad_create_query; glhd_pipe->base.create_query = galahad_create_query;
glhd_pipe->base.destroy_query = galahad_destroy_query; glhd_pipe->base.destroy_query = galahad_destroy_query;
glhd_pipe->base.begin_query = galahad_begin_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_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_sampler_views = galahad_set_vertex_sampler_views;
glhd_pipe->base.set_vertex_buffers = galahad_set_vertex_buffers; 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.resource_copy_region = galahad_resource_copy_region;
glhd_pipe->base.clear = galahad_clear; glhd_pipe->base.clear = galahad_clear;
glhd_pipe->base.clear_render_target = galahad_clear_render_target; glhd_pipe->base.clear_render_target = galahad_clear_render_target;

View File

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

View File

@ -812,6 +812,19 @@ i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
FREE( 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 static void
i915_set_sample_mask(struct pipe_context *pipe, i915_set_sample_mask(struct pipe_context *pipe,
unsigned sample_mask) 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.sampler_view_destroy = i915_sampler_view_destroy;
i915->base.set_viewport_state = i915_set_viewport_state; i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers; 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; struct pipe_resource *index_buffer;
unsigned index_size; unsigned index_size;
unsigned index_offset;
/* Updates are signalled by PIPE_NEW_INDEX_RANGE: /* 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 static int
try_draw_range_elements(struct brw_context *brw, try_draw_range_elements(struct brw_context *brw,
struct pipe_resource *index_buffer, boolean indexed,
unsigned hw_prim, unsigned hw_prim,
unsigned start, unsigned count) unsigned start, unsigned count)
{ {
@ -165,7 +165,7 @@ try_draw_range_elements(struct brw_context *brw,
if (ret) if (ret)
return 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) if (ret)
return ret; return ret;
@ -177,91 +177,54 @@ try_draw_range_elements(struct brw_context *brw,
static void static void
brw_draw_range_elements(struct pipe_context *pipe, brw_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
struct pipe_resource *index_buffer,
unsigned index_size, int index_bias,
unsigned min_index,
unsigned max_index,
unsigned mode, unsigned start, unsigned count)
{ {
struct brw_context *brw = brw_context(pipe); struct brw_context *brw = brw_context(pipe);
int ret; int ret;
uint32_t hw_prim; uint32_t hw_prim;
hw_prim = brw_set_prim(brw, mode); hw_prim = brw_set_prim(brw, info->mode);
if (BRW_DEBUG & DEBUG_PRIMS) if (BRW_DEBUG & DEBUG_PRIMS)
debug_printf("PRIM: %s start %d count %d index_buffer %p\n", 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. /* Potentially trigger upload of new index buffer range.
* * XXX: do we really care?
* XXX: do we need to go through state validation to achieve this?
* Could just call upload code directly.
*/ */
if (brw->curr.index_buffer != index_buffer || if (brw->curr.min_index != info->min_index ||
brw->curr.index_size != index_size) { brw->curr.max_index != info->max_index)
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)
{ {
brw->curr.min_index = min_index; brw->curr.min_index = info->min_index;
brw->curr.max_index = max_index; brw->curr.max_index = info->max_index;
brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE; brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE;
} }
/* Make a first attempt at drawing: /* 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: /* Otherwise, flush and retry:
*/ */
if (ret != 0) { if (ret != 0) {
brw_context_flush( brw ); 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); 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 ) boolean brw_draw_init( struct brw_context *brw )
{ {
/* Register our drawing function: /* Register our drawing function:
*/ */
brw->base.draw_arrays = brw_draw_arrays; brw->base.draw_vbo = brw_draw_vbo;
brw->base.draw_elements = brw_draw_elements;
brw->base.draw_range_elements = brw_draw_range_elements;
/* Create helpers for uploading data in user buffers: /* 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 pipe_resource *upload_buf = NULL;
struct brw_winsys_buffer *bo = NULL; struct brw_winsys_buffer *bo = NULL;
GLuint offset; GLuint offset;
GLuint index_size; GLuint index_size, index_offset;
GLuint ib_size; GLuint ib_size;
int ret; int ret;
@ -246,13 +246,14 @@ static int brw_prepare_indices(struct brw_context *brw)
ib_size = index_buffer->width0; ib_size = index_buffer->width0;
index_size = brw->curr.index_size; index_size = brw->curr.index_size;
index_offset = brw->curr.index_offset;
/* Turn userbuffer into a proper hardware buffer? /* Turn userbuffer into a proper hardware buffer?
*/ */
if (brw_buffer_is_user_buffer(index_buffer)) { if (brw_buffer_is_user_buffer(index_buffer)) {
ret = u_upload_buffer( brw->vb.upload_index, ret = u_upload_buffer( brw->vb.upload_index,
0, index_offset,
ib_size, ib_size,
index_buffer, index_buffer,
&offset, &offset,
@ -269,7 +270,7 @@ static int brw_prepare_indices(struct brw_context *brw)
else { else {
bo = brw_buffer(index_buffer)->bo; bo = brw_buffer(index_buffer)->bo;
ib_size = bo->size; ib_size = bo->size;
offset = 0; offset = index_offset;
} }
/* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the /* 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 void
brw_pipe_vertex_init( struct brw_context *brw ) brw_pipe_vertex_init( struct brw_context *brw )
{ {
brw->base.set_vertex_buffers = brw_set_vertex_buffers; 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.create_vertex_elements_state = brw_create_vertex_elements_state;
brw->base.bind_vertex_elements_state = brw_bind_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; 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 static void
identity_draw_arrays(struct pipe_context *_pipe, identity_draw_vbo(struct pipe_context *_pipe,
unsigned prim, const struct pipe_draw_info *info)
unsigned start,
unsigned count)
{ {
struct identity_context *id_pipe = identity_context(_pipe); struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe; struct pipe_context *pipe = id_pipe->pipe;
pipe->draw_arrays(pipe, pipe->draw_vbo(pipe, info);
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);
} }
static struct pipe_query * static struct pipe_query *
@ -611,6 +556,24 @@ identity_set_vertex_buffers(struct pipe_context *_pipe,
num_buffers, num_buffers,
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 static void
identity_resource_copy_region(struct pipe_context *_pipe, identity_resource_copy_region(struct pipe_context *_pipe,
struct pipe_resource *_dst, 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.draw = NULL;
id_pipe->base.destroy = identity_destroy; id_pipe->base.destroy = identity_destroy;
id_pipe->base.draw_arrays = identity_draw_arrays; id_pipe->base.draw_vbo = identity_draw_vbo;
id_pipe->base.draw_elements = identity_draw_elements;
id_pipe->base.draw_range_elements = identity_draw_range_elements;
id_pipe->base.create_query = identity_create_query; id_pipe->base.create_query = identity_create_query;
id_pipe->base.destroy_query = identity_destroy_query; id_pipe->base.destroy_query = identity_destroy_query;
id_pipe->base.begin_query = identity_begin_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_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_sampler_views = identity_set_vertex_sampler_views;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; 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.resource_copy_region = identity_resource_copy_region;
id_pipe->base.clear = identity_clear; id_pipe->base.clear = identity_clear;
id_pipe->base.clear_render_target = identity_clear_render_target; 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 distutils.version
Import('*') Import('*')
@ -16,7 +17,7 @@ env.CodeGenerate(
target = 'lp_tile_soa.c', target = 'lp_tile_soa.c',
script = 'lp_tile_soa.py', script = 'lp_tile_soa.py',
source = ['#src/gallium/auxiliary/util/u_format.csv'], 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. # 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) { if (stencil->writemask != stencilMax) {
/* compute res = (res & mask) | (stencilVals & ~mask) */ /* mask &= stencil->writemask */
LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask); LLVMValueRef writemask = lp_build_const_int_vec(type, stencil->writemask);
LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask"); mask = LLVMBuildAnd(bld->builder, mask, writemask, "");
LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1"); /* res = (res & mask) | (stencilVals & ~mask) */
LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2"); res = lp_build_select_bitwise(bld, writemask, res, stencilVals);
res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2"); }
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; return res;
} }
@ -662,9 +662,9 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
} }
/* Mix the old and new Z buffer values. /* 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) { if (stencil[0].enabled) {

View File

@ -46,6 +46,10 @@
#include "lp_query.h" #include "lp_query.h"
#include "lp_setup.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 ) static void llvmpipe_destroy( struct pipe_context *pipe )
{ {
struct llvmpipe_context *llvmpipe = llvmpipe_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 */ /* 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->no_rast = TRUE;
llvmpipe->setup = lp_setup_create( &llvmpipe->pipe, 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_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer index_buffer;
struct { struct {
struct llvmpipe_resource *buffer[PIPE_MAX_SO_BUFFERS]; struct llvmpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
int offset[PIPE_MAX_SO_BUFFERS]; int offset[PIPE_MAX_SO_BUFFERS];

View File

@ -49,20 +49,11 @@
* the drawing to the 'draw' module. * the drawing to the 'draw' module.
*/ */
static void static void
llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
struct pipe_resource *indexBuffer,
unsigned indexSize,
int indexBias,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
unsigned start,
unsigned count,
unsigned startInstance,
unsigned instanceCount)
{ {
struct llvmpipe_context *lp = llvmpipe_context(pipe); struct llvmpipe_context *lp = llvmpipe_context(pipe);
struct draw_context *draw = lp->draw; struct draw_context *draw = lp->draw;
void *mapped_indices = NULL;
unsigned i; unsigned i;
if (lp->dirty) if (lp->dirty)
@ -77,27 +68,25 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
} }
/* Map index buffer, if present */ /* Map index buffer, if present */
if (indexBuffer) { if (info->indexed && lp->index_buffer.buffer) {
void *mapped_indexes = llvmpipe_resource_data(indexBuffer); char *indices = (char *) llvmpipe_resource_data(lp->index_buffer.buffer);
draw_set_mapped_element_buffer_range(draw, mapped_indices = (void *) (indices + lp->index_buffer.offset);
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);
} }
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, llvmpipe_prepare_vertex_sampling(lp,
lp->num_vertex_sampler_views, lp->num_vertex_sampler_views,
lp->vertex_sampler_views); lp->vertex_sampler_views);
/* draw! */ /* draw! */
draw_arrays_instanced(draw, mode, start, count, draw_arrays_instanced(draw, info->mode, info->start, info->count,
startInstance, instanceCount); info->start_instance, info->instance_count);
/* /*
* unmap vertex/index buffers * 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++) { for (i = 0; i < lp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL); draw_set_mapped_vertex_buffer(draw, i, NULL);
} }
if (indexBuffer) { if (mapped_indices) {
draw_set_mapped_element_buffer(draw, 0, 0, NULL); draw_set_mapped_element_buffer(draw, 0, 0, NULL);
} }
llvmpipe_cleanup_vertex_sampling(lp); 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 void
llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe) llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe)
{ {
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays; llvmpipe->pipe.draw_vbo = llvmpipe_draw_vbo;
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;
} }

View File

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

View File

@ -40,6 +40,34 @@
#include "lp_limits.h" #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; 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); depth = lp_rast_get_depth_block_pointer(task, x, y);
/* run shader on 4x4 block */ /* run shader on 4x4 block */
BEGIN_JIT_CALL(state);
variant->jit_function[RAST_WHOLE]( &state->jit_context, variant->jit_function[RAST_WHOLE]( &state->jit_context,
x, y, x, y,
inputs->facing, inputs->facing,
@ -259,6 +288,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
depth, depth,
0xffff, 0xffff,
&task->vis_counter ); &task->vis_counter );
END_JIT_CALL();
} }

View File

@ -75,6 +75,7 @@
#include "gallivm/lp_bld_type.h" #include "gallivm/lp_bld_type.h"
#include "gallivm/lp_bld_const.h" #include "gallivm/lp_bld_const.h"
#include "gallivm/lp_bld_conv.h" #include "gallivm/lp_bld_conv.h"
#include "gallivm/lp_bld_init.h"
#include "gallivm/lp_bld_intr.h" #include "gallivm/lp_bld_intr.h"
#include "gallivm/lp_bld_logic.h" #include "gallivm/lp_bld_logic.h"
#include "gallivm/lp_bld_tgsi.h" #include "gallivm/lp_bld_tgsi.h"
@ -676,6 +677,11 @@ generate_fragment(struct llvmpipe_context *lp,
color_ptr); 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); LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(builder); LLVMDisposeBuilder(builder);
@ -710,6 +716,7 @@ generate_fragment(struct llvmpipe_context *lp,
if (gallivm_debug & GALLIVM_DEBUG_ASM) { if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(f); 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 void
llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe) 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.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers; 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_type.h"
#include "gallivm/lp_bld_debug.h" #include "gallivm/lp_bld_debug.h"
#include "lp_bld_blend.h" #include "lp_bld_blend.h"
@ -485,8 +486,7 @@ test_one(unsigned verbose,
{ {
LLVMModuleRef module = NULL; LLVMModuleRef module = NULL;
LLVMValueRef func = NULL; LLVMValueRef func = NULL;
LLVMExecutionEngineRef engine = NULL; LLVMExecutionEngineRef engine = lp_build_engine;
LLVMModuleProviderRef provider = NULL;
LLVMPassManagerRef pass = NULL; LLVMPassManagerRef pass = NULL;
char *error = NULL; char *error = NULL;
blend_test_ptr_t blend_test_ptr; blend_test_ptr_t blend_test_ptr;
@ -510,15 +510,6 @@ test_one(unsigned verbose,
} }
LLVMDisposeMessage(error); 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 #if 0
pass = LLVMCreatePassManager(); pass = LLVMCreatePassManager();
LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
@ -735,7 +726,6 @@ test_one(unsigned verbose,
LLVMFreeMachineCodeForFunction(engine, func); LLVMFreeMachineCodeForFunction(engine, func);
LLVMDisposeExecutionEngine(engine);
if(pass) if(pass)
LLVMDisposePassManager(pass); LLVMDisposePassManager(pass);

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