mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
ilo: hook up pipe context 3D functions
This commit is contained in:
parent
5b310f6230
commit
e6186b0769
4 changed files with 287 additions and 5 deletions
|
|
@ -25,17 +25,247 @@
|
|||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include "intel_winsys.h"
|
||||
|
||||
#include "ilo_3d_pipeline.h"
|
||||
#include "ilo_context.h"
|
||||
#include "ilo_cp.h"
|
||||
#include "ilo_query.h"
|
||||
#include "ilo_shader.h"
|
||||
#include "ilo_state.h"
|
||||
#include "ilo_3d.h"
|
||||
|
||||
/**
|
||||
* Hook for CP new-batch.
|
||||
*/
|
||||
void
|
||||
ilo_3d_new_cp_batch(struct ilo_3d *hw3d)
|
||||
{
|
||||
hw3d->new_batch = true;
|
||||
|
||||
/* invalidate the pipeline */
|
||||
ilo_3d_pipeline_invalidate(hw3d->pipeline,
|
||||
ILO_3D_PIPELINE_INVALIDATE_BATCH_BO |
|
||||
ILO_3D_PIPELINE_INVALIDATE_STATE_BO);
|
||||
if (!hw3d->cp->hw_ctx) {
|
||||
ilo_3d_pipeline_invalidate(hw3d->pipeline,
|
||||
ILO_3D_PIPELINE_INVALIDATE_HW);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for CP pre-flush.
|
||||
*/
|
||||
void
|
||||
ilo_3d_pre_cp_flush(struct ilo_3d *hw3d)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for CP post-flush
|
||||
*/
|
||||
void
|
||||
ilo_3d_post_cp_flush(struct ilo_3d *hw3d)
|
||||
{
|
||||
if (ilo_debug & ILO_DEBUG_3D)
|
||||
ilo_3d_pipeline_dump(hw3d->pipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a 3D context.
|
||||
*/
|
||||
struct ilo_3d *
|
||||
ilo_3d_create(struct ilo_cp *cp, int gen, int gt)
|
||||
{
|
||||
struct ilo_3d *hw3d;
|
||||
|
||||
hw3d = CALLOC_STRUCT(ilo_3d);
|
||||
if (!hw3d)
|
||||
return NULL;
|
||||
|
||||
hw3d->cp = cp;
|
||||
hw3d->new_batch = true;
|
||||
|
||||
hw3d->pipeline = ilo_3d_pipeline_create(cp, gen, gt);
|
||||
if (!hw3d->pipeline) {
|
||||
FREE(hw3d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hw3d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a 3D context.
|
||||
*/
|
||||
void
|
||||
ilo_3d_destroy(struct ilo_3d *hw3d)
|
||||
{
|
||||
ilo_3d_pipeline_destroy(hw3d->pipeline);
|
||||
FREE(hw3d);
|
||||
}
|
||||
|
||||
static bool
|
||||
draw_vbo(struct ilo_3d *hw3d, const struct ilo_context *ilo,
|
||||
const struct pipe_draw_info *info,
|
||||
int *prim_generated, int *prim_emitted)
|
||||
{
|
||||
bool need_flush;
|
||||
int max_len;
|
||||
|
||||
ilo_cp_set_ring(hw3d->cp, ILO_CP_RING_RENDER);
|
||||
|
||||
/*
|
||||
* Without a better tracking mechanism, when the framebuffer changes, we
|
||||
* have to assume that the old framebuffer may be sampled from. If that
|
||||
* happens in the middle of a batch buffer, we need to insert manual
|
||||
* flushes.
|
||||
*/
|
||||
need_flush = (!hw3d->new_batch && (ilo->dirty & ILO_DIRTY_FRAMEBUFFER));
|
||||
|
||||
/* make sure there is enough room first */
|
||||
max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
|
||||
ILO_3D_PIPELINE_DRAW, ilo);
|
||||
if (need_flush) {
|
||||
max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline,
|
||||
ILO_3D_PIPELINE_FLUSH, NULL);
|
||||
}
|
||||
|
||||
if (max_len > ilo_cp_space(hw3d->cp)) {
|
||||
ilo_cp_flush(hw3d->cp);
|
||||
need_flush = false;
|
||||
assert(max_len <= ilo_cp_space(hw3d->cp));
|
||||
}
|
||||
|
||||
if (need_flush)
|
||||
ilo_3d_pipeline_emit_flush(hw3d->pipeline);
|
||||
|
||||
return ilo_3d_pipeline_emit_draw(hw3d->pipeline, ilo, info,
|
||||
prim_generated, prim_emitted);
|
||||
}
|
||||
|
||||
static bool
|
||||
pass_render_condition(struct ilo_3d *hw3d, struct pipe_context *pipe)
|
||||
{
|
||||
uint64_t result;
|
||||
bool wait;
|
||||
|
||||
if (!hw3d->render_condition.query)
|
||||
return true;
|
||||
|
||||
switch (hw3d->render_condition.mode) {
|
||||
case PIPE_RENDER_COND_WAIT:
|
||||
case PIPE_RENDER_COND_BY_REGION_WAIT:
|
||||
wait = true;
|
||||
break;
|
||||
case PIPE_RENDER_COND_NO_WAIT:
|
||||
case PIPE_RENDER_COND_BY_REGION_NO_WAIT:
|
||||
default:
|
||||
wait = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pipe->get_query_result(pipe, hw3d->render_condition.query,
|
||||
wait, (union pipe_query_result *) &result)) {
|
||||
return (result > 0);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
struct ilo_3d *hw3d = ilo->hw3d;
|
||||
int prim_generated, prim_emitted;
|
||||
|
||||
if (!pass_render_condition(hw3d, pipe))
|
||||
return;
|
||||
|
||||
/* assume the cache is still in use by the previous batch */
|
||||
if (hw3d->new_batch)
|
||||
ilo_shader_cache_mark_busy(ilo->shader_cache);
|
||||
|
||||
ilo_finalize_states(ilo);
|
||||
|
||||
/* the shaders may be uploaded to a new shader cache */
|
||||
if (hw3d->shader_cache_seqno != ilo->shader_cache->seqno) {
|
||||
ilo_3d_pipeline_invalidate(hw3d->pipeline,
|
||||
ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO);
|
||||
}
|
||||
|
||||
/*
|
||||
* The VBs and/or IB may have different BOs due to being mapped with
|
||||
* PIPE_TRANSFER_DISCARD_x. We should track that instead of setting the
|
||||
* dirty flags for the performance reason.
|
||||
*/
|
||||
ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS | ILO_DIRTY_INDEX_BUFFER;
|
||||
|
||||
if (!draw_vbo(hw3d, ilo, info, &prim_generated, &prim_emitted))
|
||||
return;
|
||||
|
||||
/* clear dirty status */
|
||||
ilo->dirty = 0x0;
|
||||
hw3d->new_batch = false;
|
||||
hw3d->shader_cache_seqno = ilo->shader_cache->seqno;
|
||||
|
||||
if (ilo_debug & ILO_DEBUG_NOCACHE)
|
||||
ilo_3d_pipeline_emit_flush(hw3d->pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_render_condition(struct pipe_context *pipe,
|
||||
struct pipe_query *query,
|
||||
uint mode)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
struct ilo_3d *hw3d = ilo->hw3d;
|
||||
|
||||
/* reference count? */
|
||||
hw3d->render_condition.query = query;
|
||||
hw3d->render_condition.mode = mode;
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_texture_barrier(struct pipe_context *pipe)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
struct ilo_3d *hw3d = ilo->hw3d;
|
||||
|
||||
if (ilo->cp->ring != ILO_CP_RING_RENDER)
|
||||
return;
|
||||
|
||||
ilo_3d_pipeline_emit_flush(hw3d->pipeline);
|
||||
|
||||
/* don't know why */
|
||||
if (ilo->gen >= ILO_GEN(7))
|
||||
ilo_cp_flush(hw3d->cp);
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_get_sample_position(struct pipe_context *pipe,
|
||||
unsigned sample_count,
|
||||
unsigned sample_index,
|
||||
float *out_value)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
struct ilo_3d *hw3d = ilo->hw3d;
|
||||
|
||||
ilo_3d_pipeline_get_sample_position(hw3d->pipeline,
|
||||
sample_count, sample_index,
|
||||
&out_value[0], &out_value[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize 3D-related functions.
|
||||
*/
|
||||
void
|
||||
ilo_init_3d_functions(struct ilo_context *ilo)
|
||||
{
|
||||
ilo->base.draw_vbo = NULL;
|
||||
ilo->base.render_condition = NULL;
|
||||
ilo->base.texture_barrier = NULL;
|
||||
ilo->base.get_sample_position = NULL;
|
||||
ilo->base.draw_vbo = ilo_draw_vbo;
|
||||
ilo->base.render_condition = ilo_render_condition;
|
||||
ilo->base.texture_barrier = ilo_texture_barrier;
|
||||
ilo->base.get_sample_position = ilo_get_sample_position;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,42 @@
|
|||
|
||||
#include "ilo_common.h"
|
||||
|
||||
struct ilo_3d_pipeline;
|
||||
struct ilo_context;
|
||||
struct ilo_cp;
|
||||
struct ilo_query;
|
||||
|
||||
/**
|
||||
* 3D context.
|
||||
*/
|
||||
struct ilo_3d {
|
||||
struct ilo_cp *cp;
|
||||
|
||||
bool new_batch;
|
||||
uint32_t shader_cache_seqno;
|
||||
|
||||
struct {
|
||||
struct pipe_query *query;
|
||||
unsigned mode;
|
||||
} render_condition;
|
||||
|
||||
struct ilo_3d_pipeline *pipeline;
|
||||
};
|
||||
|
||||
struct ilo_3d *
|
||||
ilo_3d_create(struct ilo_cp *cp, int gen, int gt);
|
||||
|
||||
void
|
||||
ilo_3d_destroy(struct ilo_3d *hw3d);
|
||||
|
||||
void
|
||||
ilo_3d_new_cp_batch(struct ilo_3d *hw3d);
|
||||
|
||||
void
|
||||
ilo_3d_pre_cp_flush(struct ilo_3d *hw3d);
|
||||
|
||||
void
|
||||
ilo_3d_post_cp_flush(struct ilo_3d *hw3d);
|
||||
|
||||
void
|
||||
ilo_init_3d_functions(struct ilo_context *ilo);
|
||||
|
|
|
|||
|
|
@ -43,11 +43,19 @@
|
|||
static void
|
||||
ilo_context_new_cp_batch(struct ilo_cp *cp, void *data)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(data);
|
||||
|
||||
if (cp->ring == ILO_CP_RING_RENDER)
|
||||
ilo_3d_new_cp_batch(ilo->hw3d);
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_context_pre_cp_flush(struct ilo_cp *cp, void *data)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(data);
|
||||
|
||||
if (cp->ring == ILO_CP_RING_RENDER)
|
||||
ilo_3d_pre_cp_flush(ilo->hw3d);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -61,6 +69,9 @@ ilo_context_post_cp_flush(struct ilo_cp *cp, void *data)
|
|||
/* remember the just flushed bo, on which fences could wait */
|
||||
ilo->last_cp_bo = cp->bo;
|
||||
ilo->last_cp_bo->reference(ilo->last_cp_bo);
|
||||
|
||||
if (cp->ring == ILO_CP_RING_RENDER)
|
||||
ilo_3d_post_cp_flush(ilo->hw3d);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -103,6 +114,8 @@ ilo_context_destroy(struct pipe_context *pipe)
|
|||
|
||||
if (ilo->blitter)
|
||||
util_blitter_destroy(ilo->blitter);
|
||||
if (ilo->hw3d)
|
||||
ilo_3d_destroy(ilo->hw3d);
|
||||
if (ilo->shader_cache)
|
||||
ilo_shader_cache_destroy(ilo->shader_cache);
|
||||
if (ilo->cp)
|
||||
|
|
@ -177,8 +190,10 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
|
|||
|
||||
ilo->cp = ilo_cp_create(ilo->winsys, is->has_llc);
|
||||
ilo->shader_cache = ilo_shader_cache_create(ilo->winsys);
|
||||
if (ilo->cp)
|
||||
ilo->hw3d = ilo_3d_create(ilo->cp, ilo->gen, ilo->gt);
|
||||
|
||||
if (!ilo->cp || !ilo->shader_cache) {
|
||||
if (!ilo->cp || !ilo->shader_cache || !ilo->hw3d) {
|
||||
ilo_context_destroy(&ilo->base);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
struct blitter_context;
|
||||
struct intel_winsys;
|
||||
struct intel_bo;
|
||||
struct ilo_3d;
|
||||
struct ilo_cp;
|
||||
struct ilo_screen;
|
||||
struct ilo_shader_state;
|
||||
|
|
@ -87,6 +88,7 @@ struct ilo_context {
|
|||
struct intel_bo *last_cp_bo;
|
||||
|
||||
struct ilo_shader_cache *shader_cache;
|
||||
struct ilo_3d *hw3d;
|
||||
struct blitter_context *blitter;
|
||||
|
||||
uint32_t dirty;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue