# define GEN6_CONSTANT_BUFFER_1_ENABLE (1 << 13)
# define GEN6_CONSTANT_BUFFER_0_ENABLE (1 << 12)
+/* 3DSTATE_WM for Gen7 */
+/* DW1 */
+# define GEN7_WM_STATISTICS_ENABLE (1 << 31)
+# define GEN7_WM_DEPTH_CLEAR (1 << 30)
+# define GEN7_WM_DISPATCH_ENABLE (1 << 29)
+# define GEN6_WM_DEPTH_RESOLVE (1 << 28)
+# define GEN7_WM_HIERARCHICAL_DEPTH_RESOLVE (1 << 27)
+# define GEN7_WM_KILL_ENABLE (1 << 25)
+# define GEN7_WM_PSCDEPTH_OFF (0 << 23)
+# define GEN7_WM_PSCDEPTH_ON (1 << 23)
+# define GEN7_WM_PSCDEPTH_ON_GE (2 << 23)
+# define GEN7_WM_PSCDEPTH_ON_LE (3 << 23)
+# define GEN7_WM_USES_SOURCE_DEPTH (1 << 20)
+# define GEN7_WM_USES_SOURCE_W (1 << 19)
+# define GEN7_WM_POSITION_ZW_PIXEL (0 << 17)
+# define GEN7_WM_POSITION_ZW_CENTROID (2 << 17)
+# define GEN7_WM_POSITION_ZW_SAMPLE (3 << 17)
+# define GEN7_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 16)
+# define GEN7_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 15)
+# define GEN7_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 14)
+# define GEN7_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 13)
+# define GEN7_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 12)
+# define GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 11)
+# define GEN7_WM_USES_INPUT_COVERAGE_MASK (1 << 10)
+# define GEN7_WM_LINE_END_CAP_AA_WIDTH_0_5 (0 << 8)
+# define GEN7_WM_LINE_END_CAP_AA_WIDTH_1_0 (1 << 8)
+# define GEN7_WM_LINE_END_CAP_AA_WIDTH_2_0 (2 << 8)
+# define GEN7_WM_LINE_END_CAP_AA_WIDTH_4_0 (3 << 8)
+# define GEN7_WM_LINE_AA_WIDTH_0_5 (0 << 6)
+# define GEN7_WM_LINE_AA_WIDTH_1_0 (1 << 6)
+# define GEN7_WM_LINE_AA_WIDTH_2_0 (2 << 6)
+# define GEN7_WM_LINE_AA_WIDTH_4_0 (3 << 6)
+# define GEN7_WM_POLYGON_STIPPLE_ENABLE (1 << 4)
+# define GEN7_WM_LINE_STIPPLE_ENABLE (1 << 3)
+# define GEN7_WM_POINT_RASTRULE_UPPER_RIGHT (1 << 2)
+# define GEN7_WM_MSRAST_OFF_PIXEL (0 << 0)
+# define GEN7_WM_MSRAST_OFF_PATTERN (1 << 0)
+# define GEN7_WM_MSRAST_ON_PIXEL (2 << 0)
+# define GEN7_WM_MSRAST_ON_PATTERN (3 << 0)
+/* DW2 */
+# define GEN7_WM_MSDISPMODE_PERPIXEL (1 << 31)
+
+#define _3DSTATE_PS 0x7820 /* GEN7+ */
+/* DW1: kernel pointer */
+/* DW2 */
+# define GEN7_PS_SPF_MODE (1 << 31)
+# define GEN7_PS_VECTOR_MASK_ENABLE (1 << 30)
+# define GEN7_PS_SAMPLER_COUNT_SHIFT 27
+# define GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT 18
+# define GEN7_PS_FLOATING_POINT_MODE_IEEE_754 (0 << 16)
+# define GEN7_PS_FLOATING_POINT_MODE_ALT (1 << 16)
+/* DW3: scratch space */
+/* DW4 */
+# define GEN7_PS_MAX_THREADS_SHIFT 23
+# define GEN7_PS_PUSH_CONSTANT_ENABLE (1 << 11)
+# define GEN7_PS_ATTRIBUTE_ENABLE (1 << 10)
+# define GEN7_PS_OMASK_TO_RENDER_TARGET (1 << 9)
+# define GEN7_PS_DUAL_SOURCE_BLEND_ENABLE (1 << 7)
+# define GEN7_PS_POSOFFSET_NONE (0 << 3)
+# define GEN7_PS_POSOFFSET_CENTROID (2 << 3)
+# define GEN7_PS_POSOFFSET_SAMPLE (3 << 3)
+# define GEN7_PS_32_DISPATCH_ENABLE (1 << 2)
+# define GEN7_PS_16_DISPATCH_ENABLE (1 << 1)
+# define GEN7_PS_8_DISPATCH_ENABLE (1 << 0)
+/* DW5 */
+# define GEN7_PS_DISPATCH_START_GRF_SHIFT_0 16
+# define GEN7_PS_DISPATCH_START_GRF_SHIFT_1 8
+# define GEN7_PS_DISPATCH_START_GRF_SHIFT_2 0
+/* DW6: kernel 1 pointer */
+/* DW7: kernel 2 pointer */
+
#define _3DSTATE_SAMPLE_MASK 0x7818 /* GEN6+ */
#define _3DSTATE_DRAWING_RECTANGLE 0x7900
--- /dev/null
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#include <stdbool.h>
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_util.h"
+#include "brw_wm.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+#include "intel_batchbuffer.h"
+
+static void
+gen7_prepare_wm_constants(struct brw_context *brw)
+{
+ struct intel_context *intel = &brw->intel;
+ struct gl_context *ctx = &intel->ctx;
+ const struct brw_fragment_program *fp =
+ brw_fragment_program_const(brw->fragment_program);
+
+ /* Updates the ParameterValues[i] pointers for all parameters of the
+ * basic type of PROGRAM_STATE_VAR.
+ */
+ /* XXX: Should this happen somewhere before to get our state flag set? */
+ _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
+
+ /* BRW_NEW_FRAGMENT_PROGRAM */
+ if (brw->wm.prog_data->nr_params != 0) {
+ float *constants;
+ unsigned int i;
+
+ constants = brw_state_batch(brw,
+ brw->wm.prog_data->nr_params *
+ sizeof(float),
+ 32, &brw->wm.push_const_offset);
+
+ for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
+ constants[i] = convert_param(brw->wm.prog_data->param_convert[i],
+ *brw->wm.prog_data->param[i]);
+ }
+
+ if (0) {
+ printf("WM constants:\n");
+ for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
+ if ((i & 7) == 0)
+ printf("g%d: ", brw->wm.prog_data->first_curbe_grf + i / 8);
+ printf("%8f ", constants[i]);
+ if ((i & 7) == 7)
+ printf("\n");
+ }
+ if ((i & 7) != 0)
+ printf("\n");
+ printf("\n");
+ }
+ }
+}
+
+const struct brw_tracked_state gen7_wm_constants = {
+ .dirty = {
+ .mesa = _NEW_PROGRAM_CONSTANTS,
+ .brw = (BRW_NEW_BATCH | BRW_NEW_FRAGMENT_PROGRAM),
+ .cache = 0,
+ },
+ .prepare = gen7_prepare_wm_constants,
+};
+
+static void
+upload_wm_state(struct brw_context *brw)
+{
+ struct intel_context *intel = &brw->intel;
+ struct gl_context *ctx = &intel->ctx;
+ const struct brw_fragment_program *fp =
+ brw_fragment_program_const(brw->fragment_program);
+ bool writes_depth = false;
+ uint32_t dw1;
+
+ dw1 = 0;
+ dw1 |= GEN7_WM_STATISTICS_ENABLE;
+ dw1 |= GEN7_WM_LINE_AA_WIDTH_1_0;
+ dw1 |= GEN7_WM_LINE_END_CAP_AA_WIDTH_0_5;
+
+ /* _NEW_LINE */
+ if (ctx->Line.StippleFlag)
+ dw1 |= GEN7_WM_LINE_STIPPLE_ENABLE;
+
+ /* _NEW_POLYGONSTIPPLE */
+ if (ctx->Polygon.StippleFlag)
+ dw1 |= GEN7_WM_POLYGON_STIPPLE_ENABLE;
+
+ /* BRW_NEW_FRAGMENT_PROGRAM */
+ if (fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS))
+ dw1 |= GEN7_WM_USES_SOURCE_DEPTH | GEN7_WM_USES_SOURCE_W;
+ if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
+ writes_depth = true;
+ dw1 |= GEN7_WM_PSCDEPTH_ON;
+ }
+
+ /* _NEW_COLOR */
+ if (fp->program.UsesKill || ctx->Color.AlphaEnabled)
+ dw1 |= GEN7_WM_KILL_ENABLE;
+
+ /* _NEW_BUFFERS */
+ if (brw_color_buffer_write_enabled(brw) || writes_depth ||
+ dw1 & GEN7_WM_KILL_ENABLE) {
+ dw1 |= GEN7_WM_DISPATCH_ENABLE;
+ }
+
+ dw1 |= GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
+
+ BEGIN_BATCH(3);
+ OUT_BATCH(_3DSTATE_WM << 16 | (3 - 2));
+ OUT_BATCH(dw1);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+}
+
+const struct brw_tracked_state gen7_wm_state = {
+ .dirty = {
+ .mesa = (_NEW_LINE | _NEW_POLYGON | _NEW_POLYGONSTIPPLE |
+ _NEW_COLOR | _NEW_BUFFERS),
+ .brw = (BRW_NEW_CURBE_OFFSETS |
+ BRW_NEW_FRAGMENT_PROGRAM |
+ BRW_NEW_NR_WM_SURFACES |
+ BRW_NEW_URB_FENCE |
+ BRW_NEW_BATCH),
+ .cache = 0,
+ },
+ .emit = upload_wm_state,
+};
+
+static void
+upload_ps_state(struct brw_context *brw)
+{
+ struct intel_context *intel = &brw->intel;
+ uint32_t dw2, dw4, dw5;
+
+ /* CACHE_NEW_WM_PROG */
+ if (brw->wm.prog_data->nr_params == 0) {
+ /* Disable the push constant buffers. */
+ BEGIN_BATCH(7);
+ OUT_BATCH(_3DSTATE_CONSTANT_PS << 16 | (7 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ } else {
+ BEGIN_BATCH(7);
+ OUT_BATCH(_3DSTATE_CONSTANT_PS << 16 | (7 - 2));
+
+ OUT_BATCH(ALIGN(brw->wm.prog_data->nr_params,
+ brw->wm.prog_data->dispatch_width) / 8);
+ OUT_BATCH(0);
+ /* Pointer to the WM constant buffer. Covered by the set of
+ * state flags from gen7_prepare_wm_constants
+ */
+ OUT_BATCH(brw->wm.push_const_offset);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ }
+
+ dw2 = dw4 = dw5 = 0;
+
+ dw2 |= (ALIGN(brw->wm.sampler_count, 4) / 4) << GEN7_PS_SAMPLER_COUNT_SHIFT;
+
+ /* BRW_NEW_NR_WM_SURFACES */
+ dw2 |= brw->wm.nr_surfaces << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT;
+
+ /* OpenGL non-ieee floating point mode */
+ dw2 |= GEN7_PS_FLOATING_POINT_MODE_ALT;
+
+ /* CACHE_NEW_SAMPLER */
+ dw4 |= (brw->wm_max_threads - 1) << GEN7_PS_MAX_THREADS_SHIFT;
+
+ /* CACHE_NEW_WM_PROG */
+ if (brw->wm.prog_data->nr_params > 0)
+ dw4 |= GEN7_PS_PUSH_CONSTANT_ENABLE;
+
+ /* BRW_NEW_FRAGMENT_PROGRAM */
+ if (brw->fragment_program->Base.InputsRead != 0)
+ dw4 |= GEN7_PS_ATTRIBUTE_ENABLE;
+
+ if (brw->wm.prog_data->dispatch_width == 8)
+ dw4 |= GEN7_PS_8_DISPATCH_ENABLE;
+ else
+ dw4 |= GEN7_PS_16_DISPATCH_ENABLE;
+
+ /* BRW_NEW_CURBE_OFFSETS */
+ dw5 |= (brw->wm.prog_data->first_curbe_grf <<
+ GEN7_PS_DISPATCH_START_GRF_SHIFT_0);
+
+ BEGIN_BATCH(8);
+ OUT_BATCH(_3DSTATE_PS << 16 | (8 - 2));
+ OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+ OUT_BATCH(dw2);
+ OUT_BATCH(0); /* scratch space base offset */
+ OUT_BATCH(dw4);
+ OUT_BATCH(dw5);
+ /* FINISHME: need to upload the SIMD16 program */
+ OUT_BATCH(0); /* kernel 1 pointer */
+ OUT_BATCH(0); /* kernel 2 pointer */
+ ADVANCE_BATCH();
+}
+
+const struct brw_tracked_state gen7_ps_state = {
+ .dirty = {
+ .mesa = (_NEW_LINE | _NEW_POLYGON | _NEW_POLYGONSTIPPLE |
+ _NEW_PROGRAM_CONSTANTS),
+ .brw = (BRW_NEW_CURBE_OFFSETS |
+ BRW_NEW_FRAGMENT_PROGRAM |
+ BRW_NEW_NR_WM_SURFACES |
+ BRW_NEW_URB_FENCE |
+ BRW_NEW_BATCH),
+ .cache = (CACHE_NEW_SAMPLER |
+ CACHE_NEW_WM_PROG)
+ },
+ .emit = upload_ps_state,
+};