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 "gen8_pack.h"
35 gen8_fill_buffer_surface_state(void *state
, const struct anv_format
*format
,
36 uint32_t offset
, uint32_t range
, uint32_t stride
)
38 uint32_t num_elements
= range
/ stride
;
40 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
41 .SurfaceType
= SURFTYPE_BUFFER
,
42 .SurfaceArray
= false,
43 .SurfaceFormat
= format
->surface_format
,
44 .SurfaceVerticalAlignment
= VALIGN4
,
45 .SurfaceHorizontalAlignment
= HALIGN4
,
47 .SamplerL2BypassModeDisable
= true,
48 .RenderCacheReadWriteMode
= WriteOnlyCache
,
49 .MemoryObjectControlState
= GEN8_MOCS
,
50 .Height
= ((num_elements
- 1) >> 7) & 0x3fff,
51 .Width
= (num_elements
- 1) & 0x7f,
52 .Depth
= ((num_elements
- 1) >> 21) & 0x3f,
53 .SurfacePitch
= stride
- 1,
54 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
55 .ShaderChannelSelectRed
= SCS_RED
,
56 .ShaderChannelSelectGreen
= SCS_GREEN
,
57 .ShaderChannelSelectBlue
= SCS_BLUE
,
58 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
59 /* FIXME: We assume that the image must be bound at this time. */
60 .SurfaceBaseAddress
= { NULL
, offset
},
63 GEN8_RENDER_SURFACE_STATE_pack(NULL
, state
, &surface_state
);
66 static const uint8_t anv_halign
[] = {
72 static const uint8_t anv_valign
[] = {
78 static struct anv_state
79 gen8_alloc_surface_state(struct anv_device
*device
,
80 struct anv_cmd_buffer
*cmd_buffer
)
83 return anv_cmd_buffer_alloc_surface_state(cmd_buffer
);
85 return anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
90 gen8_image_view_init(struct anv_image_view
*iview
,
91 struct anv_device
*device
,
92 const VkImageViewCreateInfo
* pCreateInfo
,
93 struct anv_cmd_buffer
*cmd_buffer
)
95 ANV_FROM_HANDLE(anv_image
, image
, pCreateInfo
->image
);
97 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
99 struct anv_surface
*surface
=
100 anv_image_get_surface_for_aspect_mask(image
, range
->aspectMask
);
102 uint32_t depth
= 1; /* RENDER_SURFACE_STATE::Depth */
103 uint32_t rt_view_extent
= 1; /* RENDER_SURFACE_STATE::RenderTargetViewExtent */
105 const struct anv_format
*format_info
=
106 anv_format_for_vk_format(pCreateInfo
->format
);
108 iview
->image
= image
;
109 iview
->bo
= image
->bo
;
110 iview
->offset
= image
->offset
+ surface
->offset
;
111 iview
->format
= format_info
;
113 iview
->extent
= (VkExtent3D
) {
114 .width
= anv_minify(image
->extent
.width
, range
->baseMipLevel
),
115 .height
= anv_minify(image
->extent
.height
, range
->baseMipLevel
),
116 .depth
= anv_minify(image
->extent
.depth
, range
->baseMipLevel
),
119 switch (image
->type
) {
120 case VK_IMAGE_TYPE_1D
:
121 case VK_IMAGE_TYPE_2D
:
122 /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
124 * For SURFTYPE_1D, 2D, and CUBE: The range of this field is reduced
125 * by one for each increase from zero of Minimum Array Element. For
126 * example, if Minimum Array Element is set to 1024 on a 2D surface,
127 * the range of this field is reduced to [0,1023].
129 depth
= range
->arraySize
;
131 /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
133 * For Render Target and Typed Dataport 1D and 2D Surfaces:
134 * This field must be set to the same value as the Depth field.
136 rt_view_extent
= depth
;
138 case VK_IMAGE_TYPE_3D
:
139 /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
141 * If the volume texture is MIP-mapped, this field specifies the
142 * depth of the base MIP level.
144 depth
= image
->extent
.depth
;
146 /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
148 * For Render Target and Typed Dataport 3D Surfaces: This field
149 * indicates the extent of the accessible 'R' coordinates minus 1 on
150 * the LOD currently being rendered to.
152 rt_view_extent
= iview
->extent
.depth
;
155 unreachable(!"bad VkImageType");
158 static const uint32_t vk_to_gen_swizzle
[] = {
159 [VK_CHANNEL_SWIZZLE_ZERO
] = SCS_ZERO
,
160 [VK_CHANNEL_SWIZZLE_ONE
] = SCS_ONE
,
161 [VK_CHANNEL_SWIZZLE_R
] = SCS_RED
,
162 [VK_CHANNEL_SWIZZLE_G
] = SCS_GREEN
,
163 [VK_CHANNEL_SWIZZLE_B
] = SCS_BLUE
,
164 [VK_CHANNEL_SWIZZLE_A
] = SCS_ALPHA
167 static const uint8_t isl_to_gen_tiling
[] = {
168 [ISL_TILING_LINEAR
] = LINEAR
,
169 [ISL_TILING_X
] = XMAJOR
,
170 [ISL_TILING_Y
] = YMAJOR
,
171 [ISL_TILING_Yf
] = YMAJOR
,
172 [ISL_TILING_Ys
] = YMAJOR
,
173 [ISL_TILING_W
] = WMAJOR
,
176 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
177 .SurfaceType
= image
->surface_type
,
178 .SurfaceArray
= image
->array_size
> 1,
179 .SurfaceFormat
= format_info
->surface_format
,
180 .SurfaceVerticalAlignment
= anv_valign
[surface
->v_align
],
181 .SurfaceHorizontalAlignment
= anv_halign
[surface
->h_align
],
182 .TileMode
= isl_to_gen_tiling
[surface
->tiling
],
183 .VerticalLineStride
= 0,
184 .VerticalLineStrideOffset
= 0,
185 .SamplerL2BypassModeDisable
= true,
186 .RenderCacheReadWriteMode
= WriteOnlyCache
,
187 .MemoryObjectControlState
= GEN8_MOCS
,
189 /* The driver sets BaseMipLevel in SAMPLER_STATE, not here in
190 * RENDER_SURFACE_STATE. The Broadwell PRM says "it is illegal to have
191 * both Base Mip Level fields nonzero".
195 .SurfaceQPitch
= surface
->qpitch
>> 2,
196 .Height
= image
->extent
.height
- 1,
197 .Width
= image
->extent
.width
- 1,
199 .SurfacePitch
= surface
->stride
- 1,
200 .RenderTargetViewExtent
= rt_view_extent
- 1,
201 .MinimumArrayElement
= range
->baseArrayLayer
,
202 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
206 .MIPCountLOD
= 0, /* TEMPLATE */
207 .SurfaceMinLOD
= 0, /* TEMPLATE */
209 .AuxiliarySurfaceMode
= AUX_NONE
,
211 .GreenClearColor
= 0,
213 .AlphaClearColor
= 0,
214 .ShaderChannelSelectRed
= vk_to_gen_swizzle
[pCreateInfo
->channels
.r
],
215 .ShaderChannelSelectGreen
= vk_to_gen_swizzle
[pCreateInfo
->channels
.g
],
216 .ShaderChannelSelectBlue
= vk_to_gen_swizzle
[pCreateInfo
->channels
.b
],
217 .ShaderChannelSelectAlpha
= vk_to_gen_swizzle
[pCreateInfo
->channels
.a
],
218 .ResourceMinLOD
= 0.0,
219 .SurfaceBaseAddress
= { NULL
, iview
->offset
},
222 if (image
->needs_nonrt_surface_state
) {
223 iview
->nonrt_surface_state
=
224 gen8_alloc_surface_state(device
, cmd_buffer
);
226 /* For non render target surfaces, the hardware interprets field
227 * MIPCount/LOD as MIPCount. The range of levels accessible by the
228 * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
230 surface_state
.SurfaceMinLOD
= range
->baseMipLevel
;
231 surface_state
.MIPCountLOD
= range
->mipLevels
- 1;
233 GEN8_RENDER_SURFACE_STATE_pack(NULL
, iview
->nonrt_surface_state
.map
,
237 if (image
->needs_color_rt_surface_state
) {
238 iview
->color_rt_surface_state
=
239 gen8_alloc_surface_state(device
, cmd_buffer
);
241 /* For render target surfaces, the hardware interprets field
242 * MIPCount/LOD as LOD. The Broadwell PRM says:
244 * MIPCountLOD defines the LOD that will be rendered into.
245 * SurfaceMinLOD is ignored.
247 surface_state
.MIPCountLOD
= range
->baseMipLevel
;
248 surface_state
.SurfaceMinLOD
= 0;
250 GEN8_RENDER_SURFACE_STATE_pack(NULL
, iview
->color_rt_surface_state
.map
,
255 VkResult
gen8_CreateSampler(
257 const VkSamplerCreateInfo
* pCreateInfo
,
260 ANV_FROM_HANDLE(anv_device
, device
, _device
);
261 struct anv_sampler
*sampler
;
262 uint32_t mag_filter
, min_filter
, max_anisotropy
;
264 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
266 sampler
= anv_device_alloc(device
, sizeof(*sampler
), 8,
267 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
269 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
271 static const uint32_t vk_to_gen_tex_filter
[] = {
272 [VK_TEX_FILTER_NEAREST
] = MAPFILTER_NEAREST
,
273 [VK_TEX_FILTER_LINEAR
] = MAPFILTER_LINEAR
276 static const uint32_t vk_to_gen_mipmap_mode
[] = {
277 [VK_TEX_MIPMAP_MODE_BASE
] = MIPFILTER_NONE
,
278 [VK_TEX_MIPMAP_MODE_NEAREST
] = MIPFILTER_NEAREST
,
279 [VK_TEX_MIPMAP_MODE_LINEAR
] = MIPFILTER_LINEAR
282 static const uint32_t vk_to_gen_tex_address
[] = {
283 [VK_TEX_ADDRESS_MODE_WRAP
] = TCM_WRAP
,
284 [VK_TEX_ADDRESS_MODE_MIRROR
] = TCM_MIRROR
,
285 [VK_TEX_ADDRESS_MODE_CLAMP
] = TCM_CLAMP
,
286 [VK_TEX_ADDRESS_MODE_MIRROR_ONCE
] = TCM_MIRROR_ONCE
,
287 [VK_TEX_ADDRESS_MODE_CLAMP_BORDER
] = TCM_CLAMP_BORDER
,
290 static const uint32_t vk_to_gen_compare_op
[] = {
291 [VK_COMPARE_OP_NEVER
] = PREFILTEROPNEVER
,
292 [VK_COMPARE_OP_LESS
] = PREFILTEROPLESS
,
293 [VK_COMPARE_OP_EQUAL
] = PREFILTEROPEQUAL
,
294 [VK_COMPARE_OP_LESS_EQUAL
] = PREFILTEROPLEQUAL
,
295 [VK_COMPARE_OP_GREATER
] = PREFILTEROPGREATER
,
296 [VK_COMPARE_OP_NOT_EQUAL
] = PREFILTEROPNOTEQUAL
,
297 [VK_COMPARE_OP_GREATER_EQUAL
] = PREFILTEROPGEQUAL
,
298 [VK_COMPARE_OP_ALWAYS
] = PREFILTEROPALWAYS
,
301 if (pCreateInfo
->maxAnisotropy
> 1) {
302 mag_filter
= MAPFILTER_ANISOTROPIC
;
303 min_filter
= MAPFILTER_ANISOTROPIC
;
304 max_anisotropy
= (pCreateInfo
->maxAnisotropy
- 2) / 2;
306 mag_filter
= vk_to_gen_tex_filter
[pCreateInfo
->magFilter
];
307 min_filter
= vk_to_gen_tex_filter
[pCreateInfo
->minFilter
];
308 max_anisotropy
= RATIO21
;
311 struct GEN8_SAMPLER_STATE sampler_state
= {
312 .SamplerDisable
= false,
313 .TextureBorderColorMode
= DX10OGL
,
314 .LODPreClampMode
= 0,
316 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipMode
],
317 .MagModeFilter
= mag_filter
,
318 .MinModeFilter
= min_filter
,
319 .TextureLODBias
= anv_clamp_f(pCreateInfo
->mipLodBias
, -16, 15.996),
320 .AnisotropicAlgorithm
= EWAApproximation
,
321 .MinLOD
= anv_clamp_f(pCreateInfo
->minLod
, 0, 14),
322 .MaxLOD
= anv_clamp_f(pCreateInfo
->maxLod
, 0, 14),
323 .ChromaKeyEnable
= 0,
326 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
327 .CubeSurfaceControlMode
= 0,
329 .IndirectStatePointer
=
330 device
->border_colors
.offset
+
331 pCreateInfo
->borderColor
* sizeof(float) * 4,
333 .LODClampMagnificationMode
= MIPNONE
,
334 .MaximumAnisotropy
= max_anisotropy
,
335 .RAddressMinFilterRoundingEnable
= 0,
336 .RAddressMagFilterRoundingEnable
= 0,
337 .VAddressMinFilterRoundingEnable
= 0,
338 .VAddressMagFilterRoundingEnable
= 0,
339 .UAddressMinFilterRoundingEnable
= 0,
340 .UAddressMagFilterRoundingEnable
= 0,
341 .TrilinearFilterQuality
= 0,
342 .NonnormalizedCoordinateEnable
= pCreateInfo
->unnormalizedCoordinates
,
343 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeU
],
344 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeV
],
345 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeW
],
348 GEN8_SAMPLER_STATE_pack(NULL
, sampler
->state
, &sampler_state
);
350 *pSampler
= anv_sampler_to_handle(sampler
);