Merge branch 'master' into glsl2
This commit is contained in:
commit
443a7e4e9a
|
@ -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@
|
||||||
|
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 */
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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( ®->Indirect, CHAN_X );
|
swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, CHAN_X );
|
||||||
fetch_src_file_channel(mach,
|
fetch_src_file_channel(mach,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
|
|
||||||
#if defined(PIPE_ARCH_SSE)
|
#if defined(PIPE_ARCH_SSE)
|
||||||
|
|
||||||
#include <xmmintrin.h>
|
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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::
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
|
@ -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];*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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:
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue