1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "util/u_inlines.h" 27bf215546Sopenharmony_ci#include "util/u_memory.h" 28bf215546Sopenharmony_ci#include "pipe/p_defines.h" 29bf215546Sopenharmony_ci#include "util/u_math.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "svga_resource_texture.h" 32bf215546Sopenharmony_ci#include "svga_sampler_view.h" 33bf215546Sopenharmony_ci#include "svga_winsys.h" 34bf215546Sopenharmony_ci#include "svga_context.h" 35bf215546Sopenharmony_ci#include "svga_shader.h" 36bf215546Sopenharmony_ci#include "svga_state.h" 37bf215546Sopenharmony_ci#include "svga_cmd.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci/** 41bf215546Sopenharmony_ci * Called when tearing down a context to free resources and samplers. 42bf215546Sopenharmony_ci */ 43bf215546Sopenharmony_civoid 44bf215546Sopenharmony_cisvga_cleanup_tss_binding(struct svga_context *svga) 45bf215546Sopenharmony_ci{ 46bf215546Sopenharmony_ci const enum pipe_shader_type shader = PIPE_SHADER_FRAGMENT; 47bf215546Sopenharmony_ci unsigned i; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(svga->state.hw_draw.views); i++) { 50bf215546Sopenharmony_ci struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; 51bf215546Sopenharmony_ci if (view) { 52bf215546Sopenharmony_ci svga_sampler_view_reference(&view->v, NULL); 53bf215546Sopenharmony_ci pipe_sampler_view_reference(&svga->curr.sampler_views[shader][i], 54bf215546Sopenharmony_ci NULL); 55bf215546Sopenharmony_ci pipe_resource_reference(&view->texture, NULL); 56bf215546Sopenharmony_ci view->dirty = TRUE; 57bf215546Sopenharmony_ci } 58bf215546Sopenharmony_ci } 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_cistruct bind_queue { 63bf215546Sopenharmony_ci struct { 64bf215546Sopenharmony_ci unsigned unit; 65bf215546Sopenharmony_ci struct svga_hw_view_state *view; 66bf215546Sopenharmony_ci } bind[PIPE_MAX_SAMPLERS]; 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci unsigned bind_count; 69bf215546Sopenharmony_ci}; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci/** 73bf215546Sopenharmony_ci * Update the texture binding for one texture unit. 74bf215546Sopenharmony_ci */ 75bf215546Sopenharmony_cistatic void 76bf215546Sopenharmony_ciemit_tex_binding_unit(struct svga_context *svga, 77bf215546Sopenharmony_ci unsigned unit, 78bf215546Sopenharmony_ci const struct svga_sampler_state *s, 79bf215546Sopenharmony_ci const struct pipe_sampler_view *sv, 80bf215546Sopenharmony_ci struct svga_hw_view_state *view, 81bf215546Sopenharmony_ci boolean reemit, 82bf215546Sopenharmony_ci struct bind_queue *queue) 83bf215546Sopenharmony_ci{ 84bf215546Sopenharmony_ci struct pipe_resource *texture = NULL; 85bf215546Sopenharmony_ci unsigned last_level, min_lod, max_lod; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci /* get min max lod */ 88bf215546Sopenharmony_ci if (sv && s) { 89bf215546Sopenharmony_ci if (s->mipfilter == SVGA3D_TEX_FILTER_NONE) { 90bf215546Sopenharmony_ci /* just use the base level image */ 91bf215546Sopenharmony_ci min_lod = max_lod = sv->u.tex.first_level; 92bf215546Sopenharmony_ci } 93bf215546Sopenharmony_ci else { 94bf215546Sopenharmony_ci last_level = MIN2(sv->u.tex.last_level, sv->texture->last_level); 95bf215546Sopenharmony_ci min_lod = s->view_min_lod + sv->u.tex.first_level; 96bf215546Sopenharmony_ci min_lod = MIN2(min_lod, last_level); 97bf215546Sopenharmony_ci max_lod = MIN2(s->view_max_lod + sv->u.tex.first_level, last_level); 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci texture = sv->texture; 100bf215546Sopenharmony_ci } 101bf215546Sopenharmony_ci else { 102bf215546Sopenharmony_ci min_lod = 0; 103bf215546Sopenharmony_ci max_lod = 0; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci if (view->texture != texture || 107bf215546Sopenharmony_ci view->min_lod != min_lod || 108bf215546Sopenharmony_ci view->max_lod != max_lod) { 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci svga_sampler_view_reference(&view->v, NULL); 111bf215546Sopenharmony_ci pipe_resource_reference(&view->texture, texture); 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci view->dirty = TRUE; 114bf215546Sopenharmony_ci view->min_lod = min_lod; 115bf215546Sopenharmony_ci view->max_lod = max_lod; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci if (texture) { 118bf215546Sopenharmony_ci view->v = svga_get_tex_sampler_view(&svga->pipe, 119bf215546Sopenharmony_ci texture, 120bf215546Sopenharmony_ci min_lod, 121bf215546Sopenharmony_ci max_lod); 122bf215546Sopenharmony_ci } 123bf215546Sopenharmony_ci } 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci /* 126bf215546Sopenharmony_ci * We need to reemit non-null texture bindings, even when they are not 127bf215546Sopenharmony_ci * dirty, to ensure that the resources are paged in. 128bf215546Sopenharmony_ci */ 129bf215546Sopenharmony_ci if (view->dirty || (reemit && view->v)) { 130bf215546Sopenharmony_ci queue->bind[queue->bind_count].unit = unit; 131bf215546Sopenharmony_ci queue->bind[queue->bind_count].view = view; 132bf215546Sopenharmony_ci queue->bind_count++; 133bf215546Sopenharmony_ci } 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci if (!view->dirty && view->v) { 136bf215546Sopenharmony_ci svga_validate_sampler_view(svga, view->v); 137bf215546Sopenharmony_ci } 138bf215546Sopenharmony_ci} 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_cistatic enum pipe_error 142bf215546Sopenharmony_ciupdate_tss_binding(struct svga_context *svga, uint64_t dirty ) 143bf215546Sopenharmony_ci{ 144bf215546Sopenharmony_ci const enum pipe_shader_type shader = PIPE_SHADER_FRAGMENT; 145bf215546Sopenharmony_ci boolean reemit = svga->rebind.flags.texture_samplers; 146bf215546Sopenharmony_ci unsigned i; 147bf215546Sopenharmony_ci unsigned count = MAX2(svga->curr.num_sampler_views[shader], 148bf215546Sopenharmony_ci svga->state.hw_draw.num_views); 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci struct bind_queue queue; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci assert(!svga_have_vgpu10(svga)); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci queue.bind_count = 0; 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci for (i = 0; i < count; i++) { 157bf215546Sopenharmony_ci emit_tex_binding_unit(svga, i, 158bf215546Sopenharmony_ci svga->curr.sampler[shader][i], 159bf215546Sopenharmony_ci svga->curr.sampler_views[shader][i], 160bf215546Sopenharmony_ci &svga->state.hw_draw.views[i], 161bf215546Sopenharmony_ci reemit, 162bf215546Sopenharmony_ci &queue); 163bf215546Sopenharmony_ci } 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci svga->state.hw_draw.num_views = svga->curr.num_sampler_views[shader]; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci /* Polygon stipple */ 168bf215546Sopenharmony_ci if (svga->curr.rast->templ.poly_stipple_enable) { 169bf215546Sopenharmony_ci const unsigned unit = 170bf215546Sopenharmony_ci svga_fs_variant(svga->state.hw_draw.fs)->pstipple_sampler_unit; 171bf215546Sopenharmony_ci emit_tex_binding_unit(svga, unit, 172bf215546Sopenharmony_ci svga->polygon_stipple.sampler, 173bf215546Sopenharmony_ci &svga->polygon_stipple.sampler_view->base, 174bf215546Sopenharmony_ci &svga->state.hw_draw.views[unit], 175bf215546Sopenharmony_ci reemit, 176bf215546Sopenharmony_ci &queue); 177bf215546Sopenharmony_ci } 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci svga->state.hw_draw.num_backed_views = 0; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if (queue.bind_count) { 182bf215546Sopenharmony_ci SVGA3dTextureState *ts; 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci if (SVGA3D_BeginSetTextureState(svga->swc, &ts, 185bf215546Sopenharmony_ci queue.bind_count) != PIPE_OK) 186bf215546Sopenharmony_ci goto fail; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci for (i = 0; i < queue.bind_count; i++) { 189bf215546Sopenharmony_ci struct svga_winsys_surface *handle; 190bf215546Sopenharmony_ci struct svga_hw_view_state *view = queue.bind[i].view; 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci ts[i].stage = queue.bind[i].unit; 193bf215546Sopenharmony_ci ts[i].name = SVGA3D_TS_BIND_TEXTURE; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci if (view->v) { 196bf215546Sopenharmony_ci handle = view->v->handle; 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci /* Keep track of number of views with a backing copy 199bf215546Sopenharmony_ci * of texture. 200bf215546Sopenharmony_ci */ 201bf215546Sopenharmony_ci if (handle != svga_texture(view->texture)->handle) 202bf215546Sopenharmony_ci svga->state.hw_draw.num_backed_views++; 203bf215546Sopenharmony_ci } 204bf215546Sopenharmony_ci else { 205bf215546Sopenharmony_ci handle = NULL; 206bf215546Sopenharmony_ci } 207bf215546Sopenharmony_ci svga->swc->surface_relocation(svga->swc, 208bf215546Sopenharmony_ci &ts[i].value, 209bf215546Sopenharmony_ci NULL, 210bf215546Sopenharmony_ci handle, 211bf215546Sopenharmony_ci SVGA_RELOC_READ); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci queue.bind[i].view->dirty = FALSE; 214bf215546Sopenharmony_ci } 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci SVGA_FIFOCommitAll(svga->swc); 217bf215546Sopenharmony_ci } 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci svga->rebind.flags.texture_samplers = FALSE; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci return PIPE_OK; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_cifail: 224bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 225bf215546Sopenharmony_ci} 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci/* 229bf215546Sopenharmony_ci * Rebind textures. 230bf215546Sopenharmony_ci * 231bf215546Sopenharmony_ci * Similar to update_tss_binding, but without any state checking/update. 232bf215546Sopenharmony_ci * 233bf215546Sopenharmony_ci * Called at the beginning of every new command buffer to ensure that 234bf215546Sopenharmony_ci * non-dirty textures are properly paged-in. 235bf215546Sopenharmony_ci */ 236bf215546Sopenharmony_cienum pipe_error 237bf215546Sopenharmony_cisvga_reemit_tss_bindings(struct svga_context *svga) 238bf215546Sopenharmony_ci{ 239bf215546Sopenharmony_ci unsigned i; 240bf215546Sopenharmony_ci enum pipe_error ret; 241bf215546Sopenharmony_ci struct bind_queue queue; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci assert(!svga_have_vgpu10(svga)); 244bf215546Sopenharmony_ci assert(svga->rebind.flags.texture_samplers); 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci queue.bind_count = 0; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci for (i = 0; i < svga->state.hw_draw.num_views; i++) { 249bf215546Sopenharmony_ci struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci if (view->v) { 252bf215546Sopenharmony_ci queue.bind[queue.bind_count].unit = i; 253bf215546Sopenharmony_ci queue.bind[queue.bind_count].view = view; 254bf215546Sopenharmony_ci queue.bind_count++; 255bf215546Sopenharmony_ci } 256bf215546Sopenharmony_ci } 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci /* Polygon stipple */ 259bf215546Sopenharmony_ci if (svga->curr.rast && svga->curr.rast->templ.poly_stipple_enable) { 260bf215546Sopenharmony_ci const unsigned unit = 261bf215546Sopenharmony_ci svga_fs_variant(svga->state.hw_draw.fs)->pstipple_sampler_unit; 262bf215546Sopenharmony_ci struct svga_hw_view_state *view = &svga->state.hw_draw.views[unit]; 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci if (view->v) { 265bf215546Sopenharmony_ci queue.bind[queue.bind_count].unit = unit; 266bf215546Sopenharmony_ci queue.bind[queue.bind_count].view = view; 267bf215546Sopenharmony_ci queue.bind_count++; 268bf215546Sopenharmony_ci } 269bf215546Sopenharmony_ci } 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci if (queue.bind_count) { 272bf215546Sopenharmony_ci SVGA3dTextureState *ts; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci ret = SVGA3D_BeginSetTextureState(svga->swc, &ts, queue.bind_count); 275bf215546Sopenharmony_ci if (ret != PIPE_OK) { 276bf215546Sopenharmony_ci return ret; 277bf215546Sopenharmony_ci } 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci for (i = 0; i < queue.bind_count; i++) { 280bf215546Sopenharmony_ci struct svga_winsys_surface *handle; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci ts[i].stage = queue.bind[i].unit; 283bf215546Sopenharmony_ci ts[i].name = SVGA3D_TS_BIND_TEXTURE; 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci assert(queue.bind[i].view->v); 286bf215546Sopenharmony_ci handle = queue.bind[i].view->v->handle; 287bf215546Sopenharmony_ci svga->swc->surface_relocation(svga->swc, 288bf215546Sopenharmony_ci &ts[i].value, 289bf215546Sopenharmony_ci NULL, 290bf215546Sopenharmony_ci handle, 291bf215546Sopenharmony_ci SVGA_RELOC_READ); 292bf215546Sopenharmony_ci } 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci SVGA_FIFOCommitAll(svga->swc); 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci svga->rebind.flags.texture_samplers = FALSE; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci return PIPE_OK; 300bf215546Sopenharmony_ci} 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_tss_binding = { 304bf215546Sopenharmony_ci "texture binding emit", 305bf215546Sopenharmony_ci SVGA_NEW_FRAME_BUFFER | 306bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_BINDING | 307bf215546Sopenharmony_ci SVGA_NEW_STIPPLE | 308bf215546Sopenharmony_ci SVGA_NEW_SAMPLER, 309bf215546Sopenharmony_ci update_tss_binding 310bf215546Sopenharmony_ci}; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_cistruct ts_queue { 315bf215546Sopenharmony_ci unsigned ts_count; 316bf215546Sopenharmony_ci SVGA3dTextureState ts[PIPE_MAX_SAMPLERS*SVGA3D_TS_MAX]; 317bf215546Sopenharmony_ci}; 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_cistatic inline void 321bf215546Sopenharmony_cisvga_queue_tss(struct ts_queue *q, unsigned unit, unsigned tss, unsigned value) 322bf215546Sopenharmony_ci{ 323bf215546Sopenharmony_ci assert(q->ts_count < ARRAY_SIZE(q->ts)); 324bf215546Sopenharmony_ci q->ts[q->ts_count].stage = unit; 325bf215546Sopenharmony_ci q->ts[q->ts_count].name = tss; 326bf215546Sopenharmony_ci q->ts[q->ts_count].value = value; 327bf215546Sopenharmony_ci q->ts_count++; 328bf215546Sopenharmony_ci} 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci#define EMIT_TS(svga, unit, val, token) \ 332bf215546Sopenharmony_cido { \ 333bf215546Sopenharmony_ci assert(unit < ARRAY_SIZE(svga->state.hw_draw.ts)); \ 334bf215546Sopenharmony_ci STATIC_ASSERT(SVGA3D_TS_##token < ARRAY_SIZE(svga->state.hw_draw.ts[unit])); \ 335bf215546Sopenharmony_ci if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) { \ 336bf215546Sopenharmony_ci svga_queue_tss(queue, unit, SVGA3D_TS_##token, val); \ 337bf215546Sopenharmony_ci svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val; \ 338bf215546Sopenharmony_ci } \ 339bf215546Sopenharmony_ci} while (0) 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci#define EMIT_TS_FLOAT(svga, unit, fvalue, token) \ 342bf215546Sopenharmony_cido { \ 343bf215546Sopenharmony_ci unsigned val = fui(fvalue); \ 344bf215546Sopenharmony_ci assert(unit < ARRAY_SIZE(svga->state.hw_draw.ts)); \ 345bf215546Sopenharmony_ci STATIC_ASSERT(SVGA3D_TS_##token < ARRAY_SIZE(svga->state.hw_draw.ts[unit])); \ 346bf215546Sopenharmony_ci if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) { \ 347bf215546Sopenharmony_ci svga_queue_tss(queue, unit, SVGA3D_TS_##token, val); \ 348bf215546Sopenharmony_ci svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val; \ 349bf215546Sopenharmony_ci } \ 350bf215546Sopenharmony_ci} while (0) 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci/** 354bf215546Sopenharmony_ci * Emit texture sampler state (tss) for one texture unit. 355bf215546Sopenharmony_ci */ 356bf215546Sopenharmony_cistatic void 357bf215546Sopenharmony_ciemit_tss_unit(struct svga_context *svga, unsigned unit, 358bf215546Sopenharmony_ci const struct svga_sampler_state *state, 359bf215546Sopenharmony_ci struct ts_queue *queue) 360bf215546Sopenharmony_ci{ 361bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->mipfilter, MIPFILTER); 362bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->min_lod, TEXTURE_MIPMAP_LEVEL); 363bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->magfilter, MAGFILTER); 364bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->minfilter, MINFILTER); 365bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->aniso_level, TEXTURE_ANISOTROPIC_LEVEL); 366bf215546Sopenharmony_ci EMIT_TS_FLOAT(svga, unit, state->lod_bias, TEXTURE_LOD_BIAS); 367bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->addressu, ADDRESSU); 368bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->addressw, ADDRESSW); 369bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->bordercolor, BORDERCOLOR); 370bf215546Sopenharmony_ci // TEXCOORDINDEX -- hopefully not needed 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci if (svga->curr.tex_flags.flag_1d & (1 << unit)) 373bf215546Sopenharmony_ci EMIT_TS(svga, unit, SVGA3D_TEX_ADDRESS_WRAP, ADDRESSV); 374bf215546Sopenharmony_ci else 375bf215546Sopenharmony_ci EMIT_TS(svga, unit, state->addressv, ADDRESSV); 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci if (svga->curr.tex_flags.flag_srgb & (1 << unit)) 378bf215546Sopenharmony_ci EMIT_TS_FLOAT(svga, unit, 2.2f, GAMMA); 379bf215546Sopenharmony_ci else 380bf215546Sopenharmony_ci EMIT_TS_FLOAT(svga, unit, 1.0f, GAMMA); 381bf215546Sopenharmony_ci} 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_cistatic enum pipe_error 384bf215546Sopenharmony_ciupdate_tss(struct svga_context *svga, uint64_t dirty ) 385bf215546Sopenharmony_ci{ 386bf215546Sopenharmony_ci const enum pipe_shader_type shader = PIPE_SHADER_FRAGMENT; 387bf215546Sopenharmony_ci unsigned i; 388bf215546Sopenharmony_ci struct ts_queue queue; 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci assert(!svga_have_vgpu10(svga)); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci queue.ts_count = 0; 393bf215546Sopenharmony_ci for (i = 0; i < svga->curr.num_samplers[shader]; i++) { 394bf215546Sopenharmony_ci if (svga->curr.sampler[shader][i]) { 395bf215546Sopenharmony_ci const struct svga_sampler_state *curr = svga->curr.sampler[shader][i]; 396bf215546Sopenharmony_ci emit_tss_unit(svga, i, curr, &queue); 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci } 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci /* polygon stipple sampler */ 401bf215546Sopenharmony_ci if (svga->curr.rast->templ.poly_stipple_enable) { 402bf215546Sopenharmony_ci emit_tss_unit(svga, 403bf215546Sopenharmony_ci svga_fs_variant(svga->state.hw_draw.fs)->pstipple_sampler_unit, 404bf215546Sopenharmony_ci svga->polygon_stipple.sampler, 405bf215546Sopenharmony_ci &queue); 406bf215546Sopenharmony_ci } 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci if (queue.ts_count) { 409bf215546Sopenharmony_ci SVGA3dTextureState *ts; 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci if (SVGA3D_BeginSetTextureState(svga->swc, &ts, queue.ts_count) != PIPE_OK) 412bf215546Sopenharmony_ci goto fail; 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci memcpy(ts, queue.ts, queue.ts_count * sizeof queue.ts[0]); 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci SVGA_FIFOCommitAll(svga->swc); 417bf215546Sopenharmony_ci } 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci return PIPE_OK; 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_cifail: 422bf215546Sopenharmony_ci /* XXX: need to poison cached hardware state on failure to ensure 423bf215546Sopenharmony_ci * dirty state gets re-emitted. Fix this by re-instating partial 424bf215546Sopenharmony_ci * FIFOCommit command and only updating cached hw state once the 425bf215546Sopenharmony_ci * initial allocation has succeeded. 426bf215546Sopenharmony_ci */ 427bf215546Sopenharmony_ci memset(svga->state.hw_draw.ts, 0xcd, sizeof(svga->state.hw_draw.ts)); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 430bf215546Sopenharmony_ci} 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_tss = { 434bf215546Sopenharmony_ci "texture state emit", 435bf215546Sopenharmony_ci (SVGA_NEW_SAMPLER | 436bf215546Sopenharmony_ci SVGA_NEW_STIPPLE | 437bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_FLAGS), 438bf215546Sopenharmony_ci update_tss 439bf215546Sopenharmony_ci}; 440bf215546Sopenharmony_ci 441