126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul/*
226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * Copyright 2013 VMware, Inc.  All rights reserved.
326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul *
426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * Permission is hereby granted, free of charge, to any person
526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * obtaining a copy of this software and associated documentation
626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * files (the "Software"), to deal in the Software without
726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * restriction, including without limitation the rights to use, copy,
826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * modify, merge, publish, distribute, sublicense, and/or sell copies
926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * of the Software, and to permit persons to whom the Software is
1026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * furnished to do so, subject to the following conditions:
1126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul *
1226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * The above copyright notice and this permission notice shall be
1326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * included in all copies or substantial portions of the Software.
1426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul *
1526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * SOFTWARE.
2326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul */
2426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
2526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
2626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul/**
2726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * VGPU10 sampler and sampler view functions.
2826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul */
2926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
3026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
3126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "pipe/p_defines.h"
3226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "util/u_bitmask.h"
337cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák#include "util/u_format.h"
3426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "util/u_inlines.h"
3526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "util/u_math.h"
3626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "util/u_memory.h"
3726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
3826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "svga_cmd.h"
3926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "svga_context.h"
4026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "svga_format.h"
4126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "svga_resource_buffer.h"
4226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "svga_resource_texture.h"
43ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul#include "svga_sampler_view.h"
4426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "svga_shader.h"
4526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul#include "svga_state.h"
46ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul#include "svga_surface.h"
4726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
4826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
4926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul/** Get resource handle for a texture or buffer */
50e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paulstatic inline struct svga_winsys_surface *
5126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulsvga_resource_handle(struct pipe_resource *res)
5226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul{
5326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   if (res->target == PIPE_BUFFER) {
5426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      return svga_buffer(res)->handle;
5526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   }
5626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   else {
5726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      return svga_texture(res)->handle;
5826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   }
5926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul}
6026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
6126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
6226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul/**
6326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * This helper function returns TRUE if the specified resource collides with
6426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * any of the resources bound to any of the currently bound sampler views.
6526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul */
6626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulboolean
6726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulsvga_check_sampler_view_resource_collision(struct svga_context *svga,
68b2fd41ce465e16a178d51000b843b5228640b670Charmaine Lee                                           struct svga_winsys_surface *res,
69f5602c27ec681f1f66cdb8d79378991b79ce45e7Brian Paul                                           enum pipe_shader_type shader)
7026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul{
7126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   struct pipe_screen *screen = svga->pipe.screen;
72b2fd41ce465e16a178d51000b843b5228640b670Charmaine Lee   unsigned i;
7326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
7426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   if (svga_screen(screen)->debug.no_surface_view) {
7526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      return FALSE;
7626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   }
7726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
78b2fd41ce465e16a178d51000b843b5228640b670Charmaine Lee   for (i = 0; i < svga->curr.num_sampler_views[shader]; i++) {
79b2fd41ce465e16a178d51000b843b5228640b670Charmaine Lee      struct svga_pipe_sampler_view *sv =
80b2fd41ce465e16a178d51000b843b5228640b670Charmaine Lee         svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
8126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
82b2fd41ce465e16a178d51000b843b5228640b670Charmaine Lee      if (sv && res == svga_resource_handle(sv->base.texture)) {
83b2fd41ce465e16a178d51000b843b5228640b670Charmaine Lee         return TRUE;
8426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
8526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   }
8626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
8726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   return FALSE;
8826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul}
8926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
9026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
9126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul/**
92ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul * Check if there are any resources that are both bound to a render target
93ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul * and bound as a shader resource for the given type of shader.
94ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul */
95ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paulboolean
96ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paulsvga_check_sampler_framebuffer_resource_collision(struct svga_context *svga,
97ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul                                                  enum pipe_shader_type shader)
98ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul{
99ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul   struct svga_surface *surf;
100ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul   unsigned i;
101ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul
102ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul   for (i = 0; i < svga->curr.framebuffer.nr_cbufs; i++) {
103ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul      surf = svga_surface(svga->curr.framebuffer.cbufs[i]);
104ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul      if (surf &&
105ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul          svga_check_sampler_view_resource_collision(svga, surf->handle,
106ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul                                                     shader)) {
107ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul         return TRUE;
108ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul      }
109ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul   }
110ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul
111ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul   surf = svga_surface(svga->curr.framebuffer.zsbuf);
112ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul   if (surf &&
113ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul       svga_check_sampler_view_resource_collision(svga, surf->handle, shader)) {
114ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul      return TRUE;
115ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul   }
116ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul
117ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul   return FALSE;
118ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul}
119ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul
120ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul
121ff500ed5a1287eadc06fc19661f0aad8767b664dBrian Paul/**
12226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * Create a DX ShaderResourceSamplerView for the given pipe_sampler_view,
12326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul * if needed.
12426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul */
1256303231a1ddf646b05c43c6bbc7fa71314ebb3fcCharmaine Leeenum pipe_error
12626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulsvga_validate_pipe_sampler_view(struct svga_context *svga,
12726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                struct svga_pipe_sampler_view *sv)
12826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul{
12926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   enum pipe_error ret = PIPE_OK;
13026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
13126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   if (sv->id == SVGA3D_INVALID_ID) {
13226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      struct svga_screen *ss = svga_screen(svga->pipe.screen);
13326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      struct pipe_resource *texture = sv->base.texture;
13426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      struct svga_winsys_surface *surface = svga_resource_handle(texture);
13526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      SVGA3dSurfaceFormat format;
13626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      SVGA3dResourceType resourceDim;
13726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      SVGA3dShaderResourceViewDesc viewDesc;
1388b731b8b0364a19917a62d69ebd106423555ec27Brian Paul      enum pipe_format viewFormat = sv->base.format;
139f1410c5b910911e690290e8a95aeb9f95e7cc470Sinclair Yeh
140f1410c5b910911e690290e8a95aeb9f95e7cc470Sinclair Yeh      /* vgpu10 cannot create a BGRX view for a BGRA resource, so force it to
14168388043f3280bbac9383721e37f8ca7685b7f01Brian Paul       * create a BGRA view (and vice versa).
142f1410c5b910911e690290e8a95aeb9f95e7cc470Sinclair Yeh       */
1438b731b8b0364a19917a62d69ebd106423555ec27Brian Paul      if (viewFormat == PIPE_FORMAT_B8G8R8X8_UNORM &&
1448b731b8b0364a19917a62d69ebd106423555ec27Brian Paul          texture->format == PIPE_FORMAT_B8G8R8A8_UNORM) {
1458b731b8b0364a19917a62d69ebd106423555ec27Brian Paul         viewFormat = PIPE_FORMAT_B8G8R8A8_UNORM;
146f1410c5b910911e690290e8a95aeb9f95e7cc470Sinclair Yeh      }
1478b731b8b0364a19917a62d69ebd106423555ec27Brian Paul      else if (viewFormat == PIPE_FORMAT_B8G8R8A8_UNORM &&
1488b731b8b0364a19917a62d69ebd106423555ec27Brian Paul          texture->format == PIPE_FORMAT_B8G8R8X8_UNORM) {
1498b731b8b0364a19917a62d69ebd106423555ec27Brian Paul         viewFormat = PIPE_FORMAT_B8G8R8X8_UNORM;
15068388043f3280bbac9383721e37f8ca7685b7f01Brian Paul      }
15126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
1528b731b8b0364a19917a62d69ebd106423555ec27Brian Paul      format = svga_translate_format(ss, viewFormat,
15326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                     PIPE_BIND_SAMPLER_VIEW);
15426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      assert(format != SVGA3D_FORMAT_INVALID);
15526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
1561a90e3e1e3ee70504f2ce57462fb592b448269beBrian Paul      /* Convert the format to a sampler-friendly format, if needed */
1571a90e3e1e3ee70504f2ce57462fb592b448269beBrian Paul      format = svga_sampler_format(format);
1581a90e3e1e3ee70504f2ce57462fb592b448269beBrian Paul
15926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      if (texture->target == PIPE_BUFFER) {
1607cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák         unsigned elem_size = util_format_get_blocksize(sv->base.format);
1617cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák
1627cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák         viewDesc.buffer.firstElement = sv->base.u.buf.offset / elem_size;
1637cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák         viewDesc.buffer.numElements = sv->base.u.buf.size / elem_size;
16426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
16526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      else {
16626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         viewDesc.tex.mostDetailedMip = sv->base.u.tex.first_level;
16726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         viewDesc.tex.firstArraySlice = sv->base.u.tex.first_layer;
16826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         viewDesc.tex.mipLevels = (sv->base.u.tex.last_level -
16926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                   sv->base.u.tex.first_level + 1);
17026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
17126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
17226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      /* arraySize in viewDesc specifies the number of array slices in a
173e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul       * texture array. For 3D texture, last_layer in
17426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul       * pipe_sampler_view specifies the last slice of the texture
17526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul       * which is different from the last slice in a texture array,
17626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul       * hence we need to set arraySize to 1 explicitly.
17726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul       */
178e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul      viewDesc.tex.arraySize =
179e054251ed11e25a080f64b92db9334c9b07c8c76Brian Paul         (texture->target == PIPE_TEXTURE_3D ||
18026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul          texture->target == PIPE_BUFFER) ? 1 :
18126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            (sv->base.u.tex.last_layer - sv->base.u.tex.first_layer + 1);
18226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
18326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      switch (texture->target) {
18426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_BUFFER:
18526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         resourceDim = SVGA3D_RESOURCE_BUFFER;
18626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         break;
18726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_TEXTURE_1D:
18826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_TEXTURE_1D_ARRAY:
18926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         resourceDim = SVGA3D_RESOURCE_TEXTURE1D;
19026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         break;
19126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_TEXTURE_RECT:
19226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_TEXTURE_2D:
19326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_TEXTURE_2D_ARRAY:
19426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         resourceDim = SVGA3D_RESOURCE_TEXTURE2D;
19526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         break;
19626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_TEXTURE_3D:
19726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         resourceDim = SVGA3D_RESOURCE_TEXTURE3D;
19826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         break;
19926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_TEXTURE_CUBE:
20026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      case PIPE_TEXTURE_CUBE_ARRAY:
20126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         resourceDim = SVGA3D_RESOURCE_TEXTURECUBE;
20226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         break;
20326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
20426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      default:
20526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         assert(!"Unexpected texture type");
20626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         resourceDim = SVGA3D_RESOURCE_TEXTURE2D;
20726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
20826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
20926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      sv->id = util_bitmask_add(svga->sampler_view_id_bm);
21026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
21126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      ret = SVGA3D_vgpu10_DefineShaderResourceView(svga->swc,
21226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                   sv->id,
21326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                   surface,
21426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                   format,
21526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                   resourceDim,
21626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                   &viewDesc);
21726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      if (ret != PIPE_OK) {
21826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         util_bitmask_clear(svga->sampler_view_id_bm, sv->id);
21926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         sv->id = SVGA3D_INVALID_ID;
22026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
22126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   }
22226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
22326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   return ret;
22426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul}
22526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
22626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
22726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulstatic enum pipe_error
22826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulupdate_sampler_resources(struct svga_context *svga, unsigned dirty)
22926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul{
23026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   enum pipe_error ret = PIPE_OK;
231f5602c27ec681f1f66cdb8d79378991b79ce45e7Brian Paul   enum pipe_shader_type shader;
23226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
23326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   if (!svga_have_vgpu10(svga))
23426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      return PIPE_OK;
23526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
23626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
23726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      SVGA3dShaderResourceViewId ids[PIPE_MAX_SAMPLERS];
23826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
2392781d603753148771c1a706150b7a9a54592befeCharmaine Lee      struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
24026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      unsigned count;
24126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      unsigned nviews;
24226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      unsigned i;
24326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
24426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      count = svga->curr.num_sampler_views[shader];
24526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      for (i = 0; i < count; i++) {
24626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         struct svga_pipe_sampler_view *sv =
24726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
24826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
24926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         if (sv) {
2502781d603753148771c1a706150b7a9a54592befeCharmaine Lee            surfaces[i] = svga_resource_handle(sv->base.texture);
25126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
25226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            ret = svga_validate_pipe_sampler_view(svga, sv);
25326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            if (ret != PIPE_OK)
25426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul               return ret;
25526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
25626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            assert(sv->id != SVGA3D_INVALID_ID);
25726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            ids[i] = sv->id;
2582781d603753148771c1a706150b7a9a54592befeCharmaine Lee            sampler_views[i] = &sv->base;
25926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         }
26026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         else {
2612781d603753148771c1a706150b7a9a54592befeCharmaine Lee            surfaces[i] = NULL;
26226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            ids[i] = SVGA3D_INVALID_ID;
2632781d603753148771c1a706150b7a9a54592befeCharmaine Lee            sampler_views[i] = NULL;
26426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         }
26526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
26626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
2672781d603753148771c1a706150b7a9a54592befeCharmaine Lee      for (; i < svga->state.hw_draw.num_sampler_views[shader]; i++) {
26826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         ids[i] = SVGA3D_INVALID_ID;
26926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         surfaces[i] = NULL;
2702781d603753148771c1a706150b7a9a54592befeCharmaine Lee         sampler_views[i] = NULL;
27126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
27226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
27326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      /* Number of ShaderResources that need to be modified. This includes
27426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul       * the one that need to be unbound.
27526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul       */
27626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      nviews = MAX2(svga->state.hw_draw.num_sampler_views[shader], count);
27726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      if (nviews > 0) {
2782781d603753148771c1a706150b7a9a54592befeCharmaine Lee         if (count != svga->state.hw_draw.num_sampler_views[shader] ||
2792781d603753148771c1a706150b7a9a54592befeCharmaine Lee             memcmp(sampler_views, svga->state.hw_draw.sampler_views[shader],
2802781d603753148771c1a706150b7a9a54592befeCharmaine Lee                    count * sizeof(sampler_views[0])) != 0) {
2812781d603753148771c1a706150b7a9a54592befeCharmaine Lee            ret = SVGA3D_vgpu10_SetShaderResources(svga->swc,
28226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                svga_shader_type(shader),
28326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                0, /* startView */
28426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                nviews,
28526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                ids,
28626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul                                                surfaces);
2872781d603753148771c1a706150b7a9a54592befeCharmaine Lee            if (ret != PIPE_OK)
2882781d603753148771c1a706150b7a9a54592befeCharmaine Lee               return ret;
28926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
2902781d603753148771c1a706150b7a9a54592befeCharmaine Lee            /* Save referenced sampler views in the hw draw state.  */
2912781d603753148771c1a706150b7a9a54592befeCharmaine Lee            svga->state.hw_draw.num_sampler_views[shader] = count;
2922781d603753148771c1a706150b7a9a54592befeCharmaine Lee            for (i = 0; i < nviews; i++) {
2932781d603753148771c1a706150b7a9a54592befeCharmaine Lee               pipe_sampler_view_reference(
2942781d603753148771c1a706150b7a9a54592befeCharmaine Lee                  &svga->state.hw_draw.sampler_views[shader][i],
2952781d603753148771c1a706150b7a9a54592befeCharmaine Lee                  sampler_views[i]);
2962781d603753148771c1a706150b7a9a54592befeCharmaine Lee            }
2972781d603753148771c1a706150b7a9a54592befeCharmaine Lee         }
2982781d603753148771c1a706150b7a9a54592befeCharmaine Lee      }
29926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   }
30026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
3012781d603753148771c1a706150b7a9a54592befeCharmaine Lee   /* Handle polygon stipple sampler view */
3022781d603753148771c1a706150b7a9a54592befeCharmaine Lee   if (svga->curr.rast->templ.poly_stipple_enable) {
3032781d603753148771c1a706150b7a9a54592befeCharmaine Lee      const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
3042781d603753148771c1a706150b7a9a54592befeCharmaine Lee      struct svga_pipe_sampler_view *sv = svga->polygon_stipple.sampler_view;
3052781d603753148771c1a706150b7a9a54592befeCharmaine Lee      struct svga_winsys_surface *surface;
3062781d603753148771c1a706150b7a9a54592befeCharmaine Lee
3072781d603753148771c1a706150b7a9a54592befeCharmaine Lee      assert(sv);
3082781d603753148771c1a706150b7a9a54592befeCharmaine Lee      if (!sv) {
3092781d603753148771c1a706150b7a9a54592befeCharmaine Lee         return PIPE_OK;  /* probably out of memory */
3102781d603753148771c1a706150b7a9a54592befeCharmaine Lee      }
3112781d603753148771c1a706150b7a9a54592befeCharmaine Lee
3122781d603753148771c1a706150b7a9a54592befeCharmaine Lee      ret = svga_validate_pipe_sampler_view(svga, sv);
3132781d603753148771c1a706150b7a9a54592befeCharmaine Lee      if (ret != PIPE_OK)
3142781d603753148771c1a706150b7a9a54592befeCharmaine Lee         return ret;
3152781d603753148771c1a706150b7a9a54592befeCharmaine Lee
3162781d603753148771c1a706150b7a9a54592befeCharmaine Lee      surface = svga_resource_handle(sv->base.texture);
3172781d603753148771c1a706150b7a9a54592befeCharmaine Lee      ret = SVGA3D_vgpu10_SetShaderResources(
3182781d603753148771c1a706150b7a9a54592befeCharmaine Lee               svga->swc,
3192781d603753148771c1a706150b7a9a54592befeCharmaine Lee               svga_shader_type(PIPE_SHADER_FRAGMENT),
3202781d603753148771c1a706150b7a9a54592befeCharmaine Lee               unit, /* startView */
3212781d603753148771c1a706150b7a9a54592befeCharmaine Lee               1,
3222781d603753148771c1a706150b7a9a54592befeCharmaine Lee               &sv->id,
3232781d603753148771c1a706150b7a9a54592befeCharmaine Lee               &surface);
3242781d603753148771c1a706150b7a9a54592befeCharmaine Lee   }
32526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   return ret;
32626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul}
32726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
32826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
32926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulstruct svga_tracked_state svga_hw_sampler_bindings = {
33026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   "shader resources emit",
33126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   SVGA_NEW_STIPPLE |
33226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   SVGA_NEW_TEXTURE_BINDING,
33326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   update_sampler_resources
33426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul};
33526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
33626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
33726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
33826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulstatic enum pipe_error
33926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulupdate_samplers(struct svga_context *svga, unsigned dirty )
34026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul{
34126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   enum pipe_error ret = PIPE_OK;
342f5602c27ec681f1f66cdb8d79378991b79ce45e7Brian Paul   enum pipe_shader_type shader;
34326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
34426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   if (!svga_have_vgpu10(svga))
34526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      return PIPE_OK;
34626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
34726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
34826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      const unsigned count = svga->curr.num_samplers[shader];
34926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      SVGA3dSamplerId ids[PIPE_MAX_SAMPLERS];
35026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      unsigned i;
3513f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee      unsigned nsamplers;
35226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
35326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      for (i = 0; i < count; i++) {
35426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         if (svga->curr.sampler[shader][i]) {
35526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            ids[i] = svga->curr.sampler[shader][i]->id;
35626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            assert(ids[i] != SVGA3D_INVALID_ID);
35726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         }
35826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         else {
35926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul            ids[i] = SVGA3D_INVALID_ID;
36026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         }
36126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
36226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
3633f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee      for (; i < svga->state.hw_draw.num_samplers[shader]; i++) {
3643f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee         ids[i] = SVGA3D_INVALID_ID;
3653f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee      }
3663f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee
3673f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee      nsamplers = MAX2(svga->state.hw_draw.num_samplers[shader], count);
3683f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee      if (nsamplers > 0) {
36927d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul         if (count != svga->state.hw_draw.num_samplers[shader] ||
37027d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul             memcmp(ids, svga->state.hw_draw.samplers[shader],
37127d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul                    count * sizeof(ids[0])) != 0) {
37227d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul            /* HW state is really changing */
37327d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul            ret = SVGA3D_vgpu10_SetSamplers(svga->swc,
3743f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee                                            nsamplers,
37527d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul                                            0,                       /* start */
37627d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul                                            svga_shader_type(shader), /* type */
37727d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul                                            ids);
37827d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul            if (ret != PIPE_OK)
37927d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul               return ret;
38027d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul            memcpy(svga->state.hw_draw.samplers[shader], ids,
3813f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee                   nsamplers * sizeof(ids[0]));
38227d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul            svga->state.hw_draw.num_samplers[shader] = count;
38327d5be0b8fafecefc4f0378ca940cea8c0415715Brian Paul         }
38426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
38526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   }
38626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
38726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   /* Handle polygon stipple sampler texture */
38826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   if (svga->curr.rast->templ.poly_stipple_enable) {
38926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
39026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      struct svga_sampler_state *sampler = svga->polygon_stipple.sampler;
39126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
39226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      assert(sampler);
39326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      if (!sampler) {
39426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul         return PIPE_OK; /* probably out of memory */
39526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul      }
39626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
3973f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee      if (svga->state.hw_draw.samplers[PIPE_SHADER_FRAGMENT][unit]
3983f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee          != sampler->id) {
3993f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee         ret = SVGA3D_vgpu10_SetSamplers(svga->swc,
4003f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee                                         1, /* count */
4013f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee                                         unit, /* start */
4023f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee                                         SVGA3D_SHADERTYPE_PS,
4033f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee                                         &sampler->id);
4043f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee         if (ret != PIPE_OK)
4053f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee            return ret;
4063f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee
4073f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee         /* save the polygon stipple sampler in the hw draw state */
4083f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee         svga->state.hw_draw.samplers[PIPE_SHADER_FRAGMENT][unit] =
4093f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee            sampler->id;
4103f51a3f6ac2aad0400e25ef6f772ff9c4b240d5fCharmaine Lee      }
41126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   }
41226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
41326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   return ret;
41426d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul}
41526d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
41626d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul
41726d8bae88908b490a37b6ba39b88f44945bb5613Brian Paulstruct svga_tracked_state svga_hw_sampler = {
41826d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   "texture sampler emit",
41926d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   (SVGA_NEW_SAMPLER |
42026d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul    SVGA_NEW_STIPPLE |
42126d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul    SVGA_NEW_TEXTURE_FLAGS),
42226d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul   update_samplers
42326d8bae88908b490a37b6ba39b88f44945bb5613Brian Paul};
424