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"
33 gen7_fill_buffer_surface_state(void *state
, const struct anv_format
*format
,
34 uint32_t offset
, uint32_t range
)
36 /* This assumes RGBA float format. */
38 uint32_t stride
= 16; /* Depends on whether accessing shader is simd8 or
39 * vec4. Will need one of each for buffers that are
40 * used in both vec4 and simd8. */
42 uint32_t num_elements
= range
/ stride
;
44 struct GEN7_RENDER_SURFACE_STATE surface_state
= {
45 .SurfaceType
= SURFTYPE_BUFFER
,
46 .SurfaceFormat
= format
->surface_format
,
47 .SurfaceVerticalAlignment
= VALIGN_4
,
48 .SurfaceHorizontalAlignment
= HALIGN_4
,
49 .TiledSurface
= false,
50 .RenderCacheReadWriteMode
= false,
51 .SurfaceObjectControlState
= GEN7_MOCS
,
52 .Height
= (num_elements
>> 7) & 0x3fff,
53 .Width
= num_elements
& 0x7f,
54 .Depth
= (num_elements
>> 21) & 0x3f,
55 .SurfacePitch
= stride
- 1,
56 .SurfaceBaseAddress
= { NULL
, offset
},
59 GEN7_RENDER_SURFACE_STATE_pack(NULL
, state
, &surface_state
);
62 VkResult
gen7_CreateBufferView(
64 const VkBufferViewCreateInfo
* pCreateInfo
,
67 ANV_FROM_HANDLE(anv_device
, device
, _device
);
68 struct anv_buffer_view
*bview
;
71 result
= anv_buffer_view_create(device
, pCreateInfo
, &bview
);
72 if (result
!= VK_SUCCESS
)
75 const struct anv_format
*format
=
76 anv_format_for_vk_format(pCreateInfo
->format
);
78 gen7_fill_buffer_surface_state(bview
->surface_state
.map
, format
,
79 bview
->offset
, pCreateInfo
->range
);
81 *pView
= anv_buffer_view_to_handle(bview
);
86 static const uint32_t vk_to_gen_tex_filter
[] = {
87 [VK_TEX_FILTER_NEAREST
] = MAPFILTER_NEAREST
,
88 [VK_TEX_FILTER_LINEAR
] = MAPFILTER_LINEAR
91 static const uint32_t vk_to_gen_mipmap_mode
[] = {
92 [VK_TEX_MIPMAP_MODE_BASE
] = MIPFILTER_NONE
,
93 [VK_TEX_MIPMAP_MODE_NEAREST
] = MIPFILTER_NEAREST
,
94 [VK_TEX_MIPMAP_MODE_LINEAR
] = MIPFILTER_LINEAR
97 static const uint32_t vk_to_gen_tex_address
[] = {
98 [VK_TEX_ADDRESS_MODE_WRAP
] = TCM_WRAP
,
99 [VK_TEX_ADDRESS_MODE_MIRROR
] = TCM_MIRROR
,
100 [VK_TEX_ADDRESS_MODE_CLAMP
] = TCM_CLAMP
,
101 [VK_TEX_ADDRESS_MODE_MIRROR_ONCE
] = TCM_MIRROR_ONCE
,
102 [VK_TEX_ADDRESS_MODE_CLAMP_BORDER
] = TCM_CLAMP_BORDER
,
105 static const uint32_t vk_to_gen_compare_op
[] = {
106 [VK_COMPARE_OP_NEVER
] = PREFILTEROPNEVER
,
107 [VK_COMPARE_OP_LESS
] = PREFILTEROPLESS
,
108 [VK_COMPARE_OP_EQUAL
] = PREFILTEROPEQUAL
,
109 [VK_COMPARE_OP_LESS_EQUAL
] = PREFILTEROPLEQUAL
,
110 [VK_COMPARE_OP_GREATER
] = PREFILTEROPGREATER
,
111 [VK_COMPARE_OP_NOT_EQUAL
] = PREFILTEROPNOTEQUAL
,
112 [VK_COMPARE_OP_GREATER_EQUAL
] = PREFILTEROPGEQUAL
,
113 [VK_COMPARE_OP_ALWAYS
] = PREFILTEROPALWAYS
,
116 VkResult
gen7_CreateSampler(
118 const VkSamplerCreateInfo
* pCreateInfo
,
121 ANV_FROM_HANDLE(anv_device
, device
, _device
);
122 struct anv_sampler
*sampler
;
123 uint32_t mag_filter
, min_filter
, max_anisotropy
;
125 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
127 sampler
= anv_device_alloc(device
, sizeof(*sampler
), 8,
128 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
130 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
132 if (pCreateInfo
->maxAnisotropy
> 1) {
133 mag_filter
= MAPFILTER_ANISOTROPIC
;
134 min_filter
= MAPFILTER_ANISOTROPIC
;
135 max_anisotropy
= (pCreateInfo
->maxAnisotropy
- 2) / 2;
137 mag_filter
= vk_to_gen_tex_filter
[pCreateInfo
->magFilter
];
138 min_filter
= vk_to_gen_tex_filter
[pCreateInfo
->minFilter
];
139 max_anisotropy
= RATIO21
;
142 struct GEN7_SAMPLER_STATE sampler_state
= {
143 .SamplerDisable
= false,
144 .TextureBorderColorMode
= DX10OGL
,
146 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipMode
],
147 .MagModeFilter
= mag_filter
,
148 .MinModeFilter
= min_filter
,
149 .TextureLODBias
= pCreateInfo
->mipLodBias
* 256,
150 .AnisotropicAlgorithm
= EWAApproximation
,
151 .MinLOD
= pCreateInfo
->minLod
,
152 .MaxLOD
= pCreateInfo
->maxLod
,
153 .ChromaKeyEnable
= 0,
156 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
157 .CubeSurfaceControlMode
= 0,
159 .BorderColorPointer
=
160 device
->border_colors
.offset
+
161 pCreateInfo
->borderColor
* sizeof(float) * 4,
163 .MaximumAnisotropy
= max_anisotropy
,
164 .RAddressMinFilterRoundingEnable
= 0,
165 .RAddressMagFilterRoundingEnable
= 0,
166 .VAddressMinFilterRoundingEnable
= 0,
167 .VAddressMagFilterRoundingEnable
= 0,
168 .UAddressMinFilterRoundingEnable
= 0,
169 .UAddressMagFilterRoundingEnable
= 0,
170 .TrilinearFilterQuality
= 0,
171 .NonnormalizedCoordinateEnable
= 0,
172 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeU
],
173 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeV
],
174 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeW
],
177 GEN7_SAMPLER_STATE_pack(NULL
, sampler
->state
, &sampler_state
);
179 *pSampler
= anv_sampler_to_handle(sampler
);
183 VkResult
gen7_CreateDynamicRasterState(
185 const VkDynamicRasterStateCreateInfo
* pCreateInfo
,
186 VkDynamicRasterState
* pState
)
188 ANV_FROM_HANDLE(anv_device
, device
, _device
);
189 struct anv_dynamic_rs_state
*state
;
191 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO
);
193 state
= anv_device_alloc(device
, sizeof(*state
), 8,
194 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
196 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
198 bool enable_bias
= pCreateInfo
->depthBias
!= 0.0f
||
199 pCreateInfo
->slopeScaledDepthBias
!= 0.0f
;
201 struct GEN7_3DSTATE_SF sf
= {
202 GEN7_3DSTATE_SF_header
,
203 .LineWidth
= pCreateInfo
->lineWidth
,
204 .GlobalDepthOffsetEnableSolid
= enable_bias
,
205 .GlobalDepthOffsetEnableWireframe
= enable_bias
,
206 .GlobalDepthOffsetEnablePoint
= enable_bias
,
207 .GlobalDepthOffsetConstant
= pCreateInfo
->depthBias
,
208 .GlobalDepthOffsetScale
= pCreateInfo
->slopeScaledDepthBias
,
209 .GlobalDepthOffsetClamp
= pCreateInfo
->depthBiasClamp
212 GEN7_3DSTATE_SF_pack(NULL
, state
->gen7
.sf
, &sf
);
214 *pState
= anv_dynamic_rs_state_to_handle(state
);
219 VkResult
gen7_CreateDynamicDepthStencilState(
221 const VkDynamicDepthStencilStateCreateInfo
* pCreateInfo
,
222 VkDynamicDepthStencilState
* pState
)
224 ANV_FROM_HANDLE(anv_device
, device
, _device
);
225 struct anv_dynamic_ds_state
*state
;
227 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO
);
229 state
= anv_device_alloc(device
, sizeof(*state
), 8,
230 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
232 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
234 struct GEN7_DEPTH_STENCIL_STATE depth_stencil_state
= {
235 .StencilTestMask
= pCreateInfo
->stencilReadMask
& 0xff,
236 .StencilWriteMask
= pCreateInfo
->stencilWriteMask
& 0xff,
237 .BackfaceStencilTestMask
= pCreateInfo
->stencilReadMask
& 0xff,
238 .BackfaceStencilWriteMask
= pCreateInfo
->stencilWriteMask
& 0xff,
241 GEN7_DEPTH_STENCIL_STATE_pack(NULL
, state
->gen7
.depth_stencil_state
,
242 &depth_stencil_state
);
244 struct GEN7_COLOR_CALC_STATE color_calc_state
= {
245 .StencilReferenceValue
= pCreateInfo
->stencilFrontRef
,
246 .BackFaceStencilReferenceValue
= pCreateInfo
->stencilBackRef
249 GEN7_COLOR_CALC_STATE_pack(NULL
, state
->gen7
.color_calc_state
, &color_calc_state
);
251 *pState
= anv_dynamic_ds_state_to_handle(state
);
256 static const uint8_t anv_halign
[] = {
261 static const uint8_t anv_valign
[] = {
267 gen7_image_view_init(struct anv_image_view
*iview
,
268 struct anv_device
*device
,
269 const VkImageViewCreateInfo
* pCreateInfo
,
270 struct anv_cmd_buffer
*cmd_buffer
)
272 ANV_FROM_HANDLE(anv_image
, image
, pCreateInfo
->image
);
274 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
275 struct anv_surface
*surface
=
276 anv_image_get_surface_for_aspect_mask(image
, range
->aspectMask
);
278 const struct anv_format
*format
=
279 anv_format_for_vk_format(pCreateInfo
->format
);
281 const struct anv_image_view_info view_type_info
=
282 anv_image_view_info_for_vk_image_view_type(pCreateInfo
->viewType
);
284 if (pCreateInfo
->viewType
!= VK_IMAGE_VIEW_TYPE_2D
)
285 anv_finishme("non-2D image views");
287 iview
->bo
= image
->bo
;
288 iview
->offset
= image
->offset
+ surface
->offset
;
289 iview
->format
= anv_format_for_vk_format(pCreateInfo
->format
);
291 iview
->extent
= (VkExtent3D
) {
292 .width
= anv_minify(image
->extent
.width
, range
->baseMipLevel
),
293 .height
= anv_minify(image
->extent
.height
, range
->baseMipLevel
),
294 .depth
= anv_minify(image
->extent
.depth
, range
->baseMipLevel
),
298 if (range
->arraySize
> 1) {
299 depth
= range
->arraySize
;
300 } else if (image
->extent
.depth
> 1) {
301 depth
= image
->extent
.depth
;
304 struct GEN7_RENDER_SURFACE_STATE surface_state
= {
305 .SurfaceType
= view_type_info
.surface_type
,
306 .SurfaceArray
= image
->array_size
> 1,
307 .SurfaceFormat
= format
->surface_format
,
308 .SurfaceVerticalAlignment
= anv_valign
[surface
->v_align
],
309 .SurfaceHorizontalAlignment
= anv_halign
[surface
->h_align
],
311 /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
312 * Tiled Surface is False."
314 .TiledSurface
= surface
->tile_mode
> LINEAR
,
315 .TileWalk
= surface
->tile_mode
== YMAJOR
? TILEWALK_YMAJOR
: TILEWALK_XMAJOR
,
317 .VerticalLineStride
= 0,
318 .VerticalLineStrideOffset
= 0,
319 .RenderCacheReadWriteMode
= false,
321 .Height
= image
->extent
.height
- 1,
322 .Width
= image
->extent
.width
- 1,
324 .SurfacePitch
= surface
->stride
- 1,
325 .MinimumArrayElement
= range
->baseArraySlice
,
326 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
330 .SurfaceObjectControlState
= GEN7_MOCS
,
332 /* For render target surfaces, the hardware interprets field MIPCount/LOD as
333 * LOD. The Broadwell PRM says:
335 * MIPCountLOD defines the LOD that will be rendered into.
336 * SurfaceMinLOD is ignored.
338 .MIPCountLOD
= range
->mipLevels
- 1,
339 .SurfaceMinLOD
= range
->baseMipLevel
,
343 .GreenClearColor
= 0,
345 .AlphaClearColor
= 0,
346 .ResourceMinLOD
= 0.0,
347 .SurfaceBaseAddress
= { NULL
, iview
->offset
},
351 iview
->surface_state
=
352 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
354 iview
->surface_state
=
355 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
358 GEN7_RENDER_SURFACE_STATE_pack(NULL
, iview
->surface_state
.map
,
363 gen7_color_attachment_view_init(struct anv_attachment_view
*aview
,
364 struct anv_device
*device
,
365 const VkAttachmentViewCreateInfo
* pCreateInfo
,
366 struct anv_cmd_buffer
*cmd_buffer
)
368 ANV_FROM_HANDLE(anv_image
, image
, pCreateInfo
->image
);
369 struct anv_image_view
*iview
= &aview
->image_view
;
370 struct anv_surface
*surface
=
371 anv_image_get_surface_for_color_attachment(image
);
373 aview
->attachment_type
= ANV_ATTACHMENT_VIEW_TYPE_COLOR
;
375 anv_assert(pCreateInfo
->arraySize
> 0);
376 anv_assert(pCreateInfo
->mipLevel
< image
->levels
);
377 anv_assert(pCreateInfo
->baseArraySlice
+ pCreateInfo
->arraySize
<= image
->array_size
);
379 iview
->bo
= image
->bo
;
380 iview
->offset
= image
->offset
+ surface
->offset
;
381 iview
->format
= anv_format_for_vk_format(pCreateInfo
->format
);
383 iview
->extent
= (VkExtent3D
) {
384 .width
= anv_minify(image
->extent
.width
, pCreateInfo
->mipLevel
),
385 .height
= anv_minify(image
->extent
.height
, pCreateInfo
->mipLevel
),
386 .depth
= anv_minify(image
->extent
.depth
, pCreateInfo
->mipLevel
),
390 if (pCreateInfo
->arraySize
> 1) {
391 depth
= pCreateInfo
->arraySize
;
392 } else if (image
->extent
.depth
> 1) {
393 depth
= image
->extent
.depth
;
397 iview
->surface_state
=
398 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
400 iview
->surface_state
=
401 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
404 struct GEN7_RENDER_SURFACE_STATE surface_state
= {
405 .SurfaceType
= SURFTYPE_2D
,
406 .SurfaceArray
= image
->array_size
> 1,
407 .SurfaceFormat
= iview
->format
->surface_format
,
408 .SurfaceVerticalAlignment
= anv_valign
[surface
->v_align
],
409 .SurfaceHorizontalAlignment
= anv_halign
[surface
->h_align
],
411 /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
412 * Tiled Surface is False."
414 .TiledSurface
= surface
->tile_mode
> LINEAR
,
415 .TileWalk
= surface
->tile_mode
== YMAJOR
? TILEWALK_YMAJOR
: TILEWALK_XMAJOR
,
417 .VerticalLineStride
= 0,
418 .VerticalLineStrideOffset
= 0,
419 .RenderCacheReadWriteMode
= WriteOnlyCache
,
421 .Height
= image
->extent
.height
- 1,
422 .Width
= image
->extent
.width
- 1,
424 .SurfacePitch
= surface
->stride
- 1,
425 .MinimumArrayElement
= pCreateInfo
->baseArraySlice
,
426 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
430 .SurfaceObjectControlState
= GEN7_MOCS
,
432 /* For render target surfaces, the hardware interprets field MIPCount/LOD as
433 * LOD. The Broadwell PRM says:
435 * MIPCountLOD defines the LOD that will be rendered into.
436 * SurfaceMinLOD is ignored.
439 .MIPCountLOD
= pCreateInfo
->mipLevel
,
443 .GreenClearColor
= 0,
445 .AlphaClearColor
= 0,
446 .ResourceMinLOD
= 0.0,
447 .SurfaceBaseAddress
= { NULL
, iview
->offset
},
451 GEN7_RENDER_SURFACE_STATE_pack(NULL
, iview
->surface_state
.map
,