1 /*
2 * Copyright 2020 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 <stdint.h>
25
26 #define __gen_address_type uint64_t
27 #define __gen_user_data void
28
29 static uint64_t
__gen_combine_address(void * data,void * loc,uint64_t addr,uint32_t delta)30 __gen_combine_address(__attribute__((unused)) void *data,
31 __attribute__((unused)) void *loc, uint64_t addr,
32 uint32_t delta)
33 {
34 return addr + delta;
35 }
36
37 #include "genxml/gen_macros.h"
38 #include "genxml/genX_pack.h"
39
40 #include "isl_priv.h"
41 #include "isl_genX_helpers.h"
42
43 #if GFX_VERx10 >= 125
44 static const uint8_t isl_encode_tiling[] = {
45 [ISL_TILING_4] = TILE4,
46 [ISL_TILING_64] = TILE64,
47 [ISL_TILING_64_XE2] = TILE64,
48 };
49 #endif
50
51 void
isl_genX(emit_cpb_control_s)52 isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch,
53 const struct isl_cpb_emit_info *restrict info)
54 {
55 #if GFX_VERx10 >= 125
56 if (info->surf) {
57 assert((info->surf->usage & ISL_SURF_USAGE_CPB_BIT));
58 assert(info->surf->dim != ISL_SURF_DIM_3D);
59 assert(info->surf->tiling == ISL_TILING_4 ||
60 isl_tiling_is_64(info->surf->tiling));
61 assert(info->surf->format == ISL_FORMAT_R8_UINT);
62 }
63
64 struct GENX(3DSTATE_CPSIZE_CONTROL_BUFFER) cpb = {
65 GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_header),
66 };
67
68 if (info->surf) {
69 /* BSpec 46962 has a number of restriction on the fields of this packet
70 * like :
71 *
72 * "The Width specified by this field must be less than or equal to
73 * the surface pitch (specified in bytes via the Surface Pitch field).
74 * For cube maps, Width must be set equal to Height.
75 *
76 * 1. The Width ofthis buffer must be the same as the Width of the
77 * render target(s) (defined in SURFACE_STATE), unless Surface
78 * Type is SURFTYPE_1D or SURFTYPE_2D with Depth = 0 (non-array)
79 * and LOD = 0 (non-mip mapped).
80 *
81 * 2. Depth buffer (defined in 3DSTATE_DEPTH_BUFFER) unless either
82 * the depth buffer or this buffer surf_typeare SURFTYPE_NULL"
83 *
84 * Unfortunately APIs like Vulkan do not give guarantees that every
85 * framebuffer attachment will match in size (RT & CPB surfaces for
86 * example). But at least it gives a guarantee that all the attachments
87 * of a render pass will be at least be large enough to handle the
88 * rendered area. So here we use the CPB surface values, even if they
89 * don't strictly match the various BSpec restrictions.
90 */
91 cpb.Width = (info->surf->logical_level0_px.width * 8) - 1;
92 cpb.Height = (info->surf->logical_level0_px.height * 8) - 1;
93 cpb.Depth = info->view->array_len - 1;
94 cpb.RenderTargetViewExtent = cpb.Depth;
95
96 cpb.SurfLOD = info->view->base_level;
97 cpb.MinimumArrayElement = info->view->base_array_layer;
98 cpb.SurfaceType = SURFTYPE_2D;
99 cpb.SurfacePitch = info->surf->row_pitch_B - 1;
100 cpb.MOCS = info->mocs;
101 cpb.SurfaceQPitch = isl_surf_get_array_pitch_sa_rows(info->surf) >> 2;
102 cpb.TiledMode = isl_encode_tiling[info->surf->tiling];
103
104 assert(info->address % info->surf->alignment_B == 0);
105 cpb.SurfaceBaseAddress = info->address;
106
107 cpb.MipTailStartLOD = info->surf->miptail_start_level;
108 /* TODO:
109 *
110 * cpb.CPCBCompressionEnable is this CCS compression? Currently disabled
111 * in isl_surf_supports_ccs() for CPB buffers.
112 */
113 #if GFX_VER >= 20
114 cpb.CompressionFormat =
115 isl_get_render_compression_format(info->surf->format);
116 #endif
117 } else {
118 cpb.SurfaceType = SURFTYPE_NULL;
119 cpb.TiledMode = TILE64;
120 }
121
122 /* Pack everything into the batch */
123 uint32_t *dw = batch;
124 GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_pack)(NULL, dw, &cpb);
125 #else
126 unreachable("Coarse pixel shading not supported");
127 #endif
128 }
129