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