Add blitter functions to perform Depth Buffer Clear, Depth Buffer Resolve, and Hierarchical Depth Buffer Resolve. Those functions set ilo_blitter up and pass it to the pipelines to emit the commands.tags/mesa-10.1-rc1
@@ -8,6 +8,7 @@ C_SOURCES := \ | |||
ilo_blitter.c \ | |||
ilo_blitter_blt.c \ | |||
ilo_blitter_pipe.c \ | |||
ilo_blitter_rectlist.c \ | |||
ilo_context.c \ | |||
ilo_cp.c \ | |||
ilo_format.c \ |
@@ -156,7 +156,7 @@ ilo_3d_release_render_ring(struct ilo_cp *cp, void *data) | |||
ilo_3d_pause_queries(hw3d); | |||
} | |||
static void | |||
void | |||
ilo_3d_own_render_ring(struct ilo_3d *hw3d) | |||
{ | |||
ilo_cp_set_ring(hw3d->cp, ILO_CP_RING_RENDER); |
@@ -73,6 +73,9 @@ ilo_3d_destroy(struct ilo_3d *hw3d); | |||
void | |||
ilo_3d_cp_flushed(struct ilo_3d *hw3d); | |||
void | |||
ilo_3d_own_render_ring(struct ilo_3d *hw3d); | |||
void | |||
ilo_3d_begin_query(struct ilo_context *ilo, struct ilo_query *q); | |||
@@ -28,6 +28,7 @@ | |||
#include "util/u_prim.h" | |||
#include "intel_winsys.h" | |||
#include "ilo_blitter.h" | |||
#include "ilo_context.h" | |||
#include "ilo_cp.h" | |||
#include "ilo_state.h" | |||
@@ -258,6 +259,48 @@ ilo_3d_pipeline_emit_write_depth_count(struct ilo_3d_pipeline *p, | |||
p->emit_write_depth_count(p, bo, index); | |||
} | |||
void | |||
ilo_3d_pipeline_emit_rectlist(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter) | |||
{ | |||
const int max_len = ilo_3d_pipeline_estimate_size(p, | |||
ILO_3D_PIPELINE_RECTLIST, blitter); | |||
if (max_len > ilo_cp_space(p->cp)) | |||
ilo_cp_flush(p->cp, "out of space"); | |||
while (true) { | |||
struct ilo_cp_jmp_buf jmp; | |||
int err; | |||
/* we will rewind if aperture check below fails */ | |||
ilo_cp_setjmp(p->cp, &jmp); | |||
handle_invalid_batch_bo(p, false); | |||
ilo_cp_assert_no_implicit_flush(p->cp, true); | |||
p->emit_rectlist(p, blitter); | |||
ilo_cp_assert_no_implicit_flush(p->cp, false); | |||
err = intel_winsys_check_aperture_space(blitter->ilo->winsys, | |||
&p->cp->bo, 1); | |||
if (err) { | |||
/* rewind */ | |||
ilo_cp_longjmp(p->cp, &jmp); | |||
/* flush and try again */ | |||
if (!ilo_cp_empty(p->cp)) { | |||
ilo_cp_flush(p->cp, "out of aperture"); | |||
continue; | |||
} | |||
} | |||
break; | |||
} | |||
ilo_3d_pipeline_invalidate(p, ILO_3D_PIPELINE_INVALIDATE_HW); | |||
} | |||
void | |||
ilo_3d_pipeline_get_sample_position(struct ilo_3d_pipeline *p, | |||
unsigned sample_count, |
@@ -32,6 +32,7 @@ | |||
#include "ilo_gpe.h" | |||
struct intel_bo; | |||
struct ilo_blitter; | |||
struct ilo_cp; | |||
struct ilo_context; | |||
@@ -49,6 +50,7 @@ enum ilo_3d_pipeline_action { | |||
ILO_3D_PIPELINE_FLUSH, | |||
ILO_3D_PIPELINE_WRITE_TIMESTAMP, | |||
ILO_3D_PIPELINE_WRITE_DEPTH_COUNT, | |||
ILO_3D_PIPELINE_RECTLIST, | |||
}; | |||
/** | |||
@@ -81,6 +83,9 @@ struct ilo_3d_pipeline { | |||
void (*emit_write_depth_count)(struct ilo_3d_pipeline *pipeline, | |||
struct intel_bo *bo, int index); | |||
void (*emit_rectlist)(struct ilo_3d_pipeline *pipeline, | |||
const struct ilo_blitter *blitter); | |||
/** | |||
* HW states. | |||
*/ | |||
@@ -171,6 +176,10 @@ void | |||
ilo_3d_pipeline_emit_write_depth_count(struct ilo_3d_pipeline *p, | |||
struct intel_bo *bo, int index); | |||
void | |||
ilo_3d_pipeline_emit_rectlist(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter); | |||
void | |||
ilo_3d_pipeline_get_sample_position(struct ilo_3d_pipeline *p, | |||
unsigned sample_count, |
@@ -29,6 +29,7 @@ | |||
#include "util/u_prim.h" | |||
#include "intel_reg.h" | |||
#include "ilo_blitter.h" | |||
#include "ilo_3d.h" | |||
#include "ilo_context.h" | |||
#include "ilo_cp.h" | |||
@@ -1518,6 +1519,178 @@ ilo_3d_pipeline_emit_write_depth_count_gen6(struct ilo_3d_pipeline *p, | |||
true, p->cp); | |||
} | |||
static void | |||
gen6_rectlist_vs_to_sf(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
gen6_emit_3DSTATE_CONSTANT_VS(p->dev, NULL, NULL, 0, p->cp); | |||
gen6_emit_3DSTATE_VS(p->dev, NULL, 0, p->cp); | |||
gen6_wa_pipe_control_vs_const_flush(p); | |||
gen6_emit_3DSTATE_CONSTANT_GS(p->dev, NULL, NULL, 0, p->cp); | |||
gen6_emit_3DSTATE_GS(p->dev, NULL, NULL, 0, p->cp); | |||
gen6_emit_3DSTATE_CLIP(p->dev, NULL, NULL, false, 0, p->cp); | |||
gen6_emit_3DSTATE_SF(p->dev, NULL, NULL, p->cp); | |||
} | |||
static void | |||
gen6_rectlist_wm(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
uint32_t hiz_op; | |||
switch (blitter->op) { | |||
case ILO_BLITTER_RECTLIST_CLEAR_ZS: | |||
hiz_op = GEN6_WM_DEPTH_CLEAR; | |||
break; | |||
case ILO_BLITTER_RECTLIST_RESOLVE_Z: | |||
hiz_op = GEN6_WM_DEPTH_RESOLVE; | |||
break; | |||
case ILO_BLITTER_RECTLIST_RESOLVE_HIZ: | |||
hiz_op = GEN6_WM_HIERARCHICAL_DEPTH_RESOLVE; | |||
break; | |||
default: | |||
hiz_op = 0; | |||
break; | |||
} | |||
gen6_emit_3DSTATE_CONSTANT_PS(p->dev, NULL, NULL, 0, p->cp); | |||
gen6_wa_pipe_control_wm_max_threads_stall(p); | |||
gen6_emit_3DSTATE_WM(p->dev, NULL, 0, NULL, false, false, hiz_op, p->cp); | |||
} | |||
static void | |||
gen6_rectlist_wm_depth(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
gen6_wa_pipe_control_wm_depth_flush(p); | |||
if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) { | |||
gen6_emit_3DSTATE_DEPTH_BUFFER(p->dev, | |||
&blitter->fb.dst.u.zs, p->cp); | |||
gen6_emit_3DSTATE_HIER_DEPTH_BUFFER(p->dev, | |||
&blitter->fb.dst.u.zs, p->cp); | |||
} | |||
if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL) { | |||
gen6_emit_3DSTATE_STENCIL_BUFFER(p->dev, | |||
&blitter->fb.dst.u.zs, p->cp); | |||
} | |||
gen6_emit_3DSTATE_CLEAR_PARAMS(p->dev, | |||
blitter->depth_clear_value, p->cp); | |||
} | |||
static void | |||
gen6_rectlist_wm_multisample(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
const uint32_t *packed_sample_pos = (blitter->fb.num_samples > 1) ? | |||
&p->packed_sample_position_4x : &p->packed_sample_position_1x; | |||
gen6_wa_pipe_control_wm_multisample_flush(p); | |||
gen6_emit_3DSTATE_MULTISAMPLE(p->dev, blitter->fb.num_samples, | |||
packed_sample_pos, true, p->cp); | |||
gen6_emit_3DSTATE_SAMPLE_MASK(p->dev, | |||
(1 << blitter->fb.num_samples) - 1, p->cp); | |||
} | |||
static void | |||
gen6_rectlist_commands(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
gen6_wa_pipe_control_post_sync(p, false); | |||
gen6_rectlist_wm_multisample(p, blitter, session); | |||
gen6_emit_STATE_BASE_ADDRESS(p->dev, | |||
NULL, /* General State Base */ | |||
p->cp->bo, /* Surface State Base */ | |||
p->cp->bo, /* Dynamic State Base */ | |||
NULL, /* Indirect Object Base */ | |||
NULL, /* Instruction Base */ | |||
0, 0, 0, 0, p->cp); | |||
gen6_emit_3DSTATE_VERTEX_BUFFERS(p->dev, | |||
&blitter->ve, &blitter->vb, p->cp); | |||
gen6_emit_3DSTATE_VERTEX_ELEMENTS(p->dev, | |||
&blitter->ve, false, false, p->cp); | |||
gen6_emit_3DSTATE_URB(p->dev, | |||
p->dev->urb_size, 0, blitter->ve.count * 4 * sizeof(float), 0, p->cp); | |||
/* 3DSTATE_URB workaround */ | |||
if (p->state.gs.active) { | |||
ilo_3d_pipeline_emit_flush_gen6(p); | |||
p->state.gs.active = false; | |||
} | |||
if (blitter->uses & | |||
(ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_CC)) { | |||
gen6_emit_3DSTATE_CC_STATE_POINTERS(p->dev, 0, | |||
session->DEPTH_STENCIL_STATE, session->COLOR_CALC_STATE, p->cp); | |||
} | |||
gen6_rectlist_vs_to_sf(p, blitter, session); | |||
gen6_rectlist_wm(p, blitter, session); | |||
if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) { | |||
gen6_emit_3DSTATE_VIEWPORT_STATE_POINTERS(p->dev, | |||
0, 0, session->CC_VIEWPORT, p->cp); | |||
} | |||
gen6_rectlist_wm_depth(p, blitter, session); | |||
gen6_emit_3DSTATE_DRAWING_RECTANGLE(p->dev, 0, 0, | |||
blitter->fb.width, blitter->fb.height, p->cp); | |||
gen6_emit_3DPRIMITIVE(p->dev, &blitter->draw, NULL, true, p->cp); | |||
} | |||
static void | |||
gen6_rectlist_states(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
if (blitter->uses & ILO_BLITTER_USE_DSA) { | |||
session->DEPTH_STENCIL_STATE = | |||
gen6_emit_DEPTH_STENCIL_STATE(p->dev, &blitter->dsa, p->cp); | |||
} | |||
if (blitter->uses & ILO_BLITTER_USE_CC) { | |||
session->COLOR_CALC_STATE = | |||
gen6_emit_COLOR_CALC_STATE(p->dev, &blitter->cc.stencil_ref, | |||
blitter->cc.alpha_ref, &blitter->cc.blend_color, p->cp); | |||
} | |||
if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) { | |||
session->CC_VIEWPORT = | |||
gen6_emit_CC_VIEWPORT(p->dev, &blitter->viewport, 1, p->cp); | |||
} | |||
} | |||
static void | |||
ilo_3d_pipeline_emit_rectlist_gen6(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter) | |||
{ | |||
struct gen6_rectlist_session session; | |||
memset(&session, 0, sizeof(session)); | |||
gen6_rectlist_states(p, blitter, &session); | |||
gen6_rectlist_commands(p, blitter, &session); | |||
} | |||
static int | |||
gen6_pipeline_estimate_commands(const struct ilo_3d_pipeline *p, | |||
const struct ilo_context *ilo) | |||
@@ -1702,6 +1875,9 @@ ilo_3d_pipeline_estimate_size_gen6(struct ilo_3d_pipeline *p, | |||
size = ilo_gpe_gen6_estimate_command_size(p->dev, | |||
ILO_GPE_GEN6_PIPE_CONTROL, 1) * 3; | |||
break; | |||
case ILO_3D_PIPELINE_RECTLIST: | |||
size = 64 + 256; /* states + commands */ | |||
break; | |||
default: | |||
assert(!"unknown 3D pipeline action"); | |||
size = 0; | |||
@@ -1719,4 +1895,5 @@ ilo_3d_pipeline_init_gen6(struct ilo_3d_pipeline *p) | |||
p->emit_flush = ilo_3d_pipeline_emit_flush_gen6; | |||
p->emit_write_timestamp = ilo_3d_pipeline_emit_write_timestamp_gen6; | |||
p->emit_write_depth_count = ilo_3d_pipeline_emit_write_depth_count_gen6; | |||
p->emit_rectlist = ilo_3d_pipeline_emit_rectlist_gen6; | |||
} |
@@ -73,6 +73,12 @@ struct gen6_pipeline_session { | |||
int num_surfaces[PIPE_SHADER_TYPES]; | |||
}; | |||
struct gen6_rectlist_session { | |||
uint32_t DEPTH_STENCIL_STATE; | |||
uint32_t COLOR_CALC_STATE; | |||
uint32_t CC_VIEWPORT; | |||
}; | |||
void | |||
gen6_pipeline_prepare(const struct ilo_3d_pipeline *p, | |||
const struct ilo_context *ilo, |
@@ -28,7 +28,7 @@ | |||
#include "util/u_dual_blend.h" | |||
#include "intel_reg.h" | |||
#include "ilo_common.h" | |||
#include "ilo_blitter.h" | |||
#include "ilo_context.h" | |||
#include "ilo_cp.h" | |||
#include "ilo_gpe_gen7.h" | |||
@@ -650,6 +650,233 @@ ilo_3d_pipeline_emit_draw_gen7(struct ilo_3d_pipeline *p, | |||
gen6_pipeline_end(p, ilo, &session); | |||
} | |||
static void | |||
gen7_rectlist_pcb_alloc(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
/* | |||
* Push constant buffers are only allowed to take up at most the first | |||
* 16KB of the URB. Split the space evenly for VS and FS. | |||
*/ | |||
const int max_size = | |||
(p->dev->gen == ILO_GEN(7.5) && p->dev->gt == 3) ? 32768 : 16384; | |||
const int size = max_size / 2; | |||
int offset = 0; | |||
gen7_emit_3DSTATE_PUSH_CONSTANT_ALLOC_VS(p->dev, offset, size, p->cp); | |||
offset += size; | |||
gen7_emit_3DSTATE_PUSH_CONSTANT_ALLOC_PS(p->dev, offset, size, p->cp); | |||
gen7_wa_pipe_control_cs_stall(p, true, true); | |||
} | |||
static void | |||
gen7_rectlist_urb(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
/* the first 16KB are reserved for VS and PS PCBs */ | |||
const int offset = | |||
(p->dev->gen == ILO_GEN(7.5) && p->dev->gt == 3) ? 32768 : 16384; | |||
gen7_emit_3DSTATE_URB_VS(p->dev, offset, p->dev->urb_size - offset, | |||
blitter->ve.count * 4 * sizeof(float), p->cp); | |||
gen7_emit_3DSTATE_URB_GS(p->dev, offset, 0, 0, p->cp); | |||
gen7_emit_3DSTATE_URB_HS(p->dev, offset, 0, 0, p->cp); | |||
gen7_emit_3DSTATE_URB_DS(p->dev, offset, 0, 0, p->cp); | |||
} | |||
static void | |||
gen7_rectlist_vs_to_sf(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
gen7_emit_3DSTATE_CONSTANT_VS(p->dev, NULL, NULL, 0, p->cp); | |||
gen6_emit_3DSTATE_VS(p->dev, NULL, 0, p->cp); | |||
gen7_emit_3DSTATE_CONSTANT_HS(p->dev, NULL, NULL, 0, p->cp); | |||
gen7_emit_3DSTATE_HS(p->dev, NULL, 0, p->cp); | |||
gen7_emit_3DSTATE_TE(p->dev, p->cp); | |||
gen7_emit_3DSTATE_CONSTANT_DS(p->dev, NULL, NULL, 0, p->cp); | |||
gen7_emit_3DSTATE_DS(p->dev, NULL, 0, p->cp); | |||
gen7_emit_3DSTATE_CONSTANT_GS(p->dev, NULL, NULL, 0, p->cp); | |||
gen7_emit_3DSTATE_GS(p->dev, NULL, 0, p->cp); | |||
gen7_emit_3DSTATE_STREAMOUT(p->dev, 0x0, 0, false, p->cp); | |||
gen6_emit_3DSTATE_CLIP(p->dev, NULL, NULL, false, 0, p->cp); | |||
gen7_wa_pipe_control_cs_stall(p, true, true); | |||
gen7_emit_3DSTATE_SF(p->dev, NULL, blitter->fb.dst.base.format, p->cp); | |||
gen7_emit_3DSTATE_SBE(p->dev, NULL, NULL, p->cp); | |||
} | |||
static void | |||
gen7_rectlist_wm(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
uint32_t hiz_op; | |||
switch (blitter->op) { | |||
case ILO_BLITTER_RECTLIST_CLEAR_ZS: | |||
hiz_op = GEN7_WM_DEPTH_CLEAR; | |||
break; | |||
case ILO_BLITTER_RECTLIST_RESOLVE_Z: | |||
hiz_op = GEN7_WM_DEPTH_RESOLVE; | |||
break; | |||
case ILO_BLITTER_RECTLIST_RESOLVE_HIZ: | |||
hiz_op = GEN7_WM_HIERARCHICAL_DEPTH_RESOLVE; | |||
break; | |||
default: | |||
hiz_op = 0; | |||
break; | |||
} | |||
gen7_wa_pipe_control_wm_max_threads_stall(p); | |||
gen7_emit_3DSTATE_WM(p->dev, NULL, NULL, false, hiz_op, p->cp); | |||
gen7_emit_3DSTATE_CONSTANT_PS(p->dev, NULL, NULL, 0, p->cp); | |||
gen7_emit_3DSTATE_PS(p->dev, NULL, 0, false, p->cp); | |||
} | |||
static void | |||
gen7_rectlist_wm_depth(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
gen7_wa_pipe_control_wm_depth_stall(p, true); | |||
if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) { | |||
gen6_emit_3DSTATE_DEPTH_BUFFER(p->dev, | |||
&blitter->fb.dst.u.zs, p->cp); | |||
gen6_emit_3DSTATE_HIER_DEPTH_BUFFER(p->dev, | |||
&blitter->fb.dst.u.zs, p->cp); | |||
} | |||
if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL) { | |||
gen6_emit_3DSTATE_STENCIL_BUFFER(p->dev, | |||
&blitter->fb.dst.u.zs, p->cp); | |||
} | |||
gen7_emit_3DSTATE_CLEAR_PARAMS(p->dev, | |||
blitter->depth_clear_value, p->cp); | |||
} | |||
static void | |||
gen7_rectlist_wm_multisample(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
const uint32_t *packed_sample_pos = | |||
(blitter->fb.num_samples > 4) ? p->packed_sample_position_8x : | |||
(blitter->fb.num_samples > 1) ? &p->packed_sample_position_4x : | |||
&p->packed_sample_position_1x; | |||
gen7_wa_pipe_control_cs_stall(p, true, true); | |||
gen6_emit_3DSTATE_MULTISAMPLE(p->dev, blitter->fb.num_samples, | |||
packed_sample_pos, true, p->cp); | |||
gen7_emit_3DSTATE_SAMPLE_MASK(p->dev, | |||
(1 << blitter->fb.num_samples) - 1, blitter->fb.num_samples, p->cp); | |||
} | |||
static void | |||
gen7_rectlist_commands(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
gen7_rectlist_wm_multisample(p, blitter, session); | |||
gen6_emit_STATE_BASE_ADDRESS(p->dev, | |||
NULL, /* General State Base */ | |||
p->cp->bo, /* Surface State Base */ | |||
p->cp->bo, /* Dynamic State Base */ | |||
NULL, /* Indirect Object Base */ | |||
NULL, /* Instruction Base */ | |||
0, 0, 0, 0, p->cp); | |||
gen6_emit_3DSTATE_VERTEX_BUFFERS(p->dev, | |||
&blitter->ve, &blitter->vb, p->cp); | |||
gen6_emit_3DSTATE_VERTEX_ELEMENTS(p->dev, | |||
&blitter->ve, false, false, p->cp); | |||
gen7_rectlist_pcb_alloc(p, blitter, session); | |||
/* needed for any VS-related commands */ | |||
gen7_wa_pipe_control_vs_depth_stall(p); | |||
gen7_rectlist_urb(p, blitter, session); | |||
if (blitter->uses & ILO_BLITTER_USE_DSA) { | |||
gen7_emit_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(p->dev, | |||
session->DEPTH_STENCIL_STATE, p->cp); | |||
} | |||
if (blitter->uses & ILO_BLITTER_USE_CC) { | |||
gen7_emit_3DSTATE_CC_STATE_POINTERS(p->dev, | |||
session->COLOR_CALC_STATE, p->cp); | |||
} | |||
gen7_rectlist_vs_to_sf(p, blitter, session); | |||
gen7_rectlist_wm(p, blitter, session); | |||
if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) { | |||
gen7_emit_3DSTATE_VIEWPORT_STATE_POINTERS_CC(p->dev, | |||
session->CC_VIEWPORT, p->cp); | |||
} | |||
gen7_rectlist_wm_depth(p, blitter, session); | |||
gen6_emit_3DSTATE_DRAWING_RECTANGLE(p->dev, 0, 0, | |||
blitter->fb.width, blitter->fb.height, p->cp); | |||
gen7_emit_3DPRIMITIVE(p->dev, &blitter->draw, NULL, true, p->cp); | |||
} | |||
static void | |||
gen7_rectlist_states(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter, | |||
struct gen6_rectlist_session *session) | |||
{ | |||
if (blitter->uses & ILO_BLITTER_USE_DSA) { | |||
session->DEPTH_STENCIL_STATE = | |||
gen6_emit_DEPTH_STENCIL_STATE(p->dev, &blitter->dsa, p->cp); | |||
} | |||
if (blitter->uses & ILO_BLITTER_USE_CC) { | |||
session->COLOR_CALC_STATE = | |||
gen6_emit_COLOR_CALC_STATE(p->dev, &blitter->cc.stencil_ref, | |||
blitter->cc.alpha_ref, &blitter->cc.blend_color, p->cp); | |||
} | |||
if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) { | |||
session->CC_VIEWPORT = | |||
gen6_emit_CC_VIEWPORT(p->dev, &blitter->viewport, 1, p->cp); | |||
} | |||
} | |||
static void | |||
ilo_3d_pipeline_emit_rectlist_gen7(struct ilo_3d_pipeline *p, | |||
const struct ilo_blitter *blitter) | |||
{ | |||
struct gen6_rectlist_session session; | |||
memset(&session, 0, sizeof(session)); | |||
gen7_rectlist_states(p, blitter, &session); | |||
gen7_rectlist_commands(p, blitter, &session); | |||
} | |||
static int | |||
gen7_pipeline_estimate_commands(const struct ilo_3d_pipeline *p, | |||
const struct ilo_context *ilo) | |||
@@ -809,6 +1036,9 @@ ilo_3d_pipeline_estimate_size_gen7(struct ilo_3d_pipeline *p, | |||
size = ilo_gpe_gen7_estimate_command_size(p->dev, | |||
ILO_GPE_GEN7_PIPE_CONTROL, 1); | |||
break; | |||
case ILO_3D_PIPELINE_RECTLIST: | |||
size = 64 + 256; /* states + commands */ | |||
break; | |||
default: | |||
assert(!"unknown 3D pipeline action"); | |||
size = 0; | |||
@@ -826,4 +1056,5 @@ ilo_3d_pipeline_init_gen7(struct ilo_3d_pipeline *p) | |||
p->emit_flush = ilo_3d_pipeline_emit_flush_gen6; | |||
p->emit_write_timestamp = ilo_3d_pipeline_emit_write_timestamp_gen6; | |||
p->emit_write_depth_count = ilo_3d_pipeline_emit_write_depth_count_gen6; | |||
p->emit_rectlist = ilo_3d_pipeline_emit_rectlist_gen7; | |||
} |
@@ -70,5 +70,10 @@ ilo_blitter_destroy(struct ilo_blitter *blitter) | |||
if (blitter->pipe_blitter) | |||
util_blitter_destroy(blitter->pipe_blitter); | |||
if (blitter->buffer.res) { | |||
struct pipe_screen *screen = blitter->ilo->base.screen; | |||
screen->resource_destroy(screen, blitter->buffer.res); | |||
} | |||
FREE(blitter); | |||
} |
@@ -29,14 +29,64 @@ | |||
#define ILO_BLITTER_H | |||
#include "ilo_common.h" | |||
#include "ilo_context.h" | |||
#include "ilo_gpe.h" | |||
enum ilo_blitter_uses { | |||
ILO_BLITTER_USE_DSA = 1 << 0, | |||
ILO_BLITTER_USE_CC = 1 << 1, | |||
ILO_BLITTER_USE_VIEWPORT = 1 << 2, | |||
ILO_BLITTER_USE_FB_DEPTH = 1 << 3, | |||
ILO_BLITTER_USE_FB_STENCIL = 1 << 4, | |||
}; | |||
enum ilo_blitter_rectlist_op { | |||
ILO_BLITTER_RECTLIST_CLEAR_ZS, | |||
ILO_BLITTER_RECTLIST_RESOLVE_Z, | |||
ILO_BLITTER_RECTLIST_RESOLVE_HIZ, | |||
}; | |||
struct ilo_context; | |||
struct blitter_context; | |||
struct pipe_resource; | |||
struct pipe_surface; | |||
struct ilo_blitter { | |||
struct ilo_context *ilo; | |||
struct blitter_context *pipe_blitter; | |||
/* | |||
* A minimal context with the goal to send RECTLISTs down the pipeline. | |||
*/ | |||
enum ilo_blitter_rectlist_op op; | |||
uint32_t uses; | |||
bool initialized; | |||
struct { | |||
struct pipe_resource *res; | |||
unsigned offset, size; | |||
} buffer; | |||
struct ilo_ve_state ve; | |||
struct ilo_vb_state vb; | |||
struct pipe_draw_info draw; | |||
struct ilo_viewport_cso viewport; | |||
struct ilo_dsa_state dsa; | |||
struct { | |||
struct pipe_stencil_ref stencil_ref; | |||
ubyte alpha_ref; | |||
struct pipe_blend_color blend_color; | |||
} cc; | |||
uint32_t depth_clear_value; | |||
struct { | |||
struct ilo_surface_cso dst; | |||
unsigned width, height; | |||
unsigned num_samples; | |||
} fb; | |||
}; | |||
struct ilo_blitter * | |||
@@ -99,4 +149,20 @@ ilo_blitter_blt_clear_zs(struct ilo_blitter *blitter, | |||
unsigned x, unsigned y, | |||
unsigned width, unsigned height); | |||
bool | |||
ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter, | |||
struct pipe_surface *zs, | |||
unsigned clear_flags, | |||
double depth, unsigned stencil); | |||
void | |||
ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter, | |||
struct pipe_resource *res, | |||
unsigned level, unsigned slice); | |||
void | |||
ilo_blitter_rectlist_resolve_hiz(struct ilo_blitter *blitter, | |||
struct pipe_resource *res, | |||
unsigned level, unsigned slice); | |||
#endif /* ILO_BLITTER_H */ |
@@ -0,0 +1,525 @@ | |||
/* | |||
* Mesa 3-D graphics library | |||
* | |||
* Copyright (C) 2014 LunarG, Inc. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
* DEALINGS IN THE SOFTWARE. | |||
* | |||
* Authors: | |||
* Chia-I Wu <olv@lunarg.com> | |||
*/ | |||
#include "util/u_draw.h" | |||
#include "util/u_pack_color.h" | |||
#include "ilo_blitter.h" | |||
#include "ilo_3d.h" | |||
#include "ilo_3d_pipeline.h" | |||
#include "ilo_gpe.h" | |||
#include "ilo_gpe_gen6.h" /* for ve_init_cso_with_components */ | |||
/** | |||
* Set the states that are invariant between all ops. | |||
*/ | |||
static bool | |||
ilo_blitter_set_invariants(struct ilo_blitter *blitter) | |||
{ | |||
struct pipe_screen *screen = blitter->ilo->base.screen; | |||
struct pipe_resource templ; | |||
struct pipe_vertex_element velems[2]; | |||
struct pipe_viewport_state vp; | |||
if (blitter->initialized) | |||
return true; | |||
blitter->buffer.size = 4096; | |||
/* allocate the vertex buffer */ | |||
memset(&templ, 0, sizeof(templ)); | |||
templ.target = PIPE_BUFFER; | |||
templ.width0 = blitter->buffer.size; | |||
templ.usage = PIPE_USAGE_STREAM; | |||
templ.bind = PIPE_BIND_VERTEX_BUFFER; | |||
blitter->buffer.res = screen->resource_create(screen, &templ); | |||
if (!blitter->buffer.res) | |||
return false; | |||
/* do not increase reference count */ | |||
blitter->vb.states[0].buffer = blitter->buffer.res; | |||
/* only vertex X and Y */ | |||
blitter->vb.states[0].stride = 2 * sizeof(float); | |||
blitter->vb.enabled_mask = 0x1; | |||
memset(&velems, 0, sizeof(velems)); | |||
velems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; | |||
ilo_gpe_init_ve(blitter->ilo->dev, 2, velems, &blitter->ve); | |||
/* override first VE to be VUE header */ | |||
ve_init_cso_with_components(blitter->ilo->dev, | |||
BRW_VE1_COMPONENT_STORE_0, /* Reserved */ | |||
BRW_VE1_COMPONENT_STORE_0, /* Render Target Array Index */ | |||
BRW_VE1_COMPONENT_STORE_0, /* Viewport Index */ | |||
BRW_VE1_COMPONENT_STORE_0, /* Point Width */ | |||
&blitter->ve.cso[0]); | |||
/* a rectangle has 3 vertices in a RECTLIST */ | |||
util_draw_init_info(&blitter->draw); | |||
blitter->draw.count = 3; | |||
/** | |||
* From the Haswell PRM, volume 7, page 615: | |||
* | |||
* "The clear value must be between the min and max depth values | |||
* (inclusive) defined in the CC_VIEWPORT." | |||
* | |||
* Even though clipping and viewport transformation will be disabled, we | |||
* still need to set up the viewport states. | |||
*/ | |||
memset(&vp, 0, sizeof(vp)); | |||
vp.scale[0] = 1.0f; | |||
vp.scale[1] = 1.0f; | |||
vp.scale[2] = 1.0f; | |||
vp.scale[3] = 1.0f; | |||
ilo_gpe_set_viewport_cso(blitter->ilo->dev, &vp, &blitter->viewport); | |||
blitter->initialized = true; | |||
return true; | |||
} | |||
static void | |||
ilo_blitter_set_op(struct ilo_blitter *blitter, | |||
enum ilo_blitter_rectlist_op op) | |||
{ | |||
blitter->op = op; | |||
} | |||
/** | |||
* Set the rectangle primitive. | |||
*/ | |||
static void | |||
ilo_blitter_set_rectlist(struct ilo_blitter *blitter, | |||
unsigned x, unsigned y, | |||
unsigned width, unsigned height) | |||
{ | |||
unsigned usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED; | |||
float vertices[3][2]; | |||
struct pipe_box box; | |||
/* | |||
* From the Sandy Bridge PRM, volume 2 part 1, page 11: | |||
* | |||
* "(RECTLIST) A list of independent rectangles, where only 3 vertices | |||
* are provided per rectangle object, with the fourth vertex implied | |||
* by the definition of a rectangle. V0=LowerRight, V1=LowerLeft, | |||
* V2=UpperLeft. Implied V3 = V0- V1+V2." | |||
*/ | |||
vertices[0][0] = (float) (x + width); | |||
vertices[0][1] = (float) (y + height); | |||
vertices[1][0] = (float) x; | |||
vertices[1][1] = (float) (y + height); | |||
vertices[2][0] = (float) x; | |||
vertices[2][1] = (float) y; | |||
/* buffer is full */ | |||
if (blitter->buffer.offset + sizeof(vertices) > blitter->buffer.size) { | |||
if (!ilo_buffer_alloc_bo(ilo_buffer(blitter->buffer.res))) | |||
usage &= ~PIPE_TRANSFER_UNSYNCHRONIZED; | |||
blitter->buffer.offset = 0; | |||
} | |||
u_box_1d(blitter->buffer.offset, sizeof(vertices), &box); | |||
blitter->ilo->base.transfer_inline_write(&blitter->ilo->base, | |||
blitter->buffer.res, 0, usage, &box, vertices, 0, 0); | |||
blitter->vb.states[0].buffer_offset = blitter->buffer.offset; | |||
blitter->buffer.offset += sizeof(vertices); | |||
} | |||
static void | |||
ilo_blitter_set_clear_values(struct ilo_blitter *blitter, | |||
uint32_t depth, ubyte stencil) | |||
{ | |||
blitter->depth_clear_value = depth; | |||
blitter->cc.stencil_ref.ref_value[0] = stencil; | |||
} | |||
static void | |||
ilo_blitter_set_dsa(struct ilo_blitter *blitter, | |||
const struct pipe_depth_stencil_alpha_state *state) | |||
{ | |||
ilo_gpe_init_dsa(blitter->ilo->dev, state, &blitter->dsa); | |||
} | |||
static void | |||
ilo_blitter_set_fb(struct ilo_blitter *blitter, | |||
const struct pipe_resource *res, unsigned level, | |||
const struct ilo_surface_cso *cso) | |||
{ | |||
blitter->fb.width = u_minify(res->width0, level); | |||
blitter->fb.height = u_minify(res->height0, level); | |||
blitter->fb.num_samples = res->nr_samples; | |||
if (!blitter->fb.num_samples) | |||
blitter->fb.num_samples = 1; | |||
memcpy(&blitter->fb.dst, cso, sizeof(*cso)); | |||
} | |||
static void | |||
ilo_blitter_set_fb_from_surface(struct ilo_blitter *blitter, | |||
struct pipe_surface *surf) | |||
{ | |||
ilo_blitter_set_fb(blitter, surf->texture, surf->u.tex.level, | |||
(const struct ilo_surface_cso *) surf); | |||
} | |||
static void | |||
ilo_blitter_set_fb_from_resource(struct ilo_blitter *blitter, | |||
struct pipe_resource *res, | |||
enum pipe_format format, | |||
unsigned level, unsigned slice) | |||
{ | |||
struct pipe_surface templ, *surf; | |||
memset(&templ, 0, sizeof(templ)); | |||
templ.format = format; | |||
templ.u.tex.level = level; | |||
templ.u.tex.first_layer = slice; | |||
templ.u.tex.last_layer = slice; | |||
/* if we did not call create_surface(), it would never fail */ | |||
surf = blitter->ilo->base.create_surface(&blitter->ilo->base, res, &templ); | |||
assert(surf); | |||
ilo_blitter_set_fb(blitter, res, level, | |||
(const struct ilo_surface_cso *) surf); | |||
pipe_surface_reference(&surf, NULL); | |||
} | |||
static void | |||
ilo_blitter_set_uses(struct ilo_blitter *blitter, uint32_t uses) | |||
{ | |||
blitter->uses = uses; | |||
} | |||
static void | |||
hiz_emit_rectlist(struct ilo_blitter *blitter) | |||
{ | |||
struct ilo_3d *hw3d = blitter->ilo->hw3d; | |||
struct ilo_3d_pipeline *p = hw3d->pipeline; | |||
ilo_3d_own_render_ring(hw3d); | |||
/* | |||
* From the Sandy Bridge PRM, volume 2 part 1, page 313: | |||
* | |||
* "If other rendering operations have preceded this clear, a | |||
* PIPE_CONTROL with write cache flush enabled and Z-inhibit | |||
* disabled must be issued before the rectangle primitive used for | |||
* the depth buffer clear operation." | |||
* | |||
* From the Sandy Bridge PRM, volume 2 part 1, page 314: | |||
* | |||
* "Depth buffer clear pass must be followed by a PIPE_CONTROL | |||
* command with DEPTH_STALL bit set and Then followed by Depth | |||
* FLUSH" | |||
* | |||
* But the pipeline has to be flushed both before and after not only | |||
* because of these workarounds. We need them for reasons such as | |||
* | |||
* - we may sample from a texture that was rendered to | |||
* - we may sample from the fb shortly after | |||
*/ | |||
if (!ilo_cp_empty(p->cp)) | |||
ilo_3d_pipeline_emit_flush(p); | |||
ilo_3d_pipeline_emit_rectlist(p, blitter); | |||
ilo_3d_pipeline_emit_flush(p); | |||
} | |||
/** | |||
* This must be called after ilo_blitter_set_fb(). | |||
*/ | |||
static void | |||
hiz_set_rectlist(struct ilo_blitter *blitter, bool aligned) | |||
{ | |||
unsigned width = blitter->fb.width; | |||
unsigned height = blitter->fb.height; | |||
/* | |||
* From the Sandy Bridge PRM, volume 2 part 1, page 313-314: | |||
* | |||
* "A rectangle primitive representing the clear area is delivered. The | |||
* primitive must adhere to the following restrictions on size: | |||
* | |||
* - If Number of Multisamples is NUMSAMPLES_1, the rectangle must be | |||
* aligned to an 8x4 pixel block relative to the upper left corner | |||
* of the depth buffer, and contain an integer number of these pixel | |||
* blocks, and all 8x4 pixels must be lit. | |||
* | |||
* - If Number of Multisamples is NUMSAMPLES_4, the rectangle must be | |||
* aligned to a 4x2 pixel block (8x4 sample block) relative to the | |||
* upper left corner of the depth buffer, and contain an integer | |||
* number of these pixel blocks, and all samples of the 4x2 pixels | |||
* must be lit | |||
* | |||
* - If Number of Multisamples is NUMSAMPLES_8, the rectangle must be | |||
* aligned to a 2x2 pixel block (8x4 sample block) relative to the | |||
* upper left corner of the depth buffer, and contain an integer | |||
* number of these pixel blocks, and all samples of the 2x2 pixels | |||
* must be list." | |||
* | |||
* "The following is required when performing a depth buffer resolve: | |||
* | |||
* - A rectangle primitive of the same size as the previous depth | |||
* buffer clear operation must be delivered, and depth buffer state | |||
* cannot have changed since the previous depth buffer clear | |||
* operation." | |||
* | |||
* Making the RECTLIST aligned to 8x4 is easy. But how about | |||
* 3DSTATE_DRAWING_RECTANGLE and 3DSTATE_DEPTH_BUFFER? Since we use | |||
* HALIGN_8 and VALIGN_4 for depth buffers, we can safely align the drawing | |||
* rectangle, except that the PRM requires the drawing rectangle to be | |||
* clampped to the render target boundary. For 3DSTATE_DEPTH_BUFFER, we | |||
* cannot align the Width and Height fields if level or slice is greater | |||
* than zero. | |||
*/ | |||
if (aligned) { | |||
switch (blitter->fb.num_samples) { | |||
case 1: | |||
width = align(width, 8); | |||
height = align(height, 4); | |||
break; | |||
case 2: | |||
width = align(width, 4); | |||
height = align(height, 4); | |||
break; | |||
case 4: | |||
width = align(width, 4); | |||
height = align(height, 2); | |||
break; | |||
case 8: | |||
default: | |||
width = align(width, 2); | |||
height = align(height, 2); | |||
break; | |||
} | |||
} | |||
ilo_blitter_set_rectlist(blitter, 0, 0, width, height); | |||
} | |||
static bool | |||
hiz_can_clear_zs(const struct ilo_blitter *blitter, | |||
const struct ilo_texture *tex) | |||
{ | |||
if (blitter->ilo->dev->gen > ILO_GEN(6)) | |||
return true; | |||
/* | |||
* From the Sandy Bridge PRM, volume 2 part 1, page 314: | |||
* | |||
* Several cases exist where Depth Buffer Clear cannot be enabled (the | |||
* legacy method of clearing must be performed): | |||
* | |||
* - If the depth buffer format is D32_FLOAT_S8X24_UINT or | |||
* D24_UNORM_S8_UINT. | |||
* | |||
* - If stencil test is enabled but the separate stencil buffer is | |||
* disabled. | |||
* | |||
* - [DevSNB-A{W/A}]: ... | |||
* | |||
* - [DevSNB{W/A}]: When depth buffer format is D16_UNORM and the | |||
* width of the map (LOD0) is not multiple of 16, fast clear | |||
* optimization must be disabled. | |||
*/ | |||
switch (tex->bo_format) { | |||
case PIPE_FORMAT_Z16_UNORM: | |||
if (tex->base.width0 % 16) | |||
return false; | |||
break; | |||
case PIPE_FORMAT_Z24_UNORM_S8_UINT: | |||
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: | |||
assert(!"HiZ with combined depth/stencil"); | |||
return false; | |||
break; | |||
default: | |||
break; | |||
} | |||
return true; | |||
} | |||
bool | |||
ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter, | |||
struct pipe_surface *zs, | |||
unsigned clear_flags, | |||
double depth, unsigned stencil) | |||
{ | |||
struct ilo_texture *tex = ilo_texture(zs->texture); | |||
struct pipe_depth_stencil_alpha_state dsa_state; | |||
uint32_t uses; | |||
if (!tex->hiz.bo) | |||
return false; | |||
if (!hiz_can_clear_zs(blitter, tex)) | |||
return false; | |||
/* | |||
* From the Sandy Bridge PRM, volume 2 part 1, page 313-314: | |||
* | |||
* "- Depth Test Enable must be disabled and Depth Buffer Write Enable | |||
* must be enabled (if depth is being cleared). | |||
* | |||
* - Stencil buffer clear can be performed at the same time by | |||
* enabling Stencil Buffer Write Enable. Stencil Test Enable must | |||
* be enabled and Stencil Pass Depth Pass Op set to REPLACE, and the | |||
* clear value that is placed in the stencil buffer is the Stencil | |||
* Reference Value from COLOR_CALC_STATE. | |||
* | |||
* - Note also that stencil buffer clear can be performed without | |||
* depth buffer clear. For stencil only clear, Depth Test Enable and | |||
* Depth Buffer Write Enable must be disabled. | |||
* | |||
* - [DevSNB] errata: For stencil buffer only clear, the previous | |||
* depth clear value must be delivered during the clear." | |||
*/ | |||
memset(&dsa_state, 0, sizeof(dsa_state)); | |||
if (clear_flags & PIPE_CLEAR_DEPTH) | |||
dsa_state.depth.writemask = true; | |||
if (clear_flags & PIPE_CLEAR_STENCIL) { | |||
dsa_state.stencil[0].enabled = true; | |||
dsa_state.stencil[0].func = PIPE_FUNC_ALWAYS; | |||
dsa_state.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; | |||
dsa_state.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; | |||
dsa_state.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; | |||
/* | |||
* From the Ivy Bridge PRM, volume 2 part 1, page 277: | |||
* | |||
* "Additionally the following must be set to the correct values. | |||
* | |||
* - DEPTH_STENCIL_STATE::Stencil Write Mask must be 0xFF | |||
* - DEPTH_STENCIL_STATE::Stencil Test Mask must be 0xFF | |||
* - DEPTH_STENCIL_STATE::Back Face Stencil Write Mask must be 0xFF | |||
* - DEPTH_STENCIL_STATE::Back Face Stencil Test Mask must be 0xFF" | |||
*/ | |||
dsa_state.stencil[0].valuemask = 0xff; | |||
dsa_state.stencil[0].writemask = 0xff; | |||
dsa_state.stencil[1].valuemask = 0xff; | |||
dsa_state.stencil[1].writemask = 0xff; | |||
} | |||
ilo_blitter_set_invariants(blitter); | |||
ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_CLEAR_ZS); | |||
ilo_blitter_set_dsa(blitter, &dsa_state); | |||
ilo_blitter_set_clear_values(blitter, | |||
util_pack_z(zs->format, depth), (ubyte) stencil); | |||
ilo_blitter_set_fb_from_surface(blitter, zs); | |||
uses = ILO_BLITTER_USE_DSA; | |||
if (clear_flags & PIPE_CLEAR_DEPTH) | |||
uses |= ILO_BLITTER_USE_VIEWPORT | ILO_BLITTER_USE_FB_DEPTH; | |||
if (clear_flags & PIPE_CLEAR_STENCIL) | |||
uses |= ILO_BLITTER_USE_CC | ILO_BLITTER_USE_FB_STENCIL; | |||
ilo_blitter_set_uses(blitter, uses); | |||
hiz_set_rectlist(blitter, true); | |||
hiz_emit_rectlist(blitter); | |||
return true; | |||
} | |||
void | |||
ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter, | |||
struct pipe_resource *res, | |||
unsigned level, unsigned slice) | |||
{ | |||
struct ilo_texture *tex = ilo_texture(res); | |||
struct pipe_depth_stencil_alpha_state dsa_state; | |||
if (!tex->hiz.bo) | |||
return; | |||
/* | |||
* From the Sandy Bridge PRM, volume 2 part 1, page 314: | |||
* | |||
* "Depth Test Enable must be enabled with the Depth Test Function set | |||
* to NEVER. Depth Buffer Write Enable must be enabled. Stencil Test | |||
* Enable and Stencil Buffer Write Enable must be disabled." | |||
*/ | |||
memset(&dsa_state, 0, sizeof(dsa_state)); | |||
dsa_state.depth.writemask = true; | |||
dsa_state.depth.enabled = true; | |||
dsa_state.depth.func = PIPE_FUNC_NEVER; | |||
ilo_blitter_set_invariants(blitter); | |||
ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_RESOLVE_Z); | |||
ilo_blitter_set_dsa(blitter, &dsa_state); | |||
ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice); | |||
ilo_blitter_set_uses(blitter, | |||
ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH); | |||
hiz_set_rectlist(blitter, true); | |||
hiz_emit_rectlist(blitter); | |||
} | |||
void | |||
ilo_blitter_rectlist_resolve_hiz(struct ilo_blitter *blitter, | |||
struct pipe_resource *res, | |||
unsigned level, unsigned slice) | |||
{ | |||
struct ilo_texture *tex = ilo_texture(res); | |||
struct pipe_depth_stencil_alpha_state dsa_state; | |||
if (!tex->hiz.bo) | |||
return; | |||
/* | |||
* From the Sandy Bridge PRM, volume 2 part 1, page 315: | |||
* | |||
* "(Hierarchical Depth Buffer Resolve) Depth Test Enable must be | |||
* disabled. Depth Buffer Write Enable must be enabled. Stencil Test | |||
* Enable and Stencil Buffer Write Enable must be disabled." | |||
*/ | |||
memset(&dsa_state, 0, sizeof(dsa_state)); | |||
dsa_state.depth.writemask = true; | |||
ilo_blitter_set_invariants(blitter); | |||
ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_RESOLVE_HIZ); | |||
ilo_blitter_set_dsa(blitter, &dsa_state); | |||
ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice); | |||
ilo_blitter_set_uses(blitter, | |||
ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH); | |||
hiz_set_rectlist(blitter, false); | |||
hiz_emit_rectlist(blitter); | |||
} |