st/nine: Back all shader constants to nine_context
[mesa.git] / src / gallium / state_trackers / nine / vertexdeclaration9.c
index 08b95e22fc42969748faec0d12f86536255405ac..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,7 +90,7 @@ 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) {
@@ -162,7 +162,7 @@ static const char *nine_declusage_names[] =
     [NINE_DECLUSAGE_FOG]             = "FOG",
     [NINE_DECLUSAGE_NONE]            = "(NONE)",
 };
-static INLINE const char *
+static inline const char *
 nine_declusage_name(unsigned ndcl)
 {
     return nine_declusage_names[ndcl % NINE_DECLUSAGE_COUNT];
@@ -174,21 +174,24 @@ 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));
     This->usage_map = CALLOC(This->nelems, sizeof(uint16_t));
@@ -200,6 +203,9 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This,
                                                      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;
         This->elems[i].vertex_buffer_index = This->decls[i].Stream;
@@ -220,6 +226,8 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This,
 void
 NineVertexDeclaration9_dtor( struct NineVertexDeclaration9 *This )
 {
+    DBG("This=%p\n", This);
+
     FREE(This->decls);
     FREE(This->elems);
     FREE(This->usage_map);
@@ -227,7 +235,7 @@ NineVertexDeclaration9_dtor( struct NineVertexDeclaration9 *This )
     NineUnknown_dtor(&This->base);
 }
 
-HRESULT WINAPI
+HRESULT NINE_WINAPI
 NineVertexDeclaration9_GetDeclaration( struct NineVertexDeclaration9 *This,
                                        D3DVERTEXELEMENT9 *pElement,
                                        UINT *pNumElements )
@@ -401,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
@@ -414,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",
@@ -469,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;
 }