summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robclark@freedesktop.org>2015-08-11 16:47:16 -0400
committerRob Clark <robclark@freedesktop.org>2015-08-12 18:37:43 -0400
commit500025a23784877c8a61d8b3c7a8eab6fddf242a (patch)
tree06d610c3c384587632687c8a7e1ffc1683394a5a
parentfb07c49f4883b12cef37748271d99e2fcf217a72 (diff)
freedreno/a3xx+a4xx: add texture buffer object support
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>
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c6
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_texture.c4
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_emit.c3
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_texture.c4
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c16
-rw-r--r--src/gallium/drivers/freedreno/freedreno_surface.c3
-rw-r--r--src/gallium/drivers/freedreno/freedreno_util.h16
7 files changed, 41 insertions, 11 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 49b3d97cce..752e7f88cb 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
index a278bf5c60..c30658d0e7 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
@@ -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)
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
index c3226d5121..b75be29e52 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
index 6ba25d0816..d2bc5fee6c 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
@@ -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;
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index 26802b0188..3aeed57b04 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/freedreno_surface.c b/src/gallium/drivers/freedreno/freedreno_surface.c
index 250fe4bc0f..70c44eb79c 100644
--- a/src/gallium/drivers/freedreno/freedreno_surface.c
+++ b/src/gallium/drivers/freedreno/freedreno_surface.c
@@ -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;
diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h
index d6a08b5fa1..7129a1bddd 100644
--- a/src/gallium/drivers/freedreno/freedreno_util.h
+++ b/src/gallium/drivers/freedreno/freedreno_util.h
@@ -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)
{