st/nine: Integrate nine_pipe_context_clear to nine_context_clear
[mesa.git] / src / gallium / state_trackers / nine / nine_pipe.h
index 86117866ed5316281edfbfc64ea670d5421d7d38..6bd4a0c89720026cc5911358e378631743b1341f 100644 (file)
@@ -38,38 +38,11 @@ extern const enum pipe_format nine_d3d9_to_pipe_format_map[120];
 extern const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT];
 
 void nine_convert_dsa_state(struct pipe_depth_stencil_alpha_state *, const DWORD *);
-void nine_convert_rasterizer_state(struct pipe_rasterizer_state *, const DWORD *);
+void nine_convert_rasterizer_state(struct NineDevice9 *, struct pipe_rasterizer_state *, const DWORD *);
 void nine_convert_blend_state(struct pipe_blend_state *, const DWORD *);
 void nine_convert_sampler_state(struct cso_context *, int idx, const DWORD *);
 
-void nine_pipe_context_clear(struct NineDevice9 *);
-
-static inline unsigned d3dlock_buffer_to_pipe_transfer_usage(DWORD Flags)
-{
-    unsigned usage;
-
-    if (Flags & D3DLOCK_DISCARD)
-        usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
-    else
-    if (Flags & D3DLOCK_READONLY)
-        usage = PIPE_TRANSFER_READ;
-    else
-        usage = PIPE_TRANSFER_READ_WRITE;
-
-    if (Flags & D3DLOCK_NOOVERWRITE)
-        usage = (PIPE_TRANSFER_UNSYNCHRONIZED |
-                 PIPE_TRANSFER_DISCARD_RANGE | usage) & ~PIPE_TRANSFER_READ;
-    else
-    if (Flags & D3DLOCK_DONOTWAIT)
-        usage |= PIPE_TRANSFER_DONTBLOCK;
-
-    /*
-    if (Flags & D3DLOCK_NO_DIRTY_UPDATE)
-        usage |= PIPE_TRANSFER_FLUSH_EXPLICIT;
-    */
-
-    return usage;
-}
+#define is_ATI1_ATI2(format) (format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC2_UNORM)
 
 static inline void
 rect_to_pipe_box(struct pipe_box *dst, const RECT *src)
@@ -266,8 +239,7 @@ d3d9_get_pipe_depth_format_bindings(D3DFORMAT format)
     case D3DFMT_D32F_LOCKABLE:
     case D3DFMT_D16_LOCKABLE:
     case D3DFMT_D32_LOCKABLE:
-        return PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_TRANSFER_READ |
-               PIPE_BIND_TRANSFER_WRITE;
+        return PIPE_BIND_DEPTH_STENCIL;
     case D3DFMT_DF16:
     case D3DFMT_DF24:
     case D3DFMT_INTZ:
@@ -324,7 +296,8 @@ d3d9_to_pipe_format_checked(struct pipe_screen *screen,
                             enum pipe_texture_target target,
                             unsigned sample_count,
                             unsigned bindings,
-                            boolean srgb)
+                            boolean srgb,
+                            boolean bypass_check)
 {
     enum pipe_format result;
 
@@ -335,7 +308,11 @@ d3d9_to_pipe_format_checked(struct pipe_screen *screen,
     if (srgb)
         result = util_format_srgb(result);
 
-    if (format_check_internal(result))
+    /* bypass_check: Used for D3DPOOL_SCRATCH, which
+     * isn't limited to the formats supported by the
+     * device, and to check we are not using a format
+     * fallback. */
+    if (bypass_check || format_check_internal(result))
         return result;
 
     /* fallback to another format for formats
@@ -353,12 +330,77 @@ d3d9_to_pipe_format_checked(struct pipe_screen *screen,
         case D3DFMT_D24X8:
             if (format_check_internal(PIPE_FORMAT_Z24X8_UNORM))
                 return PIPE_FORMAT_Z24X8_UNORM;
+            break;
+        /* Support for X8L8V8U8 bumpenvmap format with lighting bits.
+         * X8L8V8U8 is commonly supported among dx9 cards.
+         * To avoid precision loss, we use PIPE_FORMAT_R32G32B32X32_FLOAT,
+         * however using PIPE_FORMAT_R8G8B8A8_SNORM should be ok */
+        case D3DFMT_X8L8V8U8:
+            if (bindings & PIPE_BIND_RENDER_TARGET)
+                return PIPE_FORMAT_NONE;
+            if (format_check_internal(PIPE_FORMAT_R32G32B32X32_FLOAT))
+                return PIPE_FORMAT_R32G32B32X32_FLOAT;
         default:
             break;
     }
     return PIPE_FORMAT_NONE;
 }
 
