summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/kernel_interface.md4
-rw-r--r--native/driver/etna_internal.h6
-rw-r--r--native/driver/etna_pipe.c45
-rw-r--r--native/driver/etna_screen.c12
-rw-r--r--native/etnaviv/etna_mem.c5
5 files changed, 57 insertions, 15 deletions
diff --git a/doc/kernel_interface.md b/doc/kernel_interface.md
index 4121843..f03dc28 100644
--- a/doc/kernel_interface.md
+++ b/doc/kernel_interface.md
@@ -209,7 +209,7 @@ The event queue effectively schedules kernel operations to happen in the future,
committed command buffers. This can be used to implement, for example, a fenced free that will release a buffer as soon as the GPU
is finished with it.
-Events queues are sent to the kernel using the command `HAL_EVENT_COMMIT`. Types of interfaces that can be sent using an event are:
+Event queues are sent to the kernel using the command `HAL_EVENT_COMMIT`. Types of interfaces that can be sent using an event are:
- `FREE_NON_PAGED_MEMORY`: free earlier allocated non paged memory
- `FREE_CONTIGUOUS_MEMORY`: free earier allocated contiguous memory
@@ -219,7 +219,7 @@ Events queues are sent to the kernel using the command `HAL_EVENT_COMMIT`. Types
- `SIGNAL`: command from the signal API described in this section
- `UNMAP_USER_MEMORY`: unmap earlier mapped user memory
-Userspace can then wait for them using `USER_SIGNAL` with subcommand `USER_SIGNAL_WAIT`.
+Userspace can wait for the signal using `USER_SIGNAL` with subcommand `USER_SIGNAL_WAIT`.
Anatomy of a small rendering test
----------------------------------
diff --git a/native/driver/etna_internal.h b/native/driver/etna_internal.h
index 0fd3ec2..862c077 100644
--- a/native/driver/etna_internal.h
+++ b/native/driver/etna_internal.h
@@ -51,6 +51,10 @@ struct etna_pipe_specs
uint32_t ts_clear_value;
/* base of vertex texture units */
unsigned vertex_sampler_offset;
+ /* number of fragment sampler units */
+ unsigned fragment_sampler_count;
+ /* number of vertex sampler units */
+ unsigned vertex_sampler_count;
/* needs z=(z+w)/2, for older GCxxx */
bool vs_need_z_div;
/* size of vertex shader output buffer */
@@ -167,6 +171,7 @@ struct compiled_sampler_view
/* Compiled pipe_framebuffer_state */
struct compiled_framebuffer_state
{
+ struct pipe_surface *cbuf, *zsbuf; /* keep reference to surfaces */
uint32_t GL_MULTI_SAMPLE_CONFIG;
uint32_t PE_COLOR_FORMAT;
uint32_t PE_DEPTH_CONFIG;
@@ -208,6 +213,7 @@ struct compiled_set_vertex_buffer
/* Compiled context->set_index_buffer result */
struct compiled_set_index_buffer
{
+ struct pipe_resource *buffer; /* keep reference to buffer */
uint32_t FE_INDEX_STREAM_CONTROL;
uint32_t FE_INDEX_STREAM_BASE_ADDR;
};
diff --git a/native/driver/etna_pipe.c b/native/driver/etna_pipe.c
index 6ea368a..c707b3b 100644
--- a/native/driver/etna_pipe.c
+++ b/native/driver/etna_pipe.c
@@ -942,6 +942,12 @@ static void etna_pipe_set_framebuffer_state(struct pipe_context *pipe,
bool color_supertiled = (cbuf->layout & 2)!=0;
bool depth_supertiled = (zsbuf->layout & 2)!=0;
+ /* acquire or release references to underlying surfaces */
+ if(cbuf != NULL)
+ pipe_surface_reference(&cs->cbuf, &cbuf->base);
+ if(zsbuf != NULL)
+ pipe_surface_reference(&cs->zsbuf, &zsbuf->base);
+
/* XXX support multisample 2X/4X, take care that required width/height is doubled */
SET_STATE(GL_MULTI_SAMPLE_CONFIG,
VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE
@@ -980,7 +986,7 @@ static void etna_pipe_set_framebuffer_state(struct pipe_context *pipe,
else if (priv->ctx->conn->chip.pixel_pipes == 2)
{
SET_STATE(PE_PIPE_COLOR_ADDR[0], zsbuf->surf.address);
- SET_STATE(PE_PIPE_DEPTH_ADDR[1], zsbuf->surf.address); /* TODO */
+ SET_STATE(PE_PIPE_COLOR_ADDR[1], zsbuf->surf.address); /* TODO */
}
SET_STATE(PE_COLOR_STRIDE, cbuf->surf.stride);
@@ -989,7 +995,7 @@ static void etna_pipe_set_framebuffer_state(struct pipe_context *pipe,
SET_STATE_FIXP(SE_SCISSOR_RIGHT, (sv->width << 16)-1);
SET_STATE_FIXP(SE_SCISSOR_BOTTOM, (sv->height << 16)-1);
- /* Set up TS as well. Warning: this is shared with RS */
+ /* Set up TS as well. Warning: this state is used by both the RS and PE */
uint32_t ts_mem_config = 0;
if(zsbuf->surf.ts_address)
{
@@ -1061,13 +1067,18 @@ static void etna_pipe_set_fragment_sampler_views(struct pipe_context *pipe,
struct pipe_sampler_view **info)
{
struct etna_pipe_context_priv *priv = ETNA_PIPE(pipe);
+ unsigned idx;
priv->dirty_bits |= ETNA_STATE_SAMPLER_VIEWS;
priv->num_fragment_sampler_views = num_views;
- for(int idx=0; idx<num_views; ++idx)
+ for(idx=0; idx<num_views; ++idx)
{
- priv->sampler_view_s[idx] = info[idx]; /* TODO reference */
+ pipe_sampler_view_reference(&priv->sampler_view_s[idx], info[idx]);
priv->sampler_view[idx] = *etna_sampler_view(info[idx])->internal;
}
+ for(; idx<priv->specs.fragment_sampler_count; ++idx)
+ {
+ pipe_sampler_view_reference(&priv->sampler_view_s[idx], NULL);
+ }
}
static void etna_pipe_set_vertex_sampler_views(struct pipe_context *pipe,
@@ -1075,12 +1086,18 @@ static void etna_pipe_set_vertex_sampler_views(struct pipe_context *pipe,
struct pipe_sampler_view **info)
{
struct etna_pipe_context_priv *priv = ETNA_PIPE(pipe);
+ unsigned idx;
+ unsigned offset = priv->specs.vertex_sampler_offset;
priv->dirty_bits |= ETNA_STATE_SAMPLER_VIEWS;
priv->num_vertex_sampler_views = num_views;
- for(int idx=0; idx<num_views; ++idx)
+ for(idx=0; idx<num_views; ++idx)
{
- priv->sampler_view_s[priv->specs.vertex_sampler_offset + idx] = info[idx];
- priv->sampler_view[priv->specs.vertex_sampler_offset + idx] = *etna_sampler_view(info[idx])->internal;
+ pipe_sampler_view_reference(&priv->sampler_view_s[offset + idx], info[idx]);
+ priv->sampler_view[offset + idx] = *etna_sampler_view(info[idx])->internal;
+ }
+ for(; idx<priv->specs.vertex_sampler_count; ++idx)
+ {
+ pipe_sampler_view_reference(&priv->sampler_view_s[offset + idx], NULL);
}
}
@@ -1108,11 +1125,13 @@ static void etna_pipe_set_index_buffer( struct pipe_context *pipe,
struct compiled_set_index_buffer *cs = &priv->index_buffer;
if(ib == NULL)
{
+ pipe_resource_reference(&cs->buffer, NULL); /* update reference to buffer */
SET_STATE(FE_INDEX_STREAM_CONTROL, 0);
SET_STATE(FE_INDEX_STREAM_BASE_ADDR, 0);
} else
{
- assert(ib->buffer); /* XXX user_buffer */
+ assert(ib->buffer); /* user index buffers not handled */
+ pipe_resource_reference(&cs->buffer, ib->buffer); /* update reference to buffer */
SET_STATE(FE_INDEX_STREAM_CONTROL,
translate_index_size(ib->index_size));
SET_STATE(FE_INDEX_STREAM_BASE_ADDR, etna_resource(ib->buffer)->levels[0].address + ib->offset);
@@ -1236,6 +1255,8 @@ static struct pipe_sampler_view *etna_pipe_create_sampler_view(struct pipe_conte
struct etna_sampler_view *sv = CALLOC_STRUCT(etna_sampler_view);
sv->base = *templat;
sv->base.context = pipe;
+ sv->base.texture = 0;
+ pipe_resource_reference(&sv->base.texture, texture);
sv->base.texture = texture;
assert(sv->base.texture);
@@ -1271,6 +1292,7 @@ static void etna_pipe_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
//struct etna_pipe_context_priv *priv = ETNA_PIPE(pipe);
+ pipe_resource_reference(&view->texture, NULL);
FREE(etna_sampler_view(view)->internal);
FREE(view);
}
@@ -1288,6 +1310,10 @@ static struct pipe_surface *etna_pipe_create_surface(struct pipe_context *pipe,
assert(layer < resource->base.array_size);
surf->base.context = pipe;
+
+ pipe_reference_init(&surf->base.reference, 1);
+ pipe_resource_reference(&surf->base.texture, &resource->base);
+
surf->base.texture = &resource->base;
surf->base.format = resource->base.format;
surf->base.width = resource->levels[level].width;
@@ -1327,6 +1353,7 @@ static struct pipe_surface *etna_pipe_create_surface(struct pipe_context *pipe,
static void etna_pipe_surface_destroy(struct pipe_context *pipe, struct pipe_surface *surf)
{
//struct etna_pipe_context_priv *priv = ETNA_PIPE(pipe);
+ pipe_resource_reference(&surf->texture, NULL);
FREE(surf);
}
@@ -1474,7 +1501,7 @@ static void etna_set_constant_buffer(struct pipe_context *pipe,
{
struct etna_pipe_context_priv *priv = ETNA_PIPE(pipe);
assert(buf->buffer == NULL && buf->user_buffer != NULL);
- /* support only user buffer for now; XXX support PIPE_BIND_CONSTANT buffers */
+ /* support only user buffer for now */
assert(priv->vs && priv->fs);
if(index == 0)
{
diff --git a/native/driver/etna_screen.c b/native/driver/etna_screen.c
index 09e1e5e..cd174bb 100644
--- a/native/driver/etna_screen.c
+++ b/native/driver/etna_screen.c
@@ -35,6 +35,7 @@
#include "util/u_format.h"
#include "util/u_transfer.h"
#include "util/u_math.h"
+#include "util/u_inlines.h"
#include <stdio.h>
@@ -57,7 +58,7 @@ static const char *etna_screen_get_vendor( struct pipe_screen *screen )
static int etna_screen_get_param( struct pipe_screen *screen, enum pipe_cap param )
{
- /* struct etna_screen *priv = etna_screen(screen); */
+ struct etna_screen *priv = etna_screen(screen);
switch (param) {
/* Supported features (boolean caps). */
case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -135,7 +136,7 @@ static int etna_screen_get_param( struct pipe_screen *screen, enum pipe_cap para
case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
return 0;
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
- return 12; /* XXX depends on caps */
+ return priv->specs.fragment_sampler_count + priv->specs.vertex_sampler_count;
case PIPE_CAP_CUBE_MAP_ARRAY:
return 0;
case PIPE_CAP_MIN_TEXEL_OFFSET:
@@ -192,6 +193,7 @@ static float etna_screen_get_paramf( struct pipe_screen *screen, enum pipe_capf
static int etna_screen_get_shader_param( struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param )
{
+ struct etna_screen *priv = etna_screen(screen);
switch(shader)
{
case PIPE_SHADER_FRAGMENT:
@@ -245,7 +247,8 @@ static int etna_screen_get_shader_param( struct pipe_screen *screen, unsigned sh
case PIPE_SHADER_CAP_INTEGERS: /* XXX supported on gc2000 */
return 0;
case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
- return shader==PIPE_SHADER_FRAGMENT ? 16 : 8;
+ return shader==PIPE_SHADER_FRAGMENT ? priv->specs.fragment_sampler_count :
+ priv->specs.vertex_sampler_count;
case PIPE_SHADER_CAP_PREFERRED_IR:
return PIPE_SHADER_IR_TGSI;
default:
@@ -566,6 +569,7 @@ static struct pipe_resource * etna_screen_resource_create(struct pipe_screen *sc
resource->layout = layout;
resource->surface = rt;
resource->ts = rt_ts;
+ pipe_reference_init(&resource->base.reference, 1);
for(unsigned ix=0; ix<=resource->base.last_level; ++ix)
{
@@ -610,6 +614,8 @@ etna_screen_create(struct viv_conn *dev)
screen->specs.bits_per_tile = VIV_FEATURE(dev, chipMinorFeatures0, 2BITPERTILE)?2:4;
screen->specs.ts_clear_value = VIV_FEATURE(dev, chipMinorFeatures0, 2BITPERTILE)?0x55555555:0x11111111;
screen->specs.vertex_sampler_offset = 8; /* vertex and fragment samplers live in one address space */
+ screen->specs.fragment_sampler_count = 8;
+ screen->specs.vertex_sampler_count = 4;
screen->specs.vs_need_z_div = dev->chip.chip_model < 0x1000 && dev->chip.chip_model != 0x880;
screen->specs.vertex_output_buffer_size = dev->chip.vertex_output_buffer_size;
screen->specs.vertex_cache_size = dev->chip.vertex_cache_size;
diff --git a/native/etnaviv/etna_mem.c b/native/etnaviv/etna_mem.c
index 4cec75d..004af08 100644
--- a/native/etnaviv/etna_mem.c
+++ b/native/etnaviv/etna_mem.c
@@ -95,7 +95,10 @@ int etna_vidmem_unlock(struct viv_conn *conn, struct etna_vidmem *mem)
int etna_vidmem_free(struct viv_conn *conn, struct etna_vidmem *mem)
{
if(mem == NULL) return ETNA_INVALID_ADDR;
- viv_free_vidmem(conn, mem->node);
+ if(etna_vidmem_unlock(conn, mem))
+ {
+ printf("etna: Warning: could not unlock memory\n");
+ }
ETNA_FREE(mem);
return ETNA_OK;
}