anv/state: Use the new emit macro
[mesa.git] / src / intel / vulkan / genX_state.c
1 /*
2 * Copyright © 2015 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 <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "anv_private.h"
31
32 #include "genxml/gen_macros.h"
33 #include "genxml/genX_pack.h"
34
35 VkResult
36 genX(init_device_state)(struct anv_device *device)
37 {
38 GENX(MEMORY_OBJECT_CONTROL_STATE_pack)(NULL, &device->default_mocs,
39 &GENX(MOCS));
40
41 struct anv_batch batch;
42
43 uint32_t cmds[64];
44 batch.start = batch.next = cmds;
45 batch.end = (void *) cmds + sizeof(cmds);
46
47 anv_batch_emit_blk(&batch, GENX(PIPELINE_SELECT), ps) {
48 #if GEN_GEN >= 9
49 ps.MaskBits = 3;
50 #endif
51 ps.PipelineSelection = _3D;
52 }
53
54 anv_batch_emit_blk(&batch, GENX(3DSTATE_VF_STATISTICS), vfs)
55 vfs.StatisticsEnable = true;
56
57 anv_batch_emit_blk(&batch, GENX(3DSTATE_HS), hs);
58 anv_batch_emit_blk(&batch, GENX(3DSTATE_TE), ts);
59 anv_batch_emit_blk(&batch, GENX(3DSTATE_DS), ds);
60
61 anv_batch_emit_blk(&batch, GENX(3DSTATE_STREAMOUT), so);
62 anv_batch_emit_blk(&batch, GENX(3DSTATE_AA_LINE_PARAMETERS), aa);
63
64 #if GEN_GEN >= 8
65 anv_batch_emit_blk(&batch, GENX(3DSTATE_WM_CHROMAKEY), ck);
66
67 /* See the Vulkan 1.0 spec Table 24.1 "Standard sample locations" and
68 * VkPhysicalDeviceFeatures::standardSampleLocations.
69 */
70 anv_batch_emit_blk(&batch, GENX(3DSTATE_SAMPLE_PATTERN), sp) {
71 sp._1xSample0XOffset = 0.5;
72 sp._1xSample0YOffset = 0.5;
73 sp._2xSample0XOffset = 0.25;
74 sp._2xSample0YOffset = 0.25;
75 sp._2xSample1XOffset = 0.75;
76 sp._2xSample1YOffset = 0.75;
77 sp._4xSample0XOffset = 0.375;
78 sp._4xSample0YOffset = 0.125;
79 sp._4xSample1XOffset = 0.875;
80 sp._4xSample1YOffset = 0.375;
81 sp._4xSample2XOffset = 0.125;
82 sp._4xSample2YOffset = 0.625;
83 sp._4xSample3XOffset = 0.625;
84 sp._4xSample3YOffset = 0.875;
85 sp._8xSample0XOffset = 0.5625;
86 sp._8xSample0YOffset = 0.3125;
87 sp._8xSample1XOffset = 0.4375;
88 sp._8xSample1YOffset = 0.6875;
89 sp._8xSample2XOffset = 0.8125;
90 sp._8xSample2YOffset = 0.5625;
91 sp._8xSample3XOffset = 0.3125;
92 sp._8xSample3YOffset = 0.1875;
93 sp._8xSample4XOffset = 0.1875;
94 sp._8xSample4YOffset = 0.8125;
95 sp._8xSample5XOffset = 0.0625;
96 sp._8xSample5YOffset = 0.4375;
97 sp._8xSample6XOffset = 0.6875;
98 sp._8xSample6YOffset = 0.9375;
99 sp._8xSample7XOffset = 0.9375;
100 sp._8xSample7YOffset = 0.0625;
101 #if GEN_GEN >= 9
102 sp._16xSample0XOffset = 0.5625;
103 sp._16xSample0YOffset = 0.5625;
104 sp._16xSample1XOffset = 0.4375;
105 sp._16xSample1YOffset = 0.3125;
106 sp._16xSample2XOffset = 0.3125;
107 sp._16xSample2YOffset = 0.6250;
108 sp._16xSample3XOffset = 0.7500;
109 sp._16xSample3YOffset = 0.4375;
110 sp._16xSample4XOffset = 0.1875;
111 sp._16xSample4YOffset = 0.3750;
112 sp._16xSample5XOffset = 0.6250;
113 sp._16xSample5YOffset = 0.8125;
114 sp._16xSample6XOffset = 0.8125;
115 sp._16xSample6YOffset = 0.6875;
116 sp._16xSample7XOffset = 0.6875;
117 sp._16xSample7YOffset = 0.1875;
118 sp._16xSample8XOffset = 0.3750;
119 sp._16xSample8YOffset = 0.8750;
120 sp._16xSample9XOffset = 0.5000;
121 sp._16xSample9YOffset = 0.0625;
122 sp._16xSample10XOffset = 0.2500;
123 sp._16xSample10YOffset = 0.1250;
124 sp._16xSample11XOffset = 0.1250;
125 sp._16xSample11YOffset = 0.7500;
126 sp._16xSample12XOffset = 0.0000;
127 sp._16xSample12YOffset = 0.5000;
128 sp._16xSample13XOffset = 0.9375;
129 sp._16xSample13YOffset = 0.2500;
130 sp._16xSample14XOffset = 0.8750;
131 sp._16xSample14YOffset = 0.9375;
132 sp._16xSample15XOffset = 0.0625;
133 sp._16xSample15YOffset = 0.0000;
134 #endif
135 }
136 #endif
137
138 anv_batch_emit_blk(&batch, GENX(MI_BATCH_BUFFER_END), bbe);
139
140 assert(batch.next <= batch.end);
141
142 return anv_device_submit_simple_batch(device, &batch);
143 }
144
145 static inline uint32_t
146 vk_to_gen_tex_filter(VkFilter filter, bool anisotropyEnable)
147 {
148 switch (filter) {
149 default:
150 assert(!"Invalid filter");
151 case VK_FILTER_NEAREST:
152 return MAPFILTER_NEAREST;
153 case VK_FILTER_LINEAR:
154 return anisotropyEnable ? MAPFILTER_ANISOTROPIC : MAPFILTER_LINEAR;
155 }
156 }
157
158 static inline uint32_t
159 vk_to_gen_max_anisotropy(float ratio)
160 {
161 return (anv_clamp_f(ratio, 2, 16) - 2) / 2;
162 }
163
164 static const uint32_t vk_to_gen_mipmap_mode[] = {
165 [VK_SAMPLER_MIPMAP_MODE_NEAREST] = MIPFILTER_NEAREST,
166 [VK_SAMPLER_MIPMAP_MODE_LINEAR] = MIPFILTER_LINEAR
167 };
168
169 static const uint32_t vk_to_gen_tex_address[] = {
170 [VK_SAMPLER_ADDRESS_MODE_REPEAT] = TCM_WRAP,
171 [VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT] = TCM_MIRROR,
172 [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE] = TCM_CLAMP,
173 [VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE] = TCM_MIRROR_ONCE,
174 [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER] = TCM_CLAMP_BORDER,
175 };
176
177 /* Vulkan specifies the result of shadow comparisons as:
178 * 1 if ref <op> texel,
179 * 0 otherwise.
180 *
181 * The hardware does:
182 * 0 if texel <op> ref,
183 * 1 otherwise.
184 *
185 * So, these look a bit strange because there's both a negation
186 * and swapping of the arguments involved.
187 */
188 static const uint32_t vk_to_gen_shadow_compare_op[] = {
189 [VK_COMPARE_OP_NEVER] = PREFILTEROPALWAYS,
190 [VK_COMPARE_OP_LESS] = PREFILTEROPLEQUAL,
191 [VK_COMPARE_OP_EQUAL] = PREFILTEROPNOTEQUAL,
192 [VK_COMPARE_OP_LESS_OR_EQUAL] = PREFILTEROPLESS,
193 [VK_COMPARE_OP_GREATER] = PREFILTEROPGEQUAL,
194 [VK_COMPARE_OP_NOT_EQUAL] = PREFILTEROPEQUAL,
195 [VK_COMPARE_OP_GREATER_OR_EQUAL] = PREFILTEROPGREATER,
196 [VK_COMPARE_OP_ALWAYS] = PREFILTEROPNEVER,
197 };
198
199 VkResult genX(CreateSampler)(
200 VkDevice _device,
201 const VkSamplerCreateInfo* pCreateInfo,
202 const VkAllocationCallbacks* pAllocator,
203 VkSampler* pSampler)
204 {
205 ANV_FROM_HANDLE(anv_device, device, _device);
206 struct anv_sampler *sampler;
207
208 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
209
210 sampler = anv_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
211 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
212 if (!sampler)
213 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
214
215 uint32_t border_color_offset = device->border_colors.offset +
216 pCreateInfo->borderColor * 64;
217
218 struct GENX(SAMPLER_STATE) sampler_state = {
219 .SamplerDisable = false,
220 .TextureBorderColorMode = DX10OGL,
221
222 #if GEN_GEN >= 8
223 .LODPreClampMode = CLAMP_MODE_OGL,
224 #else
225 .LODPreClampEnable = CLAMP_ENABLE_OGL,
226 #endif
227
228 #if GEN_GEN == 8
229 .BaseMipLevel = 0.0,
230 #endif
231 .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipmapMode],
232 .MagModeFilter = vk_to_gen_tex_filter(pCreateInfo->magFilter,
233 pCreateInfo->anisotropyEnable),
234 .MinModeFilter = vk_to_gen_tex_filter(pCreateInfo->minFilter,
235 pCreateInfo->anisotropyEnable),
236 .TextureLODBias = anv_clamp_f(pCreateInfo->mipLodBias, -16, 15.996),
237 .AnisotropicAlgorithm = EWAApproximation,
238 .MinLOD = anv_clamp_f(pCreateInfo->minLod, 0, 14),
239 .MaxLOD = anv_clamp_f(pCreateInfo->maxLod, 0, 14),
240 .ChromaKeyEnable = 0,
241 .ChromaKeyIndex = 0,
242 .ChromaKeyMode = 0,
243 .ShadowFunction = vk_to_gen_shadow_compare_op[pCreateInfo->compareOp],
244 .CubeSurfaceControlMode = OVERRIDE,
245
246 .BorderColorPointer = border_color_offset,
247
248 #if GEN_GEN >= 8
249 .LODClampMagnificationMode = MIPNONE,
250 #endif
251
252 .MaximumAnisotropy = vk_to_gen_max_anisotropy(pCreateInfo->maxAnisotropy),
253 .RAddressMinFilterRoundingEnable = 0,
254 .RAddressMagFilterRoundingEnable = 0,
255 .VAddressMinFilterRoundingEnable = 0,
256 .VAddressMagFilterRoundingEnable = 0,
257 .UAddressMinFilterRoundingEnable = 0,
258 .UAddressMagFilterRoundingEnable = 0,
259 .TrilinearFilterQuality = 0,
260 .NonnormalizedCoordinateEnable = pCreateInfo->unnormalizedCoordinates,
261 .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeU],
262 .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeV],
263 .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeW],
264 };
265
266 GENX(SAMPLER_STATE_pack)(NULL, sampler->state, &sampler_state);
267
268 *pSampler = anv_sampler_to_handle(sampler);
269
270 return VK_SUCCESS;
271 }