i965/vec4: Add a test for copy propagation behavior.
[mesa.git] / src / mesa / drivers / dri / i965 / gen7_misc_state.c
1 /*
2 * Copyright © 2011 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 "main/mtypes.h"
25 #include "intel_batchbuffer.h"
26 #include "intel_mipmap_tree.h"
27 #include "intel_regions.h"
28 #include "intel_fbo.h"
29 #include "brw_context.h"
30 #include "brw_state.h"
31 #include "brw_defines.h"
32
33 void
34 gen7_emit_depth_stencil_hiz(struct brw_context *brw,
35 struct intel_mipmap_tree *depth_mt,
36 uint32_t depth_offset, uint32_t depthbuffer_format,
37 uint32_t depth_surface_type,
38 struct intel_mipmap_tree *stencil_mt,
39 bool hiz, bool separate_stencil,
40 uint32_t width, uint32_t height,
41 uint32_t tile_x, uint32_t tile_y)
42 {
43 struct gl_context *ctx = &brw->ctx;
44 const uint8_t mocs = GEN7_MOCS_L3;
45 struct gl_framebuffer *fb = ctx->DrawBuffer;
46 uint32_t surftype;
47 unsigned int depth = 1;
48 unsigned int min_array_element;
49 GLenum gl_target = GL_TEXTURE_2D;
50 unsigned int lod;
51 const struct intel_mipmap_tree *mt = depth_mt ? depth_mt : stencil_mt;
52 const struct intel_renderbuffer *irb = NULL;
53 const struct gl_renderbuffer *rb = NULL;
54
55 intel_emit_depth_stall_flushes(brw);
56
57 irb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
58 if (!irb)
59 irb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
60 rb = (struct gl_renderbuffer*) irb;
61
62 if (rb) {
63 depth = MAX2(rb->Depth, 1);
64 if (rb->TexImage)
65 gl_target = rb->TexImage->TexObject->Target;
66 }
67
68 switch (gl_target) {
69 case GL_TEXTURE_CUBE_MAP_ARRAY:
70 case GL_TEXTURE_CUBE_MAP:
71 /* The PRM claims that we should use BRW_SURFACE_CUBE for this
72 * situation, but experiments show that gl_Layer doesn't work when we do
73 * this. So we use BRW_SURFACE_2D, since for rendering purposes this is
74 * equivalent.
75 */
76 surftype = BRW_SURFACE_2D;
77 depth *= 6;
78 break;
79 default:
80 surftype = translate_tex_target(gl_target);
81 break;
82 }
83
84 if (fb->MaxNumLayers > 0 || !irb) {
85 min_array_element = 0;
86 } else if (irb->mt->num_samples > 1) {
87 /* Convert physical layer to logical layer. */
88 min_array_element = irb->mt_layer / irb->mt->num_samples;
89 } else {
90 min_array_element = irb->mt_layer;
91 }
92
93 lod = irb ? irb->mt_level - irb->mt->first_level : 0;
94
95 if (mt) {
96 width = mt->logical_width0;
97 height = mt->logical_height0;
98 }
99
100 /* _NEW_DEPTH, _NEW_STENCIL, _NEW_BUFFERS */
101 BEGIN_BATCH(7);
102 /* 3DSTATE_DEPTH_BUFFER dw0 */
103 OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
104
105 /* 3DSTATE_DEPTH_BUFFER dw1 */
106 OUT_BATCH((depth_mt ? depth_mt->region->pitch - 1 : 0) |
107 (depthbuffer_format << 18) |
108 ((hiz ? 1 : 0) << 22) |
109 ((stencil_mt != NULL && ctx->Stencil._WriteEnabled) << 27) |
110 ((ctx->Depth.Mask != 0) << 28) |
111 (surftype << 29));
112
113 /* 3DSTATE_DEPTH_BUFFER dw2 */
114 if (depth_mt) {
115 OUT_RELOC(depth_mt->region->bo,
116 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
117 0);
118 } else {
119 OUT_BATCH(0);
120 }
121
122 /* 3DSTATE_DEPTH_BUFFER dw3 */
123 OUT_BATCH(((width - 1) << 4) |
124 ((height - 1) << 18) |
125 lod);
126
127 /* 3DSTATE_DEPTH_BUFFER dw4 */
128 OUT_BATCH(((depth - 1) << 21) |
129 (min_array_element << 10) |
130 mocs);
131
132 /* 3DSTATE_DEPTH_BUFFER dw5 */
133 OUT_BATCH(0);
134
135 /* 3DSTATE_DEPTH_BUFFER dw6 */
136 OUT_BATCH((depth - 1) << 21);
137 ADVANCE_BATCH();
138
139 if (!hiz) {
140 BEGIN_BATCH(3);
141 OUT_BATCH(GEN7_3DSTATE_HIER_DEPTH_BUFFER << 16 | (3 - 2));
142 OUT_BATCH(0);
143 OUT_BATCH(0);
144 ADVANCE_BATCH();
145 } else {
146 struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_mt;
147 BEGIN_BATCH(3);
148 OUT_BATCH(GEN7_3DSTATE_HIER_DEPTH_BUFFER << 16 | (3 - 2));
149 OUT_BATCH((mocs << 25) |
150 (hiz_mt->region->pitch - 1));
151 OUT_RELOC(hiz_mt->region->bo,
152 I915_GEM_DOMAIN_RENDER,
153 I915_GEM_DOMAIN_RENDER,
154 0);
155 ADVANCE_BATCH();
156 }
157
158 if (stencil_mt == NULL) {
159 BEGIN_BATCH(3);
160 OUT_BATCH(GEN7_3DSTATE_STENCIL_BUFFER << 16 | (3 - 2));
161 OUT_BATCH(0);
162 OUT_BATCH(0);
163 ADVANCE_BATCH();
164 } else {
165 const int enabled = brw->is_haswell ? HSW_STENCIL_ENABLED : 0;
166
167 BEGIN_BATCH(3);
168 OUT_BATCH(GEN7_3DSTATE_STENCIL_BUFFER << 16 | (3 - 2));
169 /* The stencil buffer has quirky pitch requirements. From the
170 * Sandybridge PRM, Volume 2 Part 1, page 329 (3DSTATE_STENCIL_BUFFER
171 * dword 1 bits 16:0 - Surface Pitch):
172 *
173 * The pitch must be set to 2x the value computed based on width, as
174 * the stencil buffer is stored with two rows interleaved.
175 *
176 * While the Ivybridge PRM lacks this comment, the BSpec contains the
177 * same text, and experiments indicate that this is necessary.
178 */
179 OUT_BATCH(enabled |
180 mocs << 25 |
181 (2 * stencil_mt->region->pitch - 1));
182 OUT_RELOC(stencil_mt->region->bo,
183 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
184 0);
185 ADVANCE_BATCH();
186 }
187
188 BEGIN_BATCH(3);
189 OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS << 16 | (3 - 2));
190 OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0);
191 OUT_BATCH(1);
192 ADVANCE_BATCH();
193 }
194
195 /**
196 * \see brw_context.state.depth_region
197 */
198 const struct brw_tracked_state gen7_depthbuffer = {
199 .dirty = {
200 .mesa = (_NEW_BUFFERS | _NEW_DEPTH | _NEW_STENCIL),
201 .brw = BRW_NEW_BATCH,
202 .cache = 0,
203 },
204 .emit = brw_emit_depthbuffer,
205 };