Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/d3d10umd/InputAssembly.cpp
4565 views
1
/**************************************************************************
2
*
3
* Copyright 2012-2021 VMware, Inc.
4
* All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
* USE OR OTHER DEALINGS IN THE SOFTWARE.
21
*
22
* The above copyright notice and this permission notice (including the
23
* next paragraph) shall be included in all copies or substantial portions
24
* of the Software.
25
*
26
**************************************************************************/
27
28
/*
29
* InputAssembly.cpp --
30
* Functions that manipulate the input assembly stage.
31
*/
32
33
34
#include <stdio.h>
35
#if defined(_MSC_VER) && !defined(snprintf)
36
#define snprintf _snprintf
37
#endif
38
39
#include "InputAssembly.h"
40
#include "State.h"
41
42
#include "Debug.h"
43
#include "Format.h"
44
45
46
/*
47
* ----------------------------------------------------------------------
48
*
49
* IaSetTopology --
50
*
51
* The IaSetTopology function sets the primitive topology to
52
* enable drawing for the input assember.
53
*
54
* ----------------------------------------------------------------------
55
*/
56
57
void APIENTRY
58
IaSetTopology(D3D10DDI_HDEVICE hDevice, // IN
59
D3D10_DDI_PRIMITIVE_TOPOLOGY PrimitiveTopology) // IN
60
{
61
LOG_ENTRYPOINT();
62
63
Device *pDevice = CastDevice(hDevice);
64
65
enum pipe_prim_type primitive;
66
switch (PrimitiveTopology) {
67
case D3D10_DDI_PRIMITIVE_TOPOLOGY_UNDEFINED:
68
/* Apps might set topology to UNDEFINED when cleaning up on exit. */
69
primitive = PIPE_PRIM_MAX;
70
break;
71
case D3D10_DDI_PRIMITIVE_TOPOLOGY_POINTLIST:
72
primitive = PIPE_PRIM_POINTS;
73
break;
74
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINELIST:
75
primitive = PIPE_PRIM_LINES;
76
break;
77
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINESTRIP:
78
primitive = PIPE_PRIM_LINE_STRIP;
79
break;
80
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLELIST:
81
primitive = PIPE_PRIM_TRIANGLES;
82
break;
83
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
84
primitive = PIPE_PRIM_TRIANGLE_STRIP;
85
break;
86
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINELIST_ADJ:
87
primitive = PIPE_PRIM_LINES_ADJACENCY;
88
break;
89
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ:
90
primitive = PIPE_PRIM_LINE_STRIP_ADJACENCY;
91
break;
92
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ:
93
primitive = PIPE_PRIM_TRIANGLES_ADJACENCY;
94
break;
95
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ:
96
primitive = PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY;
97
break;
98
default:
99
assert(0);
100
primitive = PIPE_PRIM_MAX;
101
break;
102
}
103
104
pDevice->primitive = primitive;
105
}
106
107
108
/*
109
* ----------------------------------------------------------------------
110
*
111
* IaSetVertexBuffers --
112
*
113
* The IaSetVertexBuffers function sets vertex buffers
114
* for an input assembler.
115
*
116
* ----------------------------------------------------------------------
117
*/
118
119
void APIENTRY
120
IaSetVertexBuffers(D3D10DDI_HDEVICE hDevice, // IN
121
UINT StartBuffer, // IN
122
UINT NumBuffers, // IN
123
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers, // IN
124
__in_ecount (NumBuffers) const UINT *pStrides, // IN
125
__in_ecount (NumBuffers) const UINT *pOffsets) // IN
126
{
127
static const float dummy[4] = {0.0f, 0.0f, 0.0f, 0.0f};
128
129
LOG_ENTRYPOINT();
130
131
Device *pDevice = CastDevice(hDevice);
132
struct pipe_context *pipe = pDevice->pipe;
133
unsigned i;
134
135
for (i = 0; i < NumBuffers; i++) {
136
struct pipe_vertex_buffer *vb = &pDevice->vertex_buffers[StartBuffer + i];
137
struct pipe_resource *resource = CastPipeResource(phBuffers[i]);
138
Resource *res = CastResource(phBuffers[i]);
139
struct pipe_stream_output_target *so_target =
140
res ? res->so_target : NULL;
141
142
if (so_target && pDevice->draw_so_target != so_target) {
143
if (pDevice->draw_so_target) {
144
pipe_so_target_reference(&pDevice->draw_so_target, NULL);
145
}
146
pipe_so_target_reference(&pDevice->draw_so_target,
147
so_target);
148
}
149
150
if (resource) {
151
vb->stride = pStrides[i];
152
vb->buffer_offset = pOffsets[i];
153
if (vb->is_user_buffer) {
154
vb->buffer.resource = NULL;
155
vb->is_user_buffer = FALSE;
156
}
157
pipe_resource_reference(&vb->buffer.resource, resource);
158
}
159
else {
160
vb->stride = 0;
161
vb->buffer_offset = 0;
162
if (!vb->is_user_buffer) {
163
pipe_resource_reference(&vb->buffer.resource, NULL);
164
vb->is_user_buffer = TRUE;
165
}
166
vb->buffer.user = dummy;
167
}
168
}
169
170
for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) {
171
struct pipe_vertex_buffer *vb = &pDevice->vertex_buffers[i];
172
173
/* XXX this is odd... */
174
if (!vb->is_user_buffer && !vb->buffer.resource) {
175
vb->stride = 0;
176
vb->buffer_offset = 0;
177
vb->is_user_buffer = TRUE;
178
vb->buffer.user = dummy;
179
}
180
}
181
182
/* Resubmit old and new vertex buffers.
183
*/
184
pipe->set_vertex_buffers(pipe, 0, PIPE_MAX_ATTRIBS, 0, FALSE, pDevice->vertex_buffers);
185
}
186
187
188
/*
189
* ----------------------------------------------------------------------
190
*
191
* IaSetIndexBuffer --
192
*
193
* The IaSetIndexBuffer function sets an index buffer for
194
* an input assembler.
195
*
196
* ----------------------------------------------------------------------
197
*/
198
199
void APIENTRY
200
IaSetIndexBuffer(D3D10DDI_HDEVICE hDevice, // IN
201
D3D10DDI_HRESOURCE hBuffer, // IN
202
DXGI_FORMAT Format, // IN
203
UINT Offset) // IN
204
{
205
LOG_ENTRYPOINT();
206
207
Device *pDevice = CastDevice(hDevice);
208
struct pipe_resource *resource = CastPipeResource(hBuffer);
209
210
if (resource) {
211
pDevice->ib_offset = Offset;
212
213
switch (Format) {
214
case DXGI_FORMAT_R16_UINT:
215
pDevice->index_size = 2;
216
pDevice->restart_index = 0xffff;
217
break;
218
case DXGI_FORMAT_R32_UINT:
219
pDevice->restart_index = 0xffffffff;
220
pDevice->index_size = 4;
221
break;
222
default:
223
assert(0); /* should not happen */
224
pDevice->index_size = 2;
225
break;
226
}
227
pipe_resource_reference(&pDevice->index_buffer, resource);
228
} else {
229
pipe_resource_reference(&pDevice->index_buffer, NULL);
230
}
231
}
232
233
234
/*
235
* ----------------------------------------------------------------------
236
*
237
* CalcPrivateElementLayoutSize --
238
*
239
* The CalcPrivateElementLayoutSize function determines the size
240
* of the user-mode display driver's private region of memory
241
* (that is, the size of internal driver structures, not the size
242
* of the resource video memory) for an element layout.
243
*
244
* ----------------------------------------------------------------------
245
*/
246
247
SIZE_T APIENTRY
248
CalcPrivateElementLayoutSize(
249
D3D10DDI_HDEVICE hDevice, // IN
250
__in const D3D10DDIARG_CREATEELEMENTLAYOUT *pCreateElementLayout) // IN
251
{
252
return sizeof(ElementLayout);
253
}
254
255
256
/*
257
* ----------------------------------------------------------------------
258
*
259
* CreateElementLayout --
260
*
261
* The CreateElementLayout function creates an element layout.
262
*
263
* ----------------------------------------------------------------------
264
*/
265
266
void APIENTRY
267
CreateElementLayout(
268
D3D10DDI_HDEVICE hDevice, // IN
269
__in const D3D10DDIARG_CREATEELEMENTLAYOUT *pCreateElementLayout, // IN
270
D3D10DDI_HELEMENTLAYOUT hElementLayout, // IN
271
D3D10DDI_HRTELEMENTLAYOUT hRTElementLayout) // IN
272
{
273
LOG_ENTRYPOINT();
274
275
struct pipe_context *pipe = CastPipeContext(hDevice);
276
ElementLayout *pElementLayout = CastElementLayout(hElementLayout);
277
278
struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS];
279
memset(elements, 0, sizeof elements);
280
281
unsigned num_elements = pCreateElementLayout->NumElements;
282
unsigned max_elements = 0;
283
for (unsigned i = 0; i < num_elements; i++) {
284
const D3D10DDIARG_INPUT_ELEMENT_DESC* pVertexElement =
285
&pCreateElementLayout->pVertexElements[i];
286
struct pipe_vertex_element *ve =
287
&elements[pVertexElement->InputRegister];
288
289
ve->src_offset = pVertexElement->AlignedByteOffset;
290
ve->vertex_buffer_index = pVertexElement->InputSlot;
291
ve->src_format = FormatTranslate(pVertexElement->Format, FALSE);
292
293
switch (pVertexElement->InputSlotClass) {
294
case D3D10_DDI_INPUT_PER_VERTEX_DATA:
295
ve->instance_divisor = 0;
296
break;
297
case D3D10_DDI_INPUT_PER_INSTANCE_DATA:
298
if (!pVertexElement->InstanceDataStepRate) {
299
LOG_UNSUPPORTED(!pVertexElement->InstanceDataStepRate);
300
ve->instance_divisor = ~0;
301
} else {
302
ve->instance_divisor = pVertexElement->InstanceDataStepRate;
303
}
304
break;
305
default:
306
assert(0);
307
break;
308
}
309
310
max_elements = MAX2(max_elements, pVertexElement->InputRegister + 1);
311
}
312
313
/* XXX: What do we do when there's a gap? */
314
if (max_elements != num_elements) {
315
DebugPrintf("%s: gap\n", __FUNCTION__);
316
}
317
318
pElementLayout->handle =
319
pipe->create_vertex_elements_state(pipe, max_elements, elements);
320
}
321
322
323
/*
324
* ----------------------------------------------------------------------
325
*
326
* DestroyElementLayout --
327
*
328
* The DestroyElementLayout function destroys the specified
329
* element layout object. The element layout object can be
330
* destoyed only if it is not currently bound to a display device.
331
*
332
* ----------------------------------------------------------------------
333
*/
334
335
void APIENTRY
336
DestroyElementLayout(D3D10DDI_HDEVICE hDevice, // IN
337
D3D10DDI_HELEMENTLAYOUT hElementLayout) // IN
338
{
339
LOG_ENTRYPOINT();
340
341
struct pipe_context *pipe = CastPipeContext(hDevice);
342
ElementLayout *pElementLayout = CastElementLayout(hElementLayout);
343
344
pipe->delete_vertex_elements_state(pipe, pElementLayout->handle);}
345
346
347
/*
348
* ----------------------------------------------------------------------
349
*
350
* IaSetInputLayout --
351
*
352
* The IaSetInputLayout function sets an input layout for
353
* the input assembler.
354
*
355
* ----------------------------------------------------------------------
356
*/
357
358
void APIENTRY
359
IaSetInputLayout(D3D10DDI_HDEVICE hDevice, // IN
360
D3D10DDI_HELEMENTLAYOUT hInputLayout) // IN
361
{
362
LOG_ENTRYPOINT();
363
364
struct pipe_context *pipe = CastPipeContext(hDevice);
365
void *state = CastPipeInputLayout(hInputLayout);
366
367
pipe->bind_vertex_elements_state(pipe, state);
368
}
369
370
371
372