Exemplo n.º 1
0
/**
 * Check if there are any resources that are both bound to a render target
 * and bound as a shader resource for the given type of shader.
 */
boolean
svga_check_sampler_framebuffer_resource_collision(struct svga_context *svga,
                                                  enum pipe_shader_type shader)
{
   struct svga_surface *surf;
   unsigned i;

   for (i = 0; i < svga->curr.framebuffer.nr_cbufs; i++) {
      surf = svga_surface(svga->curr.framebuffer.cbufs[i]);
      if (surf &&
          svga_check_sampler_view_resource_collision(svga, surf->handle,
                                                     shader)) {
         return TRUE;
      }
   }

   surf = svga_surface(svga->curr.framebuffer.zsbuf);
   if (surf &&
       svga_check_sampler_view_resource_collision(svga, surf->handle, shader)) {
      return TRUE;
   }

   return FALSE;
}
Exemplo n.º 2
0
/**
 * Create a DX RenderTarget/DepthStencil View for the given surface,
 * if needed.
 */
struct pipe_surface *
svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
{
   enum pipe_error ret = PIPE_OK;
   unsigned shader;

   assert(svga_have_vgpu10(svga));

   /**
    * DX spec explicitly specifies that no resource can be bound to a render
    * target view and a shader resource view simultanously.
    * So first check if the resource bound to this surface view collides with
    * a sampler view. If so, then we will clone this surface view and its
    * associated resource. We will then use the cloned surface view for
    * render target.
    */
   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
      if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
         SVGA_DBG(DEBUG_VIEWS,
                  "same resource used in shaderResource and renderTarget 0x%x\n",
                  s->handle);
         s = create_backed_surface_view(svga, s);
         if (!s)
            return NULL;

         break;
      }
   }

   if (s->view_id == SVGA3D_INVALID_ID) {
      SVGA3dResourceType resType;
      SVGA3dRenderTargetViewDesc desc;

      desc.tex.mipSlice = s->real_level;
      desc.tex.firstArraySlice = s->real_layer + s->real_zslice;
      desc.tex.arraySize =
         s->base.u.tex.last_layer - s->base.u.tex.first_layer + 1;

      s->view_id = util_bitmask_add(svga->surface_view_id_bm);

      switch (s->base.texture->target) {
      case PIPE_TEXTURE_1D:
      case PIPE_TEXTURE_1D_ARRAY:
         resType = SVGA3D_RESOURCE_TEXTURE1D;
         break;
      case PIPE_TEXTURE_RECT:
      case PIPE_TEXTURE_2D:
      case PIPE_TEXTURE_2D_ARRAY:
      case PIPE_TEXTURE_CUBE:
         /* drawing to cube map is treated as drawing to 2D array */
         resType = SVGA3D_RESOURCE_TEXTURE2D;
         break;
      case PIPE_TEXTURE_3D:
         resType = SVGA3D_RESOURCE_TEXTURE3D;
         break;
      default:
         assert(!"Unexpected texture target");
         resType = SVGA3D_RESOURCE_TEXTURE2D;
      }

      if (util_format_is_depth_or_stencil(s->base.format)) {
         ret = SVGA3D_vgpu10_DefineDepthStencilView(svga->swc,
                                                    s->view_id,
                                                    s->handle,
                                                    s->key.format,
                                                    resType,
                                                    &desc);
      }
      else {
         ret = SVGA3D_vgpu10_DefineRenderTargetView(svga->swc,
                                                    s->view_id,
                                                    s->handle,
                                                    s->key.format,
                                                    resType,
                                                    &desc);
      }

      if (ret != PIPE_OK) {
         util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
         s->view_id = SVGA3D_INVALID_ID;
         return NULL;
      }
   }
   return &s->base;
}