• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2022 Imagination Technologies Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * 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 THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include <stdint.h>
25 #include <vulkan/vulkan.h>
26 
27 #include "hwdef/rogue_hw_defs.h"
28 #include "pipe/p_defines.h"
29 #include "pvr_csb.h"
30 #include "pvr_device_info.h"
31 #include "pvr_formats.h"
32 #include "pvr_private.h"
33 #include "pvr_tex_state.h"
34 #include "util/macros.h"
35 #include "util/u_math.h"
36 #include "vk_format.h"
37 #include "vk_log.h"
38 
pvr_get_hw_swizzle(VkComponentSwizzle comp,enum pipe_swizzle swz)39 static enum ROGUE_TEXSTATE_SWIZ pvr_get_hw_swizzle(VkComponentSwizzle comp,
40                                                    enum pipe_swizzle swz)
41 {
42    switch (swz) {
43    case PIPE_SWIZZLE_0:
44       return ROGUE_TEXSTATE_SWIZ_SRC_ZERO;
45    case PIPE_SWIZZLE_1:
46       return ROGUE_TEXSTATE_SWIZ_SRC_ONE;
47    case PIPE_SWIZZLE_X:
48       return ROGUE_TEXSTATE_SWIZ_SRCCHAN_0;
49    case PIPE_SWIZZLE_Y:
50       return ROGUE_TEXSTATE_SWIZ_SRCCHAN_1;
51    case PIPE_SWIZZLE_Z:
52       return ROGUE_TEXSTATE_SWIZ_SRCCHAN_2;
53    case PIPE_SWIZZLE_W:
54       return ROGUE_TEXSTATE_SWIZ_SRCCHAN_3;
55    case PIPE_SWIZZLE_NONE:
56       if (comp == VK_COMPONENT_SWIZZLE_A)
57          return ROGUE_TEXSTATE_SWIZ_SRC_ONE;
58       else
59          return ROGUE_TEXSTATE_SWIZ_SRC_ZERO;
60    default:
61       unreachable("Unknown enum pipe_swizzle");
62    };
63 }
64 
65 VkResult
pvr_pack_tex_state(struct pvr_device * device,struct pvr_texture_state_info * info,uint64_t state[static const ROGUE_NUM_TEXSTATE_IMAGE_WORDS])66 pvr_pack_tex_state(struct pvr_device *device,
67                    struct pvr_texture_state_info *info,
68                    uint64_t state[static const ROGUE_NUM_TEXSTATE_IMAGE_WORDS])
69 {
70    const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
71    uint32_t texture_type;
72 
73    pvr_csb_pack (&state[0], TEXSTATE_IMAGE_WORD0, word0) {
74       /* Determine texture type */
75       if (info->is_cube && info->tex_state_type == PVR_TEXTURE_STATE_SAMPLE) {
76          word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_CUBE);
77       } else if (info->mem_layout == PVR_MEMLAYOUT_TWIDDLED ||
78                  info->mem_layout == PVR_MEMLAYOUT_3DTWIDDLED) {
79          if (info->type == VK_IMAGE_VIEW_TYPE_3D) {
80             word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_3D);
81          } else if (info->type == VK_IMAGE_VIEW_TYPE_1D ||
82                     info->type == VK_IMAGE_VIEW_TYPE_1D_ARRAY) {
83             word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_1D);
84          } else if (info->type == VK_IMAGE_VIEW_TYPE_2D ||
85                     info->type == VK_IMAGE_VIEW_TYPE_2D_ARRAY) {
86             word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_2D);
87          } else {
88             return vk_error(device, VK_ERROR_FORMAT_NOT_SUPPORTED);
89          }
90       } else if (info->mem_layout == PVR_MEMLAYOUT_LINEAR) {
91          word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_STRIDE);
92       } else {
93          return vk_error(device, VK_ERROR_FORMAT_NOT_SUPPORTED);
94       }
95 
96       word0.texformat = pvr_get_tex_format(info->format);
97       word0.smpcnt = util_logbase2(info->sample_count);
98       word0.swiz0 =
99          pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_R, info->swizzle[0]);
100       word0.swiz1 =
101          pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_G, info->swizzle[1]);
102       word0.swiz2 =
103          pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_B, info->swizzle[2]);
104       word0.swiz3 =
105          pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_A, info->swizzle[3]);
106 
107       /* Gamma */
108       if (vk_format_is_srgb(info->format)) {
109          /* Gamma for 2 Component Formats has to be handled differently. */
110          if (vk_format_get_nr_components(info->format) == 2) {
111             /* Enable Gamma only for Channel 0 if Channel 1 is an Alpha
112              * Channel.
113              */
114             if (vk_format_has_alpha(info->format)) {
115                word0.twocomp_gamma = PVRX(TEXSTATE_TWOCOMP_GAMMA_R);
116             } else {
117                /* Otherwise Enable Gamma for both the Channels. */
118                word0.twocomp_gamma = PVRX(TEXSTATE_TWOCOMP_GAMMA_RG);
119 
120                /* If Channel 0 happens to be the Alpha Channel, the
121                 * ALPHA_MSB bit would not be set thereby disabling Gamma
122                 * for Channel 0.
123                 */
124             }
125          } else {
126             word0.gamma = PVRX(TEXSTATE_GAMMA_ON);
127          }
128       }
129 
130       word0.width = info->extent.width - 1;
131       if (info->type != VK_IMAGE_VIEW_TYPE_1D &&
132           info->type != VK_IMAGE_VIEW_TYPE_1D_ARRAY)
133          word0.height = info->extent.height - 1;
134    }
135 
136    /* Texture type specific stuff (word 1) */
137    if (texture_type == PVRX(TEXSTATE_TEXTYPE_STRIDE)) {
138       pvr_csb_pack (&state[1], TEXSTATE_STRIDE_IMAGE_WORD1, word1) {
139          assert(info->stride > 0U);
140          word1.stride = info->stride - 1U;
141          word1.num_mip_levels = info->mip_levels;
142          word1.mipmaps_present = info->mipmaps_present;
143 
144          word1.texaddr = PVR_DEV_ADDR_OFFSET(info->addr, info->offset);
145 
146          if (vk_format_is_alpha_on_msb(info->format))
147             word1.alpha_msb = true;
148 
149          if (!PVR_HAS_FEATURE(dev_info, tpu_extended_integer_lookup) &&
150              !PVR_HAS_FEATURE(dev_info, tpu_image_state_v2)) {
151             if (info->flags & PVR_TEXFLAGS_INDEX_LOOKUP ||
152                 info->flags & PVR_TEXFLAGS_BUFFER)
153                word1.index_lookup = true;
154          }
155 
156          if (info->flags & PVR_TEXFLAGS_BUFFER)
157             word1.mipmaps_present = false;
158 
159          if (PVR_HAS_FEATURE(dev_info, tpu_image_state_v2) &&
160              vk_format_is_compressed(info->format))
161             word1.tpu_image_state_v2_compression_mode =
162                PVRX(TEXSTATE_COMPRESSION_MODE_TPU);
163       }
164    } else {
165       pvr_csb_pack (&state[1], TEXSTATE_IMAGE_WORD1, word1) {
166          word1.num_mip_levels = info->mip_levels;
167          word1.mipmaps_present = info->mipmaps_present;
168          word1.baselevel = info->base_level;
169 
170          if (info->extent.depth > 0) {
171             word1.depth = info->extent.depth - 1;
172          } else if (PVR_HAS_FEATURE(dev_info, tpu_array_textures)) {
173             uint32_t array_layers = info->array_size;
174 
175             if (info->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY &&
176                 info->tex_state_type == PVR_TEXTURE_STATE_SAMPLE)
177                array_layers /= 6;
178 
179             word1.depth = array_layers - 1;
180          }
181 
182          word1.texaddr = PVR_DEV_ADDR_OFFSET(info->addr, info->offset);
183 
184          if (!PVR_HAS_FEATURE(dev_info, tpu_extended_integer_lookup) &&
185              !PVR_HAS_FEATURE(dev_info, tpu_image_state_v2)) {
186             if (info->flags & PVR_TEXFLAGS_INDEX_LOOKUP ||
187                 info->flags & PVR_TEXFLAGS_BUFFER)
188                word1.index_lookup = true;
189          }
190 
191          if (info->flags & PVR_TEXFLAGS_BUFFER)
192             word1.mipmaps_present = false;
193 
194          if (info->flags & PVR_TEXFLAGS_BORDER)
195             word1.border = true;
196 
197          if (vk_format_is_alpha_on_msb(info->format))
198             word1.alpha_msb = true;
199 
200          if (PVR_HAS_FEATURE(dev_info, tpu_image_state_v2) &&
201              vk_format_is_compressed(info->format))
202             word1.tpu_image_state_v2_compression_mode =
203                PVRX(TEXSTATE_COMPRESSION_MODE_TPU);
204       }
205    }
206 
207    return VK_SUCCESS;
208 }
209