freedreno/a3xx+a4xx: add texture buffer object support
authorRob Clark <robclark@freedesktop.org>
Tue, 11 Aug 2015 20:47:16 +0000 (16:47 -0400)
committerRob Clark <robclark@freedesktop.org>
Wed, 12 Aug 2015 22:37:43 +0000 (18:37 -0400)
Basic texture buffer support.  Should be straightforward to add first/
last_element support.  And with a bit of work in ir3 emulate larger
texture buffer sizes.  But this seems to be enough for stk gl31 render
paths.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a3xx/fd3_texture.c
src/gallium/drivers/freedreno/a4xx/fd4_emit.c
src/gallium/drivers/freedreno/a4xx/fd4_texture.c
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_surface.c
src/gallium/drivers/freedreno/freedreno_util.h

index 49b3d97cce8a0dddd3006ebfea6c3d7030e3fd18..752e7f88cb974599d4b40db0d0f36c5c3b7fb7e1 100644 (file)
@@ -251,14 +251,15 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
                for (i = 0; i < tex->num_textures; i++) {
                        static const struct fd3_pipe_sampler_view dummy_view = {
+                                       .base.target = PIPE_TEXTURE_1D, /* anything !PIPE_BUFFER */
                                        .base.u.tex.first_level = 1,
                        };
                        const struct fd3_pipe_sampler_view *view = tex->textures[i] ?
                                        fd3_pipe_sampler_view(tex->textures[i]) :
                                        &dummy_view;
                        struct fd_resource *rsc = fd_resource(view->base.texture);
-                       unsigned start = view->base.u.tex.first_level;
-                       unsigned end   = view->base.u.tex.last_level;
+                       unsigned start = fd_sampler_first_level(&view->base);
+                       unsigned end   = fd_sampler_last_level(&view->base);;
 
                        for (j = 0; j < (end - start + 1); j++) {
                                struct fd_resource_slice *slice =
@@ -341,6 +342,7 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring,
                        format = fd3_gmem_restore_format(rsc->base.b.format);
                }
 
+               /* note: PIPE_BUFFER disallowed for surfaces */
                unsigned lvl = psurf[i]->u.tex.level;
                struct fd_resource_slice *slice = fd_resource_slice(rsc, lvl);
 
index a278bf5c603d5464b8908423a128ae7580d152c0..c30658d0e7b363ee4549fbc4b3df3ac24935f640 100644 (file)
@@ -210,8 +210,8 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 {
        struct fd3_pipe_sampler_view *so = CALLOC_STRUCT(fd3_pipe_sampler_view);
        struct fd_resource *rsc = fd_resource(prsc);
-       unsigned lvl = cso->u.tex.first_level;
-       unsigned miplevels = cso->u.tex.last_level - lvl;
+       unsigned lvl = fd_sampler_first_level(cso);
+       unsigned miplevels = fd_sampler_last_level(cso) - lvl;
        uint32_t sz2 = 0;
 
        if (!so)
index c3226d5121f87ef2e56c750198a9590e94e8e8e7..b75be29e523ab9bef7db097f76596ee80b4db6d9 100644 (file)
@@ -172,7 +172,7 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        const struct fd4_pipe_sampler_view *view = tex->textures[i] ?
                                        fd4_pipe_sampler_view(tex->textures[i]) :
                                        &dummy_view;
-                       unsigned start = view->base.u.tex.first_level;
+                       unsigned start = fd_sampler_first_level(&view->base);
 
                        OUT_RING(ring, view->texconst0);
                        OUT_RING(ring, view->texconst1);
@@ -235,6 +235,7 @@ fd4_emit_gmem_restore_tex(struct fd_ringbuffer *ring, unsigned nr_bufs,
        for (i = 0; i < nr_bufs; i++) {
                if (bufs[i]) {
                        struct fd_resource *rsc = fd_resource(bufs[i]->texture);
+                       /* note: PIPE_BUFFER disallowed for surfaces */
                        unsigned lvl = bufs[i]->u.tex.level;
                        struct fd_resource_slice *slice = fd_resource_slice(rsc, lvl);
                        uint32_t offset = fd_resource_offset(rsc, lvl, bufs[i]->u.tex.first_layer);
index 6ba25d0816d3afcdbff4626e8bd641c879d9a81e..d2bc5fee6c0bc6751ddf23e2164335f85d6fab95 100644 (file)
@@ -150,8 +150,8 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 {
        struct fd4_pipe_sampler_view *so = CALLOC_STRUCT(fd4_pipe_sampler_view);
        struct fd_resource *rsc = fd_resource(prsc);
-       unsigned lvl = cso->u.tex.first_level;
-       unsigned miplevels = cso->u.tex.last_level - lvl;
+       unsigned lvl = fd_sampler_first_level(cso);
+       unsigned miplevels = fd_sampler_last_level(cso) - lvl;
 
        if (!so)
                return NULL;
index 26802b0188ae57d0d42442eccb54d8eb00f02d1b..3aeed57b0432fddbef843d1e2ee319c065ee4176 100644 (file)
@@ -164,9 +164,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_TEXTURE_BARRIER:
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
        case PIPE_CAP_CUBE_MAP_ARRAY:
-       case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
-       case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
-       case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
        case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
        case PIPE_CAP_START_INSTANCE:
        case PIPE_CAP_COMPUTE:
@@ -178,8 +175,21 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
        case PIPE_CAP_INDEP_BLEND_ENABLE:
        case PIPE_CAP_INDEP_BLEND_FUNC:
+       case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
                return is_a3xx(screen) || is_a4xx(screen);
 
+       case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+               /* ignoring first/last_element.. but I guess that should be
+                * easy to add..
+                */
+               return 0;
+       case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
+               /* I think 32k on a4xx.. and we could possibly emulate more
+                * by pretending 2d/rect textures and splitting high bits
+                * of index into 2nd dimension..
+                */
+               return 16383;
+
        case PIPE_CAP_DEPTH_CLIP_DISABLE:
                return is_a3xx(screen);
 
index 250fe4bc0f5ad6df5efd013fdc6d196b7558f508..70c44eb79c362e6bee4768f3da2b2b49b7c4dd88 100644 (file)
@@ -41,7 +41,8 @@ fd_create_surface(struct pipe_context *pctx,
 //     struct fd_resource* tex = fd_resource(ptex);
        struct fd_surface* surface = CALLOC_STRUCT(fd_surface);
 
-       assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
+       debug_assert(ptex->target != PIPE_BUFFER);
+       debug_assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
 
        if (surface) {
                struct pipe_surface *psurf = &surface->base;
index d6a08b5fa139034928457cc7420e15965dabe8da..7129a1bddd1e1cd9caf145810e6d2ea544c9d93d 100644 (file)
@@ -140,6 +140,22 @@ fd_surface_half_precision(const struct pipe_surface *psurf)
        return true;
 }
 
+static inline unsigned
+fd_sampler_first_level(const struct pipe_sampler_view *view)
+{
+       if (view->target == PIPE_BUFFER)
+               return 0;
+       return view->u.tex.first_level;
+}
+
+static inline unsigned
+fd_sampler_last_level(const struct pipe_sampler_view *view)
+{
+       if (view->target == PIPE_BUFFER)
+               return 0;
+       return view->u.tex.last_level;
+}
+
 static inline bool
 fd_half_precision(struct pipe_framebuffer_state *pfb)
 {