ilo: update WM and PS related functions for Gen8

This commit is contained in:
Chia-I Wu
2015-01-26 18:06:00 +08:00
parent 584d3369b6
commit 6366fbc1a8
2 changed files with 269 additions and 81 deletions
@@ -517,6 +517,33 @@ gen7_3DSTATE_WM(struct ilo_builder *builder,
dw[2] = dw2;
}
static inline void
gen8_3DSTATE_WM(struct ilo_builder *builder,
const struct ilo_shader_state *fs,
const struct ilo_rasterizer_state *rasterizer)
{
const uint8_t cmd_len = 2;
const struct ilo_shader_cso *cso;
uint32_t dw1, interps, *dw;
ILO_DEV_ASSERT(builder->dev, 8, 8);
/* see rasterizer_get_wm_gen8() */
dw1 = rasterizer->wm.payload[0];
dw1 |= GEN7_WM_DW1_STATISTICS;
/* see fs_init_cso_gen8() */
cso = ilo_shader_get_kernel_cso(fs);
interps = cso->payload[4];
assert(!(dw1 & interps));
ilo_builder_batch_pointer(builder, cmd_len, &dw);
dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
dw[1] = dw1 | interps;
}
static inline void
gen7_hiz_3DSTATE_WM(struct ilo_builder *builder, uint32_t hiz_op)
{
@@ -542,6 +569,7 @@ gen7_3DSTATE_PS(struct ilo_builder *builder,
ILO_DEV_ASSERT(builder->dev, 7, 7.5);
/* see fs_init_cso_gen7() */
cso = ilo_shader_get_kernel_cso(fs);
dw2 = cso->payload[0];
dw4 = cso->payload[1];
@@ -600,6 +628,64 @@ gen7_disable_3DSTATE_PS(struct ilo_builder *builder)
dw[7] = 0;
}
static inline void
gen8_3DSTATE_PS(struct ilo_builder *builder,
const struct ilo_shader_state *fs)
{
const uint8_t cmd_len = 12;
const struct ilo_shader_cso *cso;
uint32_t dw3, dw6, dw7, *dw;
ILO_DEV_ASSERT(builder->dev, 8, 8);
/* see fs_init_cso_gen8() */
cso = ilo_shader_get_kernel_cso(fs);
dw3 = cso->payload[0];
dw6 = cso->payload[1];
dw7 = cso->payload[2];
ilo_builder_batch_pointer(builder, cmd_len, &dw);
dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
dw[1] = ilo_shader_get_kernel_offset(fs);
dw[2] = 0;
dw[3] = dw3;
dw[4] = 0; /* scratch */
dw[5] = 0;
dw[6] = dw6;
dw[7] = dw7;
dw[8] = 0; /* kernel 1 */
dw[9] = 0;
dw[10] = 0; /* kernel 2 */
dw[11] = 0;
}
static inline void
gen8_3DSTATE_PS_EXTRA(struct ilo_builder *builder,
const struct ilo_shader_state *fs,
bool cc_may_kill, bool per_sample)
{
const uint8_t cmd_len = 2;
const struct ilo_shader_cso *cso;
uint32_t dw1, *dw;
ILO_DEV_ASSERT(builder->dev, 8, 8);
/* see fs_init_cso_gen8() */
cso = ilo_shader_get_kernel_cso(fs);
dw1 = cso->payload[3];
if (cc_may_kill)
dw1 |= GEN8_PSX_DW1_DISPATCH_ENABLE | GEN8_PSX_DW1_KILL_PIXEL;
if (per_sample)
dw1 |= GEN8_PSX_DW1_PER_SAMPLE;
ilo_builder_batch_pointer(builder, cmd_len, &dw);
dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_EXTRA) | (cmd_len - 2);
dw[1] = dw1;
}
static inline void
gen6_3DSTATE_CONSTANT_PS(struct ilo_builder *builder,
const uint32_t *bufs, const int *sizes,
+183 -81
View File
@@ -492,13 +492,6 @@ rasterizer_init_wm_gen6(const struct ilo_dev_info *dev,
if (state->line_stipple_enable)
dw5 |= GEN6_WM_DW5_LINE_STIPPLE_ENABLE;
dw6 = GEN6_WM_DW6_ZW_INTERP_PIXEL |
GEN6_WM_DW6_MSRASTMODE_OFF_PIXEL |
GEN6_WM_DW6_MSDISPMODE_PERSAMPLE;
if (state->bottom_edge_rule)
dw6 |= GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT;
/*
* assertion that makes sure
*
@@ -508,6 +501,10 @@ rasterizer_init_wm_gen6(const struct ilo_dev_info *dev,
*/
STATIC_ASSERT(GEN6_WM_DW6_MSRASTMODE_OFF_PIXEL == 0 &&
GEN6_WM_DW6_MSDISPMODE_PERSAMPLE == 0);
dw6 = GEN6_WM_DW6_ZW_INTERP_PIXEL;
if (state->bottom_edge_rule)
dw6 |= GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT;
wm->dw_msaa_rast =
(state->multisample) ? GEN6_WM_DW6_MSRASTMODE_ON_PATTERN : 0;
@@ -527,9 +524,19 @@ rasterizer_init_wm_gen7(const struct ilo_dev_info *dev,
ILO_DEV_ASSERT(dev, 7, 7.5);
/*
* assertion that makes sure
*
* dw1 |= wm->dw_msaa_rast;
* dw2 |= wm->dw_msaa_disp;
*
* is valid
*/
STATIC_ASSERT(GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL == 0 &&
GEN7_WM_DW2_MSDISPMODE_PERSAMPLE == 0);
dw1 = GEN7_WM_DW1_ZW_INTERP_PIXEL |
GEN7_WM_DW1_AA_LINE_WIDTH_2_0 |
GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL;
GEN7_WM_DW1_AA_LINE_WIDTH_2_0;
dw2 = 0;
/* same value as in 3DSTATE_SF */
if (state->line_smooth)
@@ -543,19 +550,6 @@ rasterizer_init_wm_gen7(const struct ilo_dev_info *dev,
if (state->bottom_edge_rule)
dw1 |= GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
dw2 = GEN7_WM_DW2_MSDISPMODE_PERSAMPLE;
/*
* assertion that makes sure
*
* dw1 |= wm->dw_msaa_rast;
* dw2 |= wm->dw_msaa_disp;
*
* is valid
*/
STATIC_ASSERT(GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL == 0 &&
GEN7_WM_DW2_MSDISPMODE_PERSAMPLE == 0);
wm->dw_msaa_rast =
(state->multisample) ? GEN7_WM_DW1_MSRASTMODE_ON_PATTERN : 0;
wm->dw_msaa_disp = GEN7_WM_DW2_MSDISPMODE_PERPIXEL;
@@ -565,6 +559,32 @@ rasterizer_init_wm_gen7(const struct ilo_dev_info *dev,
wm->payload[1] = dw2;
}
static uint32_t
rasterizer_get_wm_gen8(const struct ilo_dev_info *dev,
const struct pipe_rasterizer_state *state)
{
uint32_t dw;
ILO_DEV_ASSERT(dev, 8, 8);
dw = GEN7_WM_DW1_ZW_INTERP_PIXEL |
GEN7_WM_DW1_AA_LINE_WIDTH_2_0;
/* same value as in 3DSTATE_SF */
if (state->line_smooth)
dw |= GEN7_WM_DW1_AA_LINE_CAP_1_0;
if (state->poly_stipple_enable)
dw |= GEN7_WM_DW1_POLY_STIPPLE_ENABLE;
if (state->line_stipple_enable)
dw |= GEN7_WM_DW1_LINE_STIPPLE_ENABLE;
if (state->bottom_edge_rule)
dw |= GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
return dw;
}
void
ilo_gpe_init_rasterizer(const struct ilo_dev_info *dev,
const struct pipe_rasterizer_state *state,
@@ -573,7 +593,9 @@ ilo_gpe_init_rasterizer(const struct ilo_dev_info *dev,
rasterizer_init_clip(dev, state, &rasterizer->clip);
if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
rasterizer_init_wm_gen7(dev, state, &rasterizer->wm);
memset(&rasterizer->wm, 0, sizeof(rasterizer->wm));
rasterizer->wm.payload[0] = rasterizer_get_wm_gen8(dev, state);
rasterizer_init_sf_gen8(dev, state, &rasterizer->sf);
} else if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
rasterizer_init_wm_gen7(dev, state, &rasterizer->wm);
@@ -681,6 +703,68 @@ fs_init_cso_gen6(const struct ilo_dev_info *dev,
cso->payload[3] = dw6;
}
static uint32_t
fs_get_wm_gen7(const struct ilo_dev_info *dev,
const struct ilo_shader_state *fs)
{
uint32_t dw;
ILO_DEV_ASSERT(dev, 7, 7.5);
dw = ilo_shader_get_kernel_param(fs,
ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) <<
GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;
/*
* TODO set this bit only when
*
* a) fs writes colors and color is not masked, or
* b) fs writes depth, or
* c) fs or cc kills
*/
dw |= GEN7_WM_DW1_PS_DISPATCH_ENABLE;
/*
* From the Ivy Bridge PRM, volume 2 part 1, page 278:
*
* "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that
* the PS kernel or color calculator has the ability to kill
* (discard) pixels or samples, other than due to depth or stencil
* testing. This bit is required to be ENABLED in the following
* situations:
*
* - The API pixel shader program contains "killpix" or "discard"
* instructions, or other code in the pixel shader kernel that
* can cause the final pixel mask to differ from the pixel mask
* received on dispatch.
*
* - A sampler with chroma key enabled with kill pixel mode is used
* by the pixel shader.
*
* - Any render target has Alpha Test Enable or AlphaToCoverage
* Enable enabled.
*
* - The pixel shader kernel generates and outputs oMask.
*
* Note: As ClipDistance clipping is fully supported in hardware
* and therefore not via PS instructions, there should be no need
* to ENABLE this bit due to ClipDistance clipping."
*/
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
dw |= GEN7_WM_DW1_PS_KILL_PIXEL;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
dw |= GEN7_WM_DW1_PSCDEPTH_ON;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
dw |= GEN7_WM_DW1_PS_USE_DEPTH;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
dw |= GEN7_WM_DW1_PS_USE_W;
return dw;
}
static void
fs_init_cso_gen7(const struct ilo_dev_info *dev,
const struct ilo_shader_state *fs,
@@ -688,7 +772,6 @@ fs_init_cso_gen7(const struct ilo_dev_info *dev,
{
int start_grf, sampler_count, max_threads;
uint32_t dw2, dw4, dw5;
uint32_t wm_interps, wm_dw1;
ILO_DEV_ASSERT(dev, 7, 7.5);
@@ -727,66 +810,83 @@ fs_init_cso_gen7(const struct ilo_dev_info *dev,
0 << GEN7_PS_DW5_URB_GRF_START1__SHIFT |
0 << GEN7_PS_DW5_URB_GRF_START2__SHIFT;
/* FS affects 3DSTATE_WM too */
wm_dw1 = 0;
/*
* TODO set this bit only when
*
* a) fs writes colors and color is not masked, or
* b) fs writes depth, or
* c) fs or cc kills
*/
wm_dw1 |= GEN7_WM_DW1_PS_DISPATCH_ENABLE;
/*
* From the Ivy Bridge PRM, volume 2 part 1, page 278:
*
* "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that
* the PS kernel or color calculator has the ability to kill
* (discard) pixels or samples, other than due to depth or stencil
* testing. This bit is required to be ENABLED in the following
* situations:
*
* - The API pixel shader program contains "killpix" or "discard"
* instructions, or other code in the pixel shader kernel that
* can cause the final pixel mask to differ from the pixel mask
* received on dispatch.
*
* - A sampler with chroma key enabled with kill pixel mode is used
* by the pixel shader.
*
* - Any render target has Alpha Test Enable or AlphaToCoverage
* Enable enabled.
*
* - The pixel shader kernel generates and outputs oMask.
*
* Note: As ClipDistance clipping is fully supported in hardware
* and therefore not via PS instructions, there should be no need
* to ENABLE this bit due to ClipDistance clipping."
*/
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
wm_dw1 |= GEN7_WM_DW1_PS_KILL_PIXEL;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
wm_dw1 |= GEN7_WM_DW1_PSCDEPTH_ON;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
wm_dw1 |= GEN7_WM_DW1_PS_USE_DEPTH;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
wm_dw1 |= GEN7_WM_DW1_PS_USE_W;
wm_interps = ilo_shader_get_kernel_param(fs,
ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
wm_dw1 |= wm_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;
STATIC_ASSERT(Elements(cso->payload) >= 4);
cso->payload[0] = dw2;
cso->payload[1] = dw4;
cso->payload[2] = dw5;
cso->payload[3] = wm_dw1;
cso->payload[3] = fs_get_wm_gen7(dev, fs);
}
static uint32_t
fs_get_psx_gen8(const struct ilo_dev_info *dev,
const struct ilo_shader_state *fs)
{
uint32_t dw;
ILO_DEV_ASSERT(dev, 8, 8);
dw = GEN8_PSX_DW1_DISPATCH_ENABLE;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
dw |= GEN8_PSX_DW1_KILL_PIXEL;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
dw |= GEN8_PSX_DW1_PSCDEPTH_ON;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
dw |= GEN8_PSX_DW1_USE_DEPTH;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
dw |= GEN8_PSX_DW1_USE_W;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
dw |= GEN8_PSX_DW1_ATTR_ENABLE;
return dw;
}
static uint32_t
fs_get_wm_gen8(const struct ilo_dev_info *dev,
const struct ilo_shader_state *fs)
{
ILO_DEV_ASSERT(dev, 8, 8);
return ilo_shader_get_kernel_param(fs,
ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) <<
GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;
}
static void
fs_init_cso_gen8(const struct ilo_dev_info *dev,
const struct ilo_shader_state *fs,
struct ilo_shader_cso *cso)
{
int start_grf, sampler_count;
uint32_t dw3, dw6, dw7;
ILO_DEV_ASSERT(dev, 8, 8);
start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
sampler_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_SAMPLER_COUNT);
dw3 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
dw3 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
/* always 64? */
dw6 = (64 - 2) << GEN8_PS_DW6_MAX_THREADS__SHIFT |
GEN8_PS_DW6_POSOFFSET_NONE;
if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_PCB_CBUF0_SIZE))
dw6 |= GEN8_PS_DW6_PUSH_CONSTANT_ENABLE;
assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
dw6 |= GEN6_PS_DISPATCH_8 << GEN8_PS_DW6_DISPATCH_MODE__SHIFT;
dw7 = start_grf << GEN8_PS_DW7_URB_GRF_START0__SHIFT |
0 << GEN8_PS_DW7_URB_GRF_START1__SHIFT |
0 << GEN8_PS_DW7_URB_GRF_START2__SHIFT;
STATIC_ASSERT(Elements(cso->payload) >= 5);
cso->payload[0] = dw3;
cso->payload[1] = dw6;
cso->payload[2] = dw7;
cso->payload[3] = fs_get_psx_gen8(dev, fs);
cso->payload[4] = fs_get_wm_gen8(dev, fs);
}
void
@@ -794,7 +894,9 @@ ilo_gpe_init_fs_cso(const struct ilo_dev_info *dev,
const struct ilo_shader_state *fs,
struct ilo_shader_cso *cso)
{
if (ilo_dev_gen(dev) >= ILO_GEN(7))
if (ilo_dev_gen(dev) >= ILO_GEN(8))
fs_init_cso_gen8(dev, fs, cso);
else if (ilo_dev_gen(dev) >= ILO_GEN(7))
fs_init_cso_gen7(dev, fs, cso);
else
fs_init_cso_gen6(dev, fs, cso);