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 * Shader.cpp --
30 * Functions that manipulate shader resources.
31 */
32
33
34 #include "Shader.h"
35 #include "ShaderParse.h"
36 #include "State.h"
37 #include "Query.h"
38
39 #include "Debug.h"
40 #include "Format.h"
41
42 #include "tgsi/tgsi_ureg.h"
43 #include "util/u_gen_mipmap.h"
44 #include "util/u_sampler.h"
45 #include "util/format/u_format.h"
46
47
48 /*
49 * ----------------------------------------------------------------------
50 *
51 * CreateEmptyShader --
52 *
53 * Update the driver's currently bound constant buffers.
54 *
55 * ----------------------------------------------------------------------
56 */
57
58 void *
CreateEmptyShader(Device * pDevice,enum pipe_shader_type processor)59 CreateEmptyShader(Device *pDevice,
60 enum pipe_shader_type processor)
61 {
62 struct pipe_context *pipe = pDevice->pipe;
63 struct ureg_program *ureg;
64 const struct tgsi_token *tokens;
65 uint nr_tokens;
66
67 if (processor == PIPE_SHADER_GEOMETRY) {
68 return NULL;
69 }
70
71 ureg = ureg_create(processor);
72 if (!ureg)
73 return NULL;
74
75 ureg_END(ureg);
76
77 tokens = ureg_get_tokens(ureg, &nr_tokens);
78 if (!tokens)
79 return NULL;
80
81 ureg_destroy(ureg);
82
83 struct pipe_shader_state state;
84 memset(&state, 0, sizeof state);
85 state.tokens = tokens;
86
87 void *handle;
88 switch (processor) {
89 case PIPE_SHADER_FRAGMENT:
90 handle = pipe->create_fs_state(pipe, &state);
91 break;
92 case PIPE_SHADER_VERTEX:
93 handle = pipe->create_vs_state(pipe, &state);
94 break;
95 case PIPE_SHADER_GEOMETRY:
96 handle = pipe->create_gs_state(pipe, &state);
97 break;
98 default:
99 handle = NULL;
100 assert(0);
101 }
102 assert(handle);
103
104 ureg_free_tokens(tokens);
105
106 return handle;
107 }
108
109
110 /*
111 * ----------------------------------------------------------------------
112 *
113 * CreateEmptyShader --
114 *
115 * Update the driver's currently bound constant buffers.
116 *
117 * ----------------------------------------------------------------------
118 */
119
120 void
DeleteEmptyShader(Device * pDevice,enum pipe_shader_type processor,void * handle)121 DeleteEmptyShader(Device *pDevice,
122 enum pipe_shader_type processor, void *handle)
123 {
124 struct pipe_context *pipe = pDevice->pipe;
125
126 if (processor == PIPE_SHADER_GEOMETRY) {
127 assert(handle == NULL);
128 return;
129 }
130
131 assert(handle != NULL);
132 switch (processor) {
133 case PIPE_SHADER_FRAGMENT:
134 pipe->delete_fs_state(pipe, handle);
135 break;
136 case PIPE_SHADER_VERTEX:
137 pipe->delete_vs_state(pipe, handle);
138 break;
139 case PIPE_SHADER_GEOMETRY:
140 pipe->delete_gs_state(pipe, handle);
141 break;
142 default:
143 assert(0);
144 }
145 }
146
147
148 /*
149 * ----------------------------------------------------------------------
150 *
151 * SetConstantBuffers --
152 *
153 * Update the driver's currently bound constant buffers.
154 *
155 * ----------------------------------------------------------------------
156 */
157
158 static void
SetConstantBuffers(enum pipe_shader_type shader_type,D3D10DDI_HDEVICE hDevice,UINT StartBuffer,UINT NumBuffers,const D3D10DDI_HRESOURCE * phBuffers)159 SetConstantBuffers(enum pipe_shader_type shader_type, // IN
160 D3D10DDI_HDEVICE hDevice, // IN
161 UINT StartBuffer, // IN
162 UINT NumBuffers, // IN
163 const D3D10DDI_HRESOURCE *phBuffers) // IN
164 {
165 Device *pDevice = CastDevice(hDevice);
166 struct pipe_context *pipe = pDevice->pipe;
167
168 for (UINT i = 0; i < NumBuffers; i++) {
169 struct pipe_constant_buffer cb;
170 memset(&cb, 0, sizeof cb);
171 cb.buffer = CastPipeResource(phBuffers[i]);
172 cb.buffer_offset = 0;
173 cb.buffer_size = cb.buffer ? cb.buffer->width0 : 0;
174 pipe->set_constant_buffer(pipe,
175 shader_type,
176 StartBuffer + i,
177 false,
178 &cb);
179 }
180 }
181
182
183 /*
184 * ----------------------------------------------------------------------
185 *
186 * SetSamplers --
187 *
188 * Update the driver's currently bound sampler state.
189 *
190 * ----------------------------------------------------------------------
191 */
192
193 static void
SetSamplers(enum pipe_shader_type shader_type,D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumSamplers,const D3D10DDI_HSAMPLER * phSamplers)194 SetSamplers(enum pipe_shader_type shader_type, // IN
195 D3D10DDI_HDEVICE hDevice, // IN
196 UINT Offset, // IN
197 UINT NumSamplers, // IN
198 const D3D10DDI_HSAMPLER *phSamplers) // IN
199 {
200 Device *pDevice = CastDevice(hDevice);
201 struct pipe_context *pipe = pDevice->pipe;
202
203 void **samplers = pDevice->samplers[shader_type];
204 for (UINT i = 0; i < NumSamplers; i++) {
205 assert(Offset + i < PIPE_MAX_SAMPLERS);
206 samplers[Offset + i] = CastPipeSamplerState(phSamplers[i]);
207 }
208
209 pipe->bind_sampler_states(pipe, shader_type, 0, PIPE_MAX_SAMPLERS, samplers);
210 }
211
212
213 /*
214 * ----------------------------------------------------------------------
215 *
216 * SetSamplers --
217 *
218 * Update the driver's currently bound sampler state.
219 *
220 * ----------------------------------------------------------------------
221 */
222
223 static void
SetShaderResources(enum pipe_shader_type shader_type,D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumViews,const D3D10DDI_HSHADERRESOURCEVIEW * phShaderResourceViews)224 SetShaderResources(enum pipe_shader_type shader_type, // IN
225 D3D10DDI_HDEVICE hDevice, // IN
226 UINT Offset, // IN
227 UINT NumViews, // IN
228 const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
229 {
230 Device *pDevice = CastDevice(hDevice);
231 struct pipe_context *pipe = pDevice->pipe;
232
233 assert(Offset + NumViews <= D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
234
235 struct pipe_sampler_view **sampler_views = pDevice->sampler_views[shader_type];
236 for (UINT i = 0; i < NumViews; i++) {
237 struct pipe_sampler_view *sampler_view =
238 CastPipeShaderResourceView(phShaderResourceViews[i]);
239 if (Offset + i < PIPE_MAX_SHADER_SAMPLER_VIEWS) {
240 sampler_views[Offset + i] = sampler_view;
241 } else {
242 if (sampler_view) {
243 LOG_UNSUPPORTED(true);
244 break;
245 }
246 }
247 }
248
249 /*
250 * XXX: Now that the semantics are actually the same in gallium, should
251 * probably think about not updating all always... It should just work.
252 */
253 pipe->set_sampler_views(pipe, shader_type, 0, PIPE_MAX_SHADER_SAMPLER_VIEWS,
254 0, false, sampler_views);
255 }
256
257
258 /*
259 * ----------------------------------------------------------------------
260 *
261 * CalcPrivateShaderSize --
262 *
263 * The CalcPrivateShaderSize function determines the size of
264 * the user-mode display driver's private region of memory
265 * (that is, the size of internal driver structures, not the
266 * size of the resource video memory) for a shader.
267 *
268 * ----------------------------------------------------------------------
269 */
270
271 SIZE_T APIENTRY
CalcPrivateShaderSize(D3D10DDI_HDEVICE hDevice,__in_ecount (pShaderCode[1])const UINT * pShaderCode,__in const D3D10DDIARG_STAGE_IO_SIGNATURES * pSignatures)272 CalcPrivateShaderSize(D3D10DDI_HDEVICE hDevice, // IN
273 __in_ecount (pShaderCode[1]) const UINT *pShaderCode, // IN
274 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
275 {
276 return sizeof(Shader);
277 }
278
279
280 /*
281 * ----------------------------------------------------------------------
282 *
283 * DestroyShader --
284 *
285 * The DestroyShader function destroys the specified shader object.
286 * The shader object can be destoyed only if it is not currently
287 * bound to a display device.
288 *
289 * ----------------------------------------------------------------------
290 */
291
292 void APIENTRY
DestroyShader(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADER hShader)293 DestroyShader(D3D10DDI_HDEVICE hDevice, // IN
294 D3D10DDI_HSHADER hShader) // IN
295 {
296 LOG_ENTRYPOINT();
297
298 struct pipe_context *pipe = CastPipeContext(hDevice);
299 Shader *pShader = CastShader(hShader);
300
301 if (pShader->handle) {
302 switch (pShader->type) {
303 case PIPE_SHADER_FRAGMENT:
304 pipe->delete_fs_state(pipe, pShader->handle);
305 break;
306 case PIPE_SHADER_VERTEX:
307 pipe->delete_vs_state(pipe, pShader->handle);
308 break;
309 case PIPE_SHADER_GEOMETRY:
310 pipe->delete_gs_state(pipe, pShader->handle);
311 break;
312 default:
313 assert(0);
314 }
315 }
316
317 if (pShader->state.tokens) {
318 ureg_free_tokens(pShader->state.tokens);
319 }
320 }
321
322
323 /*
324 * ----------------------------------------------------------------------
325 *
326 * CalcPrivateSamplerSize --
327 *
328 * The CalcPrivateSamplerSize function determines the size of the
329 * user-mode display driver's private region of memory (that is,
330 * the size of internal driver structures, not the size of the
331 * resource video memory) for a sampler.
332 *
333 * ----------------------------------------------------------------------
334 */
335
336 SIZE_T APIENTRY
CalcPrivateSamplerSize(D3D10DDI_HDEVICE hDevice,__in const D3D10_DDI_SAMPLER_DESC * pSamplerDesc)337 CalcPrivateSamplerSize(D3D10DDI_HDEVICE hDevice, // IN
338 __in const D3D10_DDI_SAMPLER_DESC *pSamplerDesc) // IN
339 {
340 return sizeof(SamplerState);
341 }
342
343
344 static uint
translate_address_mode(D3D10_DDI_TEXTURE_ADDRESS_MODE AddressMode)345 translate_address_mode(D3D10_DDI_TEXTURE_ADDRESS_MODE AddressMode)
346 {
347 switch (AddressMode) {
348 case D3D10_DDI_TEXTURE_ADDRESS_WRAP:
349 return PIPE_TEX_WRAP_REPEAT;
350 case D3D10_DDI_TEXTURE_ADDRESS_MIRROR:
351 return PIPE_TEX_WRAP_MIRROR_REPEAT;
352 case D3D10_DDI_TEXTURE_ADDRESS_CLAMP:
353 return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
354 case D3D10_DDI_TEXTURE_ADDRESS_BORDER:
355 return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
356 case D3D10_DDI_TEXTURE_ADDRESS_MIRRORONCE:
357 return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
358 default:
359 assert(0);
360 return PIPE_TEX_WRAP_REPEAT;
361 }
362 }
363
364 static uint
translate_comparison(D3D10_DDI_COMPARISON_FUNC Func)365 translate_comparison(D3D10_DDI_COMPARISON_FUNC Func)
366 {
367 switch (Func) {
368 case D3D10_DDI_COMPARISON_NEVER:
369 return PIPE_FUNC_NEVER;
370 case D3D10_DDI_COMPARISON_LESS:
371 return PIPE_FUNC_LESS;
372 case D3D10_DDI_COMPARISON_EQUAL:
373 return PIPE_FUNC_EQUAL;
374 case D3D10_DDI_COMPARISON_LESS_EQUAL:
375 return PIPE_FUNC_LEQUAL;
376 case D3D10_DDI_COMPARISON_GREATER:
377 return PIPE_FUNC_GREATER;
378 case D3D10_DDI_COMPARISON_NOT_EQUAL:
379 return PIPE_FUNC_NOTEQUAL;
380 case D3D10_DDI_COMPARISON_GREATER_EQUAL:
381 return PIPE_FUNC_GEQUAL;
382 case D3D10_DDI_COMPARISON_ALWAYS:
383 return PIPE_FUNC_ALWAYS;
384 default:
385 assert(0);
386 return PIPE_FUNC_ALWAYS;
387 }
388 }
389
390 static uint
translate_filter(D3D10_DDI_FILTER_TYPE Filter)391 translate_filter(D3D10_DDI_FILTER_TYPE Filter)
392 {
393 switch (Filter) {
394 case D3D10_DDI_FILTER_TYPE_POINT:
395 return PIPE_TEX_FILTER_NEAREST;
396 case D3D10_DDI_FILTER_TYPE_LINEAR:
397 return PIPE_TEX_FILTER_LINEAR;
398 default:
399 assert(0);
400 return PIPE_TEX_FILTER_NEAREST;
401 }
402 }
403
404 static uint
translate_min_filter(D3D10_DDI_FILTER Filter)405 translate_min_filter(D3D10_DDI_FILTER Filter)
406 {
407 return translate_filter(D3D10_DDI_DECODE_MIN_FILTER(Filter));
408 }
409
410 static uint
translate_mag_filter(D3D10_DDI_FILTER Filter)411 translate_mag_filter(D3D10_DDI_FILTER Filter)
412 {
413 return translate_filter(D3D10_DDI_DECODE_MAG_FILTER(Filter));
414 }
415
416 /* Gallium uses a different enum for mipfilters, to accomodate the GL
417 * MIPFILTER_NONE mode.
418 */
419 static uint
translate_mip_filter(D3D10_DDI_FILTER Filter)420 translate_mip_filter(D3D10_DDI_FILTER Filter)
421 {
422 switch (D3D10_DDI_DECODE_MIP_FILTER(Filter)) {
423 case D3D10_DDI_FILTER_TYPE_POINT:
424 return PIPE_TEX_MIPFILTER_NEAREST;
425 case D3D10_DDI_FILTER_TYPE_LINEAR:
426 return PIPE_TEX_MIPFILTER_LINEAR;
427 default:
428 assert(0);
429 return PIPE_TEX_MIPFILTER_NEAREST;
430 }
431 }
432
433 /*
434 * ----------------------------------------------------------------------
435 *
436 * CreateSampler --
437 *
438 * The CreateSampler function creates a sampler.
439 *
440 * ----------------------------------------------------------------------
441 */
442
443 void APIENTRY
CreateSampler(D3D10DDI_HDEVICE hDevice,__in const D3D10_DDI_SAMPLER_DESC * pSamplerDesc,D3D10DDI_HSAMPLER hSampler,D3D10DDI_HRTSAMPLER hRTSampler)444 CreateSampler(D3D10DDI_HDEVICE hDevice, // IN
445 __in const D3D10_DDI_SAMPLER_DESC *pSamplerDesc, // IN
446 D3D10DDI_HSAMPLER hSampler, // IN
447 D3D10DDI_HRTSAMPLER hRTSampler) // IN
448 {
449 LOG_ENTRYPOINT();
450
451 struct pipe_context *pipe = CastPipeContext(hDevice);
452 SamplerState *pSamplerState = CastSamplerState(hSampler);
453
454 struct pipe_sampler_state state;
455
456 memset(&state, 0, sizeof state);
457
458 /* d3d10 has seamless cube filtering always enabled */
459 state.seamless_cube_map = 1;
460
461 /* Wrapping modes. */
462 state.wrap_s = translate_address_mode(pSamplerDesc->AddressU);
463 state.wrap_t = translate_address_mode(pSamplerDesc->AddressV);
464 state.wrap_r = translate_address_mode(pSamplerDesc->AddressW);
465
466 /* Filtering */
467 state.min_img_filter = translate_min_filter(pSamplerDesc->Filter);
468 state.mag_img_filter = translate_mag_filter(pSamplerDesc->Filter);
469 state.min_mip_filter = translate_mip_filter(pSamplerDesc->Filter);
470
471 if (D3D10_DDI_DECODE_IS_ANISOTROPIC_FILTER(pSamplerDesc->Filter)) {
472 state.max_anisotropy = pSamplerDesc->MaxAnisotropy;
473 }
474
475 /* XXX: Handle the following bit.
476 */
477 LOG_UNSUPPORTED(D3D10_DDI_DECODE_IS_TEXT_1BIT_FILTER(pSamplerDesc->Filter));
478
479 /* Comparison. */
480 if (D3D10_DDI_DECODE_IS_COMPARISON_FILTER(pSamplerDesc->Filter)) {
481 state.compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
482 state.compare_func = translate_comparison(pSamplerDesc->ComparisonFunc);
483 }
484
485 /* Level of detail. */
486 state.lod_bias = pSamplerDesc->MipLODBias;
487 state.min_lod = pSamplerDesc->MinLOD;
488 state.max_lod = pSamplerDesc->MaxLOD;
489
490 /* Border color. */
491 state.border_color.f[0] = pSamplerDesc->BorderColor[0];
492 state.border_color.f[1] = pSamplerDesc->BorderColor[1];
493 state.border_color.f[2] = pSamplerDesc->BorderColor[2];
494 state.border_color.f[3] = pSamplerDesc->BorderColor[3];
495
496 pSamplerState->handle = pipe->create_sampler_state(pipe, &state);
497 }
498
499
500 /*
501 * ----------------------------------------------------------------------
502 *
503 * DestroySampler --
504 *
505 * The DestroySampler function destroys the specified sampler object.
506 * The sampler object can be destoyed only if it is not currently
507 * bound to a display device.
508 *
509 * ----------------------------------------------------------------------
510 */
511
512 void APIENTRY
DestroySampler(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSAMPLER hSampler)513 DestroySampler(D3D10DDI_HDEVICE hDevice, // IN
514 D3D10DDI_HSAMPLER hSampler) // IN
515 {
516 LOG_ENTRYPOINT();
517
518 struct pipe_context *pipe = CastPipeContext(hDevice);
519 SamplerState *pSamplerState = CastSamplerState(hSampler);
520
521 pipe->delete_sampler_state(pipe, pSamplerState->handle);
522 }
523
524
525 /*
526 * ----------------------------------------------------------------------
527 *
528 * CreateVertexShader --
529 *
530 * The CreateVertexShader function creates a vertex shader.
531 *
532 * ----------------------------------------------------------------------
533 */
534
535 void APIENTRY
CreateVertexShader(D3D10DDI_HDEVICE hDevice,__in_ecount (pShaderCode[1])const UINT * pCode,D3D10DDI_HSHADER hShader,D3D10DDI_HRTSHADER hRTShader,__in const D3D10DDIARG_STAGE_IO_SIGNATURES * pSignatures)536 CreateVertexShader(D3D10DDI_HDEVICE hDevice, // IN
537 __in_ecount (pShaderCode[1]) const UINT *pCode, // IN
538 D3D10DDI_HSHADER hShader, // IN
539 D3D10DDI_HRTSHADER hRTShader, // IN
540 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
541 {
542 LOG_ENTRYPOINT();
543
544 struct pipe_context *pipe = CastPipeContext(hDevice);
545 Shader *pShader = CastShader(hShader);
546
547 pShader->type = PIPE_SHADER_VERTEX;
548 pShader->output_resolved = true;
549
550 memset(&pShader->state, 0, sizeof pShader->state);
551 pShader->state.tokens = Shader_tgsi_translate(pCode, pShader->output_mapping);
552
553 pShader->handle = pipe->create_vs_state(pipe, &pShader->state);
554
555 }
556
557
558 /*
559 * ----------------------------------------------------------------------
560 *
561 * VsSetShader --
562 *
563 * The VsSetShader function sets the vertex shader code so that all
564 * of the subsequent drawing operations use that code.
565 *
566 * ----------------------------------------------------------------------
567 */
568
569 void APIENTRY
VsSetShader(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADER hShader)570 VsSetShader(D3D10DDI_HDEVICE hDevice, // IN
571 D3D10DDI_HSHADER hShader) // IN
572 {
573 LOG_ENTRYPOINT();
574
575 Device *pDevice = CastDevice(hDevice);
576 struct pipe_context *pipe = pDevice->pipe;
577 Shader *pShader = CastShader(hShader);
578 void *state = CastPipeShader(hShader);
579
580 pDevice->bound_vs = pShader;
581 if (!state) {
582 state = pDevice->empty_vs;
583 }
584
585 pipe->bind_vs_state(pipe, state);
586 }
587
588
589 /*
590 * ----------------------------------------------------------------------
591 *
592 * VsSetShaderResources --
593 *
594 * The VsSetShaderResources function sets resources for a
595 * vertex shader.
596 *
597 * ----------------------------------------------------------------------
598 */
599
600 void APIENTRY
VsSetShaderResources(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumViews,__in_ecount (NumViews)const D3D10DDI_HSHADERRESOURCEVIEW * phShaderResourceViews)601 VsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
602 UINT Offset, // IN
603 UINT NumViews, // IN
604 __in_ecount (NumViews)
605 const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
606 {
607 LOG_ENTRYPOINT();
608
609 SetShaderResources(PIPE_SHADER_VERTEX, hDevice, Offset, NumViews, phShaderResourceViews);
610
611 }
612
613
614 /*
615 * ----------------------------------------------------------------------
616 *
617 * VsSetConstantBuffers --
618 *
619 * The VsSetConstantBuffers function sets constant buffers
620 * for a vertex shader.
621 *
622 * ----------------------------------------------------------------------
623 */
624
625 void APIENTRY
VsSetConstantBuffers(D3D10DDI_HDEVICE hDevice,UINT StartBuffer,UINT NumBuffers,__in_ecount (NumBuffers)const D3D10DDI_HRESOURCE * phBuffers)626 VsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
627 UINT StartBuffer, // IN
628 UINT NumBuffers, // IN
629 __in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
630 {
631 LOG_ENTRYPOINT();
632
633 SetConstantBuffers(PIPE_SHADER_VERTEX,
634 hDevice, StartBuffer, NumBuffers, phBuffers);
635 }
636
637
638 /*
639 * ----------------------------------------------------------------------
640 *
641 * VsSetSamplers --
642 *
643 * The VsSetSamplers function sets samplers for a vertex shader.
644 *
645 * ----------------------------------------------------------------------
646 */
647
648 void APIENTRY
VsSetSamplers(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumSamplers,__in_ecount (NumSamplers)const D3D10DDI_HSAMPLER * phSamplers)649 VsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
650 UINT Offset, // IN
651 UINT NumSamplers, // IN
652 __in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
653 {
654 LOG_ENTRYPOINT();
655
656 SetSamplers(PIPE_SHADER_VERTEX, hDevice, Offset, NumSamplers, phSamplers);
657
658 }
659
660
661 /*
662 * ----------------------------------------------------------------------
663 *
664 * CreateGeometryShader --
665 *
666 * The CreateGeometryShader function creates a geometry shader.
667 *
668 * ----------------------------------------------------------------------
669 */
670
671 void APIENTRY
CreateGeometryShader(D3D10DDI_HDEVICE hDevice,__in_ecount (pShaderCode[1])const UINT * pShaderCode,D3D10DDI_HSHADER hShader,D3D10DDI_HRTSHADER hRTShader,__in const D3D10DDIARG_STAGE_IO_SIGNATURES * pSignatures)672 CreateGeometryShader(D3D10DDI_HDEVICE hDevice, // IN
673 __in_ecount (pShaderCode[1]) const UINT *pShaderCode, // IN
674 D3D10DDI_HSHADER hShader, // IN
675 D3D10DDI_HRTSHADER hRTShader, // IN
676 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
677 {
678 LOG_ENTRYPOINT();
679
680 struct pipe_context *pipe = CastPipeContext(hDevice);
681 Shader *pShader = CastShader(hShader);
682
683 pShader->type = PIPE_SHADER_GEOMETRY;
684 pShader->output_resolved = true;
685
686 memset(&pShader->state, 0, sizeof pShader->state);
687 pShader->state.tokens = Shader_tgsi_translate(pShaderCode, pShader->output_mapping);
688
689 pShader->handle = pipe->create_gs_state(pipe, &pShader->state);
690 }
691
692
693 /*
694 * ----------------------------------------------------------------------
695 *
696 * GsSetShader --
697 *
698 * The GsSetShader function sets the geometry shader code so that
699 * all of the subsequent drawing operations use that code.
700 *
701 * ----------------------------------------------------------------------
702 */
703
704 void APIENTRY
GsSetShader(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADER hShader)705 GsSetShader(D3D10DDI_HDEVICE hDevice, // IN
706 D3D10DDI_HSHADER hShader) // IN
707 {
708 LOG_ENTRYPOINT();
709
710 Device *pDevice = CastDevice(hDevice);
711 struct pipe_context *pipe = CastPipeContext(hDevice);
712 void *state = CastPipeShader(hShader);
713 Shader *pShader = CastShader(hShader);
714
715 assert(pipe->bind_gs_state);
716
717 if (pShader && !pShader->state.tokens) {
718 pDevice->bound_empty_gs = pShader;
719 } else {
720 pDevice->bound_empty_gs = NULL;
721 pipe->bind_gs_state(pipe, state);
722 }
723 }
724
725
726 /*
727 * ----------------------------------------------------------------------
728 *
729 * GsSetShaderResources --
730 *
731 * The GsSetShaderResources function sets resources for a
732 * geometry shader.
733 *
734 * ----------------------------------------------------------------------
735 */
736
737 void APIENTRY
GsSetShaderResources(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumViews,__in_ecount (NumViews)const D3D10DDI_HSHADERRESOURCEVIEW * phShaderResourceViews)738 GsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
739 UINT Offset, // IN
740 UINT NumViews, // IN
741 __in_ecount (NumViews)
742 const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
743 {
744 LOG_ENTRYPOINT();
745
746 SetShaderResources(PIPE_SHADER_GEOMETRY, hDevice, Offset, NumViews, phShaderResourceViews);
747 }
748
749
750 /*
751 * ----------------------------------------------------------------------
752 *
753 * GsSetConstantBuffers --
754 *
755 * The GsSetConstantBuffers function sets constant buffers for
756 * a geometry shader.
757 *
758 * ----------------------------------------------------------------------
759 */
760
761 void APIENTRY
GsSetConstantBuffers(D3D10DDI_HDEVICE hDevice,UINT StartBuffer,UINT NumBuffers,__in_ecount (NumBuffers)const D3D10DDI_HRESOURCE * phBuffers)762 GsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
763 UINT StartBuffer, // IN
764 UINT NumBuffers, // IN
765 __in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
766 {
767 LOG_ENTRYPOINT();
768
769 SetConstantBuffers(PIPE_SHADER_GEOMETRY,
770 hDevice, StartBuffer, NumBuffers, phBuffers);
771 }
772
773
774 /*
775 * ----------------------------------------------------------------------
776 *
777 * GsSetSamplers --
778 *
779 * The GsSetSamplers function sets samplers for a geometry shader.
780 *
781 * ----------------------------------------------------------------------
782 */
783
784 void APIENTRY
GsSetSamplers(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumSamplers,__in_ecount (NumSamplers)const D3D10DDI_HSAMPLER * phSamplers)785 GsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
786 UINT Offset, // IN
787 UINT NumSamplers, // IN
788 __in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
789 {
790 LOG_ENTRYPOINT();
791
792 SetSamplers(PIPE_SHADER_GEOMETRY, hDevice, Offset, NumSamplers, phSamplers);
793 }
794
795
796 /*
797 * ----------------------------------------------------------------------
798 *
799 * CalcPrivateGeometryShaderWithStreamOutput --
800 *
801 * The CalcPrivateGeometryShaderWithStreamOutput function determines
802 * the size of the user-mode display driver's private region of memory
803 * (that is, the size of internal driver structures, not the size of
804 * the resource video memory) for a geometry shader with stream output.
805 *
806 * ----------------------------------------------------------------------
807 */
808
809 SIZE_T APIENTRY
CalcPrivateGeometryShaderWithStreamOutput(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT * pCreateGeometryShaderWithStreamOutput,__in const D3D10DDIARG_STAGE_IO_SIGNATURES * pSignatures)810 CalcPrivateGeometryShaderWithStreamOutput(
811 D3D10DDI_HDEVICE hDevice, // IN
812 __in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT *pCreateGeometryShaderWithStreamOutput, // IN
813 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
814 {
815 LOG_ENTRYPOINT();
816 return sizeof(Shader);
817 }
818
819
820 /*
821 * ----------------------------------------------------------------------
822 *
823 * CreateGeometryShaderWithStreamOutput --
824 *
825 * The CreateGeometryShaderWithStreamOutput function creates a
826 * geometry shader with stream output.
827 *
828 * ----------------------------------------------------------------------
829 */
830
831 void APIENTRY
CreateGeometryShaderWithStreamOutput(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT * pData,D3D10DDI_HSHADER hShader,D3D10DDI_HRTSHADER hRTShader,__in const D3D10DDIARG_STAGE_IO_SIGNATURES * pSignatures)832 CreateGeometryShaderWithStreamOutput(
833 D3D10DDI_HDEVICE hDevice, // IN
834 __in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT *pData, // IN
835 D3D10DDI_HSHADER hShader, // IN
836 D3D10DDI_HRTSHADER hRTShader, // IN
837 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
838 {
839 LOG_ENTRYPOINT();
840
841 struct pipe_context *pipe = CastPipeContext(hDevice);
842 Shader *pShader = CastShader(hShader);
843 int total_components[PIPE_MAX_SO_BUFFERS] = {0};
844 unsigned num_holes = 0;
845 bool all_slot_zero = true;
846
847 pShader->type = PIPE_SHADER_GEOMETRY;
848
849 memset(&pShader->state, 0, sizeof pShader->state);
850 if (pData->pShaderCode) {
851 pShader->state.tokens = Shader_tgsi_translate(pData->pShaderCode,
852 pShader->output_mapping);
853 }
854 pShader->output_resolved = (pShader->state.tokens != NULL);
855
856 for (unsigned i = 0; i < pData->NumEntries; ++i) {
857 CONST D3D10DDIARG_STREAM_OUTPUT_DECLARATION_ENTRY* pOutputStreamDecl =
858 &pData->pOutputStreamDecl[i];
859 BYTE RegisterMask = pOutputStreamDecl->RegisterMask;
860 unsigned start_component = 0;
861 unsigned num_components = 0;
862 if (RegisterMask) {
863 while ((RegisterMask & 1) == 0) {
864 ++start_component;
865 RegisterMask >>= 1;
866 }
867 while (RegisterMask) {
868 ++num_components;
869 RegisterMask >>= 1;
870 }
871 assert(start_component < 4);
872 assert(1 <= num_components && num_components <= 4);
873 LOG_UNSUPPORTED(((1 << num_components) - 1) << start_component !=
874 pOutputStreamDecl->RegisterMask);
875 }
876
877 if (pOutputStreamDecl->RegisterIndex == 0xffffffff) {
878 ++num_holes;
879 } else {
880 unsigned idx = i - num_holes;
881 pShader->state.stream_output.output[idx].start_component =
882 start_component;
883 pShader->state.stream_output.output[idx].num_components =
884 num_components;
885 pShader->state.stream_output.output[idx].output_buffer =
886 pOutputStreamDecl->OutputSlot;
887 pShader->state.stream_output.output[idx].register_index =
888 ShaderFindOutputMapping(pShader, pOutputStreamDecl->RegisterIndex);
889 pShader->state.stream_output.output[idx].dst_offset =
890 total_components[pOutputStreamDecl->OutputSlot];
891 if (pOutputStreamDecl->OutputSlot != 0)
892 all_slot_zero = false;
893 }
894 total_components[pOutputStreamDecl->OutputSlot] += num_components;
895 }
896 pShader->state.stream_output.num_outputs = pData->NumEntries - num_holes;
897 for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; ++i) {
898 /* stream_output.stride[i] is in dwords */
899 if (all_slot_zero) {
900 pShader->state.stream_output.stride[i] =
901 pData->StreamOutputStrideInBytes / sizeof(float);
902 } else {
903 pShader->state.stream_output.stride[i] = total_components[i];
904 }
905 }
906
907 pShader->handle = pipe->create_gs_state(pipe, &pShader->state);
908 }
909
910
911 /*
912 * ----------------------------------------------------------------------
913 *
914 * SoSetTargets --
915 *
916 * The SoSetTargets function sets stream output target resources.
917 *
918 * ----------------------------------------------------------------------
919 */
920
921 void APIENTRY
SoSetTargets(D3D10DDI_HDEVICE hDevice,UINT SOTargets,UINT ClearTargets,__in_ecount (SOTargets)const D3D10DDI_HRESOURCE * phResource,__in_ecount (SOTargets)const UINT * pOffsets)922 SoSetTargets(D3D10DDI_HDEVICE hDevice, // IN
923 UINT SOTargets, // IN
924 UINT ClearTargets, // IN
925 __in_ecount (SOTargets) const D3D10DDI_HRESOURCE *phResource, // IN
926 __in_ecount (SOTargets) const UINT *pOffsets) // IN
927 {
928 unsigned i;
929
930 LOG_ENTRYPOINT();
931
932 Device *pDevice = CastDevice(hDevice);
933 struct pipe_context *pipe = pDevice->pipe;
934
935 assert(SOTargets + ClearTargets <= PIPE_MAX_SO_BUFFERS);
936
937 for (i = 0; i < SOTargets; ++i) {
938 Resource *resource = CastResource(phResource[i]);
939 struct pipe_resource *buffer = CastPipeResource(phResource[i]);
940 struct pipe_stream_output_target *so_target =
941 resource ? resource->so_target : NULL;
942
943 if (buffer) {
944 unsigned buffer_size = buffer->width0;
945
946 if (!so_target ||
947 so_target->buffer != buffer ||
948 so_target->buffer_size != buffer_size) {
949 if (so_target) {
950 pipe_so_target_reference(&so_target, NULL);
951 }
952 so_target = pipe->create_stream_output_target(pipe, buffer,
953 0,/*buffer offset*/
954 buffer_size);
955 resource->so_target = so_target;
956 }
957 }
958 pDevice->so_targets[i] = so_target;
959 }
960
961 for (i = 0; i < ClearTargets; ++i) {
962 pDevice->so_targets[SOTargets + i] = NULL;
963 }
964
965 if (!pipe->set_stream_output_targets) {
966 LOG_UNSUPPORTED(pipe->set_stream_output_targets);
967 return;
968 }
969
970 pipe->set_stream_output_targets(pipe, SOTargets, pDevice->so_targets,
971 pOffsets);
972 }
973
974
975 /*
976 * ----------------------------------------------------------------------
977 *
978 * CreatePixelShader --
979 *
980 * The CreatePixelShader function converts pixel shader code into a
981 * hardware-specific format and associates this code with a
982 * shader handle.
983 *
984 * ----------------------------------------------------------------------
985 */
986
987 void APIENTRY
CreatePixelShader(D3D10DDI_HDEVICE hDevice,__in_ecount (pShaderCode[1])const UINT * pShaderCode,D3D10DDI_HSHADER hShader,D3D10DDI_HRTSHADER hRTShader,__in const D3D10DDIARG_STAGE_IO_SIGNATURES * pSignatures)988 CreatePixelShader(D3D10DDI_HDEVICE hDevice, // IN
989 __in_ecount (pShaderCode[1]) const UINT *pShaderCode, // IN
990 D3D10DDI_HSHADER hShader, // IN
991 D3D10DDI_HRTSHADER hRTShader, // IN
992 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
993 {
994 LOG_ENTRYPOINT();
995
996 struct pipe_context *pipe = CastPipeContext(hDevice);
997 Shader *pShader = CastShader(hShader);
998
999 pShader->type = PIPE_SHADER_FRAGMENT;
1000 pShader->output_resolved = true;
1001
1002 memset(&pShader->state, 0, sizeof pShader->state);
1003 pShader->state.tokens = Shader_tgsi_translate(pShaderCode,
1004 pShader->output_mapping);
1005
1006 pShader->handle = pipe->create_fs_state(pipe, &pShader->state);
1007
1008 }
1009
1010
1011 /*
1012 * ----------------------------------------------------------------------
1013 *
1014 * PsSetShader --
1015 *
1016 * The PsSetShader function sets a pixel shader to be used
1017 * in all drawing operations.
1018 *
1019 * ----------------------------------------------------------------------
1020 */
1021
1022 void APIENTRY
PsSetShader(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADER hShader)1023 PsSetShader(D3D10DDI_HDEVICE hDevice, // IN
1024 D3D10DDI_HSHADER hShader) // IN
1025 {
1026 LOG_ENTRYPOINT();
1027
1028 Device *pDevice = CastDevice(hDevice);
1029 struct pipe_context *pipe = pDevice->pipe;
1030 void *state = CastPipeShader(hShader);
1031
1032 if (!state) {
1033 state = pDevice->empty_fs;
1034 }
1035
1036 pipe->bind_fs_state(pipe, state);
1037 }
1038
1039
1040 /*
1041 * ----------------------------------------------------------------------
1042 *
1043 * PsSetShaderResources --
1044 *
1045 * The PsSetShaderResources function sets resources for a pixel shader.
1046 *
1047 * ----------------------------------------------------------------------
1048 */
1049
1050 void APIENTRY
PsSetShaderResources(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumViews,__in_ecount (NumViews)const D3D10DDI_HSHADERRESOURCEVIEW * phShaderResourceViews)1051 PsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
1052 UINT Offset, // IN
1053 UINT NumViews, // IN
1054 __in_ecount (NumViews)
1055 const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
1056 {
1057 LOG_ENTRYPOINT();
1058
1059 SetShaderResources(PIPE_SHADER_FRAGMENT, hDevice, Offset, NumViews, phShaderResourceViews);
1060 }
1061
1062
1063 /*
1064 * ----------------------------------------------------------------------
1065 *
1066 * PsSetConstantBuffers --
1067 *
1068 * The PsSetConstantBuffers function sets constant buffers for
1069 * a pixel shader.
1070 *
1071 * ----------------------------------------------------------------------
1072 */
1073
1074 void APIENTRY
PsSetConstantBuffers(D3D10DDI_HDEVICE hDevice,UINT StartBuffer,UINT NumBuffers,__in_ecount (NumBuffers)const D3D10DDI_HRESOURCE * phBuffers)1075 PsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
1076 UINT StartBuffer, // IN
1077 UINT NumBuffers, // IN
1078 __in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
1079 {
1080 LOG_ENTRYPOINT();
1081
1082 SetConstantBuffers(PIPE_SHADER_FRAGMENT,
1083 hDevice, StartBuffer, NumBuffers, phBuffers);
1084 }
1085
1086 /*
1087 * ----------------------------------------------------------------------
1088 *
1089 * PsSetSamplers --
1090 *
1091 * The PsSetSamplers function sets samplers for a pixel shader.
1092 *
1093 * ----------------------------------------------------------------------
1094 */
1095
1096 void APIENTRY
PsSetSamplers(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumSamplers,__in_ecount (NumSamplers)const D3D10DDI_HSAMPLER * phSamplers)1097 PsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
1098 UINT Offset, // IN
1099 UINT NumSamplers, // IN
1100 __in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
1101 {
1102 LOG_ENTRYPOINT();
1103
1104 SetSamplers(PIPE_SHADER_FRAGMENT, hDevice, Offset, NumSamplers, phSamplers);
1105 }
1106
1107
1108 /*
1109 * ----------------------------------------------------------------------
1110 *
1111 * ShaderResourceViewReadAfterWriteHazard --
1112 *
1113 * The ShaderResourceViewReadAfterWriteHazard function informs
1114 * the usermode display driver that the specified resource was
1115 * used as an output from the graphics processing unit (GPU)
1116 * and that the resource will be used as an input to the GPU.
1117 * A shader resource view is also provided to indicate which
1118 * view caused the hazard.
1119 *
1120 * ----------------------------------------------------------------------
1121 */
1122
1123 void APIENTRY
ShaderResourceViewReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,D3D10DDI_HRESOURCE hResource)1124 ShaderResourceViewReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice, // IN
1125 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
1126 D3D10DDI_HRESOURCE hResource) // IN
1127 {
1128 LOG_ENTRYPOINT();
1129
1130 /* Not actually necessary */
1131 }
1132
1133
1134 /*
1135 * ----------------------------------------------------------------------
1136 *
1137 * CalcPrivateShaderResourceViewSize --
1138 *
1139 * The CalcPrivateShaderResourceViewSize function determines the size
1140 * of the usermode display driver's private region of memory
1141 * (that is, the size of internal driver structures, not the size of
1142 * the resource video memory) for a shader resource view.
1143 *
1144 * ----------------------------------------------------------------------
1145 */
1146
1147 SIZE_T APIENTRY
CalcPrivateShaderResourceViewSize(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATESHADERRESOURCEVIEW * pCreateSRView)1148 CalcPrivateShaderResourceViewSize(
1149 D3D10DDI_HDEVICE hDevice, // IN
1150 __in const D3D10DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView) // IN
1151 {
1152 return sizeof(ShaderResourceView);
1153 }
1154
1155
1156 /*
1157 * ----------------------------------------------------------------------
1158 *
1159 * CalcPrivateShaderResourceViewSize --
1160 *
1161 * The CalcPrivateShaderResourceViewSize function determines the size
1162 * of the usermode display driver's private region of memory
1163 * (that is, the size of internal driver structures, not the size of
1164 * the resource video memory) for a shader resource view.
1165 *
1166 * ----------------------------------------------------------------------
1167 */
1168
1169 SIZE_T APIENTRY
CalcPrivateShaderResourceViewSize1(D3D10DDI_HDEVICE hDevice,__in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW * pCreateSRView)1170 CalcPrivateShaderResourceViewSize1(
1171 D3D10DDI_HDEVICE hDevice, // IN
1172 __in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView) // IN
1173 {
1174 return sizeof(ShaderResourceView);
1175 }
1176
1177
1178 /*
1179 * ----------------------------------------------------------------------
1180 *
1181 * CreateShaderResourceView --
1182 *
1183 * The CreateShaderResourceView function creates a shader
1184 * resource view.
1185 *
1186 * ----------------------------------------------------------------------
1187 */
1188
1189 void APIENTRY
CreateShaderResourceView(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATESHADERRESOURCEVIEW * pCreateSRView,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView)1190 CreateShaderResourceView(
1191 D3D10DDI_HDEVICE hDevice, // IN
1192 __in const D3D10DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView, // IN
1193 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
1194 D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView) // IN
1195 {
1196 LOG_ENTRYPOINT();
1197
1198 struct pipe_context *pipe = CastPipeContext(hDevice);
1199 ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
1200 struct pipe_resource *resource;
1201 enum pipe_format format;
1202
1203 struct pipe_sampler_view desc;
1204 memset(&desc, 0, sizeof desc);
1205 resource = CastPipeResource(pCreateSRView->hDrvResource);
1206 format = FormatTranslate(pCreateSRView->Format, false);
1207
1208 u_sampler_view_default_template(&desc,
1209 resource,
1210 format);
1211
1212 switch (pCreateSRView->ResourceDimension) {
1213 case D3D10DDIRESOURCE_BUFFER: {
1214 const struct util_format_description *fdesc = util_format_description(format);
1215 desc.u.buf.offset = pCreateSRView->Buffer.FirstElement *
1216 (fdesc->block.bits / 8) * fdesc->block.width;
1217 desc.u.buf.size = pCreateSRView->Buffer.NumElements *
1218 (fdesc->block.bits / 8) * fdesc->block.width;
1219 }
1220 break;
1221 case D3D10DDIRESOURCE_TEXTURE1D:
1222 desc.u.tex.first_level = pCreateSRView->Tex1D.MostDetailedMip;
1223 desc.u.tex.last_level = pCreateSRView->Tex1D.MipLevels - 1 + desc.u.tex.first_level;
1224 desc.u.tex.first_layer = pCreateSRView->Tex1D.FirstArraySlice;
1225 desc.u.tex.last_layer = pCreateSRView->Tex1D.ArraySize - 1 + desc.u.tex.first_layer;
1226 assert(pCreateSRView->Tex1D.MipLevels != 0 && pCreateSRView->Tex1D.MipLevels != (UINT)-1);
1227 assert(pCreateSRView->Tex1D.ArraySize != 0 && pCreateSRView->Tex1D.ArraySize != (UINT)-1);
1228 break;
1229 case D3D10DDIRESOURCE_TEXTURE2D:
1230 desc.u.tex.first_level = pCreateSRView->Tex2D.MostDetailedMip;
1231 desc.u.tex.last_level = pCreateSRView->Tex2D.MipLevels - 1 + desc.u.tex.first_level;
1232 desc.u.tex.first_layer = pCreateSRView->Tex2D.FirstArraySlice;
1233 desc.u.tex.last_layer = pCreateSRView->Tex2D.ArraySize - 1 + desc.u.tex.first_layer;
1234 assert(pCreateSRView->Tex2D.MipLevels != 0 && pCreateSRView->Tex2D.MipLevels != (UINT)-1);
1235 assert(pCreateSRView->Tex2D.ArraySize != 0 && pCreateSRView->Tex2D.ArraySize != (UINT)-1);
1236 break;
1237 case D3D10DDIRESOURCE_TEXTURE3D:
1238 desc.u.tex.first_level = pCreateSRView->Tex3D.MostDetailedMip;
1239 desc.u.tex.last_level = pCreateSRView->Tex3D.MipLevels - 1 + desc.u.tex.first_level;
1240 /* layer info filled in by default_template */
1241 assert(pCreateSRView->Tex3D.MipLevels != 0 && pCreateSRView->Tex3D.MipLevels != (UINT)-1);
1242 break;
1243 case D3D10DDIRESOURCE_TEXTURECUBE:
1244 desc.u.tex.first_level = pCreateSRView->TexCube.MostDetailedMip;
1245 desc.u.tex.last_level = pCreateSRView->TexCube.MipLevels - 1 + desc.u.tex.first_level;
1246 /* layer info filled in by default_template */
1247 assert(pCreateSRView->TexCube.MipLevels != 0 && pCreateSRView->TexCube.MipLevels != (UINT)-1);
1248 break;
1249 default:
1250 assert(0);
1251 return;
1252 }
1253
1254 pSRView->handle = pipe->create_sampler_view(pipe, resource, &desc);
1255 }
1256
1257
1258 /*
1259 * ----------------------------------------------------------------------
1260 *
1261 * CreateShaderResourceView1 --
1262 *
1263 * The CreateShaderResourceView function creates a shader
1264 * resource view.
1265 *
1266 * ----------------------------------------------------------------------
1267 */
1268
1269 void APIENTRY
CreateShaderResourceView1(D3D10DDI_HDEVICE hDevice,__in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW * pCreateSRView,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView)1270 CreateShaderResourceView1(
1271 D3D10DDI_HDEVICE hDevice, // IN
1272 __in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView, // IN
1273 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
1274 D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView) // IN
1275 {
1276 LOG_ENTRYPOINT();
1277
1278 struct pipe_context *pipe = CastPipeContext(hDevice);
1279 ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
1280 struct pipe_resource *resource;
1281 enum pipe_format format;
1282
1283 struct pipe_sampler_view desc;
1284 memset(&desc, 0, sizeof desc);
1285 resource = CastPipeResource(pCreateSRView->hDrvResource);
1286 format = FormatTranslate(pCreateSRView->Format, false);
1287
1288 u_sampler_view_default_template(&desc,
1289 resource,
1290 format);
1291
1292 switch (pCreateSRView->ResourceDimension) {
1293 case D3D10DDIRESOURCE_BUFFER: {
1294 const struct util_format_description *fdesc = util_format_description(format);
1295 desc.u.buf.offset = pCreateSRView->Buffer.FirstElement *
1296 (fdesc->block.bits / 8) * fdesc->block.width;
1297 desc.u.buf.size = pCreateSRView->Buffer.NumElements *
1298 (fdesc->block.bits / 8) * fdesc->block.width;
1299 }
1300 break;
1301 case D3D10DDIRESOURCE_TEXTURE1D:
1302 desc.u.tex.first_level = pCreateSRView->Tex1D.MostDetailedMip;
1303 desc.u.tex.last_level = pCreateSRView->Tex1D.MipLevels - 1 + desc.u.tex.first_level;
1304 desc.u.tex.first_layer = pCreateSRView->Tex1D.FirstArraySlice;
1305 desc.u.tex.last_layer = pCreateSRView->Tex1D.ArraySize - 1 + desc.u.tex.first_layer;
1306 assert(pCreateSRView->Tex1D.MipLevels != 0 && pCreateSRView->Tex1D.MipLevels != (UINT)-1);
1307 assert(pCreateSRView->Tex1D.ArraySize != 0 && pCreateSRView->Tex1D.ArraySize != (UINT)-1);
1308 break;
1309 case D3D10DDIRESOURCE_TEXTURE2D:
1310 desc.u.tex.first_level = pCreateSRView->Tex2D.MostDetailedMip;
1311 desc.u.tex.last_level = pCreateSRView->Tex2D.MipLevels - 1 + desc.u.tex.first_level;
1312 desc.u.tex.first_layer = pCreateSRView->Tex2D.FirstArraySlice;
1313 desc.u.tex.last_layer = pCreateSRView->Tex2D.ArraySize - 1 + desc.u.tex.first_layer;
1314 assert(pCreateSRView->Tex2D.MipLevels != 0 && pCreateSRView->Tex2D.MipLevels != (UINT)-1);
1315 assert(pCreateSRView->Tex2D.ArraySize != 0 && pCreateSRView->Tex2D.ArraySize != (UINT)-1);
1316 break;
1317 case D3D10DDIRESOURCE_TEXTURE3D:
1318 desc.u.tex.first_level = pCreateSRView->Tex3D.MostDetailedMip;
1319 desc.u.tex.last_level = pCreateSRView->Tex3D.MipLevels - 1 + desc.u.tex.first_level;
1320 /* layer info filled in by default_template */
1321 assert(pCreateSRView->Tex3D.MipLevels != 0 && pCreateSRView->Tex3D.MipLevels != (UINT)-1);
1322 break;
1323 case D3D10DDIRESOURCE_TEXTURECUBE:
1324 desc.u.tex.first_level = pCreateSRView->TexCube.MostDetailedMip;
1325 desc.u.tex.last_level = pCreateSRView->TexCube.MipLevels - 1 + desc.u.tex.first_level;
1326 desc.u.tex.first_layer = pCreateSRView->TexCube.First2DArrayFace;
1327 desc.u.tex.last_layer = 6*pCreateSRView->TexCube.NumCubes - 1 +
1328 pCreateSRView->TexCube.First2DArrayFace;
1329 assert(pCreateSRView->TexCube.MipLevels != 0 && pCreateSRView->TexCube.MipLevels != (UINT)-1);
1330 break;
1331 default:
1332 assert(0);
1333 return;
1334 }
1335
1336 pSRView->handle = pipe->create_sampler_view(pipe, resource, &desc);
1337 }
1338
1339
1340 /*
1341 * ----------------------------------------------------------------------
1342 *
1343 * DestroyShaderResourceView --
1344 *
1345 * The DestroyShaderResourceView function destroys the specified
1346 * shader resource view object. The shader resource view object
1347 * can be destoyed only if it is not currently bound to a
1348 * display device.
1349 *
1350 * ----------------------------------------------------------------------
1351 */
1352
1353 void APIENTRY
DestroyShaderResourceView(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView)1354 DestroyShaderResourceView(D3D10DDI_HDEVICE hDevice, // IN
1355 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView) // IN
1356 {
1357 LOG_ENTRYPOINT();
1358
1359 ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
1360
1361 pipe_sampler_view_reference(&pSRView->handle, NULL);
1362 }
1363
1364
1365 /*
1366 * ----------------------------------------------------------------------
1367 *
1368 * GenMips --
1369 *
1370 * The GenMips function generates the lower MIP-map levels
1371 * on the specified shader-resource view.
1372 *
1373 * ----------------------------------------------------------------------
1374 */
1375
1376 void APIENTRY
GenMips(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView)1377 GenMips(D3D10DDI_HDEVICE hDevice, // IN
1378 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView) // IN
1379 {
1380 LOG_ENTRYPOINT();
1381
1382 Device *pDevice = CastDevice(hDevice);
1383 if (!CheckPredicate(pDevice)) {
1384 return;
1385 }
1386
1387 struct pipe_context *pipe = pDevice->pipe;
1388 struct pipe_sampler_view *sampler_view = CastPipeShaderResourceView(hShaderResourceView);
1389
1390 util_gen_mipmap(pipe,
1391 sampler_view->texture,
1392 sampler_view->format,
1393 sampler_view->u.tex.first_level,
1394 sampler_view->u.tex.last_level,
1395 sampler_view->u.tex.first_layer,
1396 sampler_view->u.tex.last_layer,
1397 PIPE_TEX_FILTER_LINEAR);
1398 }
1399
1400
1401 unsigned
ShaderFindOutputMapping(Shader * shader,unsigned registerIndex)1402 ShaderFindOutputMapping(Shader *shader, unsigned registerIndex)
1403 {
1404 if (!shader || !shader->state.tokens)
1405 return registerIndex;
1406
1407 for (unsigned i = 0; i < PIPE_MAX_SHADER_OUTPUTS; ++i) {
1408 if (shader->output_mapping[i] == registerIndex)
1409 return i;
1410 }
1411 return registerIndex;
1412 }
1413