summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.c46
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.h4
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.c2
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c96
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c10
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c43
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_loader.h4
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.h29
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c7
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.c8
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.c11
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c7
12 files changed, 203 insertions, 64 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c
index 203682ef33..22e1b6dd70 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.c
+++ b/src/gallium/state_trackers/dri/common/dri_context.c
@@ -57,7 +57,20 @@ dri_create_context(gl_api api, const __GLcontextModes * visual,
struct st_api *stapi = screen->st_api;
struct dri_context *ctx = NULL;
struct st_context_iface *st_share = NULL;
- struct st_visual stvis;
+ struct st_context_attribs attribs;
+
+ memset(&attribs, 0, sizeof(attribs));
+ switch (api) {
+ case API_OPENGLES:
+ attribs.profile = ST_PROFILE_OPENGL_ES1;
+ break;
+ case API_OPENGLES2:
+ attribs.profile = ST_PROFILE_OPENGL_ES2;
+ break;
+ default:
+ attribs.profile = ST_PROFILE_DEFAULT;
+ break;
+ }
if (sharedContextPrivate) {
st_share = ((struct dri_context *)sharedContextPrivate)->st;
@@ -75,13 +88,22 @@ dri_create_context(gl_api api, const __GLcontextModes * visual,
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache, sPriv->myNum, "dri");
- dri_fill_st_visual(&stvis, screen, visual);
- ctx->st = stapi->create_context(stapi, &screen->base, &stvis, st_share);
+ dri_fill_st_visual(&attribs.visual, screen, visual);
+ ctx->st = stapi->create_context(stapi, &screen->base, &attribs, st_share);
if (ctx->st == NULL)
goto fail;
ctx->st->st_manager_private = (void *) ctx;
-
- dri_init_extensions(ctx);
+ ctx->stapi = stapi;
+
+ /*
+ * libmesagallium.a that this state tracker will be linked to expects
+ * OpenGL's _glapi_table. That is, it expects libGL.so instead of
+ * libGLESv1_CM.so or libGLESv2.so. As there is no clean way to know the
+ * shared library the app links to, use the api as a simple check.
+ * It might be as well to simply remove this function call though.
+ */
+ if (api == API_OPENGL)
+ dri_init_extensions(ctx);
return GL_TRUE;
@@ -90,7 +112,7 @@ dri_create_context(gl_api api, const __GLcontextModes * visual,
ctx->st->destroy(ctx->st);
FREE(ctx);
- return FALSE;
+ return GL_FALSE;
}
void
@@ -119,14 +141,12 @@ GLboolean
dri_unbind_context(__DRIcontext * cPriv)
{
/* dri_util.c ensures cPriv is not null */
- struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_context *ctx = dri_context(cPriv);
- struct st_api *stapi = screen->st_api;
if (--ctx->bind_count == 0) {
- if (ctx->st == stapi->get_current(stapi)) {
+ if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- stapi->make_current(stapi, NULL, NULL, NULL);
+ ctx->stapi->make_current(ctx->stapi, NULL, NULL, NULL);
}
}
@@ -139,12 +159,10 @@ dri_make_current(__DRIcontext * cPriv,
__DRIdrawable * driReadPriv)
{
/* dri_util.c ensures cPriv is not null */
- struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_context *ctx = dri_context(cPriv);
- struct st_api *stapi = screen->st_api;
struct dri_drawable *draw = dri_drawable(driDrawPriv);
struct dri_drawable *read = dri_drawable(driReadPriv);
- struct st_context_iface *old_st = stapi->get_current(stapi);
+ struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);
if (old_st && old_st != ctx->st)
old_st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
@@ -160,7 +178,7 @@ dri_make_current(__DRIcontext * cPriv,
read->texture_stamp = driReadPriv->lastStamp - 1;
}
- stapi->make_current(stapi, ctx->st, &draw->base, &read->base);
+ ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base);
return GL_TRUE;
}
diff --git a/src/gallium/state_trackers/dri/common/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h
index 35b870a8a3..ffe9eba13c 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.h
+++ b/src/gallium/state_trackers/dri/common/dri_context.h
@@ -37,7 +37,8 @@
struct pipe_context;
struct pipe_fence;
-struct st_context;
+struct st_api;
+struct st_context_iface;
struct dri_drawable;
struct dri_context
@@ -58,6 +59,7 @@ struct dri_context
unsigned int bind_count;
/* gallium */
+ struct st_api *stapi;
struct st_context_iface *st;
/* hooks filled in by dri2 & drisw */
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c
index 0ab4dd1893..475a96d196 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.c
+++ b/src/gallium/state_trackers/dri/common/dri_screen.c
@@ -378,8 +378,8 @@ dri_init_screen_helper(struct dri_screen *screen,
screen->base.get_egl_image = dri_get_egl_image;
screen->base.get_param = dri_get_param;
- screen->st_api = st_gl_api_create();
+ screen->st_api = st_gl_api_create();
if (!screen->st_api)
return NULL;
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 93f910a26d..596309bfbd 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -380,6 +380,92 @@ dri2_create_image_from_renderbuffer(__DRIcontext *context,
return NULL;
}
+static __DRIimage *
+dri2_create_image(__DRIscreen *_screen,
+ int width, int height, int format,
+ unsigned int use, void *loaderPrivate)
+{
+ struct dri_screen *screen = dri_screen(_screen);
+ __DRIimage *img;
+ struct pipe_resource templ;
+ unsigned tex_usage;
+ enum pipe_format pf;
+
+ tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_RGB565:
+ pf = PIPE_FORMAT_B5G6R5_UNORM;
+ break;
+ case __DRI_IMAGE_FORMAT_XRGB8888:
+ pf = PIPE_FORMAT_B8G8R8X8_UNORM;
+ break;
+ case __DRI_IMAGE_FORMAT_ARGB8888:
+ pf = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ default:
+ pf = PIPE_FORMAT_NONE;
+ break;
+ }
+ if (pf == PIPE_FORMAT_NONE)
+ return NULL;
+
+ img = CALLOC_STRUCT(__DRIimageRec);
+ if (!img)
+ return NULL;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.bind = tex_usage;
+ templ.format = pf;
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+
+ img->texture = screen->base.screen->resource_create(screen->base.screen, &templ);
+ if (!img->texture) {
+ FREE(img);
+ return NULL;
+ }
+
+ img->face = 0;
+ img->level = 0;
+ img->zslice = 0;
+
+ img->loader_private = loaderPrivate;
+ return img;
+}
+
+static GLboolean
+dri2_query_image(__DRIimage *image, int attrib, int *value)
+{
+ struct winsys_handle whandle;
+ memset(&whandle, 0, sizeof(whandle));
+
+ switch (attrib) {
+ case __DRI_IMAGE_ATTRIB_STRIDE:
+ image->texture->screen->resource_get_handle(image->texture->screen,
+ image->texture, &whandle);
+ *value = whandle.stride;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_HANDLE:
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ image->texture->screen->resource_get_handle(image->texture->screen,
+ image->texture, &whandle);
+ *value = whandle.handle;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_NAME:
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ image->texture->screen->resource_get_handle(image->texture->screen,
+ image->texture, &whandle);
+ *value = whandle.handle;
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
static void
dri2_destroy_image(__DRIimage *img)
{
@@ -392,6 +478,8 @@ static struct __DRIimageExtensionRec dri2ImageExtension = {
dri2_create_image_from_name,
dri2_create_image_from_renderbuffer,
dri2_destroy_image,
+ dri2_create_image,
+ dri2_query_image,
};
/*
@@ -439,6 +527,14 @@ dri2_init_screen(__DRIscreen * sPriv)
if (!configs)
goto fail;
+ sPriv->api_mask = 0;
+ if (screen->st_api->profile_mask & ST_PROFILE_DEFAULT_MASK)
+ sPriv->api_mask |= 1 << __DRI_API_OPENGL;
+ if (screen->st_api->profile_mask & ST_PROFILE_OPENGL_ES1_MASK)
+ sPriv->api_mask |= 1 << __DRI_API_GLES;
+ if (screen->st_api->profile_mask & ST_PROFILE_OPENGL_ES2_MASK)
+ sPriv->api_mask |= 1 << __DRI_API_GLES2;
+
screen->auto_fake_front = dri_with_format(sPriv);
screen->broken_invalidate = !sPriv->dri2.useInvalidate;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 4e653bdf3b..33a838fb79 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -502,13 +502,13 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
goto fail;
}
- if (gdpy->loader->api_mask & (1 << ST_API_OPENGL))
+ if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
dpy->ClientAPIsMask |= EGL_OPENGL_BIT;
- if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES1))
+ if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK)
dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
- if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES2))
+ if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK)
dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
- if (gdpy->loader->api_mask & (1 << ST_API_OPENVG))
+ if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK)
dpy->ClientAPIsMask |= EGL_OPENVG_BIT;
gdpy->smapi = egl_g3d_create_st_manager(dpy);
@@ -567,7 +567,7 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
if (procname && procname[0] == 'v' && procname[1] == 'g')
stapi = gdrv->loader->get_st_api(ST_API_OPENVG);
else if (procname && procname[0] == 'g' && procname[1] == 'l')
- stapi = gdrv->loader->guess_gl_api();
+ stapi = gdrv->loader->get_st_api(ST_API_OPENGL);
return (_EGLProc) ((stapi) ?
stapi->get_proc_address(stapi, procname) : NULL);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 3ec53653f4..c0164daf9c 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -43,19 +43,25 @@
* Return the state tracker for the given context.
*/
static struct st_api *
-egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
+egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx,
+ enum st_profile_type *profile)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
- EGLint idx = -1;
+ struct st_api *stapi;
+ EGLint api = -1;
+
+ *profile = ST_PROFILE_DEFAULT;
switch (ctx->ClientAPI) {
case EGL_OPENGL_ES_API:
switch (ctx->ClientVersion) {
case 1:
- idx = ST_API_OPENGL_ES1;
+ api = ST_API_OPENGL;
+ *profile = ST_PROFILE_OPENGL_ES1;
break;
case 2:
- idx = ST_API_OPENGL_ES2;
+ api = ST_API_OPENGL;
+ *profile = ST_PROFILE_OPENGL_ES2;
break;
default:
_eglLog(_EGL_WARNING, "unknown client version %d",
@@ -64,17 +70,31 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
}
break;
case EGL_OPENVG_API:
- idx = ST_API_OPENVG;
+ api = ST_API_OPENVG;
break;
case EGL_OPENGL_API:
- idx = ST_API_OPENGL;
+ api = ST_API_OPENGL;
break;
default:
_eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
break;
}
- return (idx >= 0) ? gdrv->loader->get_st_api(idx) : NULL;
+ switch (api) {
+ case ST_API_OPENGL:
+ stapi = gdrv->loader->guess_gl_api(*profile);
+ break;
+ case ST_API_OPENVG:
+ stapi = gdrv->loader->get_st_api(api);
+ break;
+ default:
+ stapi = NULL;
+ break;
+ }
+ if (stapi && !(stapi->profile_mask & (1 << *profile)))
+ stapi = NULL;
+
+ return stapi;
}
static _EGLContext *
@@ -85,6 +105,7 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
struct egl_g3d_context *gshare = egl_g3d_context(share);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_context *gctx;
+ struct st_context_attribs stattribs;
gctx = CALLOC_STRUCT(egl_g3d_context);
if (!gctx) {
@@ -97,14 +118,18 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}
- gctx->stapi = egl_g3d_choose_st(drv, &gctx->base);
+ memset(&stattribs, 0, sizeof(stattribs));
+ if (gconf)
+ stattribs.visual = gconf->stvis;
+
+ gctx->stapi = egl_g3d_choose_st(drv, &gctx->base, &stattribs.profile);
if (!gctx->stapi) {
FREE(gctx);
return NULL;
}
gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
- (gconf) ? &gconf->stvis : NULL, (gshare) ? gshare->stctxi : NULL);
+ &stattribs, (gshare) ? gshare->stctxi : NULL);
if (!gctx->stctxi) {
FREE(gctx);
return NULL;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
index c9141f8ad4..78bfe2131e 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
@@ -37,9 +37,9 @@ struct pipe_screen;
struct sw_winsys;
struct egl_g3d_loader {
- uint api_mask;
+ uint profile_masks[ST_API_COUNT];
struct st_api *(*get_st_api)(enum st_api_type api);
- struct st_api *(*guess_gl_api)(void);
+ struct st_api *(*guess_gl_api)(enum st_profile_type profile);
struct pipe_screen *(*create_drm_screen)(const char *name, int fd);
struct pipe_screen *(*create_sw_screen)(struct sw_winsys *ws);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.h b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
index aa25cc042d..1f9f07895b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
@@ -45,33 +45,4 @@ egl_g3d_create_st_framebuffer(_EGLSurface *surf);
void
egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
-/**
- * Return the EGL_<api>_BIT of the st api.
- */
-static INLINE int
-egl_g3d_st_api_bit(enum st_api_type api)
-{
- int bit;
-
- switch (api) {
- case ST_API_OPENGL:
- bit = EGL_OPENGL_BIT;
- break;
- case ST_API_OPENGL_ES1:
- bit = EGL_OPENGL_ES_BIT;
- break;
- case ST_API_OPENGL_ES2:
- bit = EGL_OPENGL_ES2_BIT;
- break;
- case ST_API_OPENVG:
- bit = EGL_OPENVG_BIT;
- break;
- default:
- bit = 0;
- break;
- }
-
- return bit;
-}
-
#endif /* _EGL_G3D_ST_H_ */
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index eb4ce74266..36d63c30d6 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -849,6 +849,7 @@ PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
XMesaDisplay xmdpy = xmesa_init_display(v->display);
+ struct st_context_attribs attribs;
XMesaContext c;
if (!xmdpy)
@@ -863,8 +864,12 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->xm_read_buffer = NULL;
+ memset(&attribs, 0, sizeof(attribs));
+ attribs.profile = ST_PROFILE_DEFAULT;
+ attribs.visual = v->stvis;
+
c->st = stapi->create_context(stapi, xmdpy->smapi,
- &v->stvis, (share_list) ? share_list->st : NULL);
+ &attribs, (share_list) ? share_list->st : NULL);
if (c->st == NULL)
goto fail;
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
index 0f74b3f7aa..4c0ce07a6b 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_st.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -122,6 +122,7 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
/**
* Remove outdated textures and create the requested ones.
+ * This is a helper used during framebuffer validation.
*/
static boolean
xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
@@ -193,6 +194,10 @@ xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
return TRUE;
}
+
+/**
+ * Called via st_framebuffer_iface::validate()
+ */
static boolean
xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
@@ -249,6 +254,9 @@ xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
return TRUE;
}
+/**
+ * Called via st_framebuffer_iface::flush_front()
+ */
static boolean
xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
index c2aa98b231..e7996741d1 100644
--- a/src/gallium/state_trackers/vega/vg_manager.c
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -341,13 +341,20 @@ vg_context_destroy(struct st_context_iface *stctxi)
static struct st_context_iface *
vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
- const struct st_visual *visual,
+ const struct st_context_attribs *attribs,
struct st_context_iface *shared_stctxi)
{
struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
struct vg_context *ctx;
struct pipe_context *pipe;
+ if (!(stapi->profile_mask & (1 << attribs->profile)))
+ return NULL;
+
+ /* only 1.0 is supported */
+ if (attribs->major != 1 || attribs->minor > 0)
+ return NULL;
+
pipe = smapi->screen->context_create(smapi->screen, NULL);
if (!pipe)
return NULL;
@@ -528,6 +535,8 @@ vg_api_destroy(struct st_api *stapi)
}
static const struct st_api vg_api = {
+ ST_API_OPENVG,
+ ST_PROFILE_DEFAULT_MASK,
vg_api_destroy,
vg_api_get_proc_address,
vg_api_create_context,
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index a0e14b9601..85878b4673 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -129,6 +129,7 @@ DrvCreateLayerContext(
{
int iPixelFormat;
const struct stw_pixelformat_info *pfi;
+ struct st_context_attribs attribs;
struct stw_context *ctx = NULL;
if(!stw_dev)
@@ -150,8 +151,12 @@ DrvCreateLayerContext(
ctx->hdc = hdc;
ctx->iPixelFormat = iPixelFormat;
+ memset(&attribs, 0, sizeof(attribs));
+ attribs.profile = ST_PROFILE_DEFAULT;
+ attribs.visual = pfi->stvis;
+
ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
- stw_dev->smapi, &pfi->stvis, NULL);
+ stw_dev->smapi, &attribs, NULL);
if (ctx->st == NULL)
goto no_st_ctx;