#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;
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);
* 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:
}
#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))
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);
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
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;
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;
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 )
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
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",
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;
}