diff options
-rw-r--r-- | doc/kernel_interface.md | 4 | ||||
-rw-r--r-- | native/driver/etna_internal.h | 6 | ||||
-rw-r--r-- | native/driver/etna_pipe.c | 45 | ||||
-rw-r--r-- | native/driver/etna_screen.c | 12 | ||||
-rw-r--r-- | native/etnaviv/etna_mem.c | 5 |
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; } |