2 * Copyright © 2015 Intel Corporation
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:
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
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
30 #include "anv_private.h"
32 #include "gen7_pack.h"
33 #include "gen75_pack.h"
35 #include "genX_state_util.h"
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
,
42 uint32_t num_elements
= range
/ stride
;
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,
57 .ShaderChannelSelectR
= SCS_RED
,
58 .ShaderChannelSelectG
= SCS_GREEN
,
59 .ShaderChannelSelectB
= SCS_BLUE
,
60 .ShaderChannelSelectA
= SCS_ALPHA
,
62 .SurfaceBaseAddress
= { NULL
, offset
},
65 GENX(RENDER_SURFACE_STATE_pack
)(NULL
, state
, &surface_state
);
68 static const uint32_t vk_to_gen_tex_filter
[] = {
69 [VK_FILTER_NEAREST
] = MAPFILTER_NEAREST
,
70 [VK_FILTER_LINEAR
] = MAPFILTER_LINEAR
73 static const uint32_t vk_to_gen_mipmap_mode
[] = {
74 [VK_SAMPLER_MIPMAP_MODE_BASE
] = MIPFILTER_NONE
,
75 [VK_SAMPLER_MIPMAP_MODE_NEAREST
] = MIPFILTER_NEAREST
,
76 [VK_SAMPLER_MIPMAP_MODE_LINEAR
] = MIPFILTER_LINEAR
79 static const uint32_t vk_to_gen_tex_address
[] = {
80 [VK_SAMPLER_ADDRESS_MODE_REPEAT
] = TCM_WRAP
,
81 [VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT
] = TCM_MIRROR
,
82 [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
] = TCM_CLAMP
,
83 [VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE
] = TCM_MIRROR_ONCE
,
84 [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER
] = TCM_CLAMP_BORDER
,
87 static const uint32_t vk_to_gen_compare_op
[] = {
88 [VK_COMPARE_OP_NEVER
] = PREFILTEROPNEVER
,
89 [VK_COMPARE_OP_LESS
] = PREFILTEROPLESS
,
90 [VK_COMPARE_OP_EQUAL
] = PREFILTEROPEQUAL
,
91 [VK_COMPARE_OP_LESS_OR_EQUAL
] = PREFILTEROPLEQUAL
,
92 [VK_COMPARE_OP_GREATER
] = PREFILTEROPGREATER
,
93 [VK_COMPARE_OP_NOT_EQUAL
] = PREFILTEROPNOTEQUAL
,
94 [VK_COMPARE_OP_GREATER_OR_EQUAL
] = PREFILTEROPGEQUAL
,
95 [VK_COMPARE_OP_ALWAYS
] = PREFILTEROPALWAYS
,
98 static struct anv_state
99 alloc_surface_state(struct anv_device
*device
,
100 struct anv_cmd_buffer
*cmd_buffer
)
103 return anv_cmd_buffer_alloc_surface_state(cmd_buffer
);
105 return anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
109 VkResult
genX(CreateSampler
)(
111 const VkSamplerCreateInfo
* pCreateInfo
,
112 const VkAllocationCallbacks
* pAllocator
,
115 ANV_FROM_HANDLE(anv_device
, device
, _device
);
116 struct anv_sampler
*sampler
;
117 uint32_t mag_filter
, min_filter
, max_anisotropy
;
119 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
121 sampler
= anv_alloc2(&device
->alloc
, pAllocator
, sizeof(*sampler
), 8,
122 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
124 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
126 if (pCreateInfo
->maxAnisotropy
> 1) {
127 mag_filter
= MAPFILTER_ANISOTROPIC
;
128 min_filter
= MAPFILTER_ANISOTROPIC
;
129 max_anisotropy
= (pCreateInfo
->maxAnisotropy
- 2) / 2;
131 mag_filter
= vk_to_gen_tex_filter
[pCreateInfo
->magFilter
];
132 min_filter
= vk_to_gen_tex_filter
[pCreateInfo
->minFilter
];
133 max_anisotropy
= RATIO21
;
136 struct GEN7_SAMPLER_STATE sampler_state
= {
137 .SamplerDisable
= false,
138 .TextureBorderColorMode
= DX10OGL
,
140 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipmapMode
],
141 .MagModeFilter
= mag_filter
,
142 .MinModeFilter
= min_filter
,
143 .TextureLODBias
= pCreateInfo
->mipLodBias
* 256,
144 .AnisotropicAlgorithm
= EWAApproximation
,
145 .MinLOD
= pCreateInfo
->minLod
,
146 .MaxLOD
= pCreateInfo
->maxLod
,
147 .ChromaKeyEnable
= 0,
150 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
151 .CubeSurfaceControlMode
= 0,
153 .BorderColorPointer
=
154 device
->border_colors
.offset
+
155 pCreateInfo
->borderColor
* sizeof(float) * 4,
157 .MaximumAnisotropy
= max_anisotropy
,
158 .RAddressMinFilterRoundingEnable
= 0,
159 .RAddressMagFilterRoundingEnable
= 0,
160 .VAddressMinFilterRoundingEnable
= 0,
161 .VAddressMagFilterRoundingEnable
= 0,
162 .UAddressMinFilterRoundingEnable
= 0,
163 .UAddressMagFilterRoundingEnable
= 0,
164 .TrilinearFilterQuality
= 0,
165 .NonnormalizedCoordinateEnable
= pCreateInfo
->unnormalizedCoordinates
,
166 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeU
],
167 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeV
],
168 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeW
],
171 GEN7_SAMPLER_STATE_pack(NULL
, sampler
->state
, &sampler_state
);
173 *pSampler
= anv_sampler_to_handle(sampler
);
178 static const uint8_t anv_halign
[] = {
183 static const uint8_t anv_valign
[] = {
188 GENX_FUNC(GEN7
, GEN75
) void
189 genX(image_view_init
)(struct anv_image_view
*iview
,
190 struct anv_device
*device
,
191 const VkImageViewCreateInfo
* pCreateInfo
,
192 struct anv_cmd_buffer
*cmd_buffer
)
194 ANV_FROM_HANDLE(anv_image
, image
, pCreateInfo
->image
);
196 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
198 struct anv_surface
*surface
=
199 anv_image_get_surface_for_aspect_mask(image
, range
->aspectMask
);
201 const struct anv_format
*format
=
202 anv_format_for_vk_format(pCreateInfo
->format
);
204 if (pCreateInfo
->viewType
!= VK_IMAGE_VIEW_TYPE_2D
)
205 anv_finishme("non-2D image views");
207 iview
->image
= image
;
208 iview
->bo
= image
->bo
;
209 iview
->offset
= image
->offset
+ surface
->offset
;
210 iview
->format
= anv_format_for_vk_format(pCreateInfo
->format
);
212 iview
->extent
= (VkExtent3D
) {
213 .width
= anv_minify(image
->extent
.width
, range
->baseMipLevel
),
214 .height
= anv_minify(image
->extent
.height
, range
->baseMipLevel
),
215 .depth
= anv_minify(image
->extent
.depth
, range
->baseMipLevel
),
219 if (range
->layerCount
> 1) {
220 depth
= range
->layerCount
;
221 } else if (image
->extent
.depth
> 1) {
222 depth
= image
->extent
.depth
;
225 const struct isl_extent3d image_align_sa
=
226 isl_surf_get_image_alignment_sa(&surface
->isl
);
228 struct GENX(RENDER_SURFACE_STATE
) surface_state
= {
229 .SurfaceType
= anv_surftype(image
, pCreateInfo
->viewType
, false),
230 .SurfaceArray
= image
->array_size
> 1,
231 .SurfaceFormat
= format
->surface_format
,
232 .SurfaceVerticalAlignment
= anv_valign
[image_align_sa
.height
],
233 .SurfaceHorizontalAlignment
= anv_halign
[image_align_sa
.width
],
235 /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
236 * Tiled Surface is False."
238 .TiledSurface
= surface
->isl
.tiling
!= ISL_TILING_LINEAR
,
239 .TileWalk
= surface
->isl
.tiling
== ISL_TILING_Y0
?
240 TILEWALK_YMAJOR
: TILEWALK_XMAJOR
,
242 .VerticalLineStride
= 0,
243 .VerticalLineStrideOffset
= 0,
245 .RenderCacheReadWriteMode
= 0, /* TEMPLATE */
247 .Height
= image
->extent
.height
- 1,
248 .Width
= image
->extent
.width
- 1,
250 .SurfacePitch
= surface
->isl
.row_pitch
- 1,
251 .MinimumArrayElement
= range
->baseArrayLayer
,
252 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
256 .SurfaceObjectControlState
= GENX(MOCS
),
258 .MIPCountLOD
= 0, /* TEMPLATE */
259 .SurfaceMinLOD
= 0, /* TEMPLATE */
262 # if (ANV_IS_HASWELL)
263 .ShaderChannelSelectR
= vk_to_gen_swizzle(pCreateInfo
->components
.r
,
264 VK_COMPONENT_SWIZZLE_R
),
265 .ShaderChannelSelectG
= vk_to_gen_swizzle(pCreateInfo
->components
.g
,
266 VK_COMPONENT_SWIZZLE_G
),
267 .ShaderChannelSelectB
= vk_to_gen_swizzle(pCreateInfo
->components
.b
,
268 VK_COMPONENT_SWIZZLE_B
),
269 .ShaderChannelSelectA
= vk_to_gen_swizzle(pCreateInfo
->components
.a
,
270 VK_COMPONENT_SWIZZLE_A
),
271 # else /* XXX: Seriously? */
273 .GreenClearColor
= 0,
275 .AlphaClearColor
= 0,
277 .ResourceMinLOD
= 0.0,
278 .SurfaceBaseAddress
= { NULL
, iview
->offset
},
281 if (image
->needs_nonrt_surface_state
) {
282 iview
->nonrt_surface_state
= alloc_surface_state(device
, cmd_buffer
);
284 surface_state
.RenderCacheReadWriteMode
= false;
286 /* For non render target surfaces, the hardware interprets field
287 * MIPCount/LOD as MIPCount. The range of levels accessible by the
288 * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
290 surface_state
.SurfaceMinLOD
= range
->baseMipLevel
;
291 surface_state
.MIPCountLOD
= MAX2(range
->levelCount
, 1) - 1;
293 GENX(RENDER_SURFACE_STATE_pack
)(NULL
, iview
->nonrt_surface_state
.map
,
296 if (!device
->info
.has_llc
)
297 anv_state_clflush(iview
->nonrt_surface_state
);
300 if (image
->needs_color_rt_surface_state
) {
301 iview
->color_rt_surface_state
= alloc_surface_state(device
, cmd_buffer
);
303 surface_state
.RenderCacheReadWriteMode
= 0; /* Write only */
305 /* For render target surfaces, the hardware interprets field MIPCount/LOD as
306 * LOD. The Broadwell PRM says:
308 * MIPCountLOD defines the LOD that will be rendered into.
309 * SurfaceMinLOD is ignored.
311 surface_state
.MIPCountLOD
= range
->baseMipLevel
;
312 surface_state
.SurfaceMinLOD
= 0;
314 GENX(RENDER_SURFACE_STATE_pack
)(NULL
, iview
->color_rt_surface_state
.map
,
316 if (!device
->info
.has_llc
)
317 anv_state_clflush(iview
->color_rt_surface_state
);
320 if (image
->needs_storage_surface_state
) {
321 iview
->storage_surface_state
= alloc_surface_state(device
, cmd_buffer
);
323 surface_state
.SurfaceType
=
324 anv_surftype(image
, pCreateInfo
->viewType
, true),
326 surface_state
.SurfaceFormat
=
327 isl_lower_storage_image_format(&device
->isl_dev
,
328 format
->surface_format
);
330 surface_state
.SurfaceMinLOD
= range
->baseMipLevel
;
331 surface_state
.MIPCountLOD
= MAX2(range
->levelCount
, 1) - 1;
333 GENX(RENDER_SURFACE_STATE_pack
)(NULL
, iview
->storage_surface_state
.map
,