From 6366fbc1a8055b437a97acf160596514885df6e7 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 26 Jan 2015 18:06:00 +0800 Subject: [PATCH] ilo: update WM and PS related functions for Gen8 --- .../drivers/ilo/ilo_builder_3d_bottom.h | 86 ++++++ src/gallium/drivers/ilo/ilo_state_3d_bottom.c | 254 ++++++++++++------ 2 files changed, 264 insertions(+), 76 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h index 958240a5288..9a85f2339fa 100644 --- a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h +++ b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h @@ -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, diff --git a/src/gallium/drivers/ilo/ilo_state_3d_bottom.c b/src/gallium/drivers/ilo/ilo_state_3d_bottom.c index a78c6900951..bd4e1149fc6 100644 --- a/src/gallium/drivers/ilo/ilo_state_3d_bottom.c +++ b/src/gallium/drivers/ilo/ilo_state_3d_bottom.c @@ -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; + STATIC_ASSERT(Elements(cso->payload) >= 4); + cso->payload[0] = dw2; + cso->payload[1] = dw4; + cso->payload[2] = dw5; + cso->payload[3] = fs_get_wm_gen7(dev, fs); +} - /* - * 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; +static uint32_t +fs_get_psx_gen8(const struct ilo_dev_info *dev, + const struct ilo_shader_state *fs) +{ + uint32_t dw; - /* - * 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; + ILO_DEV_ASSERT(dev, 8, 8); - if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z)) - wm_dw1 |= GEN7_WM_DW1_PSCDEPTH_ON; + 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)) - wm_dw1 |= GEN7_WM_DW1_PS_USE_DEPTH; - + dw |= GEN8_PSX_DW1_USE_DEPTH; if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W)) - wm_dw1 |= GEN7_WM_DW1_PS_USE_W; + dw |= GEN8_PSX_DW1_USE_W; + if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT)) + dw |= GEN8_PSX_DW1_ATTR_ENABLE; - wm_interps = ilo_shader_get_kernel_param(fs, - ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS); + 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); - wm_dw1 |= wm_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT; + return ilo_shader_get_kernel_param(fs, + ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) << + 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; +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); -- 2.30.2