1 2 #ifndef __NV50_BLIT_H__ 3 #define __NV50_BLIT_H__ 4 5 #include "util/u_inlines.h" 6 #include "util/format/u_format.h" 7 8 void * 9 nv50_blitter_make_fp(struct pipe_context *, 10 unsigned mode, 11 enum pipe_texture_target); 12 13 unsigned 14 nv50_blit_select_mode(const struct pipe_blit_info *); 15 16 /* Converted to a pipe->blit. */ 17 void 18 nv50_resource_resolve(struct pipe_context *, const struct pipe_resolve_info *); 19 20 #define NV50_BLIT_MODE_PASS 0 /* pass through TEX $t0/$s0 output */ 21 #define NV50_BLIT_MODE_Z24S8 1 /* encode ZS values for RGBA unorm8 */ 22 #define NV50_BLIT_MODE_S8Z24 2 23 #define NV50_BLIT_MODE_X24S8 3 24 #define NV50_BLIT_MODE_S8X24 4 25 #define NV50_BLIT_MODE_Z24X8 5 26 #define NV50_BLIT_MODE_X8Z24 6 27 #define NV50_BLIT_MODE_ZS 7 /* put $t0/$s0 into R, $t1/$s1 into G */ 28 #define NV50_BLIT_MODE_XS 8 /* put $t1/$s1 into G */ 29 #define NV50_BLIT_MODE_INT_CLAMP 9 /* unsigned to signed integer conversion */ 30 #define NV50_BLIT_MODES 10 31 32 /* CUBE and RECT textures are reinterpreted as 2D(_ARRAY) */ 33 #define NV50_BLIT_TEXTURE_BUFFER 0 34 #define NV50_BLIT_TEXTURE_1D 1 35 #define NV50_BLIT_TEXTURE_2D 2 36 #define NV50_BLIT_TEXTURE_3D 3 37 #define NV50_BLIT_TEXTURE_1D_ARRAY 4 38 #define NV50_BLIT_TEXTURE_2D_ARRAY 5 39 #define NV50_BLIT_MAX_TEXTURE_TYPES 6 40 41 static inline unsigned nv50_blit_texture_type(enum pipe_texture_target target)42nv50_blit_texture_type(enum pipe_texture_target target) 43 { 44 switch (target) { 45 case PIPE_TEXTURE_1D: return NV50_BLIT_TEXTURE_1D; 46 case PIPE_TEXTURE_2D: return NV50_BLIT_TEXTURE_2D; 47 case PIPE_TEXTURE_3D: return NV50_BLIT_TEXTURE_3D; 48 case PIPE_TEXTURE_1D_ARRAY: return NV50_BLIT_TEXTURE_1D_ARRAY; 49 case PIPE_TEXTURE_2D_ARRAY: return NV50_BLIT_TEXTURE_2D_ARRAY; 50 default: 51 assert(target == PIPE_BUFFER); 52 return NV50_BLIT_TEXTURE_BUFFER; 53 } 54 } 55 56 static inline unsigned nv50_blit_get_tgsi_texture_target(enum pipe_texture_target target)57nv50_blit_get_tgsi_texture_target(enum pipe_texture_target target) 58 { 59 switch (target) { 60 case PIPE_TEXTURE_1D: return TGSI_TEXTURE_1D; 61 case PIPE_TEXTURE_2D: return TGSI_TEXTURE_2D; 62 case PIPE_TEXTURE_3D: return TGSI_TEXTURE_3D; 63 case PIPE_TEXTURE_1D_ARRAY: return TGSI_TEXTURE_1D_ARRAY; 64 case PIPE_TEXTURE_2D_ARRAY: return TGSI_TEXTURE_2D_ARRAY; 65 default: 66 assert(target == PIPE_BUFFER); 67 return TGSI_TEXTURE_BUFFER; 68 } 69 } 70 71 static inline enum pipe_texture_target nv50_blit_reinterpret_pipe_texture_target(enum pipe_texture_target target)72nv50_blit_reinterpret_pipe_texture_target(enum pipe_texture_target target) 73 { 74 switch (target) { 75 case PIPE_TEXTURE_CUBE: 76 case PIPE_TEXTURE_CUBE_ARRAY: 77 return PIPE_TEXTURE_2D_ARRAY; 78 case PIPE_TEXTURE_RECT: 79 return PIPE_TEXTURE_2D; 80 default: 81 return target; 82 } 83 } 84 85 static inline unsigned nv50_blit_get_filter(const struct pipe_blit_info * info)86nv50_blit_get_filter(const struct pipe_blit_info *info) 87 { 88 if (info->dst.resource->nr_samples < info->src.resource->nr_samples) 89 return (util_format_is_depth_or_stencil(info->src.format) || 90 util_format_is_pure_integer(info->src.format)) ? 0 : 1; 91 92 if (info->filter != PIPE_TEX_FILTER_LINEAR) 93 return 0; 94 95 if ((info->dst.box.width == info->src.box.width || 96 info->dst.box.width == -info->src.box.width) && 97 (info->dst.box.height == info->src.box.height || 98 info->dst.box.height == -info->src.box.height)) 99 return 0; 100 101 return 1; 102 } 103 104 /* Since shaders cannot export stencil, we cannot copy stencil values when 105 * rendering to ZETA, so we attach the ZS surface to a colour render target. 106 */ 107 static inline enum pipe_format nv50_blit_zeta_to_colour_format(enum pipe_format format)108nv50_blit_zeta_to_colour_format(enum pipe_format format) 109 { 110 switch (format) { 111 case PIPE_FORMAT_Z16_UNORM: 112 return PIPE_FORMAT_R16_UNORM; 113 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 114 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 115 case PIPE_FORMAT_Z24X8_UNORM: 116 case PIPE_FORMAT_X8Z24_UNORM: 117 case PIPE_FORMAT_X24S8_UINT: 118 case PIPE_FORMAT_S8X24_UINT: 119 return PIPE_FORMAT_R8G8B8A8_UNORM; 120 case PIPE_FORMAT_Z32_FLOAT: 121 return PIPE_FORMAT_R32_FLOAT; 122 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 123 case PIPE_FORMAT_X32_S8X24_UINT: 124 return PIPE_FORMAT_R32G32_FLOAT; 125 default: 126 assert(0); 127 return PIPE_FORMAT_NONE; 128 } 129 } 130 131 132 static inline uint16_t nv50_blit_derive_color_mask(const struct pipe_blit_info * info)133nv50_blit_derive_color_mask(const struct pipe_blit_info *info) 134 { 135 const unsigned mask = info->mask; 136 137 uint16_t color_mask = 0; 138 139 switch (info->dst.format) { 140 case PIPE_FORMAT_Z24X8_UNORM: 141 case PIPE_FORMAT_X24S8_UINT: 142 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 143 if (mask & PIPE_MASK_S) 144 color_mask |= 0x1000; 145 if (mask & PIPE_MASK_Z) 146 color_mask |= 0x0111; 147 break; 148 case PIPE_FORMAT_X8Z24_UNORM: 149 case PIPE_FORMAT_S8X24_UINT: 150 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 151 if (mask & PIPE_MASK_S) 152 color_mask |= 0x0001; 153 if (mask & PIPE_MASK_Z) 154 color_mask |= 0x1110; 155 break; 156 default: 157 if (mask & (PIPE_MASK_R | PIPE_MASK_Z)) color_mask |= 0x0001; 158 if (mask & (PIPE_MASK_G | PIPE_MASK_S)) color_mask |= 0x0010; 159 if (mask & PIPE_MASK_B) color_mask |= 0x0100; 160 if (mask & PIPE_MASK_A) color_mask |= 0x1000; 161 break; 162 } 163 164 return color_mask; 165 } 166 167 static inline uint32_t nv50_blit_eng2d_get_mask(const struct pipe_blit_info * info)168nv50_blit_eng2d_get_mask(const struct pipe_blit_info *info) 169 { 170 uint32_t mask = 0; 171 172 switch (info->dst.format) { 173 case PIPE_FORMAT_Z24X8_UNORM: 174 case PIPE_FORMAT_X24S8_UINT: 175 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 176 if (info->mask & PIPE_MASK_Z) mask |= 0x00ffffff; 177 if (info->mask & PIPE_MASK_S) mask |= 0xff000000; 178 break; 179 case PIPE_FORMAT_X8Z24_UNORM: 180 case PIPE_FORMAT_S8X24_UINT: 181 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 182 if (info->mask & PIPE_MASK_Z) mask |= 0xffffff00; 183 if (info->mask & PIPE_MASK_S) mask |= 0x000000ff; 184 break; 185 default: 186 mask = 0xffffffff; 187 break; 188 } 189 return mask; 190 } 191 192 #if NOUVEAU_DRIVER == 0xc0 193 # define nv50_format_table nvc0_format_table 194 #endif 195 196 /* return true for formats that can be converted among each other by NVC0_2D */ 197 static inline bool nv50_2d_dst_format_faithful(enum pipe_format format)198nv50_2d_dst_format_faithful(enum pipe_format format) 199 { 200 const uint64_t mask = 201 NV50_ENG2D_SUPPORTED_FORMATS & 202 ~NV50_ENG2D_NOCONVERT_FORMATS; 203 uint8_t id = nv50_format_table[format].rt; 204 return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0))); 205 } 206 static inline bool nv50_2d_src_format_faithful(enum pipe_format format)207nv50_2d_src_format_faithful(enum pipe_format format) 208 { 209 const uint64_t mask = 210 NV50_ENG2D_SUPPORTED_FORMATS & 211 ~(NV50_ENG2D_LUMINANCE_FORMATS | NV50_ENG2D_INTENSITY_FORMATS); 212 uint8_t id = nv50_format_table[format].rt; 213 return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0))); 214 } 215 216 static inline bool nv50_2d_format_supported(enum pipe_format format)217nv50_2d_format_supported(enum pipe_format format) 218 { 219 uint8_t id = nv50_format_table[format].rt; 220 return (id >= 0xc0) && 221 (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))); 222 } 223 224 static inline bool nv50_2d_dst_format_ops_supported(enum pipe_format format)225nv50_2d_dst_format_ops_supported(enum pipe_format format) 226 { 227 uint8_t id = nv50_format_table[format].rt; 228 return (id >= 0xc0) && 229 (NV50_ENG2D_OPERATION_FORMATS & (1ULL << (id - 0xc0))); 230 } 231 232 #endif /* __NV50_BLIT_H__ */ 233