09c1332e450cb878807ac8f59766500ff25bcb19
[mesa.git] / src / vulkan / gen7_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 "gen7_pack.h"
33 #include "gen75_pack.h"
34
35 #include "genX_state_util.h"
36
37 GENX_FUNC(GEN7, GEN75) void
38 genX(fill_buffer_surface_state)(void *state, enum isl_format format,
39 uint32_t offset, uint32_t range,
40 uint32_t stride)
41 {
42 uint32_t num_elements = range / stride;
43
44 struct GENX(RENDER_SURFACE_STATE) surface_state = {
45 .SurfaceType = SURFTYPE_BUFFER,
46 .SurfaceFormat = format,
47 .SurfaceVerticalAlignment = VALIGN_4,
48 .SurfaceHorizontalAlignment = HALIGN_4,
49 .TiledSurface = false,
50 .RenderCacheReadWriteMode = false,
51 .SurfaceObjectControlState = GENX(MOCS),
52 .Height = (num_elements >> 7) & 0x3fff,
53 .Width = num_elements & 0x7f,
54 .Depth = (num_elements >> 21) & 0x3f,
55 .SurfacePitch = stride - 1,
56 # if (ANV_IS_HASWELL)
57 .ShaderChannelSelectR = SCS_RED,
58 .ShaderChannelSelectG = SCS_GREEN,
59 .ShaderChannelSelectB = SCS_BLUE,
60 .ShaderChannelSelectA = SCS_ALPHA,
61 # endif
62 .SurfaceBaseAddress = { NULL, offset },
63 };
64
65 GENX(RENDER_SURFACE_STATE_pack)(NULL, state, &surface_state);
66 }
67
68 static struct anv_state
69 alloc_surface_state(struct anv_device *device,
70 struct anv_cmd_buffer *cmd_buffer)
71 {
72 if (cmd_buffer) {
73 return anv_cmd_buffer_alloc_surface_state(cmd_buffer);
74 } else {
75 return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
76 }
77 }
78
79 VkResult genX(CreateSampler)(
80 VkDevice _device,
81 const VkSamplerCreateInfo* pCreateInfo,
82 const VkAllocationCallbacks* pAllocator,
83 VkSampler* pSampler)
84 {
85 ANV_FROM_HANDLE(anv_device, device, _device);
86 struct anv_sampler *sampler;
87
88 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
89
90 sampler = anv_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
91 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
92 if (!sampler)
93 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
94
95 uint32_t filter = vk_to_gen_tex_filter(pCreateInfo->magFilter,
96 pCreateInfo->anisotropyEnable);
97
98 struct GEN7_SAMPLER_STATE sampler_state = {
99 .SamplerDisable = false,
100 .TextureBorderColorMode = DX10OGL,
101 .BaseMipLevel = 0.0,
102 .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipmapMode],
103 .MagModeFilter = filter,
104 .MinModeFilter = filter,
105 .TextureLODBias = pCreateInfo->mipLodBias * 256,
106 .AnisotropicAlgorithm = EWAApproximation,
107 .MinLOD = pCreateInfo->minLod,
108 .MaxLOD = pCreateInfo->maxLod,
109 .ChromaKeyEnable = 0,
110 .ChromaKeyIndex = 0,
111 .ChromaKeyMode = 0,
112 .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
113 .CubeSurfaceControlMode = 0,
114
115 .BorderColorPointer =
116 device->border_colors.offset +
117 pCreateInfo->borderColor * sizeof(float) * 4,
118
119 .MaximumAnisotropy = vk_to_gen_max_anisotropy(pCreateInfo->maxAnisotropy),
120 .RAddressMinFilterRoundingEnable = 0,
121 .RAddressMagFilterRoundingEnable = 0,
122 .VAddressMinFilterRoundingEnable = 0,
123 .VAddressMagFilterRoundingEnable = 0,
124 .UAddressMinFilterRoundingEnable = 0,
125 .UAddressMagFilterRoundingEnable = 0,
126 .TrilinearFilterQuality = 0,
127 .NonnormalizedCoordinateEnable = pCreateInfo->unnormalizedCoordinates,
128 .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeU],
129 .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeV],
130 .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeW],
131 };
132
133 GEN7_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
134
135 *pSampler = anv_sampler_to_handle(sampler);
136
137 return VK_SUCCESS;
138 }
139
140 static const uint8_t anv_halign[] = {
141 [4] = HALIGN_4,
142 [8] = HALIGN_8,
143 };
144
145 static const uint8_t anv_valign[] = {
146 [2] = VALIGN_2,
147 [4] = VALIGN_4,
148 };
149
150 GENX_FUNC(GEN7, GEN75) void
151 genX(image_view_init)(struct anv_image_view *iview,
152 struct anv_device *device,
153 const VkImageViewCreateInfo* pCreateInfo,
154 struct anv_cmd_buffer *cmd_buffer)
155 {
156 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
157
158 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
159
160 struct anv_surface *surface =
161 anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
162
163 if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
164 anv_finishme("non-2D image views");
165
166 uint32_t depth = 1;
167 if (range->layerCount > 1) {
168 depth = range->layerCount;
169 } else if (image->extent.depth > 1) {
170 depth = image->extent.depth;
171 }
172
173 const struct isl_extent3d image_align_sa =
174 isl_surf_get_image_alignment_sa(&surface->isl);
175
176 struct GENX(RENDER_SURFACE_STATE) surface_state = {
177 .SurfaceType = anv_surftype(image, pCreateInfo->viewType, false),
178 .SurfaceArray = image->array_size > 1,
179 .SurfaceFormat = iview->format,
180 .SurfaceVerticalAlignment = anv_valign[image_align_sa.height],
181 .SurfaceHorizontalAlignment = anv_halign[image_align_sa.width],
182
183 /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
184 * Tiled Surface is False."
185 */
186 .TiledSurface = surface->isl.tiling != ISL_TILING_LINEAR,
187 .TileWalk = surface->isl.tiling == ISL_TILING_Y0 ?
188 TILEWALK_YMAJOR : TILEWALK_XMAJOR,
189
190 .VerticalLineStride = 0,
191 .VerticalLineStrideOffset = 0,
192
193 .RenderCacheReadWriteMode = 0, /* TEMPLATE */
194
195 .Height = image->extent.height - 1,
196 .Width = image->extent.width - 1,
197 .Depth = depth - 1,
198 .SurfacePitch = surface->isl.row_pitch - 1,
199 .MinimumArrayElement = range->baseArrayLayer,
200 .NumberofMultisamples = MULTISAMPLECOUNT_1,
201 .XOffset = 0,
202 .YOffset = 0,
203
204 .SurfaceObjectControlState = GENX(MOCS),
205
206 .MIPCountLOD = 0, /* TEMPLATE */
207 .SurfaceMinLOD = 0, /* TEMPLATE */
208
209 .MCSEnable = false,
210 # if (ANV_IS_HASWELL)
211 .ShaderChannelSelectR = vk_to_gen_swizzle(pCreateInfo->components.r,
212 VK_COMPONENT_SWIZZLE_R),
213 .ShaderChannelSelectG = vk_to_gen_swizzle(pCreateInfo->components.g,
214 VK_COMPONENT_SWIZZLE_G),
215 .ShaderChannelSelectB = vk_to_gen_swizzle(pCreateInfo->components.b,
216 VK_COMPONENT_SWIZZLE_B),
217 .ShaderChannelSelectA = vk_to_gen_swizzle(pCreateInfo->components.a,
218 VK_COMPONENT_SWIZZLE_A),
219 # else /* XXX: Seriously? */
220 .RedClearColor = 0,
221 .GreenClearColor = 0,
222 .BlueClearColor = 0,
223 .AlphaClearColor = 0,
224 # endif
225 .ResourceMinLOD = 0.0,
226 .SurfaceBaseAddress = { NULL, iview->offset },
227 };
228
229 if (image->needs_nonrt_surface_state) {
230 iview->nonrt_surface_state = alloc_surface_state(device, cmd_buffer);
231
232 surface_state.RenderCacheReadWriteMode = false;
233
234 /* For non render target surfaces, the hardware interprets field
235 * MIPCount/LOD as MIPCount. The range of levels accessible by the
236 * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
237 */
238 surface_state.SurfaceMinLOD = range->baseMipLevel;
239 surface_state.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
240
241 GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->nonrt_surface_state.map,
242 &surface_state);
243
244 if (!device->info.has_llc)
245 anv_state_clflush(iview->nonrt_surface_state);
246 } else {
247 iview->nonrt_surface_state.alloc_size = 0;
248 }
249
250 if (image->needs_color_rt_surface_state) {
251 iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer);
252
253 surface_state.RenderCacheReadWriteMode = 0; /* Write only */
254
255 /* For render target surfaces, the hardware interprets field MIPCount/LOD as
256 * LOD. The Broadwell PRM says:
257 *
258 * MIPCountLOD defines the LOD that will be rendered into.
259 * SurfaceMinLOD is ignored.
260 */
261 surface_state.MIPCountLOD = range->baseMipLevel;
262 surface_state.SurfaceMinLOD = 0;
263
264 GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->color_rt_surface_state.map,
265 &surface_state);
266 if (!device->info.has_llc)
267 anv_state_clflush(iview->color_rt_surface_state);
268 } else {
269 iview->color_rt_surface_state.alloc_size = 0;
270 }
271
272 if (image->needs_storage_surface_state) {
273 iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
274
275 surface_state.SurfaceType =
276 anv_surftype(image, pCreateInfo->viewType, true),
277
278 surface_state.SurfaceFormat =
279 isl_lower_storage_image_format(&device->isl_dev, iview->format);
280
281 surface_state.SurfaceMinLOD = range->baseMipLevel;
282 surface_state.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
283
284 GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->storage_surface_state.map,
285 &surface_state);
286 } else {
287 iview->storage_surface_state.alloc_size = 0;
288 }
289 }