Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/d3d10umd/OutputMerger.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
* OutputMerger.cpp --
30
* Functions that manipulate the output merger state.
31
*/
32
33
34
#include "OutputMerger.h"
35
#include "State.h"
36
37
#include "Debug.h"
38
#include "Format.h"
39
40
#include "util/u_framebuffer.h"
41
#include "util/format/u_format.h"
42
43
44
/*
45
* ----------------------------------------------------------------------
46
*
47
* CalcPrivateRenderTargetViewSize --
48
*
49
* The CalcPrivateRenderTargetViewSize function determines the size
50
* of the user-mode display driver's private region of memory
51
* (that is, the size of internal driver structures, not the size
52
* of the resource video memory) for a render target view.
53
*
54
* ----------------------------------------------------------------------
55
*/
56
57
58
SIZE_T APIENTRY
59
CalcPrivateRenderTargetViewSize(
60
D3D10DDI_HDEVICE hDevice, // IN
61
__in const D3D10DDIARG_CREATERENDERTARGETVIEW *pCreateRenderTargetView) // IN
62
{
63
return sizeof(RenderTargetView);
64
}
65
66
67
/*
68
* ----------------------------------------------------------------------
69
*
70
* CreateRenderTargetView --
71
*
72
* The CreateRenderTargetView function creates a render target view.
73
*
74
* ----------------------------------------------------------------------
75
*/
76
77
void APIENTRY
78
CreateRenderTargetView(
79
D3D10DDI_HDEVICE hDevice, // IN
80
__in const D3D10DDIARG_CREATERENDERTARGETVIEW *pCreateRenderTargetView, // IN
81
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView, // IN
82
D3D10DDI_HRTRENDERTARGETVIEW hRTRenderTargetView) // IN
83
{
84
LOG_ENTRYPOINT();
85
86
struct pipe_context *pipe = CastPipeContext(hDevice);
87
struct pipe_resource *resource = CastPipeResource(pCreateRenderTargetView->hDrvResource);
88
RenderTargetView *pRTView = CastRenderTargetView(hRenderTargetView);
89
90
struct pipe_surface desc;
91
92
memset(&desc, 0, sizeof desc);
93
desc.format = FormatTranslate(pCreateRenderTargetView->Format, FALSE);
94
95
switch (pCreateRenderTargetView->ResourceDimension) {
96
case D3D10DDIRESOURCE_BUFFER:
97
desc.u.buf.first_element = pCreateRenderTargetView->Buffer.FirstElement;
98
desc.u.buf.last_element = pCreateRenderTargetView->Buffer.NumElements - 1 +
99
desc.u.buf.first_element;
100
break;
101
case D3D10DDIRESOURCE_TEXTURE1D:
102
ASSERT(pCreateRenderTargetView->Tex1D.ArraySize != (UINT)-1);
103
desc.u.tex.level = pCreateRenderTargetView->Tex1D.MipSlice;
104
desc.u.tex.first_layer = pCreateRenderTargetView->Tex1D.FirstArraySlice;
105
desc.u.tex.last_layer = pCreateRenderTargetView->Tex1D.ArraySize - 1 +
106
desc.u.tex.first_layer;
107
break;
108
case D3D10DDIRESOURCE_TEXTURE2D:
109
ASSERT(pCreateRenderTargetView->Tex2D.ArraySize != (UINT)-1);
110
desc.u.tex.level = pCreateRenderTargetView->Tex2D.MipSlice;
111
desc.u.tex.first_layer = pCreateRenderTargetView->Tex2D.FirstArraySlice;
112
desc.u.tex.last_layer = pCreateRenderTargetView->Tex2D.ArraySize - 1 +
113
desc.u.tex.first_layer;
114
break;
115
case D3D10DDIRESOURCE_TEXTURE3D:
116
desc.u.tex.level = pCreateRenderTargetView->Tex3D.MipSlice;
117
desc.u.tex.first_layer = pCreateRenderTargetView->Tex3D.FirstW;
118
desc.u.tex.last_layer = pCreateRenderTargetView->Tex3D.WSize - 1 +
119
desc.u.tex.first_layer;
120
break;
121
case D3D10DDIRESOURCE_TEXTURECUBE:
122
ASSERT(pCreateRenderTargetView->TexCube.ArraySize != (UINT)-1);
123
desc.u.tex.level = pCreateRenderTargetView->TexCube.MipSlice;
124
desc.u.tex.first_layer = pCreateRenderTargetView->TexCube.FirstArraySlice;
125
desc.u.tex.last_layer = pCreateRenderTargetView->TexCube.ArraySize - 1 +
126
desc.u.tex.first_layer;;
127
break;
128
default:
129
ASSERT(0);
130
return;
131
}
132
133
pRTView->surface = pipe->create_surface(pipe, resource, &desc);
134
assert(pRTView->surface);
135
}
136
137
138
/*
139
* ----------------------------------------------------------------------
140
*
141
* DestroyRenderTargetView --
142
*
143
* The DestroyRenderTargetView function destroys the specified
144
* render target view object. The render target view object can
145
* be destoyed only if it is not currently bound to a display device.
146
*
147
* ----------------------------------------------------------------------
148
*/
149
150
void APIENTRY
151
DestroyRenderTargetView(D3D10DDI_HDEVICE hDevice, // IN
152
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView) // IN
153
{
154
LOG_ENTRYPOINT();
155
156
RenderTargetView *pRTView = CastRenderTargetView(hRenderTargetView);
157
158
pipe_surface_reference(&pRTView->surface, NULL);
159
}
160
161
162
/*
163
* ----------------------------------------------------------------------
164
*
165
* ClearRenderTargetView --
166
*
167
* The ClearRenderTargetView function clears the specified
168
* render target view by setting it to a constant value.
169
*
170
* ----------------------------------------------------------------------
171
*/
172
173
void APIENTRY
174
ClearRenderTargetView(D3D10DDI_HDEVICE hDevice, // IN
175
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView, // IN
176
FLOAT pColorRGBA[4]) // IN
177
{
178
LOG_ENTRYPOINT();
179
180
struct pipe_context *pipe = CastPipeContext(hDevice);
181
struct pipe_surface *surface = CastPipeRenderTargetView(hRenderTargetView);
182
union pipe_color_union clear_color;
183
184
/*
185
* DX10 always uses float clear color but gallium does not.
186
* Conversion should just be ordinary conversion. Actual clamping will
187
* be done later but need to make sure values exceeding int/uint range
188
* are handled correctly.
189
*/
190
if (util_format_is_pure_integer(surface->format)) {
191
if (util_format_is_pure_sint(surface->format)) {
192
unsigned i;
193
/* If only MIN_INT/UINT32 in c++ code would work... */
194
int min_int32 = 0x80000000;
195
int max_int32 = 0x7fffffff;
196
for (i = 0; i < 4; i++) {
197
float value = pColorRGBA[i];
198
/* This is an expanded clamp to handle NaN and integer conversion. */
199
if (util_is_nan(value)) {
200
clear_color.i[i] = 0;
201
} else if (value <= (float)min_int32) {
202
clear_color.i[i] = min_int32;
203
} else if (value >= (float)max_int32) {
204
clear_color.i[i] = max_int32;
205
} else {
206
clear_color.i[i] = value;
207
}
208
}
209
}
210
else {
211
assert(util_format_is_pure_uint(surface->format));
212
unsigned i;
213
unsigned max_uint32 = 0xffffffffU;
214
for (i = 0; i < 4; i++) {
215
float value = pColorRGBA[i];
216
/* This is an expanded clamp to handle NaN and integer conversion. */
217
if (!(value >= 0.0f)) {
218
/* Handles NaN. */
219
clear_color.ui[i] = 0;
220
} else if (value >= (float)max_uint32) {
221
clear_color.ui[i] = max_uint32;
222
} else {
223
clear_color.ui[i] = value;
224
}
225
}
226
}
227
}
228
else {
229
clear_color.f[0] = pColorRGBA[0];
230
clear_color.f[1] = pColorRGBA[1];
231
clear_color.f[2] = pColorRGBA[2];
232
clear_color.f[3] = pColorRGBA[3];
233
}
234
235
pipe->clear_render_target(pipe,
236
surface,
237
&clear_color,
238
0, 0,
239
surface->width,
240
surface->height,
241
TRUE);
242
}
243
244
245
/*
246
* ----------------------------------------------------------------------
247
*
248
* CalcPrivateDepthStencilViewSize --
249
*
250
* The CalcPrivateDepthStencilViewSize function determines the size
251
* of the user-mode display driver's private region of memory
252
* (that is, the size of internal driver structures, not the size
253
* of the resource video memory) for a depth stencil view.
254
*
255
* ----------------------------------------------------------------------
256
*/
257
258
SIZE_T APIENTRY
259
CalcPrivateDepthStencilViewSize(
260
D3D10DDI_HDEVICE hDevice, // IN
261
__in const D3D10DDIARG_CREATEDEPTHSTENCILVIEW *pCreateDepthStencilView) // IN
262
{
263
return sizeof(DepthStencilView);
264
}
265
266
267
/*
268
* ----------------------------------------------------------------------
269
*
270
* CreateDepthStencilView --
271
*
272
* The CreateDepthStencilView function creates a depth stencil view.
273
*
274
* ----------------------------------------------------------------------
275
*/
276
277
void APIENTRY
278
CreateDepthStencilView(
279
D3D10DDI_HDEVICE hDevice, // IN
280
__in const D3D10DDIARG_CREATEDEPTHSTENCILVIEW *pCreateDepthStencilView, // IN
281
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView, // IN
282
D3D10DDI_HRTDEPTHSTENCILVIEW hRTDepthStencilView) // IN
283
{
284
LOG_ENTRYPOINT();
285
286
struct pipe_context *pipe = CastPipeContext(hDevice);
287
struct pipe_resource *resource = CastPipeResource(pCreateDepthStencilView->hDrvResource);
288
DepthStencilView *pDSView = CastDepthStencilView(hDepthStencilView);
289
290
struct pipe_surface desc;
291
292
memset(&desc, 0, sizeof desc);
293
desc.format = FormatTranslate(pCreateDepthStencilView->Format, TRUE);
294
295
switch (pCreateDepthStencilView->ResourceDimension) {
296
case D3D10DDIRESOURCE_TEXTURE1D:
297
ASSERT(pCreateDepthStencilView->Tex1D.ArraySize != (UINT)-1);
298
desc.u.tex.level = pCreateDepthStencilView->Tex1D.MipSlice;
299
desc.u.tex.first_layer = pCreateDepthStencilView->Tex1D.FirstArraySlice;
300
desc.u.tex.last_layer = pCreateDepthStencilView->Tex1D.ArraySize - 1 +
301
desc.u.tex.first_layer;
302
break;
303
case D3D10DDIRESOURCE_TEXTURE2D:
304
ASSERT(pCreateDepthStencilView->Tex2D.ArraySize != (UINT)-1);
305
desc.u.tex.level = pCreateDepthStencilView->Tex2D.MipSlice;
306
desc.u.tex.first_layer = pCreateDepthStencilView->Tex2D.FirstArraySlice;
307
desc.u.tex.last_layer = pCreateDepthStencilView->Tex2D.ArraySize - 1 +
308
desc.u.tex.first_layer;
309
break;
310
case D3D10DDIRESOURCE_TEXTURECUBE:
311
ASSERT(pCreateDepthStencilView->TexCube.ArraySize != (UINT)-1);
312
desc.u.tex.level = pCreateDepthStencilView->TexCube.MipSlice;
313
desc.u.tex.first_layer = pCreateDepthStencilView->TexCube.FirstArraySlice;
314
desc.u.tex.last_layer = pCreateDepthStencilView->TexCube.ArraySize - 1 +
315
desc.u.tex.first_layer;
316
break;
317
default:
318
ASSERT(0);
319
return;
320
}
321
322
pDSView->surface = pipe->create_surface(pipe, resource, &desc);
323
assert(pDSView->surface);
324
}
325
326
327
/*
328
* ----------------------------------------------------------------------
329
*
330
* DestroyDepthStencilView --
331
*
332
* The DestroyDepthStencilView function destroys the specified
333
* depth stencil view object. The depth stencil view object can
334
* be destoyed only if it is not currently bound to a display device.
335
*
336
* ----------------------------------------------------------------------
337
*/
338
339
void APIENTRY
340
DestroyDepthStencilView(D3D10DDI_HDEVICE hDevice, // IN
341
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView) // IN
342
{
343
LOG_ENTRYPOINT();
344
345
DepthStencilView *pDSView = CastDepthStencilView(hDepthStencilView);
346
347
pipe_surface_reference(&pDSView->surface, NULL);
348
}
349
350
351
/*
352
* ----------------------------------------------------------------------
353
*
354
* ClearDepthStencilView --
355
*
356
* The ClearDepthStencilView function clears the specified
357
* currently bound depth-stencil view.
358
*
359
* ----------------------------------------------------------------------
360
*/
361
362
void APIENTRY
363
ClearDepthStencilView(D3D10DDI_HDEVICE hDevice, // IN
364
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView, // IN
365
UINT Flags, // IN
366
FLOAT Depth, // IN
367
UINT8 Stencil) // IN
368
{
369
LOG_ENTRYPOINT();
370
371
struct pipe_context *pipe = CastPipeContext(hDevice);
372
struct pipe_surface *surface = CastPipeDepthStencilView(hDepthStencilView);
373
374
unsigned flags = 0;
375
if (Flags & D3D10_DDI_CLEAR_DEPTH) {
376
flags |= PIPE_CLEAR_DEPTH;
377
}
378
if (Flags & D3D10_DDI_CLEAR_STENCIL) {
379
flags |= PIPE_CLEAR_STENCIL;
380
}
381
382
pipe->clear_depth_stencil(pipe,
383
surface,
384
flags,
385
Depth,
386
Stencil,
387
0, 0,
388
surface->width,
389
surface->height,
390
TRUE);
391
}
392
393
394
/*
395
* ----------------------------------------------------------------------
396
*
397
* CalcPrivateBlendStateSize --
398
*
399
* The CalcPrivateBlendStateSize function determines the size of
400
* the user-mode display driver's private region of memory (that
401
* is, the size of internal driver structures, not the size of
402
* the resource video memory) for a blend state.
403
*
404
* ----------------------------------------------------------------------
405
*/
406
407
SIZE_T APIENTRY
408
CalcPrivateBlendStateSize(D3D10DDI_HDEVICE hDevice, // IN
409
__in const D3D10_DDI_BLEND_DESC *pBlendDesc) // IN
410
{
411
return sizeof(BlendState);
412
}
413
414
415
/*
416
* ----------------------------------------------------------------------
417
*
418
* CalcPrivateBlendStateSize1 --
419
*
420
* The CalcPrivateBlendStateSize function determines the size of
421
* the user-mode display driver's private region of memory (that
422
* is, the size of internal driver structures, not the size of
423
* the resource video memory) for a blend state.
424
*
425
* ----------------------------------------------------------------------
426
*/
427
428
SIZE_T APIENTRY
429
CalcPrivateBlendStateSize1(D3D10DDI_HDEVICE hDevice, // IN
430
__in const D3D10_1_DDI_BLEND_DESC *pBlendDesc) // IN
431
{
432
return sizeof(BlendState);
433
}
434
435
436
/*
437
* ----------------------------------------------------------------------
438
*
439
* translateBlend --
440
*
441
* Translate blend function from svga3d to gallium representation.
442
*
443
* ----------------------------------------------------------------------
444
*/
445
static uint
446
translateBlendOp(D3D10_DDI_BLEND_OP op)
447
{
448
switch (op) {
449
case D3D10_DDI_BLEND_OP_ADD:
450
return PIPE_BLEND_ADD;
451
case D3D10_DDI_BLEND_OP_SUBTRACT:
452
return PIPE_BLEND_SUBTRACT;
453
case D3D10_DDI_BLEND_OP_REV_SUBTRACT:
454
return PIPE_BLEND_REVERSE_SUBTRACT;
455
case D3D10_DDI_BLEND_OP_MIN:
456
return PIPE_BLEND_MIN;
457
case D3D10_DDI_BLEND_OP_MAX:
458
return PIPE_BLEND_MAX;
459
default:
460
assert(0);
461
return PIPE_BLEND_ADD;
462
}
463
}
464
465
466
/*
467
* ----------------------------------------------------------------------
468
*
469
* translateBlend --
470
*
471
* Translate blend factor from svga3d to gallium representation.
472
*
473
* ----------------------------------------------------------------------
474
*/
475
static uint
476
translateBlend(Device *pDevice,
477
D3D10_DDI_BLEND blend)
478
{
479
if (!pDevice->max_dual_source_render_targets) {
480
switch (blend) {
481
case D3D10_DDI_BLEND_SRC1_COLOR:
482
case D3D10_DDI_BLEND_SRC1_ALPHA:
483
LOG_UNSUPPORTED(TRUE);
484
return D3D10_DDI_BLEND_ZERO;
485
case D3D10_DDI_BLEND_INV_SRC1_COLOR:
486
case D3D10_DDI_BLEND_INV_SRC1_ALPHA:
487
LOG_UNSUPPORTED(TRUE);
488
return D3D10_DDI_BLEND_ONE;
489
default:
490
break;
491
}
492
}
493
494
switch (blend) {
495
case D3D10_DDI_BLEND_ZERO:
496
return PIPE_BLENDFACTOR_ZERO;
497
case D3D10_DDI_BLEND_ONE:
498
return PIPE_BLENDFACTOR_ONE;
499
case D3D10_DDI_BLEND_SRC_COLOR:
500
return PIPE_BLENDFACTOR_SRC_COLOR;
501
case D3D10_DDI_BLEND_INV_SRC_COLOR:
502
return PIPE_BLENDFACTOR_INV_SRC_COLOR;
503
case D3D10_DDI_BLEND_SRC_ALPHA:
504
return PIPE_BLENDFACTOR_SRC_ALPHA;
505
case D3D10_DDI_BLEND_INV_SRC_ALPHA:
506
return PIPE_BLENDFACTOR_INV_SRC_ALPHA;
507
case D3D10_DDI_BLEND_DEST_ALPHA:
508
return PIPE_BLENDFACTOR_DST_ALPHA;
509
case D3D10_DDI_BLEND_INV_DEST_ALPHA:
510
return PIPE_BLENDFACTOR_INV_DST_ALPHA;
511
case D3D10_DDI_BLEND_DEST_COLOR:
512
return PIPE_BLENDFACTOR_DST_COLOR;
513
case D3D10_DDI_BLEND_INV_DEST_COLOR:
514
return PIPE_BLENDFACTOR_INV_DST_COLOR;
515
case D3D10_DDI_BLEND_SRC_ALPHASAT:
516
return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
517
case D3D10_DDI_BLEND_BLEND_FACTOR:
518
return PIPE_BLENDFACTOR_CONST_COLOR;
519
case D3D10_DDI_BLEND_INVBLEND_FACTOR:
520
return PIPE_BLENDFACTOR_INV_CONST_COLOR;
521
case D3D10_DDI_BLEND_SRC1_COLOR:
522
return PIPE_BLENDFACTOR_SRC1_COLOR;
523
case D3D10_DDI_BLEND_INV_SRC1_COLOR:
524
return PIPE_BLENDFACTOR_INV_SRC1_COLOR;
525
case D3D10_DDI_BLEND_SRC1_ALPHA:
526
return PIPE_BLENDFACTOR_SRC1_ALPHA;
527
case D3D10_DDI_BLEND_INV_SRC1_ALPHA:
528
return PIPE_BLENDFACTOR_INV_SRC1_ALPHA;
529
default:
530
assert(0);
531
return PIPE_BLENDFACTOR_ONE;
532
}
533
}
534
535
536
/*
537
* ----------------------------------------------------------------------
538
*
539
* CreateBlendState --
540
*
541
* The CreateBlendState function creates a blend state.
542
*
543
* ----------------------------------------------------------------------
544
*/
545
546
void APIENTRY
547
CreateBlendState(D3D10DDI_HDEVICE hDevice, // IN
548
__in const D3D10_DDI_BLEND_DESC *pBlendDesc, // IN
549
D3D10DDI_HBLENDSTATE hBlendState, // IN
550
D3D10DDI_HRTBLENDSTATE hRTBlendState) // IN
551
{
552
unsigned i;
553
554
LOG_ENTRYPOINT();
555
556
Device *pDevice = CastDevice(hDevice);
557
struct pipe_context *pipe = pDevice->pipe;
558
BlendState *pBlendState = CastBlendState(hBlendState);
559
560
struct pipe_blend_state state;
561
memset(&state, 0, sizeof state);
562
563
for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) {
564
state.rt[i].blend_enable = pBlendDesc->BlendEnable[i];
565
state.rt[i].colormask = pBlendDesc->RenderTargetWriteMask[i];
566
567
if (pBlendDesc->BlendEnable[0] != pBlendDesc->BlendEnable[i] ||
568
pBlendDesc->RenderTargetWriteMask[0] != pBlendDesc->RenderTargetWriteMask[i]) {
569
state.independent_blend_enable = 1;
570
}
571
}
572
573
state.rt[0].rgb_func = translateBlendOp(pBlendDesc->BlendOp);
574
if (pBlendDesc->BlendOp == D3D10_DDI_BLEND_OP_MIN ||
575
pBlendDesc->BlendOp == D3D10_DDI_BLEND_OP_MAX) {
576
state.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
577
state.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
578
} else {
579
state.rt[0].rgb_src_factor = translateBlend(pDevice, pBlendDesc->SrcBlend);
580
state.rt[0].rgb_dst_factor = translateBlend(pDevice, pBlendDesc->DestBlend);
581
}
582
583
state.rt[0].alpha_func = translateBlendOp(pBlendDesc->BlendOpAlpha);
584
if (pBlendDesc->BlendOpAlpha == D3D10_DDI_BLEND_OP_MIN ||
585
pBlendDesc->BlendOpAlpha == D3D10_DDI_BLEND_OP_MAX) {
586
state.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
587
state.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
588
} else {
589
state.rt[0].alpha_src_factor = translateBlend(pDevice, pBlendDesc->SrcBlendAlpha);
590
state.rt[0].alpha_dst_factor = translateBlend(pDevice, pBlendDesc->DestBlendAlpha);
591
}
592
593
/*
594
* Propagate to all the other rendertargets
595
*/
596
for (i = 1; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) {
597
state.rt[i].rgb_func = state.rt[0].rgb_func;
598
state.rt[i].rgb_src_factor = state.rt[0].rgb_src_factor;
599
state.rt[i].rgb_dst_factor = state.rt[0].rgb_dst_factor;
600
state.rt[i].alpha_func = state.rt[0].alpha_func;
601
state.rt[i].alpha_src_factor = state.rt[0].alpha_src_factor;
602
state.rt[i].alpha_dst_factor = state.rt[0].alpha_dst_factor;
603
}
604
605
state.alpha_to_coverage = pBlendDesc->AlphaToCoverageEnable;
606
607
pBlendState->handle = pipe->create_blend_state(pipe, &state);
608
}
609
610
611
/*
612
* ----------------------------------------------------------------------
613
*
614
* CreateBlendState1 --
615
*
616
* The CreateBlendState function creates a blend state.
617
*
618
* ----------------------------------------------------------------------
619
*/
620
621
void APIENTRY
622
CreateBlendState1(D3D10DDI_HDEVICE hDevice, // IN
623
__in const D3D10_1_DDI_BLEND_DESC *pBlendDesc, // IN
624
D3D10DDI_HBLENDSTATE hBlendState, // IN
625
D3D10DDI_HRTBLENDSTATE hRTBlendState) // IN
626
{
627
unsigned i;
628
629
LOG_ENTRYPOINT();
630
631
Device *pDevice = CastDevice(hDevice);
632
struct pipe_context *pipe = pDevice->pipe;
633
BlendState *pBlendState = CastBlendState(hBlendState);
634
635
struct pipe_blend_state state;
636
memset(&state, 0, sizeof state);
637
638
state.alpha_to_coverage = pBlendDesc->AlphaToCoverageEnable;
639
state.independent_blend_enable = pBlendDesc->IndependentBlendEnable;
640
641
for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) {
642
state.rt[i].blend_enable = pBlendDesc->RenderTarget[i].BlendEnable;
643
state.rt[i].colormask = pBlendDesc->RenderTarget[i].RenderTargetWriteMask;
644
645
state.rt[i].rgb_func = translateBlendOp(pBlendDesc->RenderTarget[i].BlendOp);
646
if (pBlendDesc->RenderTarget[i].BlendOp == D3D10_DDI_BLEND_OP_MIN ||
647
pBlendDesc->RenderTarget[i].BlendOp == D3D10_DDI_BLEND_OP_MAX) {
648
state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
649
state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
650
} else {
651
state.rt[i].rgb_src_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].SrcBlend);
652
state.rt[i].rgb_dst_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].DestBlend);
653
}
654
655
state.rt[i].alpha_func = translateBlendOp(pBlendDesc->RenderTarget[i].BlendOpAlpha);
656
if (pBlendDesc->RenderTarget[i].BlendOpAlpha == D3D10_DDI_BLEND_OP_MIN ||
657
pBlendDesc->RenderTarget[i].BlendOpAlpha == D3D10_DDI_BLEND_OP_MAX) {
658
state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
659
state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
660
} else {
661
state.rt[i].alpha_src_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].SrcBlendAlpha);
662
state.rt[i].alpha_dst_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].DestBlendAlpha);
663
}
664
}
665
666
pBlendState->handle = pipe->create_blend_state(pipe, &state);
667
}
668
669
670
/*
671
* ----------------------------------------------------------------------
672
*
673
* DestroyBlendState --
674
*
675
* The DestroyBlendState function destroys the specified blend
676
* state object. The blend state object can be destoyed only if
677
* it is not currently bound to a display device.
678
*
679
* ----------------------------------------------------------------------
680
*/
681
682
void APIENTRY
683
DestroyBlendState(D3D10DDI_HDEVICE hDevice, // IN
684
D3D10DDI_HBLENDSTATE hBlendState) // IN
685
{
686
LOG_ENTRYPOINT();
687
688
struct pipe_context *pipe = CastPipeContext(hDevice);
689
BlendState *pBlendState = CastBlendState(hBlendState);
690
691
pipe->delete_blend_state(pipe, pBlendState->handle);
692
}
693
694
695
/*
696
* ----------------------------------------------------------------------
697
*
698
* SetBlendState --
699
*
700
* The SetBlendState function sets a blend state.
701
*
702
* ----------------------------------------------------------------------
703
*/
704
705
void APIENTRY
706
SetBlendState(D3D10DDI_HDEVICE hDevice, // IN
707
D3D10DDI_HBLENDSTATE hState, // IN
708
const FLOAT pBlendFactor[4], // IN
709
UINT SampleMask) // IN
710
{
711
LOG_ENTRYPOINT();
712
713
struct pipe_context *pipe = CastPipeContext(hDevice);
714
void *state = CastPipeBlendState(hState);
715
716
pipe->bind_blend_state(pipe, state);
717
718
struct pipe_blend_color color;
719
color.color[0] = pBlendFactor[0];
720
color.color[1] = pBlendFactor[1];
721
color.color[2] = pBlendFactor[2];
722
color.color[3] = pBlendFactor[3];
723
724
pipe->set_blend_color(pipe, &color);
725
726
pipe->set_sample_mask(pipe, SampleMask);
727
}
728
729
730
/*
731
* ----------------------------------------------------------------------
732
*
733
* SetRenderTargets --
734
*
735
* Set the rendertargets.
736
*
737
* ----------------------------------------------------------------------
738
*/
739
740
void APIENTRY
741
SetRenderTargets(D3D10DDI_HDEVICE hDevice, // IN
742
__in_ecount (NumViews)
743
const D3D10DDI_HRENDERTARGETVIEW *phRenderTargetView, // IN
744
UINT RTargets, // IN
745
UINT ClearTargets, // IN
746
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView) // IN
747
{
748
LOG_ENTRYPOINT();
749
750
Device *pDevice = CastDevice(hDevice);
751
752
struct pipe_context *pipe = pDevice->pipe;
753
754
pDevice->fb.nr_cbufs = 0;
755
for (unsigned i = 0; i < RTargets; ++i) {
756
pipe_surface_reference(&pDevice->fb.cbufs[i],
757
CastPipeRenderTargetView(phRenderTargetView[i]));
758
if (pDevice->fb.cbufs[i]) {
759
pDevice->fb.nr_cbufs = i + 1;
760
}
761
}
762
763
for (unsigned i = RTargets; i < PIPE_MAX_COLOR_BUFS; ++i) {
764
pipe_surface_reference(&pDevice->fb.cbufs[i], NULL);
765
}
766
767
pipe_surface_reference(&pDevice->fb.zsbuf,
768
CastPipeDepthStencilView(hDepthStencilView));
769
770
/*
771
* Calculate the width/height fields for this framebuffer. D3D10
772
* actually specifies that they be identical for all bound views.
773
*/
774
unsigned width, height;
775
util_framebuffer_min_size(&pDevice->fb, &width, &height);
776
pDevice->fb.width = width;
777
pDevice->fb.height = height;
778
779
pipe->set_framebuffer_state(pipe, &pDevice->fb);
780
}
781
782
783
/*
784
* ----------------------------------------------------------------------
785
*
786
* CalcPrivateDepthStencilStateSize --
787
*
788
* The CalcPrivateDepthStencilStateSize function determines the size
789
* of the user-mode display driver's private region of memory (that
790
* is, the size of internal driver structures, not the size of the
791
* resource video memory) for a depth stencil state.
792
*
793
* ----------------------------------------------------------------------
794
*/
795
796
SIZE_T APIENTRY
797
CalcPrivateDepthStencilStateSize(
798
D3D10DDI_HDEVICE hDevice, // IN
799
__in const D3D10_DDI_DEPTH_STENCIL_DESC *pDepthStencilDesc) // IN
800
{
801
return sizeof(DepthStencilState);
802
}
803
804
805
/*
806
* ----------------------------------------------------------------------
807
*
808
* translateComparison --
809
*
810
* Translate comparison function from DX10 to gallium representation.
811
*
812
* ----------------------------------------------------------------------
813
*/
814
static uint
815
translateComparison(D3D10_DDI_COMPARISON_FUNC Func)
816
{
817
switch (Func) {
818
case D3D10_DDI_COMPARISON_NEVER:
819
return PIPE_FUNC_NEVER;
820
case D3D10_DDI_COMPARISON_LESS:
821
return PIPE_FUNC_LESS;
822
case D3D10_DDI_COMPARISON_EQUAL:
823
return PIPE_FUNC_EQUAL;
824
case D3D10_DDI_COMPARISON_LESS_EQUAL:
825
return PIPE_FUNC_LEQUAL;
826
case D3D10_DDI_COMPARISON_GREATER:
827
return PIPE_FUNC_GREATER;
828
case D3D10_DDI_COMPARISON_NOT_EQUAL:
829
return PIPE_FUNC_NOTEQUAL;
830
case D3D10_DDI_COMPARISON_GREATER_EQUAL:
831
return PIPE_FUNC_GEQUAL;
832
case D3D10_DDI_COMPARISON_ALWAYS:
833
return PIPE_FUNC_ALWAYS;
834
default:
835
assert(0);
836
return PIPE_FUNC_ALWAYS;
837
}
838
}
839
840
841
/*
842
* ----------------------------------------------------------------------
843
*
844
* translateStencilOp --
845
*
846
* Translate stencil op from DX10 to gallium representation.
847
*
848
* ----------------------------------------------------------------------
849
*/
850
static uint
851
translateStencilOp(D3D10_DDI_STENCIL_OP StencilOp)
852
{
853
switch (StencilOp) {
854
case D3D10_DDI_STENCIL_OP_KEEP:
855
return PIPE_STENCIL_OP_KEEP;
856
case D3D10_DDI_STENCIL_OP_ZERO:
857
return PIPE_STENCIL_OP_ZERO;
858
case D3D10_DDI_STENCIL_OP_REPLACE:
859
return PIPE_STENCIL_OP_REPLACE;
860
case D3D10_DDI_STENCIL_OP_INCR_SAT:
861
return PIPE_STENCIL_OP_INCR;
862
case D3D10_DDI_STENCIL_OP_DECR_SAT:
863
return PIPE_STENCIL_OP_DECR;
864
case D3D10_DDI_STENCIL_OP_INVERT:
865
return PIPE_STENCIL_OP_INVERT;
866
case D3D10_DDI_STENCIL_OP_INCR:
867
return PIPE_STENCIL_OP_INCR_WRAP;
868
case D3D10_DDI_STENCIL_OP_DECR:
869
return PIPE_STENCIL_OP_DECR_WRAP;
870
default:
871
assert(0);
872
return PIPE_STENCIL_OP_KEEP;
873
}
874
}
875
876
877
/*
878
* ----------------------------------------------------------------------
879
*
880
* CreateDepthStencilState --
881
*
882
* The CreateDepthStencilState function creates a depth stencil state.
883
*
884
* ----------------------------------------------------------------------
885
*/
886
887
void APIENTRY
888
CreateDepthStencilState(
889
D3D10DDI_HDEVICE hDevice, // IN
890
__in const D3D10_DDI_DEPTH_STENCIL_DESC *pDepthStencilDesc, // IN
891
D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState, // IN
892
D3D10DDI_HRTDEPTHSTENCILSTATE hRTDepthStencilState) // IN
893
{
894
LOG_ENTRYPOINT();
895
896
struct pipe_context *pipe = CastPipeContext(hDevice);
897
DepthStencilState *pDepthStencilState = CastDepthStencilState(hDepthStencilState);
898
899
struct pipe_depth_stencil_alpha_state state;
900
memset(&state, 0, sizeof state);
901
902
/* Depth. */
903
state.depth_enabled = (pDepthStencilDesc->DepthEnable ? 1 : 0);
904
state.depth_writemask = (pDepthStencilDesc->DepthWriteMask ? 1 : 0);
905
state.depth_func = translateComparison(pDepthStencilDesc->DepthFunc);
906
907
/* Stencil. */
908
if (pDepthStencilDesc->StencilEnable) {
909
struct pipe_stencil_state *face0 = &state.stencil[0];
910
struct pipe_stencil_state *face1 = &state.stencil[1];
911
912
face0->enabled = 1;
913
face0->func = translateComparison(pDepthStencilDesc->FrontFace.StencilFunc);
914
face0->fail_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilFailOp);
915
face0->zpass_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilPassOp);
916
face0->zfail_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilDepthFailOp);
917
face0->valuemask = pDepthStencilDesc->StencilReadMask;
918
face0->writemask = pDepthStencilDesc->StencilWriteMask;
919
920
face1->enabled = 1;
921
face1->func = translateComparison(pDepthStencilDesc->BackFace.StencilFunc);
922
face1->fail_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilFailOp);
923
face1->zpass_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilPassOp);
924
face1->zfail_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilDepthFailOp);
925
face1->valuemask = pDepthStencilDesc->StencilReadMask;
926
face1->writemask = pDepthStencilDesc->StencilWriteMask;
927
#ifdef DEBUG
928
if (!pDepthStencilDesc->FrontEnable) {
929
ASSERT(face0->func == PIPE_FUNC_ALWAYS);
930
ASSERT(face0->fail_op == PIPE_STENCIL_OP_KEEP);
931
ASSERT(face0->zpass_op == PIPE_STENCIL_OP_KEEP);
932
ASSERT(face0->zfail_op == PIPE_STENCIL_OP_KEEP);
933
}
934
935
if (!pDepthStencilDesc->BackEnable) {
936
ASSERT(face1->func == PIPE_FUNC_ALWAYS);
937
ASSERT(face1->fail_op == PIPE_STENCIL_OP_KEEP);
938
ASSERT(face1->zpass_op == PIPE_STENCIL_OP_KEEP);
939
ASSERT(face1->zfail_op == PIPE_STENCIL_OP_KEEP);
940
}
941
#endif
942
}
943
944
pDepthStencilState->handle =
945
pipe->create_depth_stencil_alpha_state(pipe, &state);
946
}
947
948
949
/*
950
* ----------------------------------------------------------------------
951
*
952
* DestroyDepthStencilState --
953
*
954
* The CreateDepthStencilState function creates a depth stencil state.
955
*
956
* ----------------------------------------------------------------------
957
*/
958
959
void APIENTRY
960
DestroyDepthStencilState(D3D10DDI_HDEVICE hDevice, // IN
961
D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState) // IN
962
{
963
LOG_ENTRYPOINT();
964
965
struct pipe_context *pipe = CastPipeContext(hDevice);
966
DepthStencilState *pDepthStencilState = CastDepthStencilState(hDepthStencilState);
967
968
pipe->delete_depth_stencil_alpha_state(pipe, pDepthStencilState->handle);
969
}
970
971
972
/*
973
* ----------------------------------------------------------------------
974
*
975
* SetDepthStencilState --
976
*
977
* The SetDepthStencilState function sets a depth-stencil state.
978
*
979
* ----------------------------------------------------------------------
980
*/
981
982
void APIENTRY
983
SetDepthStencilState(D3D10DDI_HDEVICE hDevice, // IN
984
D3D10DDI_HDEPTHSTENCILSTATE hState, // IN
985
UINT StencilRef) // IN
986
{
987
LOG_ENTRYPOINT();
988
989
struct pipe_context *pipe = CastPipeContext(hDevice);
990
void *state = CastPipeDepthStencilState(hState);
991
struct pipe_stencil_ref psr;
992
993
psr.ref_value[0] = StencilRef;
994
psr.ref_value[1] = StencilRef;
995
996
pipe->bind_depth_stencil_alpha_state(pipe, state);
997
pipe->set_stencil_ref(pipe, psr);
998
}
999
1000