summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/v3d/v3d_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/v3d/v3d_context.c')
-rw-r--r--src/gallium/drivers/v3d/v3d_context.c158
1 files changed, 94 insertions, 64 deletions
diff --git a/src/gallium/drivers/v3d/v3d_context.c b/src/gallium/drivers/v3d/v3d_context.c
index 50a0e602e34..47364abea01 100644
--- a/src/gallium/drivers/v3d/v3d_context.c
+++ b/src/gallium/drivers/v3d/v3d_context.c
@@ -32,12 +32,14 @@
#include "util/u_blitter.h"
#include "util/u_upload_mgr.h"
#include "util/u_prim.h"
+#include "util/u_debug_cb.h"
#include "pipe/p_screen.h"
#include "v3d_screen.h"
#include "v3d_context.h"
#include "v3d_resource.h"
#include "broadcom/compiler/v3d_compiler.h"
+#include "broadcom/common/v3d_util.h"
void
v3d_flush(struct pipe_context *pctx)
@@ -59,13 +61,36 @@ v3d_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
v3d_flush(pctx);
if (fence) {
+ int fd = -1;
+ /* Snapshot the last V3D rendering's out fence. We'd rather
+ * have another syncobj instead of a sync file, but this is all
+ * we get. (HandleToFD/FDToHandle just gives you another syncobj
+ * ID for the same syncobj).
+ */
+ drmSyncobjExportSyncFile(v3d->fd, v3d->out_sync, &fd);
+ if (fd == -1) {
+ fprintf(stderr, "export failed\n");
+ *fence = NULL;
+ return;
+ }
+
struct pipe_screen *screen = pctx->screen;
- struct v3d_fence *f = v3d_fence_create(v3d);
+ struct v3d_fence *f = v3d_fence_create(v3d, fd);
screen->fence_reference(screen, fence, NULL);
*fence = (struct pipe_fence_handle *)f;
}
}
+/* We can't flush the texture cache within rendering a tile, so we have to
+ * flush all rendering to the kernel so that the next job reading from the
+ * tile gets a flushed cache.
+ */
+static void
+v3d_texture_barrier(struct pipe_context *pctx, unsigned int flags)
+{
+ v3d_flush(pctx);
+}
+
static void
v3d_memory_barrier(struct pipe_context *pctx, unsigned int flags)
{
@@ -86,18 +111,6 @@ v3d_memory_barrier(struct pipe_context *pctx, unsigned int flags)
}
static void
-v3d_set_debug_callback(struct pipe_context *pctx,
- const struct pipe_debug_callback *cb)
-{
- struct v3d_context *v3d = v3d_context(pctx);
-
- if (cb)
- v3d->debug = *cb;
- else
- memset(&v3d->debug, 0, sizeof(v3d->debug));
-}
-
-static void
v3d_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
{
struct v3d_context *v3d = v3d_context(pctx);
@@ -138,7 +151,7 @@ v3d_update_primitive_counters(struct v3d_context *v3d)
if (prims_before == prims_after)
return;
- enum pipe_prim_type prim_type = u_base_prim_type(v3d->prim_mode);
+ enum mesa_prim prim_type = u_base_prim_type(v3d->prim_mode);
uint32_t num_verts = u_vertices_for_prims(prim_type,
prims_after - prims_before);
for (int i = 0; i < v3d->streamout.num_targets; i++) {
@@ -194,6 +207,20 @@ v3d_get_real_line_width(struct v3d_context *v3d)
}
void
+v3d_ensure_prim_counts_allocated(struct v3d_context *ctx)
+{
+ if (ctx->prim_counts)
+ return;
+
+ /* Init all 7 counters and 1 padding to 0 */
+ uint32_t zeroes[8] = { 0 };
+ u_upload_data(ctx->uploader,
+ 0, sizeof(zeroes), 32, zeroes,
+ &ctx->prim_counts_offset,
+ &ctx->prim_counts);
+}
+
+void
v3d_flag_dirty_sampler_state(struct v3d_context *v3d,
enum pipe_shader_type shader)
{
@@ -216,17 +243,9 @@ v3d_flag_dirty_sampler_state(struct v3d_context *v3d,
}
void
-v3d_create_texture_shader_state_bo(struct v3d_context *v3d,
- struct v3d_sampler_view *so)
-{
- if (v3d->screen->devinfo.ver >= 41)
- v3d41_create_texture_shader_state_bo(v3d, so);
- else
- v3d33_create_texture_shader_state_bo(v3d, so);
-}
-
-void
-v3d_get_tile_buffer_size(bool is_msaa,
+v3d_get_tile_buffer_size(const struct v3d_device_info *devinfo,
+ bool is_msaa,
+ bool double_buffer,
uint32_t nr_cbufs,
struct pipe_surface **cbufs,
struct pipe_surface *bbuf,
@@ -234,27 +253,17 @@ v3d_get_tile_buffer_size(bool is_msaa,
uint32_t *tile_height,
uint32_t *max_bpp)
{
- static const uint8_t tile_sizes[] = {
- 64, 64,
- 64, 32,
- 32, 32,
- 32, 16,
- 16, 16,
- };
- int tile_size_index = 0;
- if (is_msaa)
- tile_size_index += 2;
-
- if (cbufs[3] || cbufs[2])
- tile_size_index += 2;
- else if (cbufs[1])
- tile_size_index++;
+ assert(!is_msaa || !double_buffer);
+ uint32_t max_cbuf_idx = 0;
+ uint32_t total_bpp = 0;
*max_bpp = 0;
for (int i = 0; i < nr_cbufs; i++) {
if (cbufs[i]) {
struct v3d_surface *surf = v3d_surface(cbufs[i]);
*max_bpp = MAX2(*max_bpp, surf->internal_bpp);
+ total_bpp += 4 * v3d_internal_bpp_words(surf->internal_bpp);
+ max_cbuf_idx = MAX2(i, max_cbuf_idx);
}
}
@@ -262,13 +271,13 @@ v3d_get_tile_buffer_size(bool is_msaa,
struct v3d_surface *bsurf = v3d_surface(bbuf);
assert(bbuf->texture->nr_samples <= 1 || is_msaa);
*max_bpp = MAX2(*max_bpp, bsurf->internal_bpp);
+ total_bpp += 4 * v3d_internal_bpp_words(bsurf->internal_bpp);
}
- tile_size_index += *max_bpp;
-
- assert(tile_size_index < ARRAY_SIZE(tile_sizes));
- *tile_width = tile_sizes[tile_size_index * 2 + 0];
- *tile_height = tile_sizes[tile_size_index * 2 + 1];
+ v3d_choose_tile_size(devinfo, max_cbuf_idx + 1,
+ *max_bpp, total_bpp,
+ is_msaa, double_buffer,
+ tile_width, tile_height);
}
static void
@@ -291,8 +300,7 @@ v3d_context_destroy(struct pipe_context *pctx)
slab_destroy_child(&v3d->transfer_pool);
- pipe_surface_reference(&v3d->framebuffer.cbufs[0], NULL);
- pipe_surface_reference(&v3d->framebuffer.zsbuf, NULL);
+ util_unreference_framebuffer_state(&v3d->framebuffer);
if (v3d->sand8_blit_vs)
pctx->delete_vs_state(pctx, v3d->sand8_blit_vs);
@@ -300,9 +308,15 @@ v3d_context_destroy(struct pipe_context *pctx)
pctx->delete_fs_state(pctx, v3d->sand8_blit_fs_luma);
if (v3d->sand8_blit_fs_chroma)
pctx->delete_fs_state(pctx, v3d->sand8_blit_fs_chroma);
+ if (v3d->sand30_blit_vs)
+ pctx->delete_vs_state(pctx, v3d->sand30_blit_vs);
+ if (v3d->sand30_blit_fs)
+ pctx->delete_fs_state(pctx, v3d->sand30_blit_fs);
v3d_program_fini(pctx);
+ v3d_fence_context_finish(v3d);
+
ralloc_free(v3d);
}
@@ -311,31 +325,47 @@ v3d_get_sample_position(struct pipe_context *pctx,
unsigned sample_count, unsigned sample_index,
float *xy)
{
- struct v3d_context *v3d = v3d_context(pctx);
-
if (sample_count <= 1) {
xy[0] = 0.5;
xy[1] = 0.5;
} else {
- static const int xoffsets_v33[] = { 1, -3, 3, -1 };
- static const int xoffsets_v42[] = { -1, 3, -3, 1 };
- const int *xoffsets = (v3d->screen->devinfo.ver >= 42 ?
- xoffsets_v42 : xoffsets_v33);
+ static const int xoffsets[] = { -1, 3, -3, 1 };
xy[0] = 0.5 + xoffsets[sample_index] * .125;
xy[1] = .125 + sample_index * .25;
}
}
+bool
+v3d_render_condition_check(struct v3d_context *v3d)
+{
+ if (!v3d->cond_query)
+ return true;
+
+ perf_debug("Implementing conditional rendering on the CPU\n");
+
+ union pipe_query_result res = { 0 };
+ bool wait =
+ v3d->cond_mode != PIPE_RENDER_COND_NO_WAIT &&
+ v3d->cond_mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;
+
+ struct pipe_context *pctx = (struct pipe_context *)v3d;
+ if (pctx->get_query_result(pctx, v3d->cond_query, wait, &res))
+ return ((bool)res.u64) != v3d->cond_cond;
+
+ return true;
+}
+
struct pipe_context *
v3d_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
{
struct v3d_screen *screen = v3d_screen(pscreen);
struct v3d_context *v3d;
+ struct v3d_device_info *devinfo = &screen->devinfo;
/* Prevent dumping of the shaders built during context setup. */
- uint32_t saved_shaderdb_flag = V3D_DEBUG & V3D_DEBUG_SHADERDB;
- V3D_DEBUG &= ~V3D_DEBUG_SHADERDB;
+ uint32_t saved_shaderdb_flag = v3d_mesa_debug & V3D_DEBUG_SHADERDB;
+ v3d_mesa_debug &= ~V3D_DEBUG_SHADERDB;
v3d = rzalloc(NULL, struct v3d_context);
if (!v3d)
@@ -356,17 +386,13 @@ v3d_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
pctx->destroy = v3d_context_destroy;
pctx->flush = v3d_pipe_flush;
pctx->memory_barrier = v3d_memory_barrier;
- pctx->set_debug_callback = v3d_set_debug_callback;
+ pctx->set_debug_callback = u_default_set_debug_callback;
pctx->invalidate_resource = v3d_invalidate_resource;
pctx->get_sample_position = v3d_get_sample_position;
+ pctx->texture_barrier = v3d_texture_barrier;
- if (screen->devinfo.ver >= 41) {
- v3d41_draw_init(pctx);
- v3d41_state_init(pctx);
- } else {
- v3d33_draw_init(pctx);
- v3d33_state_init(pctx);
- }
+ v3d_X(devinfo, draw_init)(pctx);
+ v3d_X(devinfo, state_init)(pctx);
v3d_program_init(pctx);
v3d_query_init(pctx);
v3d_resource_context_init(pctx);
@@ -385,12 +411,16 @@ v3d_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
PIPE_BIND_CONSTANT_BUFFER,
PIPE_USAGE_STREAM, 0);
+ ret = v3d_fence_context_init(v3d);
+ if (ret)
+ goto fail;
+
v3d->blitter = util_blitter_create(pctx);
if (!v3d->blitter)
goto fail;
v3d->blitter->use_index_buffer = true;
- V3D_DEBUG |= saved_shaderdb_flag;
+ v3d_mesa_debug |= saved_shaderdb_flag;
v3d->sample_mask = (1 << V3D_MAX_SAMPLES) - 1;
v3d->active_queries = true;