1/* 2 * Copyright (c) 2012-2015 Etnaviv Project 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, sub license, 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 12 * next paragraph) shall be included in all copies or substantial portions 13 * of the 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 NON-INFRINGEMENT. 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 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * Wladimir J. van der Laan <laanwj@gmail.com> 25 */ 26 27#include "etnaviv_texture_state.h" 28 29#include "hw/common.xml.h" 30 31#include "etnaviv_clear_blit.h" 32#include "etnaviv_context.h" 33#include "etnaviv_emit.h" 34#include "etnaviv_format.h" 35#include "etnaviv_texture.h" 36#include "etnaviv_translate.h" 37#include "util/u_inlines.h" 38#include "util/u_memory.h" 39 40#include "drm-uapi/drm_fourcc.h" 41 42struct etna_sampler_state { 43 struct pipe_sampler_state base; 44 45 /* sampler offset +4*sampler, interleave when committing state */ 46 uint32_t config0; 47 uint32_t config1; 48 uint32_t config_lod; 49 uint32_t config_3d; 50 uint32_t baselod; 51 unsigned min_lod, max_lod, max_lod_min; 52}; 53 54static inline struct etna_sampler_state * 55etna_sampler_state(struct pipe_sampler_state *samp) 56{ 57 return (struct etna_sampler_state *)samp; 58} 59 60struct etna_sampler_view { 61 struct pipe_sampler_view base; 62 63 /* sampler offset +4*sampler, interleave when committing state */ 64 uint32_t config0; 65 uint32_t config0_mask; 66 uint32_t config1; 67 uint32_t config_3d; 68 uint32_t size; 69 uint32_t log_size; 70 uint32_t astc0; 71 uint32_t linear_stride; /* only LOD0 */ 72 struct etna_reloc lod_addr[VIVS_TE_SAMPLER_LOD_ADDR__LEN]; 73 unsigned min_lod, max_lod; /* 5.5 fixp */ 74 75 struct etna_sampler_ts ts; 76}; 77 78static inline struct etna_sampler_view * 79etna_sampler_view(struct pipe_sampler_view *view) 80{ 81 return (struct etna_sampler_view *)view; 82} 83 84static void * 85etna_create_sampler_state_state(struct pipe_context *pipe, 86 const struct pipe_sampler_state *ss) 87{ 88 struct etna_sampler_state *cs = CALLOC_STRUCT(etna_sampler_state); 89 struct etna_context *ctx = etna_context(pipe); 90 struct etna_screen *screen = ctx->screen; 91 const bool ansio = ss->max_anisotropy > 1; 92 const bool mipmap = ss->min_mip_filter != PIPE_TEX_MIPFILTER_NONE; 93 94 if (!cs) 95 return NULL; 96 97 cs->base = *ss; 98 99 cs->config0 = 100 VIVS_TE_SAMPLER_CONFIG0_UWRAP(translate_texture_wrapmode(ss->wrap_s)) | 101 VIVS_TE_SAMPLER_CONFIG0_VWRAP(translate_texture_wrapmode(ss->wrap_t)) | 102 VIVS_TE_SAMPLER_CONFIG0_MIN(translate_texture_filter(ss->min_img_filter)) | 103 VIVS_TE_SAMPLER_CONFIG0_MIP(translate_texture_mipfilter(ss->min_mip_filter)) | 104 VIVS_TE_SAMPLER_CONFIG0_MAG(translate_texture_filter(ss->mag_img_filter)) | 105 VIVS_TE_SAMPLER_CONFIG0_ANISOTROPY(COND(ansio, etna_log2_fixp55(ss->max_anisotropy))); 106 107 /* ROUND_UV improves precision - but not compatible with NEAREST filter */ 108 if (ss->min_img_filter != PIPE_TEX_FILTER_NEAREST && 109 ss->mag_img_filter != PIPE_TEX_FILTER_NEAREST) { 110 cs->config0 |= VIVS_TE_SAMPLER_CONFIG0_ROUND_UV; 111 } 112 113 cs->config1 = screen->specs.seamless_cube_map ? 114 COND(ss->seamless_cube_map, VIVS_TE_SAMPLER_CONFIG1_SEAMLESS_CUBE_MAP) : 0; 115 116 cs->config_lod = 117 COND(ss->lod_bias != 0.0 && mipmap, VIVS_TE_SAMPLER_LOD_CONFIG_BIAS_ENABLE) | 118 VIVS_TE_SAMPLER_LOD_CONFIG_BIAS(etna_float_to_fixp55(ss->lod_bias)); 119 120 cs->config_3d = 121 VIVS_TE_SAMPLER_3D_CONFIG_WRAP(translate_texture_wrapmode(ss->wrap_r)); 122 123 if (mipmap) { 124 cs->min_lod = etna_float_to_fixp55(ss->min_lod); 125 cs->max_lod = etna_float_to_fixp55(ss->max_lod); 126 } else { 127 /* when not mipmapping, we need to set max/min lod so that always 128 * lowest LOD is selected */ 129 cs->min_lod = cs->max_lod = etna_float_to_fixp55(0.0f); 130 } 131 132 /* if max_lod is 0, MIN filter will never be used (GC3000) 133 * when min filter is different from mag filter, we need HW to compute LOD 134 * the workaround is to set max_lod to at least 1 135 */ 136 cs->max_lod_min = (ss->min_img_filter != ss->mag_img_filter) ? 1 : 0; 137 138 cs->baselod = 139 COND(ss->compare_mode, VIVS_NTE_SAMPLER_BASELOD_COMPARE_ENABLE) | 140 VIVS_NTE_SAMPLER_BASELOD_COMPARE_FUNC(translate_texture_compare(ss->compare_func)); 141 142 /* force nearest filting for nir_lower_sample_tex_compare(..) */ 143 if ((ctx->screen->specs.halti < 2) && ss->compare_mode) { 144 cs->config0 &= ~VIVS_TE_SAMPLER_CONFIG0_MIN__MASK; 145 cs->config0 &= ~VIVS_TE_SAMPLER_CONFIG0_MAG__MASK; 146 147 cs->config0 |= 148 VIVS_TE_SAMPLER_CONFIG0_MIN(TEXTURE_FILTER_NEAREST) | 149 VIVS_TE_SAMPLER_CONFIG0_MAG(TEXTURE_FILTER_NEAREST); 150 } 151 152 return cs; 153} 154 155static void 156etna_delete_sampler_state_state(struct pipe_context *pctx, void *ss) 157{ 158 FREE(ss); 159} 160 161static struct pipe_sampler_view * 162etna_create_sampler_view_state(struct pipe_context *pctx, struct pipe_resource *prsc, 163 const struct pipe_sampler_view *so) 164{ 165 struct etna_sampler_view *sv = CALLOC_STRUCT(etna_sampler_view); 166 struct etna_context *ctx = etna_context(pctx); 167 struct etna_screen *screen = ctx->screen; 168 const uint32_t format = translate_texture_format(so->format); 169 const bool ext = !!(format & EXT_FORMAT); 170 const bool astc = !!(format & ASTC_FORMAT); 171 const bool srgb = util_format_is_srgb(so->format); 172 const uint32_t swiz = get_texture_swiz(so->format, so->swizzle_r, 173 so->swizzle_g, so->swizzle_b, 174 so->swizzle_a); 175 176 if (!sv) 177 return NULL; 178 179 struct etna_resource *res = etna_texture_handle_incompatible(pctx, prsc); 180 if (!res) { 181 free(sv); 182 return NULL; 183 } 184 185 sv->base = *so; 186 pipe_reference_init(&sv->base.reference, 1); 187 sv->base.texture = NULL; 188 pipe_resource_reference(&sv->base.texture, prsc); 189 sv->base.context = pctx; 190 191 /* merged with sampler state */ 192 sv->config0 = 193 VIVS_TE_SAMPLER_CONFIG0_TYPE(translate_texture_target(sv->base.target)) | 194 COND(!ext && !astc, VIVS_TE_SAMPLER_CONFIG0_FORMAT(format)); 195 sv->config0_mask = 0xffffffff; 196 197 uint32_t base_height = res->base.height0; 198 uint32_t base_depth = res->base.depth0; 199 bool is_array = false; 200 201 switch (sv->base.target) { 202 case PIPE_TEXTURE_1D: 203 /* use 2D texture with T wrap to repeat for 1D texture 204 * TODO: check if old HW supports 1D texture 205 */ 206 sv->config0_mask = ~VIVS_TE_SAMPLER_CONFIG0_VWRAP__MASK; 207 sv->config0 &= ~VIVS_TE_SAMPLER_CONFIG0_TYPE__MASK; 208 sv->config0 |= 209 VIVS_TE_SAMPLER_CONFIG0_TYPE(TEXTURE_TYPE_2D) | 210 VIVS_TE_SAMPLER_CONFIG0_VWRAP(TEXTURE_WRAPMODE_REPEAT); 211 break; 212 case PIPE_TEXTURE_1D_ARRAY: 213 is_array = true; 214 base_height = res->base.array_size; 215 break; 216 case PIPE_TEXTURE_2D_ARRAY: 217 is_array = true; 218 base_depth = res->base.array_size; 219 break; 220 default: 221 break; 222 } 223 224 if (res->layout == ETNA_LAYOUT_LINEAR && !util_format_is_compressed(so->format)) { 225 sv->config0 |= VIVS_TE_SAMPLER_CONFIG0_ADDRESSING_MODE(TEXTURE_ADDRESSING_MODE_LINEAR); 226 227 assert(res->base.last_level == 0); 228 sv->linear_stride = res->levels[0].stride; 229 } else { 230 sv->config0 |= VIVS_TE_SAMPLER_CONFIG0_ADDRESSING_MODE(TEXTURE_ADDRESSING_MODE_TILED); 231 sv->linear_stride = 0; 232 } 233 234 sv->config1 |= COND(ext, VIVS_TE_SAMPLER_CONFIG1_FORMAT_EXT(format)) | 235 COND(astc, VIVS_TE_SAMPLER_CONFIG1_FORMAT_EXT(TEXTURE_FORMAT_EXT_ASTC)) | 236 COND(is_array, VIVS_TE_SAMPLER_CONFIG1_TEXTURE_ARRAY) | 237 VIVS_TE_SAMPLER_CONFIG1_HALIGN(res->halign) | swiz; 238 sv->astc0 = COND(astc, VIVS_NTE_SAMPLER_ASTC0_ASTC_FORMAT(format)) | 239 COND(astc && srgb, VIVS_NTE_SAMPLER_ASTC0_ASTC_SRGB) | 240 VIVS_NTE_SAMPLER_ASTC0_UNK8(0xc) | 241 VIVS_NTE_SAMPLER_ASTC0_UNK16(0xc) | 242 VIVS_NTE_SAMPLER_ASTC0_UNK24(0xc); 243 sv->size = VIVS_TE_SAMPLER_SIZE_WIDTH(res->base.width0) | 244 VIVS_TE_SAMPLER_SIZE_HEIGHT(base_height); 245 sv->log_size = 246 VIVS_TE_SAMPLER_LOG_SIZE_WIDTH(etna_log2_fixp55(res->base.width0)) | 247 VIVS_TE_SAMPLER_LOG_SIZE_HEIGHT(etna_log2_fixp55(base_height)) | 248 COND(util_format_is_srgb(so->format) && !astc, VIVS_TE_SAMPLER_LOG_SIZE_SRGB) | 249 COND(astc, VIVS_TE_SAMPLER_LOG_SIZE_ASTC); 250 sv->config_3d = 251 VIVS_TE_SAMPLER_3D_CONFIG_DEPTH(base_depth) | 252 VIVS_TE_SAMPLER_3D_CONFIG_LOG_DEPTH(etna_log2_fixp55(base_depth)); 253 254 /* Set up levels-of-detail */ 255 for (int lod = 0; lod <= res->base.last_level; ++lod) { 256 sv->lod_addr[lod].bo = res->bo; 257 sv->lod_addr[lod].offset = res->levels[lod].offset; 258 sv->lod_addr[lod].flags = ETNA_RELOC_READ; 259 } 260 sv->min_lod = sv->base.u.tex.first_level << 5; 261 sv->max_lod = MIN2(sv->base.u.tex.last_level, res->base.last_level) << 5; 262 263 /* Workaround for npot textures -- it appears that only CLAMP_TO_EDGE is 264 * supported when the appropriate capability is not set. */ 265 if (!screen->specs.npot_tex_any_wrap && 266 (!util_is_power_of_two_or_zero(res->base.width0) || 267 !util_is_power_of_two_or_zero(res->base.height0))) { 268 sv->config0_mask = ~(VIVS_TE_SAMPLER_CONFIG0_UWRAP__MASK | 269 VIVS_TE_SAMPLER_CONFIG0_VWRAP__MASK); 270 sv->config0 |= 271 VIVS_TE_SAMPLER_CONFIG0_UWRAP(TEXTURE_WRAPMODE_CLAMP_TO_EDGE) | 272 VIVS_TE_SAMPLER_CONFIG0_VWRAP(TEXTURE_WRAPMODE_CLAMP_TO_EDGE); 273 } 274 275 return &sv->base; 276} 277 278static void 279etna_sampler_view_state_destroy(struct pipe_context *pctx, 280 struct pipe_sampler_view *view) 281{ 282 pipe_resource_reference(&view->texture, NULL); 283 FREE(view); 284} 285 286#define EMIT_STATE(state_name, src_value) \ 287 etna_coalsence_emit(stream, &coalesce, VIVS_##state_name, src_value) 288 289#define EMIT_STATE_FIXP(state_name, src_value) \ 290 etna_coalsence_emit_fixp(stream, &coalesce, VIVS_##state_name, src_value) 291 292#define EMIT_STATE_RELOC(state_name, src_value) \ 293 etna_coalsence_emit_reloc(stream, &coalesce, VIVS_##state_name, src_value) 294 295static void 296etna_emit_ts_state(struct etna_context *ctx) 297{ 298 struct etna_cmd_stream *stream = ctx->stream; 299 uint32_t active_samplers = active_samplers_bits(ctx); 300 uint32_t dirty = ctx->dirty; 301 struct etna_coalesce coalesce; 302 303 etna_coalesce_start(stream, &coalesce); 304 305 if (unlikely(dirty & ETNA_DIRTY_SAMPLER_VIEWS)) { 306 for (int x = 0; x < VIVS_TS_SAMPLER__LEN; ++x) { 307 if ((1 << x) & active_samplers) { 308 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 309 /*01720*/ EMIT_STATE(TS_SAMPLER_CONFIG(x), sv->ts.TS_SAMPLER_CONFIG); 310 } 311 } 312 for (int x = 0; x < VIVS_TS_SAMPLER__LEN; ++x) { 313 if ((1 << x) & active_samplers) { 314 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 315 /*01740*/ EMIT_STATE_RELOC(TS_SAMPLER_STATUS_BASE(x), &sv->ts.TS_SAMPLER_STATUS_BASE); 316 } 317 } 318 for (int x = 0; x < VIVS_TS_SAMPLER__LEN; ++x) { 319 if ((1 << x) & active_samplers) { 320 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 321 /*01760*/ EMIT_STATE(TS_SAMPLER_CLEAR_VALUE(x), sv->ts.TS_SAMPLER_CLEAR_VALUE); 322 } 323 } 324 for (int x = 0; x < VIVS_TS_SAMPLER__LEN; ++x) { 325 if ((1 << x) & active_samplers) { 326 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 327 /*01780*/ EMIT_STATE(TS_SAMPLER_CLEAR_VALUE2(x), sv->ts.TS_SAMPLER_CLEAR_VALUE2); 328 } 329 } 330 } 331 332 etna_coalesce_end(stream, &coalesce); 333} 334 335static void 336etna_emit_new_texture_state(struct etna_context *ctx) 337{ 338 struct etna_cmd_stream *stream = ctx->stream; 339 struct etna_screen *screen = ctx->screen; 340 uint32_t active_samplers = active_samplers_bits(ctx); 341 uint32_t dirty = ctx->dirty; 342 struct etna_coalesce coalesce; 343 344 etna_emit_ts_state(ctx); 345 346 etna_coalesce_start(stream, &coalesce); 347 348 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_SAMPLERS))) { 349 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 350 uint32_t val = 0; /* 0 == sampler inactive */ 351 352 /* set active samplers to their configuration value (determined by both 353 * the sampler state and sampler view) */ 354 if ((1 << x) & active_samplers) { 355 struct etna_sampler_state *ss = etna_sampler_state(ctx->sampler[x]); 356 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 357 358 val = (ss->config0 & sv->config0_mask) | sv->config0; 359 } 360 361 /*10000*/ EMIT_STATE(NTE_SAMPLER_CONFIG0(x), val); 362 } 363 } 364 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS))) { 365 struct etna_sampler_state *ss; 366 struct etna_sampler_view *sv; 367 368 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 369 if ((1 << x) & active_samplers) { 370 sv = etna_sampler_view(ctx->sampler_view[x]); 371 /*10080*/ EMIT_STATE(NTE_SAMPLER_SIZE(x), sv->size); 372 } 373 } 374 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 375 if ((1 << x) & active_samplers) { 376 ss = etna_sampler_state(ctx->sampler[x]); 377 sv = etna_sampler_view(ctx->sampler_view[x]); 378 uint32_t log_size = sv->log_size; 379 380 if (texture_use_int_filter(&sv->base, &ss->base, false)) 381 log_size |= VIVS_TE_SAMPLER_LOG_SIZE_INT_FILTER; 382 383 /*10100*/ EMIT_STATE(NTE_SAMPLER_LOG_SIZE(x), log_size); 384 } 385 } 386 } 387 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_SAMPLERS))) { 388 struct etna_sampler_state *ss; 389 struct etna_sampler_view *sv; 390 391 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 392 if ((1 << x) & active_samplers) { 393 ss = etna_sampler_state(ctx->sampler[x]); 394 sv = etna_sampler_view(ctx->sampler_view[x]); 395 396 unsigned max_lod = MAX2(MIN2(ss->max_lod + sv->min_lod, sv->max_lod), ss->max_lod_min); 397 unsigned min_lod = MIN2(MAX2(ss->min_lod + sv->min_lod, sv->min_lod), max_lod); 398 399 /* min and max lod is determined both by the sampler and the view */ 400 /*10180*/ EMIT_STATE(NTE_SAMPLER_LOD_CONFIG(x), 401 ss->config_lod | 402 VIVS_TE_SAMPLER_LOD_CONFIG_MAX(max_lod) | 403 VIVS_TE_SAMPLER_LOD_CONFIG_MIN(min_lod)); 404 } 405 } 406 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS))) { 407 /* only LOD0 is valid for this register */ 408 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 409 if ((1 << x) & active_samplers) { 410 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 411 /*10280*/ EMIT_STATE(NTE_SAMPLER_LINEAR_STRIDE(0, x), sv->linear_stride); 412 } 413 } 414 } 415 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 416 if ((1 << x) & active_samplers) { 417 ss = etna_sampler_state(ctx->sampler[x]); 418 sv = etna_sampler_view(ctx->sampler_view[x]); 419 420 /*10300*/ EMIT_STATE(NTE_SAMPLER_3D_CONFIG(x), ss->config_3d | 421 sv->config_3d); 422 } 423 } 424 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 425 if ((1 << x) & active_samplers) { 426 ss = etna_sampler_state(ctx->sampler[x]); 427 sv = etna_sampler_view(ctx->sampler_view[x]); 428 429 /*10380*/ EMIT_STATE(NTE_SAMPLER_CONFIG1(x), ss->config1 | 430 sv->config1 | 431 COND(sv->ts.enable, VIVS_TE_SAMPLER_CONFIG1_USE_TS)); 432 } 433 } 434 } 435 if (unlikely(screen->specs.tex_astc && (dirty & (ETNA_DIRTY_SAMPLER_VIEWS)))) { 436 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 437 if ((1 << x) & active_samplers) { 438 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 439 /*10500*/ EMIT_STATE(NTE_SAMPLER_ASTC0(x), sv->astc0); 440 } 441 } 442 } 443 if (unlikely(dirty & (ETNA_DIRTY_SAMPLERS))) { 444 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 445 if ((1 << x) & active_samplers) { 446 struct etna_sampler_state *ss = etna_sampler_state(ctx->sampler[x]); 447 /*10700*/ EMIT_STATE(NTE_SAMPLER_BASELOD(x), ss->baselod); 448 } 449 } 450 } 451 452 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS))) { 453 for (int x = 0; x < VIVS_NTE_SAMPLER__LEN; ++x) { 454 if ((1 << x) & active_samplers) { 455 for (int y = 0; y < VIVS_NTE_SAMPLER_ADDR_LOD__LEN; ++y) { 456 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 457 /*10800*/ EMIT_STATE_RELOC(NTE_SAMPLER_ADDR_LOD(x, y), &sv->lod_addr[y]); 458 } 459 } 460 } 461 } 462 463 etna_coalesce_end(stream, &coalesce); 464} 465 466/* Emit plain (non-descriptor) texture state */ 467static void 468etna_emit_texture_state(struct etna_context *ctx) 469{ 470 struct etna_cmd_stream *stream = ctx->stream; 471 struct etna_screen *screen = ctx->screen; 472 uint32_t active_samplers = active_samplers_bits(ctx); 473 uint32_t dirty = ctx->dirty; 474 struct etna_coalesce coalesce; 475 476 etna_emit_ts_state(ctx); 477 478 etna_coalesce_start(stream, &coalesce); 479 480 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_SAMPLERS))) { 481 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 482 uint32_t val = 0; /* 0 == sampler inactive */ 483 484 /* set active samplers to their configuration value (determined by both 485 * the sampler state and sampler view) */ 486 if ((1 << x) & active_samplers) { 487 struct etna_sampler_state *ss = etna_sampler_state(ctx->sampler[x]); 488 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 489 490 val = (ss->config0 & sv->config0_mask) | sv->config0; 491 } 492 493 /*02000*/ EMIT_STATE(TE_SAMPLER_CONFIG0(x), val); 494 } 495 } 496 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS))) { 497 struct etna_sampler_state *ss; 498 struct etna_sampler_view *sv; 499 500 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 501 if ((1 << x) & active_samplers) { 502 sv = etna_sampler_view(ctx->sampler_view[x]); 503 /*02040*/ EMIT_STATE(TE_SAMPLER_SIZE(x), sv->size); 504 } 505 } 506 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 507 if ((1 << x) & active_samplers) { 508 ss = etna_sampler_state(ctx->sampler[x]); 509 sv = etna_sampler_view(ctx->sampler_view[x]); 510 uint32_t log_size = sv->log_size; 511 512 if (texture_use_int_filter(&sv->base, &ss->base, false)) 513 log_size |= VIVS_TE_SAMPLER_LOG_SIZE_INT_FILTER; 514 515 /*02080*/ EMIT_STATE(TE_SAMPLER_LOG_SIZE(x), log_size); 516 } 517 } 518 } 519 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_SAMPLERS))) { 520 struct etna_sampler_state *ss; 521 struct etna_sampler_view *sv; 522 523 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 524 if ((1 << x) & active_samplers) { 525 ss = etna_sampler_state(ctx->sampler[x]); 526 sv = etna_sampler_view(ctx->sampler_view[x]); 527 528 unsigned max_lod = MAX2(MIN2(ss->max_lod + sv->min_lod, sv->max_lod), ss->max_lod_min); 529 unsigned min_lod = MIN2(MAX2(ss->min_lod + sv->min_lod, sv->min_lod), max_lod); 530 531 /* min and max lod is determined both by the sampler and the view */ 532 /*020C0*/ EMIT_STATE(TE_SAMPLER_LOD_CONFIG(x), 533 ss->config_lod | 534 VIVS_TE_SAMPLER_LOD_CONFIG_MAX(max_lod) | 535 VIVS_TE_SAMPLER_LOD_CONFIG_MIN(min_lod)); 536 } 537 } 538 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 539 if ((1 << x) & active_samplers) { 540 ss = etna_sampler_state(ctx->sampler[x]); 541 sv = etna_sampler_view(ctx->sampler_view[x]); 542 543 /*02180*/ EMIT_STATE(TE_SAMPLER_3D_CONFIG(x), ss->config_3d | 544 sv->config_3d); 545 } 546 } 547 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 548 if ((1 << x) & active_samplers) { 549 ss = etna_sampler_state(ctx->sampler[x]); 550 sv = etna_sampler_view(ctx->sampler_view[x]); 551 552 /*021C0*/ EMIT_STATE(TE_SAMPLER_CONFIG1(x), ss->config1 | 553 sv->config1 | 554 COND(sv->ts.enable, VIVS_TE_SAMPLER_CONFIG1_USE_TS)); 555 } 556 } 557 } 558 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS))) { 559 for (int y = 0; y < VIVS_TE_SAMPLER_LOD_ADDR__LEN; ++y) { 560 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 561 if ((1 << x) & active_samplers) { 562 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 563 /*02400*/ EMIT_STATE_RELOC(TE_SAMPLER_LOD_ADDR(x, y), &sv->lod_addr[y]); 564 } 565 } 566 } 567 } 568 if (unlikely(dirty & (ETNA_DIRTY_SAMPLER_VIEWS))) { 569 /* only LOD0 is valid for this register */ 570 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 571 if ((1 << x) & active_samplers) { 572 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 573 /*02C00*/ EMIT_STATE(TE_SAMPLER_LINEAR_STRIDE(0, x), sv->linear_stride); 574 } 575 } 576 } 577 if (unlikely(screen->specs.tex_astc && (dirty & (ETNA_DIRTY_SAMPLER_VIEWS)))) { 578 for (int x = 0; x < VIVS_TE_SAMPLER__LEN; ++x) { 579 if ((1 << x) & active_samplers) { 580 struct etna_sampler_view *sv = etna_sampler_view(ctx->sampler_view[x]); 581 /*10500*/ EMIT_STATE(NTE_SAMPLER_ASTC0(x), sv->astc0); 582 } 583 } 584 } 585 586 etna_coalesce_end(stream, &coalesce); 587} 588 589#undef EMIT_STATE 590#undef EMIT_STATE_FIXP 591#undef EMIT_STATE_RELOC 592 593static struct etna_sampler_ts* 594etna_ts_for_sampler_view_state(struct pipe_sampler_view *pview) 595{ 596 struct etna_sampler_view *sv = etna_sampler_view(pview); 597 return &sv->ts; 598} 599 600void 601etna_texture_state_init(struct pipe_context *pctx) 602{ 603 struct etna_context *ctx = etna_context(pctx); 604 DBG("etnaviv: Using state-based texturing"); 605 ctx->base.create_sampler_state = etna_create_sampler_state_state; 606 ctx->base.delete_sampler_state = etna_delete_sampler_state_state; 607 ctx->base.create_sampler_view = etna_create_sampler_view_state; 608 ctx->base.sampler_view_destroy = etna_sampler_view_state_destroy; 609 ctx->ts_for_sampler_view = etna_ts_for_sampler_view_state; 610 611 STATIC_ASSERT(VIVS_TE_SAMPLER_LOD_ADDR__LEN == VIVS_NTE_SAMPLER_ADDR_LOD__LEN); 612 613 if (ctx->screen->specs.halti >= 1) 614 ctx->emit_texture_state = etna_emit_new_texture_state; 615 else 616 ctx->emit_texture_state = etna_emit_texture_state; 617} 618