llvmpipe: fence debugging, add llvmpipe_finish
This commit is contained in:
@@ -85,6 +85,14 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
|
|||||||
align_free( llvmpipe );
|
align_free( llvmpipe );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_flush( struct pipe_context *pipe,
|
||||||
|
unsigned flags,
|
||||||
|
struct pipe_fence_handle **fence)
|
||||||
|
{
|
||||||
|
llvmpipe_flush(pipe, flags, fence, __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct pipe_context *
|
struct pipe_context *
|
||||||
llvmpipe_create_context( struct pipe_screen *screen, void *priv )
|
llvmpipe_create_context( struct pipe_screen *screen, void *priv )
|
||||||
@@ -109,7 +117,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
|
|||||||
llvmpipe->pipe.destroy = llvmpipe_destroy;
|
llvmpipe->pipe.destroy = llvmpipe_destroy;
|
||||||
llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
|
llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
|
||||||
llvmpipe->pipe.clear = llvmpipe_clear;
|
llvmpipe->pipe.clear = llvmpipe_clear;
|
||||||
llvmpipe->pipe.flush = llvmpipe_flush;
|
llvmpipe->pipe.flush = do_flush;
|
||||||
|
|
||||||
llvmpipe_init_blend_funcs(llvmpipe);
|
llvmpipe_init_blend_funcs(llvmpipe);
|
||||||
llvmpipe_init_clip_funcs(llvmpipe);
|
llvmpipe_init_clip_funcs(llvmpipe);
|
||||||
|
@@ -46,6 +46,8 @@ st_print_current(void);
|
|||||||
#define DEBUG_SHOW_TILES 0x200
|
#define DEBUG_SHOW_TILES 0x200
|
||||||
#define DEBUG_SHOW_SUBTILES 0x400
|
#define DEBUG_SHOW_SUBTILES 0x400
|
||||||
#define DEBUG_COUNTERS 0x800
|
#define DEBUG_COUNTERS 0x800
|
||||||
|
#define DEBUG_SCENE 0x1000
|
||||||
|
#define DEBUG_FENCE 0x2000
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
struct lp_fence *
|
struct lp_fence *
|
||||||
lp_fence_create(unsigned rank)
|
lp_fence_create(unsigned rank)
|
||||||
{
|
{
|
||||||
|
static int fence_id;
|
||||||
struct lp_fence *fence = CALLOC_STRUCT(lp_fence);
|
struct lp_fence *fence = CALLOC_STRUCT(lp_fence);
|
||||||
|
|
||||||
pipe_reference_init(&fence->reference, 1);
|
pipe_reference_init(&fence->reference, 1);
|
||||||
@@ -51,8 +52,12 @@ lp_fence_create(unsigned rank)
|
|||||||
pipe_mutex_init(fence->mutex);
|
pipe_mutex_init(fence->mutex);
|
||||||
pipe_condvar_init(fence->signalled);
|
pipe_condvar_init(fence->signalled);
|
||||||
|
|
||||||
|
fence->id = fence_id++;
|
||||||
fence->rank = rank;
|
fence->rank = rank;
|
||||||
|
|
||||||
|
if (LP_DEBUG & DEBUG_FENCE)
|
||||||
|
debug_printf("%s %d\n", __FUNCTION__, fence->id);
|
||||||
|
|
||||||
return fence;
|
return fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +66,9 @@ lp_fence_create(unsigned rank)
|
|||||||
void
|
void
|
||||||
lp_fence_destroy(struct lp_fence *fence)
|
lp_fence_destroy(struct lp_fence *fence)
|
||||||
{
|
{
|
||||||
|
if (LP_DEBUG & DEBUG_FENCE)
|
||||||
|
debug_printf("%s %d\n", __FUNCTION__, fence->id);
|
||||||
|
|
||||||
pipe_mutex_destroy(fence->mutex);
|
pipe_mutex_destroy(fence->mutex);
|
||||||
pipe_condvar_destroy(fence->signalled);
|
pipe_condvar_destroy(fence->signalled);
|
||||||
FREE(fence);
|
FREE(fence);
|
||||||
@@ -126,13 +134,17 @@ llvmpipe_fence_finish(struct pipe_screen *screen,
|
|||||||
void
|
void
|
||||||
lp_fence_signal(struct lp_fence *fence)
|
lp_fence_signal(struct lp_fence *fence)
|
||||||
{
|
{
|
||||||
|
if (LP_DEBUG & DEBUG_FENCE)
|
||||||
|
debug_printf("%s %d\n", __FUNCTION__, fence->id);
|
||||||
|
|
||||||
pipe_mutex_lock(fence->mutex);
|
pipe_mutex_lock(fence->mutex);
|
||||||
|
|
||||||
fence->count++;
|
fence->count++;
|
||||||
assert(fence->count <= fence->rank);
|
assert(fence->count <= fence->rank);
|
||||||
|
|
||||||
LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__,
|
if (LP_DEBUG & DEBUG_FENCE)
|
||||||
fence->count, fence->rank);
|
debug_printf("%s count=%u rank=%u\n", __FUNCTION__,
|
||||||
|
fence->count, fence->rank);
|
||||||
|
|
||||||
pipe_condvar_signal(fence->signalled);
|
pipe_condvar_signal(fence->signalled);
|
||||||
|
|
||||||
|
@@ -41,6 +41,7 @@ struct pipe_screen;
|
|||||||
struct lp_fence
|
struct lp_fence
|
||||||
{
|
{
|
||||||
struct pipe_reference reference;
|
struct pipe_reference reference;
|
||||||
|
unsigned id;
|
||||||
|
|
||||||
pipe_mutex mutex;
|
pipe_mutex mutex;
|
||||||
pipe_condvar signalled;
|
pipe_condvar signalled;
|
||||||
|
@@ -45,14 +45,15 @@
|
|||||||
void
|
void
|
||||||
llvmpipe_flush( struct pipe_context *pipe,
|
llvmpipe_flush( struct pipe_context *pipe,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
struct pipe_fence_handle **fence )
|
struct pipe_fence_handle **fence,
|
||||||
|
const char *reason)
|
||||||
{
|
{
|
||||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||||
|
|
||||||
draw_flush(llvmpipe->draw);
|
draw_flush(llvmpipe->draw);
|
||||||
|
|
||||||
/* ask the setup module to flush */
|
/* ask the setup module to flush */
|
||||||
lp_setup_flush(llvmpipe->setup, flags, fence);
|
lp_setup_flush(llvmpipe->setup, flags, fence, reason);
|
||||||
|
|
||||||
/* Enable to dump BMPs of the color/depth buffers each frame */
|
/* Enable to dump BMPs of the color/depth buffers each frame */
|
||||||
if (0) {
|
if (0) {
|
||||||
@@ -76,6 +77,17 @@ llvmpipe_flush( struct pipe_context *pipe,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
llvmpipe_finish( struct pipe_context *pipe,
|
||||||
|
const char *reason )
|
||||||
|
{
|
||||||
|
struct pipe_fence_handle *fence = NULL;
|
||||||
|
llvmpipe_flush(pipe, 0, &fence, reason);
|
||||||
|
if (fence) {
|
||||||
|
pipe->screen->fence_finish(pipe->screen, fence, 0);
|
||||||
|
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush context if necessary.
|
* Flush context if necessary.
|
||||||
@@ -93,7 +105,8 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
|
|||||||
unsigned flush_flags,
|
unsigned flush_flags,
|
||||||
boolean read_only,
|
boolean read_only,
|
||||||
boolean cpu_access,
|
boolean cpu_access,
|
||||||
boolean do_not_block)
|
boolean do_not_block,
|
||||||
|
const char *reason)
|
||||||
{
|
{
|
||||||
unsigned referenced;
|
unsigned referenced;
|
||||||
|
|
||||||
@@ -106,31 +119,16 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
|
|||||||
/*
|
/*
|
||||||
* Flush and wait.
|
* Flush and wait.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct pipe_fence_handle *fence = NULL;
|
|
||||||
|
|
||||||
if (do_not_block)
|
if (do_not_block)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/*
|
llvmpipe_finish(pipe, reason);
|
||||||
* Do the unswizzling in parallel.
|
|
||||||
*
|
|
||||||
* XXX: Don't abuse the PIPE_FLUSH_FRAME flag for this.
|
|
||||||
*/
|
|
||||||
flush_flags |= PIPE_FLUSH_FRAME;
|
|
||||||
|
|
||||||
llvmpipe_flush(pipe, flush_flags, &fence);
|
|
||||||
|
|
||||||
if (fence) {
|
|
||||||
pipe->screen->fence_finish(pipe->screen, fence, 0);
|
|
||||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Just flush.
|
* Just flush.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
llvmpipe_flush(pipe, flush_flags, NULL);
|
llvmpipe_flush(pipe, flush_flags, NULL, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,8 +34,14 @@ struct pipe_context;
|
|||||||
struct pipe_fence_handle;
|
struct pipe_fence_handle;
|
||||||
|
|
||||||
void
|
void
|
||||||
llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
|
llvmpipe_flush(struct pipe_context *pipe,
|
||||||
struct pipe_fence_handle **fence);
|
unsigned flags,
|
||||||
|
struct pipe_fence_handle **fence,
|
||||||
|
const char *reason);
|
||||||
|
|
||||||
|
void
|
||||||
|
llvmpipe_finish( struct pipe_context *pipe,
|
||||||
|
const char *reason );
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
llvmpipe_flush_resource(struct pipe_context *pipe,
|
llvmpipe_flush_resource(struct pipe_context *pipe,
|
||||||
@@ -45,6 +51,7 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
|
|||||||
unsigned flush_flags,
|
unsigned flush_flags,
|
||||||
boolean read_only,
|
boolean read_only,
|
||||||
boolean cpu_access,
|
boolean cpu_access,
|
||||||
boolean do_not_block);
|
boolean do_not_block,
|
||||||
|
const char *reason);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -35,9 +35,9 @@
|
|||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
#include "lp_context.h"
|
#include "lp_context.h"
|
||||||
#include "lp_flush.h"
|
#include "lp_flush.h"
|
||||||
|
#include "lp_fence.h"
|
||||||
#include "lp_query.h"
|
#include "lp_query.h"
|
||||||
#include "lp_rast.h"
|
#include "lp_rast.h"
|
||||||
#include "lp_rast_priv.h"
|
|
||||||
#include "lp_state.h"
|
#include "lp_state.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -69,12 +69,7 @@ llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
|
|||||||
struct llvmpipe_query *pq = llvmpipe_query(q);
|
struct llvmpipe_query *pq = llvmpipe_query(q);
|
||||||
/* query might still be in process if we never waited for the result */
|
/* query might still be in process if we never waited for the result */
|
||||||
if (!pq->done) {
|
if (!pq->done) {
|
||||||
struct pipe_fence_handle *fence = NULL;
|
llvmpipe_finish(pipe, __FUNCTION__);
|
||||||
llvmpipe_flush(pipe, 0, &fence);
|
|
||||||
if (fence) {
|
|
||||||
pipe->screen->fence_finish(pipe->screen, fence, 0);
|
|
||||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_mutex_destroy(pq->mutex);
|
pipe_mutex_destroy(pq->mutex);
|
||||||
@@ -93,16 +88,11 @@ llvmpipe_get_query_result(struct pipe_context *pipe,
|
|||||||
|
|
||||||
if (!pq->done) {
|
if (!pq->done) {
|
||||||
if (wait) {
|
if (wait) {
|
||||||
struct pipe_fence_handle *fence = NULL;
|
llvmpipe_finish(pipe, __FUNCTION__);
|
||||||
llvmpipe_flush(pipe, 0, &fence);
|
|
||||||
if (fence) {
|
|
||||||
pipe->screen->fence_finish(pipe->screen, fence, 0);
|
|
||||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* this is a bit inconsequent but should be ok */
|
/* this is a bit inconsequent but should be ok */
|
||||||
else {
|
else {
|
||||||
llvmpipe_flush(pipe, 0, NULL);
|
llvmpipe_flush(pipe, 0, NULL, __FUNCTION__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,12 +115,7 @@ llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
|
|||||||
* frame of rendering.
|
* frame of rendering.
|
||||||
*/
|
*/
|
||||||
if (pq->binned) {
|
if (pq->binned) {
|
||||||
struct pipe_fence_handle *fence;
|
llvmpipe_finish(pipe, __FUNCTION__);
|
||||||
llvmpipe_flush(pipe, 0, &fence);
|
|
||||||
if (fence) {
|
|
||||||
pipe->screen->fence_finish(pipe->screen, fence, 0);
|
|
||||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lp_setup_begin_query(llvmpipe->setup, pq);
|
lp_setup_begin_query(llvmpipe->setup, pq);
|
||||||
|
@@ -61,6 +61,8 @@ static const struct debug_named_value lp_debug_flags[] = {
|
|||||||
{ "show_tiles", DEBUG_SHOW_TILES, NULL },
|
{ "show_tiles", DEBUG_SHOW_TILES, NULL },
|
||||||
{ "show_subtiles", DEBUG_SHOW_SUBTILES, NULL },
|
{ "show_subtiles", DEBUG_SHOW_SUBTILES, NULL },
|
||||||
{ "counters", DEBUG_COUNTERS, NULL },
|
{ "counters", DEBUG_COUNTERS, NULL },
|
||||||
|
{ "scene", DEBUG_SCENE, NULL },
|
||||||
|
{ "fence", DEBUG_FENCE, NULL },
|
||||||
DEBUG_NAMED_VALUE_END
|
DEBUG_NAMED_VALUE_END
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@@ -275,9 +275,10 @@ set_scene_state( struct lp_setup_context *setup,
|
|||||||
void
|
void
|
||||||
lp_setup_flush( struct lp_setup_context *setup,
|
lp_setup_flush( struct lp_setup_context *setup,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
struct pipe_fence_handle **fence)
|
struct pipe_fence_handle **fence,
|
||||||
|
const char *reason)
|
||||||
{
|
{
|
||||||
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
|
LP_DBG(DEBUG_SETUP, "%s %s\n", __FUNCTION__, reason);
|
||||||
|
|
||||||
if (setup->scene) {
|
if (setup->scene) {
|
||||||
if (fence) {
|
if (fence) {
|
||||||
|
@@ -85,7 +85,8 @@ lp_setup_fence( struct lp_setup_context *setup );
|
|||||||
void
|
void
|
||||||
lp_setup_flush( struct lp_setup_context *setup,
|
lp_setup_flush( struct lp_setup_context *setup,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
struct pipe_fence_handle **fence);
|
struct pipe_fence_handle **fence,
|
||||||
|
const char *reason);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -927,7 +927,6 @@ static void
|
|||||||
llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
|
llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
|
||||||
{
|
{
|
||||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||||
struct pipe_fence_handle *fence = NULL;
|
|
||||||
struct lp_fragment_shader *shader = fs;
|
struct lp_fragment_shader *shader = fs;
|
||||||
struct lp_fs_variant_list_item *li;
|
struct lp_fs_variant_list_item *li;
|
||||||
|
|
||||||
@@ -940,12 +939,7 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
|
|||||||
* Flushing alone might not sufficient we need to wait on it too.
|
* Flushing alone might not sufficient we need to wait on it too.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
llvmpipe_flush(pipe, 0, &fence);
|
llvmpipe_finish(pipe, __FUNCTION__);
|
||||||
|
|
||||||
if (fence) {
|
|
||||||
pipe->screen->fence_finish(pipe->screen, fence, 0);
|
|
||||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
li = first_elem(&shader->variants);
|
li = first_elem(&shader->variants);
|
||||||
while(!at_end(&shader->variants, li)) {
|
while(!at_end(&shader->variants, li)) {
|
||||||
@@ -1148,19 +1142,14 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) {
|
if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) {
|
||||||
struct pipe_context *pipe = &lp->pipe;
|
struct pipe_context *pipe = &lp->pipe;
|
||||||
struct pipe_fence_handle *fence = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: we need to flush the context until we have some sort of reference
|
* XXX: we need to flush the context until we have some sort of reference
|
||||||
* counting in fragment shaders as they may still be binned
|
* counting in fragment shaders as they may still be binned
|
||||||
* Flushing alone might not be sufficient we need to wait on it too.
|
* Flushing alone might not be sufficient we need to wait on it too.
|
||||||
*/
|
*/
|
||||||
llvmpipe_flush(pipe, 0, &fence);
|
llvmpipe_finish(pipe, __FUNCTION__);
|
||||||
|
|
||||||
if (fence) {
|
|
||||||
pipe->screen->fence_finish(pipe->screen, fence, 0);
|
|
||||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
for (i = 0; i < LP_MAX_SHADER_VARIANTS / 4; i++) {
|
for (i = 0; i < LP_MAX_SHADER_VARIANTS / 4; i++) {
|
||||||
struct lp_fs_variant_list_item *item = last_elem(&lp->fs_variants_list);
|
struct lp_fs_variant_list_item *item = last_elem(&lp->fs_variants_list);
|
||||||
remove_shader_variant(lp, item->base);
|
remove_shader_variant(lp, item->base);
|
||||||
|
@@ -68,14 +68,16 @@ lp_resource_copy(struct pipe_context *pipe,
|
|||||||
0, /* flush_flags */
|
0, /* flush_flags */
|
||||||
FALSE, /* read_only */
|
FALSE, /* read_only */
|
||||||
TRUE, /* cpu_access */
|
TRUE, /* cpu_access */
|
||||||
FALSE); /* do_not_block */
|
FALSE,
|
||||||
|
"blit dst"); /* do_not_block */
|
||||||
|
|
||||||
llvmpipe_flush_resource(pipe,
|
llvmpipe_flush_resource(pipe,
|
||||||
src, subsrc.face, subsrc.level,
|
src, subsrc.face, subsrc.level,
|
||||||
0, /* flush_flags */
|
0, /* flush_flags */
|
||||||
TRUE, /* read_only */
|
TRUE, /* read_only */
|
||||||
TRUE, /* cpu_access */
|
TRUE, /* cpu_access */
|
||||||
FALSE); /* do_not_block */
|
FALSE,
|
||||||
|
"blit src"); /* do_not_block */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
printf("surface copy from %u to %u: %u,%u to %u,%u %u x %u\n",
|
printf("surface copy from %u to %u: %u,%u to %u,%u %u x %u\n",
|
||||||
|
@@ -584,7 +584,8 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
|
|||||||
0, /* flush_flags */
|
0, /* flush_flags */
|
||||||
read_only,
|
read_only,
|
||||||
TRUE, /* cpu_access */
|
TRUE, /* cpu_access */
|
||||||
do_not_block)) {
|
do_not_block,
|
||||||
|
"transfer dest")) {
|
||||||
/*
|
/*
|
||||||
* It would have blocked, but state tracker requested no to.
|
* It would have blocked, but state tracker requested no to.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user