~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/frontends/nine/vertexdeclaration9.c

  • Committer: mmach
  • Date: 2022-09-22 19:58:36 UTC
  • Revision ID: netbit73@gmail.com-20220922195836-9nl9joew85y8d25o
2022-07-04 12:44:28

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
 
3
 *
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a
 
5
 * copy of this software and associated documentation files (the "Software"),
 
6
 * to deal in the Software without restriction, including without limitation
 
7
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 
8
 * license, and/or sell copies of the Software, and to permit persons to whom
 
9
 * the Software is furnished to do so, subject to the following conditions:
 
10
 *
 
11
 * The above copyright notice and this permission notice (including the next
 
12
 * paragraph) shall be included in all copies or substantial portions of the
 
13
 * Software.
 
14
 *
 
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 
18
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 
19
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
20
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 
21
 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
22
 
 
23
#include "vertexdeclaration9.h"
 
24
#include "vertexbuffer9.h"
 
25
#include "device9.h"
 
26
#include "nine_helpers.h"
 
27
#include "nine_shader.h"
 
28
 
 
29
#include "pipe/p_format.h"
 
30
#include "pipe/p_context.h"
 
31
#include "util/u_math.h"
 
32
#include "util/format/u_format.h"
 
33
#include "translate/translate.h"
 
34
 
 
35
#define DBG_CHANNEL DBG_VERTEXDECLARATION
 
36
 
 
37
static inline enum pipe_format decltype_format(BYTE type)
 
38
{
 
39
    switch (type) {
 
40
    case D3DDECLTYPE_FLOAT1:    return PIPE_FORMAT_R32_FLOAT;
 
41
    case D3DDECLTYPE_FLOAT2:    return PIPE_FORMAT_R32G32_FLOAT;
 
42
    case D3DDECLTYPE_FLOAT3:    return PIPE_FORMAT_R32G32B32_FLOAT;
 
43
    case D3DDECLTYPE_FLOAT4:    return PIPE_FORMAT_R32G32B32A32_FLOAT;
 
44
    case D3DDECLTYPE_D3DCOLOR:  return PIPE_FORMAT_B8G8R8A8_UNORM;
 
45
    case D3DDECLTYPE_UBYTE4:    return PIPE_FORMAT_R8G8B8A8_USCALED;
 
46
    case D3DDECLTYPE_SHORT2:    return PIPE_FORMAT_R16G16_SSCALED;
 
47
    case D3DDECLTYPE_SHORT4:    return PIPE_FORMAT_R16G16B16A16_SSCALED;
 
48
    case D3DDECLTYPE_UBYTE4N:   return PIPE_FORMAT_R8G8B8A8_UNORM;
 
49
    case D3DDECLTYPE_SHORT2N:   return PIPE_FORMAT_R16G16_SNORM;
 
50
    case D3DDECLTYPE_SHORT4N:   return PIPE_FORMAT_R16G16B16A16_SNORM;
 
51
    case D3DDECLTYPE_USHORT2N:  return PIPE_FORMAT_R16G16_UNORM;
 
52
    case D3DDECLTYPE_USHORT4N:  return PIPE_FORMAT_R16G16B16A16_UNORM;
 
53
    case D3DDECLTYPE_UDEC3:     return PIPE_FORMAT_R10G10B10X2_USCALED;
 
54
    case D3DDECLTYPE_DEC3N:     return PIPE_FORMAT_R10G10B10X2_SNORM;
 
55
    case D3DDECLTYPE_FLOAT16_2: return PIPE_FORMAT_R16G16_FLOAT;
 
56
    case D3DDECLTYPE_FLOAT16_4: return PIPE_FORMAT_R16G16B16A16_FLOAT;
 
57
    default:
 
58
        assert(!"Implementation error !");
 
59
    }
 
60
    return PIPE_FORMAT_NONE;
 
61
}
 
62
 
 
63
static inline unsigned decltype_size(BYTE type)
 
