|
|
@@ -111,6 +111,26 @@ gen6_wa_pre_non_pipelined(struct ilo_render *r) |
|
|
|
gen6_wa_pre_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
gen6_wa_post_3dstate_urb_no_gs(struct ilo_render *r) |
|
|
|
{ |
|
|
|
/* |
|
|
|
* From the Sandy Bridge PRM, volume 2 part 1, page 27: |
|
|
|
* |
|
|
|
* "Because of a urb corruption caused by allocating a previous |
|
|
|
* gsunit's urb entry to vsunit software is required to send a |
|
|
|
* "GS NULL Fence" (Send URB fence with VS URB size == 1 and GS URB |
|
|
|
* size == 0) plus a dummy DRAW call before any case where VS will |
|
|
|
* be taking over GS URB space." |
|
|
|
*/ |
|
|
|
const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL; |
|
|
|
|
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
gen6_wa_pre_pipe_control(r, dw1); |
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
ilo_render_pipe_control(r, dw1); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
gen6_wa_post_3dstate_constant_vs(struct ilo_render *r) |
|
|
|
{ |
|
|
@@ -123,8 +143,31 @@ gen6_wa_post_3dstate_constant_vs(struct ilo_render *r) |
|
|
|
GEN6_PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE | |
|
|
|
GEN6_PIPE_CONTROL_STATE_CACHE_INVALIDATE; |
|
|
|
|
|
|
|
gen6_wa_pre_pipe_control(r, dw1); |
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
gen6_wa_pre_pipe_control(r, dw1); |
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
ilo_render_pipe_control(r, dw1); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
gen6_wa_pre_3dstate_vs_toggle(struct ilo_render *r) |
|
|
|
{ |
|
|
|
/* |
|
|
|
* The classic driver has this undocumented WA: |
|
|
|
* |
|
|
|
* From the BSpec, 3D Pipeline > Geometry > Vertex Shader > State, |
|
|
|
* 3DSTATE_VS, Dword 5.0 "VS Function Enable": |
|
|
|
* |
|
|
|
* [DevSNB] A pipeline flush must be programmed prior to a 3DSTATE_VS |
|
|
|
* command that causes the VS Function Enable to toggle. Pipeline |
|
|
|
* flush can be executed by sending a PIPE_CONTROL command with CS |
|
|
|
* stall bit set and a post sync operation. |
|
|
|
*/ |
|
|
|
const uint32_t dw1 = GEN6_PIPE_CONTROL_WRITE_IMM | |
|
|
|
GEN6_PIPE_CONTROL_CS_STALL; |
|
|
|
|
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
gen6_wa_pre_pipe_control(r, dw1); |
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
ilo_render_pipe_control(r, dw1); |
|
|
|
} |
|
|
@@ -143,8 +186,8 @@ gen6_wa_pre_3dstate_wm_max_threads(struct ilo_render *r) |
|
|
|
|
|
|
|
ILO_DEV_ASSERT(r->dev, 6, 6); |
|
|
|
|
|
|
|
gen6_wa_pre_pipe_control(r, dw1); |
|
|
|
|
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
gen6_wa_pre_pipe_control(r, dw1); |
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
ilo_render_pipe_control(r, dw1); |
|
|
|
} |
|
|
@@ -165,8 +208,8 @@ gen6_wa_pre_3dstate_multisample(struct ilo_render *r) |
|
|
|
|
|
|
|
ILO_DEV_ASSERT(r->dev, 6, 6); |
|
|
|
|
|
|
|
gen6_wa_pre_pipe_control(r, dw1); |
|
|
|
|
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
gen6_wa_pre_pipe_control(r, dw1); |
|
|
|
if ((r->state.current_pipe_control_dw1 & dw1) != dw1) |
|
|
|
ilo_render_pipe_control(r, dw1); |
|
|
|
} |
|
|
@@ -340,17 +383,8 @@ gen6_draw_common_urb(struct ilo_render *r, |
|
|
|
gen6_3DSTATE_URB(r->builder, vs_total_size, gs_total_size, |
|
|
|
vs_entry_size, gs_entry_size); |
|
|
|
|
|
|
|
/* |
|
|
|
* From the Sandy Bridge PRM, volume 2 part 1, page 27: |
|
|
|
* |
|
|
|
* "Because of a urb corruption caused by allocating a previous |
|
|
|
* gsunit's urb entry to vsunit software is required to send a |
|
|
|
* "GS NULL Fence" (Send URB fence with VS URB size == 1 and GS URB |
|
|
|
* size == 0) plus a dummy DRAW call before any case where VS will |
|
|
|
* be taking over GS URB space." |
|
|
|
*/ |
|
|
|
if (r->state.gs.active && !gs_active) |
|
|
|
ilo_render_emit_flush(r); |
|
|
|
gen6_wa_post_3dstate_urb_no_gs(r); |
|
|
|
|
|
|
|
r->state.gs.active = gs_active; |
|
|
|
} |
|
|
@@ -469,30 +503,24 @@ gen6_draw_vs(struct ilo_render *r, |
|
|
|
const struct ilo_state_vector *vec, |
|
|
|
struct ilo_render_draw_session *session) |
|
|
|
{ |
|
|
|
const bool emit_3dstate_vs = (DIRTY(VS) || r->instruction_bo_changed); |
|
|
|
const bool emit_3dstate_constant_vs = session->pcb_vs_changed; |
|
|
|
|
|
|
|
/* |
|
|
|
* the classic i965 does this in upload_vs_state(), citing a spec that I |
|
|
|
* cannot find |
|
|
|
*/ |
|
|
|
if (emit_3dstate_vs && ilo_dev_gen(r->dev) == ILO_GEN(6)) |
|
|
|
gen6_wa_pre_non_pipelined(r); |
|
|
|
|
|
|
|
/* 3DSTATE_CONSTANT_VS */ |
|
|
|
if (emit_3dstate_constant_vs) { |
|
|
|
if (session->pcb_vs_changed) { |
|
|
|
gen6_3DSTATE_CONSTANT_VS(r->builder, |
|
|
|
&r->state.vs.PUSH_CONSTANT_BUFFER, |
|
|
|
&r->state.vs.PUSH_CONSTANT_BUFFER_size, |
|
|
|
1); |
|
|
|
|
|
|
|
if (ilo_dev_gen(r->dev) == ILO_GEN(6)) |
|
|
|
gen6_wa_post_3dstate_constant_vs(r); |
|
|
|
} |
|
|
|
|
|
|
|
/* 3DSTATE_VS */ |
|
|
|
if (emit_3dstate_vs) |
|
|
|
gen6_3DSTATE_VS(r->builder, vec->vs); |
|
|
|
if (DIRTY(VS) || r->instruction_bo_changed) { |
|
|
|
if (ilo_dev_gen(r->dev) == ILO_GEN(6)) |
|
|
|
gen6_wa_pre_3dstate_vs_toggle(r); |
|
|
|
|
|
|
|
if (emit_3dstate_constant_vs && ilo_dev_gen(r->dev) == ILO_GEN(6)) |
|
|
|
gen6_wa_post_3dstate_constant_vs(r); |
|
|
|
gen6_3DSTATE_VS(r->builder, vec->vs); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
@@ -829,10 +857,11 @@ gen6_rectlist_vs_to_sf(struct ilo_render *r, |
|
|
|
const struct ilo_blitter *blitter) |
|
|
|
{ |
|
|
|
gen6_3DSTATE_CONSTANT_VS(r->builder, NULL, NULL, 0); |
|
|
|
gen6_disable_3DSTATE_VS(r->builder); |
|
|
|
|
|
|
|
gen6_wa_post_3dstate_constant_vs(r); |
|
|
|
|
|
|
|
gen6_wa_pre_3dstate_vs_toggle(r); |
|
|
|
gen6_disable_3DSTATE_VS(r->builder); |
|
|
|
|
|
|
|
gen6_3DSTATE_CONSTANT_GS(r->builder, NULL, NULL, 0); |
|
|
|
gen6_disable_3DSTATE_GS(r->builder); |
|
|
|
|
|
|
@@ -941,9 +970,8 @@ ilo_render_emit_rectlist_commands_gen6(struct ilo_render *r, |
|
|
|
(blitter->ve.count + blitter->ve.prepend_nosrc_cso) * 4 * sizeof(float), |
|
|
|
0); |
|
|
|
|
|
|
|
/* 3DSTATE_URB workaround */ |
|
|
|
if (r->state.gs.active) { |
|
|
|
ilo_render_emit_flush(r); |
|
|
|
gen6_wa_post_3dstate_urb_no_gs(r); |
|
|
|
r->state.gs.active = false; |
|
|
|
} |
|
|
|
|