+/* The quality levels are vendor dependent, so we set our own.
+ * Every quality level has its own sample count and sample
+ * position matrix.
+ * The exact mapping might differ from system to system but thats OK,
+ * as there's no way to gather more information about quality levels
+ * in D3D9.
+ * In case of NONMASKABLE multisample map every quality-level
+ * to a MASKABLE MultiSampleType:
+ *  0: no MSAA
+ *  1: 2x MSAA
+ *  2: 4x MSAA
+ *  ...
+ *  If the requested quality level is not available to nearest
+ *  matching quality level is used.
+ *  If no multisample is available the function sets
+ *  multisample to D3DMULTISAMPLE_NONE and returns zero.
+ */
+static inline HRESULT
+d3dmultisample_type_check(struct pipe_screen *screen,
+                          D3DFORMAT format,
+                          D3DMULTISAMPLE_TYPE *multisample,
+                          DWORD multisamplequality,
+                          DWORD *levels)
+{
+    unsigned bind, i;
+
+    assert(multisample);
+
+    if (levels)
+        *levels = 1;
+
+    if (*multisample == D3DMULTISAMPLE_NONMASKABLE) {
+        if (depth_stencil_format(format))
+            bind = d3d9_get_pipe_depth_format_bindings(format);
+        else /* render-target */
+            bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+
+        *multisample = 0;
+        for (i = D3DMULTISAMPLE_2_SAMPLES; i < D3DMULTISAMPLE_16_SAMPLES &&
+            multisamplequality; ++i) {
+            if (d3d9_to_pipe_format_checked(screen, format, PIPE_TEXTURE_2D,
+                    i, bind, FALSE, FALSE) != PIPE_FORMAT_NONE) {
+                multisamplequality--;
+                if (levels)
+                    (*levels)++;
+                *multisample = i;
+            }
+        }
+    }
+    /* Make sure to get an exact match */
+    if (multisamplequality)
+        return D3DERR_INVALIDCALL;
+    return D3D_OK;
+}
+
 static inline const char *
 d3dformat_to_string(D3DFORMAT fmt)
 {
@@ -436,6 +478,7 @@ d3dformat_to_string(D3DFORMAT fmt)
     case D3DFMT_NVDB: return "D3DFMT_NVDB";
     case D3DFMT_RESZ: return "D3DFMT_RESZ";
     case D3DFMT_NULL: return "D3DFMT_NULL";
+    case D3DFMT_ATOC: return "D3DFMT_ATOC";
     default:
         break;
     }
@@ -740,8 +783,16 @@ static inline unsigned nine_format_get_level_alloc_size(enum pipe_format format,
 
     w = u_minify(width, level);
     h = u_minify(height, level);
-    size = nine_format_get_stride(format, w) *
-        util_format_get_nblocksy(format, h);
+    if (is_ATI1_ATI2(format)) {
+        /* For "unknown" formats like ATIx use width * height bytes */
+        size = w * h;
+    } else if (format == PIPE_FORMAT_NONE) { /* D3DFMT_NULL */
+        size = w * h * 4;
+    } else {
+        size = nine_format_get_stride(format, w) *
+            util_format_get_nblocksy(format, h);
+    }
+
     return size;
 }
 
@@ -757,8 +808,13 @@ static inline unsigned nine_format_get_size_and_offsets(enum pipe_format format,
         w = u_minify(width, l);
         h = u_minify(height, l);
         offsets[l] = size;
-        size += nine_format_get_stride(format, w) *
-            util_format_get_nblocksy(format, h);
+        if (is_ATI1_ATI2(format)) {
+            /* For "unknown" formats like ATIx use width * height bytes */
+            size += w * h;
+        } else {
+            size += nine_format_get_stride(format, w) *
+                util_format_get_nblocksy(format, h);
+        }
     }
 
     return size;