64
{
 
65
    switch (type) {
 
66
    case D3DDECLTYPE_FLOAT1: return 1 * sizeof(float);
 
67
    case D3DDECLTYPE_FLOAT2: return 2 * sizeof(float);
 
68
    case D3DDECLTYPE_FLOAT3: return 3 * sizeof(float);
 
69
    case D3DDECLTYPE_FLOAT4: return 4 * sizeof(float);
 
70
    case D3DDECLTYPE_D3DCOLOR: return 1 * sizeof(DWORD);
 
71
    case D3DDECLTYPE_UBYTE4: return 4 * sizeof(BYTE);
 
72
    case D3DDECLTYPE_SHORT2: return 2 * sizeof(short);
 
73
    case D3DDECLTYPE_SHORT4: return 4 * sizeof(short);
 
74
    case D3DDECLTYPE_UBYTE4N: return 4 * sizeof(BYTE);
 
75
    case D3DDECLTYPE_SHORT2N: return 2 * sizeof(short);
 
76
    case D3DDECLTYPE_SHORT4N: return 4 * sizeof(short);
 
77
    case D3DDECLTYPE_USHORT2N: return 2 * sizeof(short);
 
78
    case D3DDECLTYPE_USHORT4N: return 4 * sizeof(short);
 
79
    case D3DDECLTYPE_UDEC3: return 4;
 
80
    case D3DDECLTYPE_DEC3N: return 4;
 
81
    case D3DDECLTYPE_FLOAT16_2: return 2 * 2;
 
82
    case D3DDECLTYPE_FLOAT16_4: return 4 * 2;
 
83
    default:
 
84
        assert(!"Implementation error !");
 
85
    }
 
86
    return 0;
 
87
}
 
88
 
 
89
/* Actually, arbitrary usage index values are permitted, but a
 
90
 * simple lookup table won't work in that case. Let's just wait
 
91
 * with making this more generic until we need it.
 
92
 */
 
93
static inline boolean
 
94
nine_d3ddeclusage_check(unsigned usage, unsigned usage_idx)
 
95
{
 
96
    switch (usage) {
 
97
    case D3DDECLUSAGE_POSITIONT:
 
98
    case D3DDECLUSAGE_TESSFACTOR:
 
99
    case D3DDECLUSAGE_DEPTH:
 
100
    case D3DDECLUSAGE_NORMAL:
 
101
    case D3DDECLUSAGE_TANGENT:
 
102
    case D3DDECLUSAGE_BINORMAL:
 
103
    case D3DDECLUSAGE_POSITION:
 
104
    case D3DDECLUSAGE_BLENDWEIGHT:
 
105
    case D3DDECLUSAGE_BLENDINDICES:
 
106
    case D3DDECLUSAGE_COLOR:
 
107
        return TRUE;
 
108
    case D3DDECLUSAGE_PSIZE:
 
109
    case D3DDECLUSAGE_FOG:
 
110
    case D3DDECLUSAGE_SAMPLE:
 
111
        return usage_idx <= 0;
 
112
    case D3DDECLUSAGE_TEXCOORD:
 
113
        return usage_idx <= 15;
 
114
    default:
 
115
        return FALSE;
 
116
    }
 
117
}
 
118
 
 
119
#define NINE_DECLUSAGE_CASE0(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_##n
 
120
#define NINE_DECLUSAGE_CASEi(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_i(n, usage_idx)
 
121
uint16_t
 
122
nine_d3d9_to_nine_declusage(unsigned usage, unsigned usage_idx)
 
123
{
 
124
    if (!nine_d3ddeclusage_check(usage, usage_idx))
 
125
        ERR("D3DDECLUSAGE_%u[%u]\n",usage,usage_idx);
 
126
    assert(nine_d3ddeclusage_check(usage, usage_idx));
 
127
    switch (usage) {
 
128
    NINE_DECLUSAGE_CASEi(POSITION);
 
129
    NINE_DECLUSAGE_CASEi(BLENDWEIGHT);
 
130
    NINE_DECLUSAGE_CASEi(BLENDINDICES);
 
131
    NINE_DECLUSAGE_CASEi(NORMAL);
 
132
    NINE_DECLUSAGE_CASE0(PSIZE);
 
133
    NINE_DECLUSAGE_CASEi(TEXCOORD);
 
134
    NINE_DECLUSAGE_CASEi(TANGENT);
 
135
    NINE_DECLUSAGE_CASEi(BINORMAL);
 
136
    NINE_DECLUSAGE_CASE0(TESSFACTOR);
 
137
    NINE_DECLUSAGE_CASEi(POSITIONT);
 
138
    NINE_DECLUSAGE_CASEi(COLOR);
 
139
    NINE_DECLUSAGE_CASE0(DEPTH);
 
140
    NINE_DECLUSAGE_CASE0(FOG);
 
141
    NINE_DECLUSAGE_CASE0(SAMPLE);
 
142
    default:
 
143
        assert(!"Invalid DECLUSAGE.");
 
144
        return NINE_DECLUSAGE_NONE;
 
145
    }
 
146
}
 
