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