Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* |
2 | * Copyright © 2012 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 | |||
24 | #include "intel_batchbuffer.h" |
||
25 | |||
26 | #include "brw_context.h" |
||
27 | #include "brw_defines.h" |
||
28 | |||
29 | /* Sample positions: |
||
30 | * 2 6 a e |
||
31 | * 2 0 |
||
32 | * 6 1 |
||
33 | * a 2 |
||
34 | * e 3 |
||
35 | */ |
||
36 | static uint32_t |
||
37 | sample_positions_4x[] = { 0xae2ae662 }; |
||
38 | /* Sample positions are based on a solution to the "8 queens" puzzle. |
||
39 | * Rationale: in a solution to the 8 queens puzzle, no two queens share |
||
40 | * a row, column, or diagonal. This is a desirable property for samples |
||
41 | * in a multisampling pattern, because it ensures that the samples are |
||
42 | * relatively uniformly distributed through the pixel. |
||
43 | * |
||
44 | * There are several solutions to the 8 queens puzzle (see |
||
45 | * http://en.wikipedia.org/wiki/Eight_queens_puzzle). This solution was |
||
46 | * chosen because it has a queen close to the center; this should |
||
47 | * improve the accuracy of centroid interpolation, since the hardware |
||
48 | * implements centroid interpolation by choosing the centermost sample |
||
49 | * that overlaps with the primitive being drawn. |
||
50 | * |
||
51 | * Note: from the Ivy Bridge PRM, Vol2 Part1 p304 (3DSTATE_MULTISAMPLE: |
||
52 | * Programming Notes): |
||
53 | * |
||
54 | * "When programming the sample offsets (for NUMSAMPLES_4 or _8 and |
||
55 | * MSRASTMODE_xxx_PATTERN), the order of the samples 0 to 3 (or 7 |
||
56 | * for 8X) must have monotonically increasing distance from the |
||
57 | * pixel center. This is required to get the correct centroid |
||
58 | * computation in the device." |
||
59 | * |
||
60 | * Sample positions: |
||
61 | * 1 3 5 7 9 b d f |
||
62 | * 1 5 |
||
63 | * 3 2 |
||
64 | * 5 6 |
||
65 | * 7 4 |
||
66 | * 9 0 |
||
67 | * b 3 |
||
68 | * d 1 |
||
69 | * f 7 |
||
70 | */ |
||
71 | static uint32_t |
||
72 | sample_positions_8x[] = { 0xdbb39d79, 0x3ff55117 }; |
||
73 | |||
74 | |||
75 | void |
||
76 | gen6_get_sample_position(struct gl_context *ctx, |
||
77 | struct gl_framebuffer *fb, |
||
78 | GLuint index, GLfloat *result) |
||
79 | { |
||
80 | switch (fb->Visual.samples) { |
||
81 | case 1: |
||
82 | result[0] = result[1] = 0.5f; |
||
83 | break; |
||
84 | case 4: { |
||
85 | uint8_t val = (uint8_t)(sample_positions_4x[0] >> (8*index)); |
||
86 | result[0] = ((val >> 4) & 0xf) / 16.0f; |
||
87 | result[1] = (val & 0xf) / 16.0f; |
||
88 | break; |
||
89 | } |
||
90 | case 8: { |
||
91 | uint8_t val = (uint8_t)(sample_positions_8x[index>>2] >> (8*(index & 3))); |
||
92 | result[0] = ((val >> 4) & 0xf) / 16.0f; |
||
93 | result[1] = (val & 0xf) / 16.0f; |
||
94 | break; |
||
95 | } |
||
96 | default: |
||
97 | assert(!"Not implemented"); |
||
98 | } |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * 3DSTATE_MULTISAMPLE |
||
103 | */ |
||
104 | void |
||
105 | gen6_emit_3dstate_multisample(struct brw_context *brw, |
||
106 | unsigned num_samples) |
||
107 | { |
||
108 | uint32_t number_of_multisamples = 0; |
||
109 | uint32_t sample_positions_3210 = 0; |
||
110 | uint32_t sample_positions_7654 = 0; |
||
111 | |||
112 | switch (num_samples) { |
||
113 | case 0: |
||
114 | case 1: |
||
115 | number_of_multisamples = MS_NUMSAMPLES_1; |
||
116 | break; |
||
117 | case 4: |
||
118 | number_of_multisamples = MS_NUMSAMPLES_4; |
||
119 | sample_positions_3210 = sample_positions_4x[0]; |
||
120 | break; |
||
121 | case 8: |
||
122 | number_of_multisamples = MS_NUMSAMPLES_8; |
||
123 | sample_positions_3210 = sample_positions_8x[0]; |
||
124 | sample_positions_7654 = sample_positions_8x[1]; |
||
125 | break; |
||
126 | default: |
||
127 | assert(!"Unrecognized num_samples in gen6_emit_3dstate_multisample"); |
||
128 | break; |
||
129 | } |
||
130 | |||
4401 | Serge | 131 | /* 3DSTATE_MULTISAMPLE is nonpipelined. */ |
132 | intel_emit_post_sync_nonzero_flush(brw); |
||
133 | |||
4358 | Serge | 134 | int len = brw->gen >= 7 ? 4 : 3; |
135 | BEGIN_BATCH(len); |
||
136 | OUT_BATCH(_3DSTATE_MULTISAMPLE << 16 | (len - 2)); |
||
137 | OUT_BATCH(MS_PIXEL_LOCATION_CENTER | number_of_multisamples); |
||
138 | OUT_BATCH(sample_positions_3210); |
||
139 | if (brw->gen >= 7) |
||
140 | OUT_BATCH(sample_positions_7654); |
||
141 | ADVANCE_BATCH(); |
||
142 | } |
||
143 | |||
144 | |||
145 | /** |
||
146 | * 3DSTATE_SAMPLE_MASK |
||
147 | */ |
||
148 | void |
||
149 | gen6_emit_3dstate_sample_mask(struct brw_context *brw, |
||
150 | unsigned num_samples, float coverage, |
||
151 | bool coverage_invert, unsigned sample_mask) |
||
152 | { |
||
153 | BEGIN_BATCH(2); |
||
154 | OUT_BATCH(_3DSTATE_SAMPLE_MASK << 16 | (2 - 2)); |
||
155 | if (num_samples > 1) { |
||
156 | int coverage_int = (int) (num_samples * coverage + 0.5); |
||
157 | uint32_t coverage_bits = (1 << coverage_int) - 1; |
||
158 | if (coverage_invert) |
||
159 | coverage_bits ^= (1 << num_samples) - 1; |
||
160 | OUT_BATCH(coverage_bits & sample_mask); |
||
161 | } else { |
||
162 | OUT_BATCH(1); |
||
163 | } |
||
164 | ADVANCE_BATCH(); |
||
165 | } |
||
166 | |||
167 | |||
168 | static void upload_multisample_state(struct brw_context *brw) |
||
169 | { |
||
170 | struct gl_context *ctx = &brw->ctx; |
||
171 | float coverage = 1.0; |
||
172 | float coverage_invert = false; |
||
173 | unsigned sample_mask = ~0u; |
||
174 | |||
175 | /* _NEW_BUFFERS */ |
||
176 | unsigned num_samples = ctx->DrawBuffer->Visual.samples; |
||
177 | |||
178 | /* _NEW_MULTISAMPLE */ |
||
179 | if (ctx->Multisample._Enabled) { |
||
180 | if (ctx->Multisample.SampleCoverage) { |
||
181 | coverage = ctx->Multisample.SampleCoverageValue; |
||
182 | coverage_invert = ctx->Multisample.SampleCoverageInvert; |
||
183 | } |
||
184 | if (ctx->Multisample.SampleMask) { |
||
185 | sample_mask = ctx->Multisample.SampleMaskValue; |
||
186 | } |
||
187 | } |
||
188 | |||
189 | gen6_emit_3dstate_multisample(brw, num_samples); |
||
190 | gen6_emit_3dstate_sample_mask(brw, num_samples, coverage, |
||
191 | coverage_invert, sample_mask); |
||
192 | } |
||
193 | |||
194 | |||
195 | const struct brw_tracked_state gen6_multisample_state = { |
||
196 | .dirty = { |
||
197 | .mesa = _NEW_BUFFERS | |
||
198 | _NEW_MULTISAMPLE, |
||
199 | .brw = BRW_NEW_CONTEXT, |
||
200 | .cache = 0 |
||
201 | }, |
||
202 | .emit = upload_multisample_state |
||
203 | };><>><>><>><> |