if (DIRTY(FS) || DIRTY(FRAGMENT_SAMPLERS) ||
DIRTY(BLEND) || DIRTY(DEPTH_STENCIL_ALPHA) ||
DIRTY(RASTERIZER) || session->kernel_bo_changed) {
- const struct ilo_shader *fs = (ilo->fs)? ilo->fs->shader : NULL;
const int num_samplers = ilo->sampler[PIPE_SHADER_FRAGMENT].count;
const bool dual_blend = ilo->blend->dual_blend;
const bool cc_may_kill = (ilo->dsa->alpha.enabled ||
ilo->blend->alpha_to_coverage);
- if (fs)
- assert(!fs->pcb.clip_state_size);
+ if (ilo->fs)
+ assert(!ilo->fs->shader->pcb.clip_state_size);
if (p->dev->gen == ILO_GEN(6) && session->hw_ctx_changed)
gen6_wa_pipe_control_wm_max_threads_stall(p);
- p->gen6_3DSTATE_WM(p->dev, fs, num_samplers,
+ p->gen6_3DSTATE_WM(p->dev, ilo->fs, num_samplers,
ilo->rasterizer, dual_blend, cc_may_kill, p->cp);
}
}
/* 3DSTATE_WM */
if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DEPTH_STENCIL_ALPHA) ||
DIRTY(RASTERIZER)) {
- const struct ilo_shader *fs = (ilo->fs)? ilo->fs->shader : NULL;
const bool cc_may_kill = (ilo->dsa->alpha.enabled ||
ilo->blend->alpha_to_coverage);
- if (fs)
- assert(!fs->pcb.clip_state_size);
+ if (ilo->fs)
+ assert(!ilo->fs->shader->pcb.clip_state_size);
if (p->dev->gen == ILO_GEN(7) && session->hw_ctx_changed)
gen7_wa_pipe_control_wm_max_threads_stall(p);
- p->gen7_3DSTATE_WM(p->dev, fs, ilo->rasterizer, cc_may_kill, p->cp);
+ p->gen7_3DSTATE_WM(p->dev, ilo->fs,
+ ilo->rasterizer, cc_may_kill, p->cp);
}
/* 3DSTATE_BINDING_TABLE_POINTERS_PS */
/* 3DSTATE_PS */
if (DIRTY(FS) || DIRTY(FRAGMENT_SAMPLERS) ||
DIRTY(BLEND) || session->kernel_bo_changed) {
- const struct ilo_shader *fs = (ilo->fs)? ilo->fs->shader : NULL;
const int num_samplers = ilo->sampler[PIPE_SHADER_FRAGMENT].count;
const bool dual_blend = ilo->blend->dual_blend;
- if (fs)
- assert(!fs->pcb.clip_state_size);
+ if (ilo->fs)
+ assert(!ilo->fs->shader->pcb.clip_state_size);
- p->gen7_3DSTATE_PS(p->dev, fs, num_samplers, dual_blend, p->cp);
+ p->gen7_3DSTATE_PS(p->dev, ilo->fs, num_samplers, dual_blend, p->cp);
}
/* 3DSTATE_SCISSOR_STATE_POINTERS */
}
}
+void
+ilo_gpe_init_fs_cso_gen6(const struct ilo_dev_info *dev,
+ const struct ilo_shader_state *fs,
+ struct ilo_shader_cso *cso);
+
+void
+ilo_gpe_init_fs_cso_gen7(const struct ilo_dev_info *dev,
+ const struct ilo_shader_state *fs,
+ struct ilo_shader_cso *cso);
+
+static inline void
+ilo_gpe_init_fs_cso(const struct ilo_dev_info *dev,
+ const struct ilo_shader_state *fs,
+ struct ilo_shader_cso *cso)
+{
+ if (dev->gen >= ILO_GEN(7)) {
+ ilo_gpe_init_fs_cso_gen7(dev, fs, cso);
+ }
+ else {
+ ilo_gpe_init_fs_cso_gen6(dev, fs, cso);
+ }
+}
+
#endif /* ILO_GPE_H */
wm->payload[1] = dw6;
}
-static void
-gen6_emit_3DSTATE_WM(const struct ilo_dev_info *dev,
- const struct ilo_shader *fs,
- int num_samplers,
- const struct ilo_rasterizer_state *rasterizer,
- bool dual_blend, bool cc_may_kill,
- struct ilo_cp *cp)
+void
+ilo_gpe_init_fs_cso_gen6(const struct ilo_dev_info *dev,
+ const struct ilo_shader_state *fs,
+ struct ilo_shader_cso *cso)
{
- const uint32_t cmd = ILO_GPE_CMD(0x3, 0x0, 0x14);
- const uint8_t cmd_len = 9;
- const int num_samples = 1;
+ int start_grf, input_count, interps, max_threads;
uint32_t dw2, dw4, dw5, dw6;
- int max_threads;
ILO_GPE_VALID_GEN(dev, 6, 6);
+ start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
+ input_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT);
+ interps = ilo_shader_get_kernel_param(fs,
+ ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
+
/* see brwCreateContext() */
max_threads = (dev->gt == 2) ? 80 : 40;
- if (!fs) {
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- /* honor the valid range even if dispatching is disabled */
- ilo_cp_write(cp, (max_threads - 1) << GEN6_WM_MAX_THREADS_SHIFT);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_end(cp);
-
- return;
- }
-
- dw2 = (num_samplers + 3) / 4 << GEN6_WM_SAMPLER_COUNT_SHIFT;
- if (false)
- dw2 |= GEN6_WM_FLOATING_POINT_MODE_ALT;
+ dw2 = (true) ? 0 : GEN6_WM_FLOATING_POINT_MODE_ALT;
- dw4 = fs->in.start_grf << GEN6_WM_DISPATCH_START_GRF_SHIFT_0 |
+ dw4 = start_grf << GEN6_WM_DISPATCH_START_GRF_SHIFT_0 |
0 << GEN6_WM_DISPATCH_START_GRF_SHIFT_1 |
0 << GEN6_WM_DISPATCH_START_GRF_SHIFT_2;
- if (true) {
- dw4 |= GEN6_WM_STATISTICS_ENABLE;
- }
- else {
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 248:
- *
- * "This bit (Statistics Enable) must be disabled if either of these
- * bits is set: Depth Buffer Clear , Hierarchical Depth Buffer
- * Resolve Enable or Depth Buffer Resolve Enable."
- */
- dw4 |= GEN6_WM_DEPTH_CLEAR;
- dw4 |= GEN6_WM_DEPTH_RESOLVE;
- dw4 |= GEN6_WM_HIERARCHICAL_DEPTH_RESOLVE;
- }
-
- dw5 = rasterizer->wm.payload[0];
- dw6 = rasterizer->wm.payload[1];
-
- dw5 |= (max_threads - 1) << GEN6_WM_MAX_THREADS_SHIFT;
+ dw5 = (max_threads - 1) << GEN6_WM_MAX_THREADS_SHIFT;
/*
* From the Sandy Bridge PRM, volume 2 part 1, page 275:
* therefore not via PS instructions, there should be no need to
* ENABLE this bit due to ClipDistance clipping."
*/
- if (fs->has_kill || cc_may_kill)
+ if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
dw5 |= GEN6_WM_KILL_ENABLE;
/*
*
* TODO This is not checked yet.
*/
- if (fs->out.has_pos)
+ if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
dw5 |= GEN6_WM_COMPUTED_DEPTH;
- if (fs->in.has_pos)
- dw5 |= GEN6_WM_USES_SOURCE_DEPTH | GEN6_WM_USES_SOURCE_W;
+ if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
+ dw5 |= GEN6_WM_USES_SOURCE_DEPTH;
+
+ if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
+ dw5 |= GEN6_WM_USES_SOURCE_W;
/*
- * Set this bit if
+ * TODO set this bit only when
*
* a) fs writes colors and color is not masked, or
* b) fs writes depth, or
if (true)
dw5 |= GEN6_WM_DISPATCH_ENABLE;
+ assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
+ dw5 |= GEN6_WM_8_DISPATCH_ENABLE;
+
+ dw6 = input_count << GEN6_WM_NUM_SF_OUTPUTS_SHIFT |
+ GEN6_WM_POSOFFSET_NONE |
+ interps << GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
+
+ STATIC_ASSERT(Elements(cso->payload) >= 4);
+ cso->payload[0] = dw2;
+ cso->payload[1] = dw4;
+ cso->payload[2] = dw5;
+ cso->payload[3] = dw6;
+}
+
+static void
+gen6_emit_3DSTATE_WM(const struct ilo_dev_info *dev,
+ const struct ilo_shader_state *fs,
+ int num_samplers,
+ const struct ilo_rasterizer_state *rasterizer,
+ bool dual_blend, bool cc_may_kill,
+ struct ilo_cp *cp)
+{
+ const uint32_t cmd = ILO_GPE_CMD(0x3, 0x0, 0x14);
+ const uint8_t cmd_len = 9;
+ const int num_samples = 1;
+ const struct ilo_shader_cso *fs_cso;
+ uint32_t dw2, dw4, dw5, dw6;
+
+ ILO_GPE_VALID_GEN(dev, 6, 6);
+
+ if (!fs) {
+ /* see brwCreateContext() */
+ const int max_threads = (dev->gt == 2) ? 80 : 40;
+
+ ilo_cp_begin(cp, cmd_len);
+ ilo_cp_write(cp, cmd | (cmd_len - 2));
+ ilo_cp_write(cp, 0);
+ ilo_cp_write(cp, 0);
+ ilo_cp_write(cp, 0);
+ ilo_cp_write(cp, 0);
+ /* honor the valid range even if dispatching is disabled */
+ ilo_cp_write(cp, (max_threads - 1) << GEN6_WM_MAX_THREADS_SHIFT);
+ ilo_cp_write(cp, 0);
+ ilo_cp_write(cp, 0);
+ ilo_cp_write(cp, 0);
+ ilo_cp_end(cp);
+
+ return;
+ }
+
+ fs_cso = ilo_shader_get_kernel_cso(fs);
+ dw2 = fs_cso->payload[0];
+ dw4 = fs_cso->payload[1];
+ dw5 = fs_cso->payload[2];
+ dw6 = fs_cso->payload[3];
+
+ dw2 |= (num_samplers + 3) / 4 << GEN6_WM_SAMPLER_COUNT_SHIFT;
+
+ if (true) {
+ dw4 |= GEN6_WM_STATISTICS_ENABLE;
+ }
+ else {
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 248:
+ *
+ * "This bit (Statistics Enable) must be disabled if either of these
+ * bits is set: Depth Buffer Clear , Hierarchical Depth Buffer
+ * Resolve Enable or Depth Buffer Resolve Enable."
+ */
+ dw4 |= GEN6_WM_DEPTH_CLEAR;
+ dw4 |= GEN6_WM_DEPTH_RESOLVE;
+ dw4 |= GEN6_WM_HIERARCHICAL_DEPTH_RESOLVE;
+ }
+
+ if (cc_may_kill) {
+ dw5 |= GEN6_WM_KILL_ENABLE |
+ GEN6_WM_DISPATCH_ENABLE;
+ }
+
if (dual_blend)
dw5 |= GEN6_WM_DUAL_SOURCE_BLEND_ENABLE;
- if (fs->dispatch_16)
- dw5 |= GEN6_WM_16_DISPATCH_ENABLE;
- else
- dw5 |= GEN6_WM_8_DISPATCH_ENABLE;
+ dw5 |= rasterizer->wm.payload[0];
- dw6 |= fs->in.count << GEN6_WM_NUM_SF_OUTPUTS_SHIFT |
- GEN6_WM_POSOFFSET_NONE |
- fs->in.barycentric_interpolation_mode <<
- GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
+ dw6 |= rasterizer->wm.payload[1];
if (num_samples > 1) {
dw6 |= rasterizer->wm.dw_msaa_rast |
ilo_cp_begin(cp, cmd_len);
ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, fs->cache_offset);
+ ilo_cp_write(cp, ilo_shader_get_kernel_offset(fs));
ilo_cp_write(cp, dw2);
ilo_cp_write(cp, 0); /* scratch */
ilo_cp_write(cp, dw4);
typedef void
(*ilo_gpe_gen6_3DSTATE_WM)(const struct ilo_dev_info *dev,
- const struct ilo_shader *fs,
+ const struct ilo_shader_state *fs,
int num_samplers,
const struct ilo_rasterizer_state *rasterizer,
bool dual_blend, bool cc_may_kill,
wm->payload[1] = dw2;
}
+void
+ilo_gpe_init_fs_cso_gen7(const struct ilo_dev_info *dev,
+ const struct ilo_shader_state *fs,
+ struct ilo_shader_cso *cso)
+{
+ int start_grf, max_threads;
+ uint32_t dw2, dw4, dw5;
+ uint32_t wm_interps, wm_dw1;
+
+ ILO_GPE_VALID_GEN(dev, 7, 7);
+
+ start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
+ /* see brwCreateContext() */
+ max_threads = (dev->gt == 2) ? 172 : 48;
+
+ dw2 = (true) ? 0 : GEN7_PS_FLOATING_POINT_MODE_ALT;
+
+ dw4 = (max_threads - 1) << IVB_PS_MAX_THREADS_SHIFT |
+ GEN7_PS_POSOFFSET_NONE;
+
+ if (false)
+ dw4 |= GEN7_PS_PUSH_CONSTANT_ENABLE;
+
+ if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
+ dw4 |= GEN7_PS_ATTRIBUTE_ENABLE;
+
+ assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
+ dw4 |= GEN7_PS_8_DISPATCH_ENABLE;
+
+ dw5 = start_grf << GEN7_PS_DISPATCH_START_GRF_SHIFT_0 |
+ 0 << GEN7_PS_DISPATCH_START_GRF_SHIFT_1 |
+ 0 << GEN7_PS_DISPATCH_START_GRF_SHIFT_2;
+
+ /* 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_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_KILL_ENABLE;
+
+ if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
+ wm_dw1 |= GEN7_WM_PSCDEPTH_ON;
+
+ if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
+ wm_dw1 |= GEN7_WM_USES_SOURCE_DEPTH;
+
+ if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
+ wm_dw1 |= GEN7_WM_USES_SOURCE_W;
+
+ wm_interps = ilo_shader_get_kernel_param(fs,
+ ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
+
+ wm_dw1 |= wm_interps << GEN7_WM_BARYCENTRIC_INTERPOLATION_MODE_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
gen7_emit_3DSTATE_WM(const struct ilo_dev_info *dev,
- const struct ilo_shader *fs,
+ const struct ilo_shader_state *fs,
const struct ilo_rasterizer_state *rasterizer,
bool cc_may_kill,
struct ilo_cp *cp)
}
if (fs) {
- /*
- * Set this bit if
- *
- * a) fs writes colors and color is not masked, or
- * b) fs writes depth, or
- * c) fs or cc kills
- */
- dw1 |= GEN7_WM_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 (fs->has_kill || cc_may_kill)
- dw1 |= GEN7_WM_KILL_ENABLE;
-
- if (fs->out.has_pos)
- dw1 |= GEN7_WM_PSCDEPTH_ON;
- if (fs->in.has_pos)
- dw1 |= GEN7_WM_USES_SOURCE_DEPTH | GEN7_WM_USES_SOURCE_W;
+ const struct ilo_shader_cso *fs_cso = ilo_shader_get_kernel_cso(fs);
- dw1 |= fs->in.barycentric_interpolation_mode <<
- GEN7_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
+ dw1 |= fs_cso->payload[3];
}
- else if (cc_may_kill) {
- dw1 |= GEN7_WM_DISPATCH_ENABLE |
- GEN7_WM_KILL_ENABLE;
+
+ if (cc_may_kill) {
+ dw1 |= GEN7_WM_DISPATCH_ENABLE |
+ GEN7_WM_KILL_ENABLE;
}
if (num_samples > 1) {
static void
gen7_emit_3DSTATE_PS(const struct ilo_dev_info *dev,
- const struct ilo_shader *fs,
+ const struct ilo_shader_state *fs,
int num_samplers, bool dual_blend,
struct ilo_cp *cp)
{
const uint32_t cmd = ILO_GPE_CMD(0x3, 0x0, 0x20);
const uint8_t cmd_len = 8;
+ const struct ilo_shader_cso *cso;
uint32_t dw2, dw4, dw5;
- int max_threads;
ILO_GPE_VALID_GEN(dev, 7, 7);
- /* see brwCreateContext() */
- max_threads = (dev->gt == 2) ? 172 : 48;
-
if (!fs) {
+ /* see brwCreateContext() */
+ const int max_threads = (dev->gt == 2) ? 172 : 48;
+
ilo_cp_begin(cp, cmd_len);
ilo_cp_write(cp, cmd | (cmd_len - 2));
ilo_cp_write(cp, 0);
return;
}
- dw2 = (num_samplers + 3) / 4 << GEN7_PS_SAMPLER_COUNT_SHIFT |
- 0 << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT;
- if (false)
- dw2 |= GEN7_PS_FLOATING_POINT_MODE_ALT;
+ cso = ilo_shader_get_kernel_cso(fs);
+ dw2 = cso->payload[0];
+ dw4 = cso->payload[1];
+ dw5 = cso->payload[2];
- dw4 = (max_threads - 1) << IVB_PS_MAX_THREADS_SHIFT |
- GEN7_PS_POSOFFSET_NONE;
+ dw2 |= (num_samplers + 3) / 4 << GEN7_PS_SAMPLER_COUNT_SHIFT;
- if (false)
- dw4 |= GEN7_PS_PUSH_CONSTANT_ENABLE;
- if (fs->in.count)
- dw4 |= GEN7_PS_ATTRIBUTE_ENABLE;
if (dual_blend)
dw4 |= GEN7_PS_DUAL_SOURCE_BLEND_ENABLE;
- if (fs->dispatch_16)
- dw4 |= GEN7_PS_16_DISPATCH_ENABLE;
- else
- dw4 |= GEN7_PS_8_DISPATCH_ENABLE;
-
- dw5 = fs->in.start_grf << GEN7_PS_DISPATCH_START_GRF_SHIFT_0 |
- 0 << GEN7_PS_DISPATCH_START_GRF_SHIFT_1 |
- 0 << GEN7_PS_DISPATCH_START_GRF_SHIFT_2;
-
ilo_cp_begin(cp, cmd_len);
ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, fs->cache_offset);
+ ilo_cp_write(cp, ilo_shader_get_kernel_offset(fs));
ilo_cp_write(cp, dw2);
ilo_cp_write(cp, 0); /* scratch */
ilo_cp_write(cp, dw4);
typedef void
(*ilo_gpe_gen7_3DSTATE_WM)(const struct ilo_dev_info *dev,
- const struct ilo_shader *fs,
+ const struct ilo_shader_state *fs,
const struct ilo_rasterizer_state *rasterizer,
bool cc_may_kill,
struct ilo_cp *cp);
typedef void
(*ilo_gpe_gen7_3DSTATE_PS)(const struct ilo_dev_info *dev,
- const struct ilo_shader *fs,
+ const struct ilo_shader_state *fs,
int num_samplers, bool dual_blend,
struct ilo_cp *cp);
case PIPE_SHADER_GEOMETRY:
ilo_gpe_init_gs_cso(state->info.dev, state, &sh->cso);
break;
+ case PIPE_SHADER_FRAGMENT:
+ ilo_gpe_init_fs_cso(state->info.dev, state, &sh->cso);
+ break;
default:
break;
}