147
 
 
148
static const char *nine_declusage_names[] =
 
149
{
 
150
    [NINE_DECLUSAGE_POSITION]        = "POSITION",
 
151
    [NINE_DECLUSAGE_BLENDWEIGHT]     = "BLENDWEIGHT",
 
152
    [NINE_DECLUSAGE_BLENDINDICES]    = "BLENDINDICES",
 
153
    [NINE_DECLUSAGE_NORMAL]          = "NORMAL",
 
154
    [NINE_DECLUSAGE_PSIZE]           = "PSIZE",
 
155
    [NINE_DECLUSAGE_TEXCOORD]        = "TEXCOORD",
 
156
    [NINE_DECLUSAGE_TANGENT]         = "TANGENT",
 
157
    [NINE_DECLUSAGE_BINORMAL]        = "BINORMAL",
 
158
    [NINE_DECLUSAGE_TESSFACTOR]      = "TESSFACTOR",
 
159
    [NINE_DECLUSAGE_POSITIONT]       = "POSITIONT",
 
160
    [NINE_DECLUSAGE_COLOR]           = "DIFFUSE",
 
161
    [NINE_DECLUSAGE_DEPTH]           = "DEPTH",
 
162
    [NINE_DECLUSAGE_FOG]             = "FOG",
 
163
    [NINE_DECLUSAGE_NONE]            = "(NONE)",
 
164
};
 
165
static inline const char *
 
166
nine_declusage_name(unsigned ndcl)
 
167
{
 
168
    return nine_declusage_names[ndcl % NINE_DECLUSAGE_COUNT];
 
169
}
 
170
 
 
171
HRESULT
 
172
NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This,
 
173
                             struct NineUnknownParams *pParams,
 
174
                             const D3DVERTEXELEMENT9 *pElements )
 
175
{
 
176
    const D3DCAPS9 *caps;
 
177
    unsigned i, nelems;
 
178
    DBG("This=%p pParams=%p pElements=%p\n", This, pParams, pElements);
 
179
 
 
180
    /* wine */
 
181
    for (nelems = 0;
 
182
         pElements[nelems].Stream != 0xFF;
 
183
         ++nelems) {
 
184
        user_assert(pElements[nelems].Type != D3DDECLTYPE_UNUSED, E_FAIL);
 
185
        user_assert(!(pElements[nelems].Offset & 3), E_FAIL);
 
186
    }
 
187
 
 
188
    caps = NineDevice9_GetCaps(pParams->device);
 
189
    user_assert(nelems <= caps->MaxStreams, D3DERR_INVALIDCALL);
 
190
 
 
191
    HRESULT hr = NineUnknown_ctor(&This->base, pParams);
 
192
    if (FAILED(hr)) { return hr; }
 
193
 
 
194
    This->nelems = nelems;
 
195
    This->decls = CALLOC(This->nelems+1, sizeof(D3DVERTEXELEMENT9));
 
196
    This->elems = CALLOC(This->nelems, sizeof(struct pipe_vertex_element));
 
197
    This->usage_map = CALLOC(This->nelems, sizeof(uint16_t));
 
198
    if (!This->decls || !This->elems || !This->usage_map) { return E_OUTOFMEMORY; }
 
199
    memcpy(This->decls, pElements, sizeof(D3DVERTEXELEMENT9)*(This->nelems+1));
 
200
 
 
201
    for (i = 0; i < This->nelems; ++i) {
 
202
        uint16_t usage = nine_d3d9_to_nine_declusage(This->decls[i].Usage,
 
203
                                                     This->decls[i].UsageIndex);
 
204
        This->usage_map[i] = usage;
 
205
 
 
206
        if (This->decls[i].Usage == D3DDECLUSAGE_POSITIONT)
 
207
            This->position_t = TRUE;
 
208
 
 
209
        This->elems[i].src_offset = This->decls[i].Offset;
 
210
        This->elems[i].instance_divisor = 0;
 
211
        This->elems[i].vertex_buffer_index = This->decls[i].Stream;
 
212
        This->elems[i].src_format = decltype_format(This->decls[i].Type);
 
213
        This->elems[i].dual_slot = false;
 
214
        /* XXX Remember Method (tesselation), Usage, UsageIndex */
 
215
 
 
216
        DBG("VERTEXELEMENT[%u]: Stream=%u Offset=%u Type=%s DeclUsage=%s%d\n", i,
 
217
            This->decls[i].Stream,
 
218
            This->decls[i].Offset,
 
219
            util_format_name(This->elems[i].src_format),
 
220
            nine_declusage_name(usage),
 
221
            usage / NINE_DECLUSAGE_COUNT);
 
222
    }
 
223
 
 
224
    return D3D_OK;
 
225
}
 
