OSDN Git Service

Merge branch 'shader-file-reorg'
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / gen6_wm_state.c
1 /*
2  * Copyright © 2009 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Eric Anholt <eric@anholt.net>
25  *
26  */
27
28 #include "brw_context.h"
29 #include "brw_state.h"
30 #include "brw_defines.h"
31 #include "brw_util.h"
32 #include "program/prog_parameter.h"
33 #include "program/prog_statevars.h"
34 #include "intel_batchbuffer.h"
35
36 static void
37 upload_wm_state(struct brw_context *brw)
38 {
39    struct intel_context *intel = &brw->intel;
40    GLcontext *ctx = &intel->ctx;
41    const struct brw_fragment_program *fp =
42       brw_fragment_program_const(brw->fragment_program);
43    unsigned int nr_params = fp->program.Base.Parameters->NumParameters;
44    drm_intel_bo *constant_bo;
45    int i;
46    uint32_t dw2, dw4, dw5, dw6;
47
48    if (fp->use_const_buffer || nr_params == 0) {
49       /* Disable the push constant buffers. */
50       BEGIN_BATCH(5);
51       OUT_BATCH(CMD_3D_CONSTANT_PS_STATE << 16 | (5 - 2));
52       OUT_BATCH(0);
53       OUT_BATCH(0);
54       OUT_BATCH(0);
55       OUT_BATCH(0);
56       ADVANCE_BATCH();
57    } else {
58       /* Updates the ParamaterValues[i] pointers for all parameters of the
59        * basic type of PROGRAM_STATE_VAR.
60        */
61       _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
62
63       constant_bo = drm_intel_bo_alloc(intel->bufmgr, "WM constant_bo",
64                                        nr_params * 4 * sizeof(float),
65                                        4096);
66       drm_intel_gem_bo_map_gtt(constant_bo);
67       for (i = 0; i < nr_params; i++) {
68          memcpy((char *)constant_bo->virtual + i * 4 * sizeof(float),
69                 fp->program.Base.Parameters->ParameterValues[i],
70                 4 * sizeof(float));
71       }
72       drm_intel_gem_bo_unmap_gtt(constant_bo);
73
74       BEGIN_BATCH(5);
75       OUT_BATCH(CMD_3D_CONSTANT_PS_STATE << 16 |
76                 GEN6_CONSTANT_BUFFER_0_ENABLE |
77                 (5 - 2));
78       OUT_RELOC(constant_bo,
79                 I915_GEM_DOMAIN_RENDER, 0, /* XXX: bad domain */
80                 ALIGN(nr_params, 2) / 2 - 1);
81       OUT_BATCH(0);
82       OUT_BATCH(0);
83       OUT_BATCH(0);
84       ADVANCE_BATCH();
85
86       drm_intel_bo_unreference(constant_bo);
87    }
88
89    intel_batchbuffer_emit_mi_flush(intel->batch);
90
91    dw2 = dw4 = dw5 = dw6 = 0;
92    dw4 |= GEN6_WM_STATISTICS_ENABLE;
93    dw5 |= GEN6_WM_LINE_AA_WIDTH_1_0;
94    dw5 |= GEN6_WM_LINE_END_CAP_AA_WIDTH_0_5;
95
96    /* BRW_NEW_NR_SURFACES */
97    dw2 |= brw->wm.nr_surfaces << GEN6_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT;
98
99    /* CACHE_NEW_SAMPLER */
100    dw2 |= (ALIGN(brw->wm.sampler_count, 4) / 4) << GEN6_WM_SAMPLER_COUNT_SHIFT;
101    dw4 |= (brw->wm.prog_data->first_curbe_grf <<
102            GEN6_WM_DISPATCH_START_GRF_SHIFT_0);
103
104    dw5 |= (40 - 1) << GEN6_WM_MAX_THREADS_SHIFT;
105    dw5 |= GEN6_WM_DISPATCH_ENABLE;
106
107    /* BRW_NEW_FRAGMENT_PROGRAM */
108    if (fp->isGLSL)
109       dw5 |= GEN6_WM_8_DISPATCH_ENABLE;
110    else
111       dw5 |= GEN6_WM_16_DISPATCH_ENABLE;
112
113    /* _NEW_LINE */
114    if (ctx->Line.StippleFlag)
115       dw5 |= GEN6_WM_LINE_STIPPLE_ENABLE;
116
117    /* _NEW_POLYGONSTIPPLE */
118    if (ctx->Polygon.StippleFlag)
119       dw5 |= GEN6_WM_POLYGON_STIPPLE_ENABLE;
120
121    /* BRW_NEW_FRAGMENT_PROGRAM */
122    if (fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS))
123       dw5 |= GEN6_WM_USES_SOURCE_DEPTH | GEN6_WM_USES_SOURCE_W;
124    if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
125       dw5 |= GEN6_WM_COMPUTED_DEPTH;
126
127    /* _NEW_COLOR */
128    if (fp->program.UsesKill || ctx->Color.AlphaEnabled)
129       dw5 |= GEN6_WM_KILL_ENABLE;
130
131    /* This should probably be FS inputs read */
132    dw6 |= brw_count_bits(brw->vs.prog_data->outputs_written) <<
133       GEN6_WM_NUM_SF_OUTPUTS_SHIFT;
134
135    BEGIN_BATCH(9);
136    OUT_BATCH(CMD_3D_WM_STATE << 16 | (9 - 2));
137    OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
138    OUT_BATCH(dw2);
139    OUT_BATCH(0); /* scratch space base offset */
140    OUT_BATCH(dw4);
141    OUT_BATCH(dw5);
142    OUT_BATCH(dw6);
143    OUT_BATCH(0); /* kernel 1 pointer */
144    OUT_BATCH(0); /* kernel 2 pointer */
145    ADVANCE_BATCH();
146
147    intel_batchbuffer_emit_mi_flush(intel->batch);
148 }
149
150 const struct brw_tracked_state gen6_wm_state = {
151    .dirty = {
152       .mesa  = _NEW_LINE | _NEW_POLYGONSTIPPLE | _NEW_COLOR,
153       .brw   = (BRW_NEW_CURBE_OFFSETS |
154                 BRW_NEW_FRAGMENT_PROGRAM |
155                 BRW_NEW_NR_WM_SURFACES |
156                 BRW_NEW_URB_FENCE |
157                 BRW_NEW_BATCH),
158       .cache = CACHE_NEW_SAMPLER
159    },
160    .emit = upload_wm_state,
161 };