st/nine: Back all shader constants to nine_context
[mesa.git] / src / gallium / state_trackers / nine / vertexdeclaration9.c
index 60b1fe37ac549be85dee6ca8ce9f06a82202cbf2..e1256e2f6d5141b3f1cf98f7af2478bf4f53793c 100644 (file)
 #include "vertexbuffer9.h"
 #include "device9.h"
 #include "nine_helpers.h"
+#include "nine_shader.h"
 
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "util/u_math.h"
 #include "util/u_format.h"
-#include "util/u_box.h"
 #include "translate/translate.h"
 
 #define DBG_CHANNEL DBG_VERTEXDECLARATION
 
-static INLINE enum pipe_format decltype_format(BYTE type)
+static inline enum pipe_format decltype_format(BYTE type)
 {
     switch (type) {
     case D3DDECLTYPE_FLOAT1:    return PIPE_FORMAT_R32_FLOAT;
@@ -60,7 +60,7 @@ static INLINE enum pipe_format decltype_format(BYTE type)
     return PIPE_FORMAT_NONE;
 }
 
-static INLINE unsigned decltype_size(BYTE type)
+static inline unsigned decltype_size(BYTE type)
 {
     switch (type) {
     case D3DDECLTYPE_FLOAT1: return 1 * sizeof(float);
@@ -90,26 +90,25 @@ static INLINE unsigned decltype_size(BYTE type)
  * simple lookup table won't work in that case. Let's just wait
  * with making this more generic until we need it.
  */
-static INLINE boolean
+static inline boolean
 nine_d3ddeclusage_check(unsigned usage, unsigned usage_idx)
 {
     switch (usage) {
     case D3DDECLUSAGE_POSITIONT:
-    case D3DDECLUSAGE_PSIZE:
     case D3DDECLUSAGE_TESSFACTOR:
     case D3DDECLUSAGE_DEPTH:
-    case D3DDECLUSAGE_FOG:
-    case D3DDECLUSAGE_SAMPLE:
-        return usage_idx <= 0;
     case D3DDECLUSAGE_NORMAL:
     case D3DDECLUSAGE_TANGENT:
     case D3DDECLUSAGE_BINORMAL:
-        return usage_idx <= 1;
     case D3DDECLUSAGE_POSITION:
     case D3DDECLUSAGE_BLENDWEIGHT:
     case D3DDECLUSAGE_BLENDINDICES:
     case D3DDECLUSAGE_COLOR:
-        return usage_idx <= 4;
+        return TRUE;
+    case D3DDECLUSAGE_PSIZE:
+    case D3DDECLUSAGE_FOG:
+    case D3DDECLUSAGE_SAMPLE:
+        return usage_idx <= 0;
     case D3DDECLUSAGE_TEXCOORD:
         return usage_idx <= 15;
     default:
@@ -118,8 +117,8 @@ nine_d3ddeclusage_check(unsigned usage, unsigned usage_idx)
 }
 
 #define NINE_DECLUSAGE_CASE0(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_##n
-#define NINE_DECLUSAGE_CASEi(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_##n(usage_idx)
-INLINE unsigned
+#define NINE_DECLUSAGE_CASEi(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_i(n, usage_idx)
+uint16_t
 nine_d3d9_to_nine_declusage(unsigned usage, unsigned usage_idx)
 {
     if (!nine_d3ddeclusage_check(usage, usage_idx))
@@ -135,7 +134,7 @@ nine_d3d9_to_nine_declusage(unsigned usage, unsigned usage_idx)
     NINE_DECLUSAGE_CASEi(TANGENT);
     NINE_DECLUSAGE_CASEi(BINORMAL);
     NINE_DECLUSAGE_CASE0(TESSFACTOR);
-    NINE_DECLUSAGE_CASE0(POSITIONT);
+    NINE_DECLUSAGE_CASEi(POSITIONT);
     NINE_DECLUSAGE_CASEi(COLOR);
     NINE_DECLUSAGE_CASE0(DEPTH);
     NINE_DECLUSAGE_CASE0(FOG);
@@ -148,58 +147,25 @@ nine_d3d9_to_nine_declusage(unsigned usage, unsigned usage_idx)
 
 static const char *nine_declusage_names[] =
 {
-    [NINE_DECLUSAGE_POSITION(0)]     = "POSITION",
-    [NINE_DECLUSAGE_POSITION(1)]     = "POSITION1",
-    [NINE_DECLUSAGE_POSITION(2)]     = "POSITION2",
-    [NINE_DECLUSAGE_POSITION(3)]     = "POSITION3",
-    [NINE_DECLUSAGE_POSITION(4)]     = "POSITION4",
-    [NINE_DECLUSAGE_BLENDWEIGHT(0)]  = "BLENDWEIGHT",
-    [NINE_DECLUSAGE_BLENDWEIGHT(1)]  = "BLENDWEIGHT1",
-    [NINE_DECLUSAGE_BLENDWEIGHT(2)]  = "BLENDWEIGHT2",
-    [NINE_DECLUSAGE_BLENDWEIGHT(3)]  = "BLENDWEIGHT3",
-    [NINE_DECLUSAGE_BLENDINDICES(0)] = "BLENDINDICES",
-    [NINE_DECLUSAGE_BLENDINDICES(1)] = "BLENDINDICES1",
-    [NINE_DECLUSAGE_BLENDINDICES(2)] = "BLENDINDICES2",
-    [NINE_DECLUSAGE_BLENDINDICES(3)] = "BLENDINDICES3",
-    [NINE_DECLUSAGE_NORMAL(0)]       = "NORMAL",
-    [NINE_DECLUSAGE_NORMAL(1)]       = "NORMAL1",
+    [NINE_DECLUSAGE_POSITION]        = "POSITION",
+    [NINE_DECLUSAGE_BLENDWEIGHT]     = "BLENDWEIGHT",
+    [NINE_DECLUSAGE_BLENDINDICES]    = "BLENDINDICES",
+    [NINE_DECLUSAGE_NORMAL]          = "NORMAL",
     [NINE_DECLUSAGE_PSIZE]           = "PSIZE",
-    [NINE_DECLUSAGE_TEXCOORD(0)]     = "TEXCOORD0",
-    [NINE_DECLUSAGE_TEXCOORD(1)]     = "TEXCOORD1",
-    [NINE_DECLUSAGE_TEXCOORD(2)]     = "TEXCOORD2",
-    [NINE_DECLUSAGE_TEXCOORD(3)]     = "TEXCOORD3",
-    [NINE_DECLUSAGE_TEXCOORD(4)]     = "TEXCOORD4",
-    [NINE_DECLUSAGE_TEXCOORD(5)]     = "TEXCOORD5",
-    [NINE_DECLUSAGE_TEXCOORD(6)]     = "TEXCOORD6",
-    [NINE_DECLUSAGE_TEXCOORD(7)]     = "TEXCOORD7",
-    [NINE_DECLUSAGE_TEXCOORD(8)]     = "TEXCOORD8",
-    [NINE_DECLUSAGE_TEXCOORD(9)]     = "TEXCOORD9",
-    [NINE_DECLUSAGE_TEXCOORD(10)]    = "TEXCOORD10",
-    [NINE_DECLUSAGE_TEXCOORD(11)]    = "TEXCOORD11",
-    [NINE_DECLUSAGE_TEXCOORD(12)]    = "TEXCOORD12",
-    [NINE_DECLUSAGE_TEXCOORD(13)]    = "TEXCOORD13",
-    [NINE_DECLUSAGE_TEXCOORD(14)]    = "TEXCOORD14",
-    [NINE_DECLUSAGE_TEXCOORD(15)]    = "TEXCOORD15",
-    [NINE_DECLUSAGE_TANGENT(0)]      = "TANGENT",
-    [NINE_DECLUSAGE_TANGENT(1)]      = "TANGENT1",
-    [NINE_DECLUSAGE_BINORMAL(0)]     = "BINORMAL",
-    [NINE_DECLUSAGE_BINORMAL(1)]     = "BINORMAL1",
+    [NINE_DECLUSAGE_TEXCOORD]        = "TEXCOORD",
+    [NINE_DECLUSAGE_TANGENT]         = "TANGENT",
+    [NINE_DECLUSAGE_BINORMAL]        = "BINORMAL",
     [NINE_DECLUSAGE_TESSFACTOR]      = "TESSFACTOR",
     [NINE_DECLUSAGE_POSITIONT]       = "POSITIONT",
-    [NINE_DECLUSAGE_COLOR(0)]        = "DIFFUSE",
-    [NINE_DECLUSAGE_COLOR(1)]        = "SPECULAR",
-    [NINE_DECLUSAGE_COLOR(2)]        = "COLOR2",
-    [NINE_DECLUSAGE_COLOR(3)]        = "COLOR3",
-    [NINE_DECLUSAGE_COLOR(4)]        = "COLOR4",
+    [NINE_DECLUSAGE_COLOR]           = "DIFFUSE",
     [NINE_DECLUSAGE_DEPTH]           = "DEPTH",
     [NINE_DECLUSAGE_FOG]             = "FOG",
     [NINE_DECLUSAGE_NONE]            = "(NONE)",
-    [NINE_DECLUSAGE_COUNT]           = "(OOB)"
 };
-static INLINE const char *
+static inline const char *
 nine_declusage_name(unsigned ndcl)
 {
-    return nine_declusage_names[MIN2(ndcl, Elements(nine_declusage_names) - 1)];
+    return nine_declusage_names[ndcl % NINE_DECLUSAGE_COUNT];
 }
 
 HRESULT
@@ -208,32 +174,37 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This,
                              const D3DVERTEXELEMENT9 *pElements )
 {
     const D3DCAPS9 *caps;
-    unsigned i;
-
+    unsigned i, nelems;
     DBG("This=%p pParams=%p pElements=%p\n", This, pParams, pElements);
 
-    HRESULT hr = NineUnknown_ctor(&This->base, pParams);
-    if (FAILED(hr)) { return hr; }
+    /* wine */
+    for (nelems = 0;
+         pElements[nelems].Stream != 0xFF;
+         ++nelems) {
+        user_assert(pElements[nelems].Type != D3DDECLTYPE_UNUSED, E_FAIL);
+        user_assert(!(pElements[nelems].Offset & 3), E_FAIL);
+    }
 
-    for (This->nelems = 0;
-         pElements[This->nelems].Type != D3DDECLTYPE_UNUSED &&
-         pElements[This->nelems].Stream != 0xFF; /* wine */
-         ++This->nelems);
+    caps = NineDevice9_GetCaps(pParams->device);
+    user_assert(nelems <= caps->MaxStreams, D3DERR_INVALIDCALL);
 
-    caps = NineDevice9_GetCaps(This->base.device);
-    user_assert(This->nelems <= caps->MaxStreams, D3DERR_INVALIDCALL);
+    HRESULT hr = NineUnknown_ctor(&This->base, pParams);
+    if (FAILED(hr)) { return hr; }
 
+    This->nelems = nelems;
     This->decls = CALLOC(This->nelems+1, sizeof(D3DVERTEXELEMENT9));
     This->elems = CALLOC(This->nelems, sizeof(struct pipe_vertex_element));
-    if (!This->decls || !This->elems) { return E_OUTOFMEMORY; }
+    This->usage_map = CALLOC(This->nelems, sizeof(uint16_t));
+    if (!This->decls || !This->elems || !This->usage_map) { return E_OUTOFMEMORY; }
     memcpy(This->decls, pElements, sizeof(D3DVERTEXELEMENT9)*(This->nelems+1));
 
-    memset(This->usage_map, 0xff, sizeof(This->usage_map));
-
     for (i = 0; i < This->nelems; ++i) {
-        uint8_t usage = nine_d3d9_to_nine_declusage(This->decls[i].Usage,
-                                                    This->decls[i].UsageIndex);
-        This->usage_map[usage] = i;
+        uint16_t usage = nine_d3d9_to_nine_declusage(This->decls[i].Usage,
+                                                     This->decls[i].UsageIndex);
+        This->usage_map[i] = usage;
+
+        if (This->decls[i].Usage == D3DDECLUSAGE_POSITIONT)
+            This->position_t = TRUE;
 
         This->elems[i].src_offset = This->decls[i].Offset;
         This->elems[i].instance_divisor = 0;
@@ -241,11 +212,12 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This,
         This->elems[i].src_format = decltype_format(This->decls[i].Type);
         /* XXX Remember Method (tesselation), Usage, UsageIndex */
 
-        DBG("VERTEXELEMENT[%u]: Stream=%u Offset=%u Type=%s DeclUsage=%s\n", i,
+        DBG("VERTEXELEMENT[%u]: Stream=%u Offset=%u Type=%s DeclUsage=%s%d\n", i,
             This->decls[i].Stream,
             This->decls[i].Offset,
             util_format_name(This->elems[i].src_format),
-            nine_declusage_name(usage));
+            nine_declusage_name(usage),
+            usage / NINE_DECLUSAGE_COUNT);
     }
 
     return D3D_OK;
@@ -254,15 +226,16 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This,
 void
 NineVertexDeclaration9_dtor( struct NineVertexDeclaration9 *This )
 {
-    if (This->decls)
-        FREE(This->decls);
-    if (This->elems)
-        FREE(This->elems);
+    DBG("This=%p\n", This);
+
+    FREE(This->decls);
+    FREE(This->elems);
+    FREE(This->usage_map);
 
     NineUnknown_dtor(&This->base);
 }
 
-HRESULT WINAPI
+HRESULT NINE_WINAPI
 NineVertexDeclaration9_GetDeclaration( struct NineVertexDeclaration9 *This,
                                        D3DVERTEXELEMENT9 *pElement,
                                        UINT *pNumElements )
@@ -436,6 +409,53 @@ NineVertexDeclaration9_new_from_fvf( struct NineDevice9 *pDevice,
     NINE_DEVICE_CHILD_NEW(VertexDeclaration9, ppOut, /* args */ pDevice, elems);
 }
 
+void
+NineVertexDeclaration9_FillStreamOutputInfo(
+    struct NineVertexDeclaration9 *This,
+    struct nine_vs_output_info *ShaderOutputsInfo,
+    unsigned numOutputs,
+    struct pipe_stream_output_info *so )
+{
+    unsigned so_outputs = 0;
+    int i, j;
+
+    memset(so, 0, sizeof(struct pipe_stream_output_info));
+
+    for (i = 0; i < numOutputs; i++) {
+        BYTE output_semantic = ShaderOutputsInfo[i].output_semantic;
+        unsigned output_semantic_index = ShaderOutputsInfo[i].output_semantic_index;
+
+        for (j = 0; j < This->nelems; j++) {
+            if ((This->decls[j].Usage == output_semantic ||
+                 (output_semantic == D3DDECLUSAGE_POSITION &&
+                  This->decls[j].Usage == D3DDECLUSAGE_POSITIONT)) &&
+                This->decls[j].UsageIndex == output_semantic_index) {
+                DBG("Matching %s %d: o%d -> %d\n",
+                    nine_declusage_name(nine_d3d9_to_nine_declusage(This->decls[j].Usage, 0)),
+                    This->decls[j].UsageIndex, i, j);
+                so->output[so_outputs].register_index = ShaderOutputsInfo[i].output_index;
+                so->output[so_outputs].start_component = 0;
+                if (ShaderOutputsInfo[i].mask & 8)
+                    so->output[so_outputs].num_components = 4;
+                else if (ShaderOutputsInfo[i].mask & 4)
+                    so->output[so_outputs].num_components = 3;
+                else if (ShaderOutputsInfo[i].mask & 2)
+                    so->output[so_outputs].num_components = 2;
+                else
+                    so->output[so_outputs].num_components = 1;
+                so->output[so_outputs].output_buffer = 0;
+                so->output[so_outputs].dst_offset = so_outputs * sizeof(float[4])/4;
+                so->output[so_outputs].stream = 0;
+                so_outputs++;
+                break;
+            }
+        }
+    }
+
+    so->num_outputs = so_outputs;
+    so->stride[0] = so_outputs * sizeof(float[4])/4;
+}
+
 /* ProcessVertices runs stream output into a temporary buffer to capture
  * all outputs.
  * Now we have to convert them to the format and order set by the vertex
@@ -449,17 +469,13 @@ NineVertexDeclaration9_ConvertStreamOutput(
     struct NineVertexBuffer9 *pDstBuf,
     UINT DestIndex,
     UINT VertexCount,
-    struct pipe_resource *pSrcBuf,
+    void *pSrcBuf,
     const struct pipe_stream_output_info *so )
 {
-    struct pipe_context *pipe = This->base.device->pipe;
-    struct pipe_transfer *transfer = NULL;
     struct translate *translate;
     struct translate_key transkey;
-    struct pipe_box box;
     HRESULT hr;
     unsigned i;
-    void *src_map;
     void *dst_map;
 
     DBG("This=%p pDstBuf=%p DestIndex=%u VertexCount=%u pSrcBuf=%p so=%p\n",
@@ -504,20 +520,12 @@ NineVertexDeclaration9_ConvertStreamOutput(
     if (FAILED(hr))
         goto out;
 
-    src_map = pipe->transfer_map(pipe, pSrcBuf, 0, PIPE_TRANSFER_READ, &box,
-                                 &transfer);
-    if (!src_map) {
-        hr = D3DERR_DRIVERINTERNALERROR;
-        goto out;
-    }
-    translate->set_buffer(translate, 0, src_map, so->stride[0], ~0);
+    translate->set_buffer(translate, 0, pSrcBuf, so->stride[0] * 4, ~0);
 
     translate->run(translate, 0, VertexCount, 0, 0, dst_map);
 
     NineVertexBuffer9_Unlock(pDstBuf);
 out:
-    if (transfer)
-        pipe->transfer_unmap(pipe, transfer);
     translate->release(translate); /* TODO: cache these */
     return hr;
 }