226
 
 
227
void
 
228
NineVertexDeclaration9_dtor( struct NineVertexDeclaration9 *This )
 
229
{
 
230
    DBG("This=%p\n", This);
 
231
 
 
232
    FREE(This->decls);
 
233
    FREE(This->elems);
 
234
    FREE(This->usage_map);
 
235
 
 
236
    NineUnknown_dtor(&This->base);
 
237
}
 
238
 
 
239
HRESULT NINE_WINAPI
 
240
NineVertexDeclaration9_GetDeclaration( struct NineVertexDeclaration9 *This,
 
241
                                       D3DVERTEXELEMENT9 *pElement,
 
242
                                       UINT *pNumElements )
 
243
{
 
244
    if (!pElement) {
 
245
        user_assert(pNumElements, D3DERR_INVALIDCALL);
 
246
        *pNumElements = This->nelems+1;
 
247
        return D3D_OK;
 
248
    }
 
249
    if (pNumElements) { *pNumElements = This->nelems+1; }
 
250
    memcpy(pElement, This->decls, sizeof(D3DVERTEXELEMENT9)*(This->nelems+1));
 
251
    return D3D_OK;
 
252
}
 
253
 
 
254
IDirect3DVertexDeclaration9Vtbl NineVertexDeclaration9_vtable = {
 
255
    (void *)NineUnknown_QueryInterface,
 
256
    (void *)NineUnknown_AddRef,
 
257
    (void *)NineUnknown_Release,
 
258
    (void *)NineUnknown_GetDevice, /* actually part of VertexDecl9 iface */
 
259
    (void *)NineVertexDeclaration9_GetDeclaration
 
260
};
 
261
 
 
262
static const GUID *NineVertexDeclaration9_IIDs[] = {
 
263
    &IID_IDirect3DVertexDeclaration9,
 
264
    &IID_IUnknown,
 
265
    NULL
 
266
};
 
267
 
 
268
HRESULT
 
269
NineVertexDeclaration9_new( struct NineDevice9 *pDevice,
 
270
                            const D3DVERTEXELEMENT9 *pElements,
 
271
                            struct NineVertexDeclaration9 **ppOut )
 
272
{
 
273
    NINE_DEVICE_CHILD_NEW(VertexDeclaration9, ppOut, /* args */ pDevice, pElements);
 
274
}
 
275
 
 
276
HRESULT
 
277
NineVertexDeclaration9_new_from_fvf( struct NineDevice9 *pDevice,
 
278
                                     DWORD FVF,
 
279
                                     struct NineVertexDeclaration9 **ppOut )
 
