winsys/svga: Add support for new surface ioctl, multisample pattern
[mesa.git] / src / gallium / winsys / svga / drm / vmw_screen_svga.c
index 27a8b07016613b7e0875c438967b2fbdb2722720..7edd13032796f5c11c2425e28be4782ca2700268 100644 (file)
@@ -170,7 +170,7 @@ vmw_svga_winsys_fence_server_sync(struct svga_winsys_screen *sws,
 
 static struct svga_winsys_surface *
 vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
-                               SVGA3dSurfaceFlags flags,
+                               SVGA3dSurfaceAllFlags flags,
                                SVGA3dSurfaceFormat format,
                                unsigned usage,
                                SVGA3dSize size,
@@ -183,6 +183,8 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
    struct vmw_buffer_desc desc;
    struct pb_manager *provider;
    uint32_t buffer_size;
+   uint32_t num_samples = 1;
+   SVGA3dMSPattern multisample_pattern = SVGA3D_MS_PATTERN_NONE;
 
    memset(&desc, 0, sizeof(desc));
    surface = CALLOC_STRUCT(vmw_svga_winsys_surface);
@@ -196,12 +198,25 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
    surface->shared = !!(usage & SVGA_SURFACE_USAGE_SHARED);
    provider = (surface->shared) ? vws->pools.gmr : vws->pools.mob_fenced;
 
+   /*
+    * When multisampling is not supported sample count received is 0,
+    * otherwise should have a valid sample count.
+    */
+   if ((flags & SVGA3D_SURFACE_MULTISAMPLE) != 0) {
+      if (sampleCount == 0)
+         goto no_sid;
+      num_samples = sampleCount;
+      multisample_pattern = SVGA3D_MS_PATTERN_STANDARD;
+   }
+
    /*
     * Used for the backing buffer GB surfaces, and to approximate
     * when to flush on non-GB hosts.
     */
-   buffer_size = svga3dsurface_get_serialized_size(format, size, numMipLevels, 
-                                                   numLayers);
+   buffer_size = svga3dsurface_get_serialized_size_extended(format, size,
+                                                            numMipLevels,
+                                                            numLayers,
+                                                            num_samples);
    if (flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT)
       buffer_size += sizeof(SVGA3dDXSOState);
 
@@ -233,6 +248,7 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
                                                  size, numLayers,
                                                  numMipLevels, sampleCount,
                                                  ptr.gmrId,
+                                                 multisample_pattern,
                                                  surface->buf ? NULL :
                                                 &desc.region);
 
@@ -251,7 +267,8 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
             surface->sid = vmw_ioctl_gb_surface_create(vws, flags, format, usage,
                                                        size, numLayers,
                                                        numMipLevels, sampleCount,
-                                                       0, &desc.region);
+                                                       0, multisample_pattern,
+                                                       &desc.region);
             if (surface->sid == SVGA3D_INVALID_ID)
                goto no_sid;
          }
@@ -277,9 +294,10 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
          }
       }
    } else {
-      surface->sid = vmw_ioctl_surface_create(vws, flags, format, usage,
-                                              size, numLayers, numMipLevels,
-                                              sampleCount);
+      /* Legacy surface only support 32-bit svga3d flags */
+      surface->sid = vmw_ioctl_surface_create(vws, (SVGA3dSurface1Flags)flags,
+                                              format, usage, size, numLayers,
+                                              numMipLevels, sampleCount);
       if(surface->sid == SVGA3D_INVALID_ID)
          goto no_sid;
 
@@ -304,7 +322,8 @@ vmw_svga_winsys_surface_can_create(struct svga_winsys_screen *sws,
                                SVGA3dSurfaceFormat format,
                                SVGA3dSize size,
                                uint32 numLayers,
-                               uint32 numMipLevels)
+                               uint32 numMipLevels,
+                               uint32 numSamples)
 {
    struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
    uint32_t buffer_size;
@@ -312,6 +331,9 @@ vmw_svga_winsys_surface_can_create(struct svga_winsys_screen *sws,
    buffer_size = svga3dsurface_get_serialized_size(format, size, 
                                                    numMipLevels, 
                                                    numLayers);
+   if (numSamples > 1)
+      buffer_size *= numSamples;
+
    if (buffer_size > vws->ioctl.max_texture_size) {
        return FALSE;
    }