From a924d69b57a82c02f2d4fba3fc0b31bf6a4f744e Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 2 Feb 2011 16:00:08 -0800 Subject: [PATCH] i965: Initial Ivybridge WM/PS state setup. Copied from gen6_wm_state.c. The main change from Sandybridge seems to be that 3DSTATE_WM was split into two separate state packet commands: 3DSTATE_WM and 3DSTATE_PS. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/Makefile | 3 +- src/mesa/drivers/dri/i965/brw_defines.h | 71 ++++++ src/mesa/drivers/dri/i965/brw_state.h | 3 + src/mesa/drivers/dri/i965/brw_state_upload.c | 5 +- src/mesa/drivers/dri/i965/gen7_wm_state.c | 243 +++++++++++++++++++ 5 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 src/mesa/drivers/dri/i965/gen7_wm_state.c diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index bcfa01249ab..efe0871aa2e 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -98,7 +98,8 @@ DRIVER_SOURCES = \ gen6_vs_state.c \ gen6_wm_state.c \ gen7_sf_state.c \ - gen7_urb.c + gen7_urb.c \ + gen7_wm_state.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 4dafc28b57a..c569995e112 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -1134,6 +1134,77 @@ # 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 diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index a37ff2457f2..6125aea8373 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -111,9 +111,12 @@ extern const struct brw_tracked_state gen6_vs_constants; extern const struct brw_tracked_state gen6_vs_state; extern const struct brw_tracked_state gen6_wm_constants; extern const struct brw_tracked_state gen6_wm_state; +extern const struct brw_tracked_state gen7_ps_state; extern const struct brw_tracked_state gen7_sbe_state; extern const struct brw_tracked_state gen7_sf_state; extern const struct brw_tracked_state gen7_urb; +extern const struct brw_tracked_state gen7_wm_constants; +extern const struct brw_tracked_state gen7_wm_state; /*********************************************************************** * brw_state.c diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index e2c690ee568..accc8d47b54 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -200,7 +200,7 @@ const struct brw_tracked_state *gen7_atoms[] = &brw_vs_constants, /* Before vs_surfaces and constant_buffer */ &brw_wm_constants, /* Before wm_surfaces and constant_buffer */ &gen6_vs_constants, /* Before vs_state */ - &gen6_wm_constants, /* Before wm_state */ + &gen7_wm_constants, /* Before wm_state */ &brw_vs_surfaces, /* must do before unit */ &brw_wm_constant_surface, /* must do before wm surfaces/bind bo */ @@ -215,7 +215,8 @@ const struct brw_tracked_state *gen7_atoms[] = &gen6_clip_state, &gen7_sbe_state, &gen7_sf_state, - &gen6_wm_state, + &gen7_wm_state, + &gen7_ps_state, &gen6_scissor_state, diff --git a/src/mesa/drivers/dri/i965/gen7_wm_state.c b/src/mesa/drivers/dri/i965/gen7_wm_state.c new file mode 100644 index 00000000000..9d5a71fda4e --- /dev/null +++ b/src/mesa/drivers/dri/i965/gen7_wm_state.c @@ -0,0 +1,243 @@ +/* + * 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 +#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, +}; -- 2.30.2