280
{
 
281
    D3DVERTEXELEMENT9 elems[16], decl_end = D3DDECL_END();
 
282
    unsigned texcount, i, betas, nelems = 0;
 
283
    BYTE beta_index = 0xFF;
 
284
 
 
285
    switch (FVF & D3DFVF_POSITION_MASK) {
 
286
        case D3DFVF_XYZ: /* simple XYZ */
 
287
        case D3DFVF_XYZB1:
 
288
        case D3DFVF_XYZB2:
 
289
        case D3DFVF_XYZB3:
 
290
        case D3DFVF_XYZB4:
 
291
        case D3DFVF_XYZB5: /* XYZ with beta values */
 
292
            elems[nelems].Type = D3DDECLTYPE_FLOAT3;
 
293
            elems[nelems].Usage = D3DDECLUSAGE_POSITION;
 
294
            elems[nelems].UsageIndex = 0;
 
295
            ++nelems;
 
296
            /* simple XYZ has no beta values. break. */
 
297
            if ((FVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { break; }
 
298
 
 
299
            betas = (((FVF & D3DFVF_XYZB5)-D3DFVF_XYZB1)>>1)+1;
 
300
            if (FVF & D3DFVF_LASTBETA_D3DCOLOR) {
 
301
                beta_index = D3DDECLTYPE_D3DCOLOR;
 
302
            } else if (FVF & D3DFVF_LASTBETA_UBYTE4) {
 
303
                beta_index = D3DDECLTYPE_UBYTE4;
 
304
            } else if ((FVF & D3DFVF_XYZB5) == D3DFVF_XYZB5) {
 
305
                beta_index = D3DDECLTYPE_FLOAT1;
 
306
            }
 
307
            if (beta_index != 0xFF) { --betas; }
 
308
 
 
309
            if (betas > 0) {
 
310
                switch (betas) {
 
311
                    case 1: elems[nelems].Type = D3DDECLTYPE_FLOAT1; break;
 
312
                    case 2: elems[nelems].Type = D3DDECLTYPE_FLOAT2; break;
 
313
                    case 3: elems[nelems].Type = D3DDECLTYPE_FLOAT3; break;
 
314
                    case 4: elems[nelems].Type = D3DDECLTYPE_FLOAT4; break;
 
315
                    default:
 
316
                        assert(!"Implementation error!");
 
317
                }
 
318
                elems[nelems].Usage = D3DDECLUSAGE_BLENDWEIGHT;
 
319
                elems[nelems].UsageIndex = 0;
 
320
                ++nelems;
 
321
            }
 
322
 
 
323
            if (beta_index != 0xFF) {
 
324
                elems[nelems].Type = beta_index;
 
325
                elems[nelems].Usage = D3DDECLUSAGE_BLENDINDICES;
 
326
                elems[nelems].UsageIndex = 0;
 
327
                ++nelems;
 
328
            }
 
329
            break;
 
330
 
 
331
        case D3DFVF_XYZW: /* simple XYZW */
 
332
        case D3DFVF_XYZRHW: /* pretransformed XYZW */
 
333
            elems[nelems].Type = D3DDECLTYPE_FLOAT4;
 
334
            elems[nelems].Usage =
 
335
                ((FVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZW) ?
 
336
                D3DDECLUSAGE_POSITION : D3DDECLUSAGE_POSITIONT;
 
337
            elems[nelems].UsageIndex = 0;
 
338
            ++nelems;
 
339
            break;
 
340
 
 
341
        default:
 
342
            (void)user_error(!"Position doesn't match any known combination");
 
343
    }
 
344
 
 
345
    /* normals, psize and colors */
 
346
    if (FVF & D3DFVF_NORMAL) {
 
347
        elems[nelems].Type = D3DDECLTYPE_FLOAT3;
 
348
        elems[nelems].Usage = D3DDECLUSAGE_NORMAL;
 
349
        elems[nelems].UsageIndex = 0;
 
350
        ++nelems;
 
351
    }
 
352
    if (FVF & D3DFVF_PSIZE) {
 
353
        elems[nelems].Type = D3DDECLTYPE_FLOAT1;
 
354
        elems[nelems].Usage = D3DDECLUSAGE_PSIZE;
 
355
        elems[nelems].UsageIndex = 0;
 
356
        ++nelems;
 
357
    }
 
358
    if (FVF & D3DFVF_DIFFUSE) {
 
359
        elems[nelems].Type = D3DDECLTYPE_D3DCOLOR;
 
360
        elems[nelems].Usage = D3DDECLUSAGE_COLOR;
 
361
        elems[nelems].UsageIndex = 0;
 
362
        ++nelems;
 
363
    }
 
364
    if (FVF & D3DFVF_SPECULAR) {
 
365
        elems[nelems].Type = D3DDECLTYPE_D3DCOLOR;
 
366
        elems[nelems].Usage = D3DDECLUSAGE_COLOR;
 
367
        elems[nelems].UsageIndex = 1;
 
368
        ++nelems;
 
369
    }
 
370
 
 
371
    /* textures */
 
372
    texcount = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
 
373
    if (user_error(texcount <= 8)) { texcount = 8; }
 
374
 
 
375
    for (i = 0; i < texcount; ++i) {
 
376
        switch ((FVF >> (16+i*2)) & 0x3) {
 
377
            case D3DFVF_TEXTUREFORMAT1:
 
378
                elems[nelems].Type = D3DDECLTYPE_FLOAT1;
 
379
                break;
 
380
 
 
381
            case D3DFVF_TEXTUREFORMAT2:
 
382
                elems[nelems].Type = D3DDECLTYPE_FLOAT2;
 
383
                break;
 
384
 
 
385
            case D3DFVF_TEXTUREFORMAT3:
 
386
                elems[nelems].Type = D3DDECLTYPE_FLOAT3;
 
387
                break;
 
388
 
 
389
            case D3DFVF_TEXTUREFORMAT4:
 
390
                elems[nelems].Type = D3DDECLTYPE_FLOAT4;
 
391
                break;
 
392
 
 
393
            default:
 
394
                assert(!"Implementation error!");
 
395
        }
 
396
        elems[nelems].Usage = D3DDECLUSAGE_TEXCOORD;
 
397
        elems[nelems].UsageIndex = i;
 
398
        ++nelems;
 
399
    }
 
400
 
 
401
    /* fill out remaining data */
 
402
    for (i = 0; i < nelems; ++i) {
 
403
        elems[i].Stream = 0;
 
404
        elems[i].Offset = (i == 0) ? 0 : (elems[i-1].Offset +
 
405
                                          decltype_size(elems[i-1].Type));
 
406
        elems[i].Method = D3DDECLMETHOD_DEFAULT;
 
407
    }
 
408
    elems[nelems++] = decl_end;
 
409
 
 
410
    NINE_DEVICE_CHILD_NEW(VertexDeclaration9, ppOut, /* args */ pDevice, elems);
 
411
}
 
412
 
 
413
void
 
414
NineVertexDeclaration9_FillStreamOutputInfo(
 
415
    struct NineVertexDeclaration9 *This,
 
416
    struct nine_vs_output_info *ShaderOutputsInfo,
 
417
    unsigned numOutputs,
 
418
    struct pipe_stream_output_info *so )
 
419
{
 
420
    unsigned so_outputs = 0;
 
421
    int i, j;
 
422
 
 
423
    memset(so, 0, sizeof(struct pipe_stream_output_info));
 
424
 
 
425
    for (i = 0; i < numOutputs; i++) {
 
426
        BYTE output_semantic = ShaderOutputsInfo[i].output_semantic;
 
427
        unsigned output_semantic_index = ShaderOutputsInfo[i].output_semantic_index;
 
428
 
 
429
        for (j = 0; j < This->nelems; j++) {
 
430
            if ((This->decls[j].Usage == output_semantic ||
 
431
                 (output_semantic == D3DDECLUSAGE_POSITION &&
 
432
                  This->decls[j].Usage == D3DDECLUSAGE_POSITIONT)) &&
 
433
                This->decls[j].UsageIndex == output_semantic_index) {
 
434
                DBG("Matching %s %d: o%d -> %d\n",
 
435
                    nine_declusage_name(nine_d3d9_to_nine_declusage(This->decls[j].Usage, 0)),
 
436
                    This->decls[j].UsageIndex, i, j);
 
437
                so->output[so_outputs].register_index = ShaderOutputsInfo[i].output_index;
 
438
                so->output[so_outputs].start_component = 0;
 
439
                if (ShaderOutputsInfo[i].mask & 8)
 
440
                    so->output[so_outputs].num_components = 4;
 
441
                else if (ShaderOutputsInfo[i].mask & 4)
 
442
                    so->output[so_outputs].num_components = 3;
 
443
                else if (ShaderOutputsInfo[i].mask & 2)
 
444
                    so->output[so_outputs].num_components = 2;
 
445
                else
 
446
                    so->output[so_outputs].num_components = 1;
 
447
                so->output[so_outputs].output_buffer = 0;
 
448
                so->output[so_outputs].dst_offset = so_outputs * sizeof(float[4])/4;
 
449
                so->output[so_outputs].stream = 0;
 
450
                so_outputs++;
 
451
                break;
 
452
            }
 
453
        }
 
454
    }
 
455
 
 
456
    so->num_outputs = so_outputs;
 
457
    so->stride[0] = so_outputs * sizeof(float[4])/4;
 
458
}
 
459
 
 
460
/* ProcessVertices runs stream output into a temporary buffer to capture
 
461
 * all outputs.
 
462
 * Now we have to convert them to the format and order set by the vertex
 
463
 * declaration, for which we use u_translate.
 
464
 * This is necessary if the vertex declaration contains elements using a
 
465
 * non float32 format, because stream output only supports f32/u32/s32.
 
466
 */
 
467
HRESULT
 
468
NineVertexDeclaration9_ConvertStreamOutput(
 
469
    struct NineVertexDeclaration9 *This,
 
470
    struct NineVertexBuffer9 *pDstBuf,
 
471
    UINT DestIndex,
 
472
    UINT VertexCount,
 
473
    void *pSrcBuf,
 
474
    const struct pipe_stream_output_info *so )
 
475
{
 
476
    struct translate *translate;
 
477
    struct translate_key transkey;
 
478
    HRESULT hr;
 
479
    unsigned i;
 
480
    void *dst_map;
 
481
 
 
482
    DBG("This=%p pDstBuf=%p DestIndex=%u VertexCount=%u pSrcBuf=%p so=%p\n",
 
483
        This, pDstBuf, DestIndex, VertexCount, pSrcBuf, so);
 
484
 
 
485
    transkey.output_stride = 0;
 
486
    for (i = 0; i < This->nelems; ++i) {
 
487
        enum pipe_format format;
 
488
 
 
489
        switch (so->output[i].num_components) {
 
490
        case 1: format = PIPE_FORMAT_R32_FLOAT; break;
 
491
        case 2: format = PIPE_FORMAT_R32G32_FLOAT; break;
 
492
        case 3: format = PIPE_FORMAT_R32G32B32_FLOAT; break;
 
493
        default:
 
494
            assert(so->output[i].num_components == 4);
 
495
            format = PIPE_FORMAT_R32G32B32A32_FLOAT;
 
496
            break;
 
497
        }
 
498
        transkey.element[i].type = TRANSLATE_ELEMENT_NORMAL;
 
499
        transkey.element[i].input_format = format;
 
500
        transkey.element[i].input_buffer = 0;
 
501
        transkey.element[i].input_offset = so->output[i].dst_offset * 4;
 
502
        transkey.element[i].instance_divisor = 0;
 
503
 
 
504
        transkey.element[i].output_format = This->elems[i].src_format;
 
505
        transkey.element[i].output_offset = This->elems[i].src_offset;
 
506
        transkey.output_stride +=
 
507
            util_format_get_blocksize(This->elems[i].src_format);
 
508
 
 
509
        assert(!(transkey.output_stride & 3));
 
510
    }
 
511
    transkey.nr_elements = This->nelems;
 
512
 
 
513
    translate = translate_create(&transkey);
 
514
    if (!translate)
 
515
        return E_OUTOFMEMORY;
 
516
 
 
517
    hr = NineVertexBuffer9_Lock(pDstBuf,
 
518
                                transkey.output_stride * DestIndex,
 
519
                                transkey.output_stride * VertexCount,
 
520
                                &dst_map, D3DLOCK_DISCARD);
 
521
    if (FAILED(hr))
 
522
        goto out;
 
523
 
 
524
    translate->set_buffer(translate, 0, pSrcBuf, so->stride[0] * 4, ~0);
 
525
 
 
526
    translate->run(translate, 0, VertexCount, 0, 0, dst_map);
 
527
 
 
528
    NineVertexBuffer9_Unlock(pDstBuf);
 
529
out:
 
530
    translate->release(translate); /* TODO: cache these */
 
531
    return hr;
 
532
}