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, 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 state.normalized_coords = 1;
486
487 /* Level of detail. */
488 state.lod_bias = pSamplerDesc->MipLODBias;
489 state.min_lod = pSamplerDesc->MinLOD;
490 state.max_lod = pSamplerDesc->MaxLOD;
491
492 /* Border color. */
493 state.border_color.f[0] = pSamplerDesc->BorderColor[0];
494 state.border_color.f[1] = pSamplerDesc->BorderColor[1];
495 state.border_color.f[2] = pSamplerDesc->BorderColor[2];
496 state.border_color.f[3] = pSamplerDesc->BorderColor[3];
497
498 pSamplerState->handle = pipe->create_sampler_state(pipe, &state);
499 }
500
501
502 /*
503 * ----------------------------------------------------------------------
504 *
505 * DestroySampler --
506 *
507 * The DestroySampler function destroys the specified sampler object.
508 * The sampler object can be destoyed only if it is not currently
509 * bound to a display device.
510 *
511 * ----------------------------------------------------------------------
512 */
513
514 void APIENTRY
DestroySampler(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSAMPLER hSampler)515 DestroySampler(D3D10DDI_HDEVICE hDevice, // IN
516 D3D10DDI_HSAMPLER hSampler) // IN
517 {
518 LOG_ENTRYPOINT();
519
520 struct pipe_context *pipe = CastPipeContext(hDevice);
521 SamplerState *pSamplerState = CastSamplerState(hSampler);
522
523 pipe->delete_sampler_state(pipe, pSamplerState->handle);
524 }
525
526
527 /*
528 * ----------------------------------------------------------------------
529 *
530 * CreateVertexShader --
531 *
532 * The CreateVertexShader function creates a vertex shader.
533 *
534 * ----------------------------------------------------------------------
535 */
536
537 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)538 CreateVertexShader(D3D10DDI_HDEVICE hDevice, // IN
539 __in_ecount (pShaderCode[1]) const UINT *pCode, // IN
540 D3D10DDI_HSHADER hShader, // IN
541 D3D10DDI_HRTSHADER hRTShader, // IN
542 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
543 {
544 LOG_ENTRYPOINT();
545
546 struct pipe_context *pipe = CastPipeContext(hDevice);
547 Shader *pShader = CastShader(hShader);
548
549 pShader->type = PIPE_SHADER_VERTEX;
550 pShader->output_resolved = TRUE;
551
552 memset(&pShader->state, 0, sizeof pShader->state);
553 pShader->state.tokens = Shader_tgsi_translate(pCode, pShader->output_mapping);
554
555 pShader->handle = pipe->create_vs_state(pipe, &pShader->state);
556
557 }
558
559
560 /*
561 * ----------------------------------------------------------------------
562 *
563 * VsSetShader --
564 *
565 * The VsSetShader function sets the vertex shader code so that all
566 * of the subsequent drawing operations use that code.
567 *
568 * ----------------------------------------------------------------------
569 */
570
571 void APIENTRY
VsSetShader(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADER hShader)572 VsSetShader(D3D10DDI_HDEVICE hDevice, // IN
573 D3D10DDI_HSHADER hShader) // IN
574 {
575 LOG_ENTRYPOINT();
576
577 Device *pDevice = CastDevice(hDevice);
578 struct pipe_context *pipe = pDevice->pipe;
579 Shader *pShader = CastShader(hShader);
580 void *state = CastPipeShader(hShader);
581
582 pDevice->bound_vs = pShader;
583 if (!state) {
584 state = pDevice->empty_vs;
585 }
586
587 pipe->bind_vs_state(pipe, state);
588 }
589
590
591 /*
592 * ----------------------------------------------------------------------
593 *
594 * VsSetShaderResources --
595 *
596 * The VsSetShaderResources function sets resources for a
597 * vertex shader.
598 *
599 * ----------------------------------------------------------------------
600 */
601
602 void APIENTRY
VsSetShaderResources(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumViews,__in_ecount (NumViews)const D3D10DDI_HSHADERRESOURCEVIEW * phShaderResourceViews)603 VsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
604 UINT Offset, // IN
605 UINT NumViews, // IN
606 __in_ecount (NumViews)
607 const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
608 {
609 LOG_ENTRYPOINT();
610
611 SetShaderResources(PIPE_SHADER_VERTEX, hDevice, Offset, NumViews, phShaderResourceViews);
612
613 }
614
615
616 /*
617 * ----------------------------------------------------------------------
618 *
619 * VsSetConstantBuffers --
620 *
621 * The VsSetConstantBuffers function sets constant buffers
622 * for a vertex shader.
623 *
624 * ----------------------------------------------------------------------
625 */
626
627 void APIENTRY
VsSetConstantBuffers(D3D10DDI_HDEVICE hDevice,UINT StartBuffer,UINT NumBuffers,__in_ecount (NumBuffers)const D3D10DDI_HRESOURCE * phBuffers)628 VsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
629 UINT StartBuffer, // IN
630 UINT NumBuffers, // IN
631 __in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
632 {
633 LOG_ENTRYPOINT();
634
635 SetConstantBuffers(PIPE_SHADER_VERTEX,
636 hDevice, StartBuffer, NumBuffers, phBuffers);
637 }
638
639
640 /*
641 * ----------------------------------------------------------------------
642 *
643 * VsSetSamplers --
644 *
645 * The VsSetSamplers function sets samplers for a vertex shader.
646 *
647 * ----------------------------------------------------------------------
648 */
649
650 void APIENTRY
VsSetSamplers(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumSamplers,__in_ecount (NumSamplers)const D3D10DDI_HSAMPLER * phSamplers)651 VsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
652 UINT Offset, // IN
653 UINT NumSamplers, // IN
654 __in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
655 {
656 LOG_ENTRYPOINT();
657
658 SetSamplers(PIPE_SHADER_VERTEX, hDevice, Offset, NumSamplers, phSamplers);
659
660 }
661
662
663 /*
664 * ----------------------------------------------------------------------
665 *
666 * CreateGeometryShader --
667 *
668 * The CreateGeometryShader function creates a geometry shader.
669 *
670 * ----------------------------------------------------------------------
671 */
672
673 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)674 CreateGeometryShader(D3D10DDI_HDEVICE hDevice, // IN
675 __in_ecount (pShaderCode[1]) const UINT *pShaderCode, // IN
676 D3D10DDI_HSHADER hShader, // IN
677 D3D10DDI_HRTSHADER hRTShader, // IN
678 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
679 {
680 LOG_ENTRYPOINT();
681
682 struct pipe_context *pipe = CastPipeContext(hDevice);
683 Shader *pShader = CastShader(hShader);
684
685 pShader->type = PIPE_SHADER_GEOMETRY;
686 pShader->output_resolved = TRUE;
687
688 memset(&pShader->state, 0, sizeof pShader->state);
689 pShader->state.tokens = Shader_tgsi_translate(pShaderCode, pShader->output_mapping);
690
691 pShader->handle = pipe->create_gs_state(pipe, &pShader->state);
692 }
693
694
695 /*
696 * ----------------------------------------------------------------------
697 *
698 * GsSetShader --
699 *
700 * The GsSetShader function sets the geometry shader code so that
701 * all of the subsequent drawing operations use that code.
702 *
703 * ----------------------------------------------------------------------
704 */
705
706 void APIENTRY
GsSetShader(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADER hShader)707 GsSetShader(D3D10DDI_HDEVICE hDevice, // IN
708 D3D10DDI_HSHADER hShader) // IN
709 {
710 LOG_ENTRYPOINT();
711
712 Device *pDevice = CastDevice(hDevice);
713 struct pipe_context *pipe = CastPipeContext(hDevice);
714 void *state = CastPipeShader(hShader);
715 Shader *pShader = CastShader(hShader);
716
717 assert(pipe->bind_gs_state);
718
719 if (pShader && !pShader->state.tokens) {
720 pDevice->bound_empty_gs = pShader;
721 } else {
722 pDevice->bound_empty_gs = NULL;
723 pipe->bind_gs_state(pipe, state);
724 }
725 }
726
727
728 /*
729 * ----------------------------------------------------------------------
730 *
731 * GsSetShaderResources --
732 *
733 * The GsSetShaderResources function sets resources for a
734 * geometry shader.
735 *
736 * ----------------------------------------------------------------------
737 */
738
739 void APIENTRY
GsSetShaderResources(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumViews,__in_ecount (NumViews)const D3D10DDI_HSHADERRESOURCEVIEW * phShaderResourceViews)740 GsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
741 UINT Offset, // IN
742 UINT NumViews, // IN
743 __in_ecount (NumViews)
744 const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
745 {
746 LOG_ENTRYPOINT();
747
748 SetShaderResources(PIPE_SHADER_GEOMETRY, hDevice, Offset, NumViews, phShaderResourceViews);
749 }
750
751
752 /*
753 * ----------------------------------------------------------------------
754 *
755 * GsSetConstantBuffers --
756 *
757 * The GsSetConstantBuffers function sets constant buffers for
758 * a geometry shader.
759 *
760 * ----------------------------------------------------------------------
761 */
762
763 void APIENTRY
GsSetConstantBuffers(D3D10DDI_HDEVICE hDevice,UINT StartBuffer,UINT NumBuffers,__in_ecount (NumBuffers)const D3D10DDI_HRESOURCE * phBuffers)764 GsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
765 UINT StartBuffer, // IN
766 UINT NumBuffers, // IN
767 __in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
768 {
769 LOG_ENTRYPOINT();
770
771 SetConstantBuffers(PIPE_SHADER_GEOMETRY,
772 hDevice, StartBuffer, NumBuffers, phBuffers);
773 }
774
775
776 /*
777 * ----------------------------------------------------------------------
778 *
779 * GsSetSamplers --
780 *
781 * The GsSetSamplers function sets samplers for a geometry shader.
782 *
783 * ----------------------------------------------------------------------
784 */
785
786 void APIENTRY
GsSetSamplers(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumSamplers,__in_ecount (NumSamplers)const D3D10DDI_HSAMPLER * phSamplers)787 GsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
788 UINT Offset, // IN
789 UINT NumSamplers, // IN
790 __in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
791 {
792 LOG_ENTRYPOINT();
793
794 SetSamplers(PIPE_SHADER_GEOMETRY, hDevice, Offset, NumSamplers, phSamplers);
795 }
796
797
798 /*
799 * ----------------------------------------------------------------------
800 *
801 * CalcPrivateGeometryShaderWithStreamOutput --
802 *
803 * The CalcPrivateGeometryShaderWithStreamOutput function determines
804 * the size of the user-mode display driver's private region of memory
805 * (that is, the size of internal driver structures, not the size of
806 * the resource video memory) for a geometry shader with stream output.
807 *
808 * ----------------------------------------------------------------------
809 */
810
811 SIZE_T APIENTRY
CalcPrivateGeometryShaderWithStreamOutput(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT * pCreateGeometryShaderWithStreamOutput,__in const D3D10DDIARG_STAGE_IO_SIGNATURES * pSignatures)812 CalcPrivateGeometryShaderWithStreamOutput(
813 D3D10DDI_HDEVICE hDevice, // IN
814 __in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT *pCreateGeometryShaderWithStreamOutput, // IN
815 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
816 {
817 LOG_ENTRYPOINT();
818 return sizeof(Shader);
819 }
820
821
822 /*
823 * ----------------------------------------------------------------------
824 *
825 * CreateGeometryShaderWithStreamOutput --
826 *
827 * The CreateGeometryShaderWithStreamOutput function creates a
828 * geometry shader with stream output.
829 *
830 * ----------------------------------------------------------------------
831 */
832
833 void APIENTRY
CreateGeometryShaderWithStreamOutput(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT * pData,D3D10DDI_HSHADER hShader,D3D10DDI_HRTSHADER hRTShader,__in const D3D10DDIARG_STAGE_IO_SIGNATURES * pSignatures)834 CreateGeometryShaderWithStreamOutput(
835 D3D10DDI_HDEVICE hDevice, // IN
836 __in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT *pData, // IN
837 D3D10DDI_HSHADER hShader, // IN
838 D3D10DDI_HRTSHADER hRTShader, // IN
839 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
840 {
841 LOG_ENTRYPOINT();
842
843 struct pipe_context *pipe = CastPipeContext(hDevice);
844 Shader *pShader = CastShader(hShader);
845 int total_components[PIPE_MAX_SO_BUFFERS] = {0};
846 unsigned num_holes = 0;
847 boolean all_slot_zero = TRUE;
848
849 pShader->type = PIPE_SHADER_GEOMETRY;
850
851 memset(&pShader->state, 0, sizeof pShader->state);
852 if (pData->pShaderCode) {
853 pShader->state.tokens = Shader_tgsi_translate(pData->pShaderCode,
854 pShader->output_mapping);
855 }
856 pShader->output_resolved = (pShader->state.tokens != NULL);
857
858 for (unsigned i = 0; i < pData->NumEntries; ++i) {
859 CONST D3D10DDIARG_STREAM_OUTPUT_DECLARATION_ENTRY* pOutputStreamDecl =
860 &pData->pOutputStreamDecl[i];
861 BYTE RegisterMask = pOutputStreamDecl->RegisterMask;
862 unsigned start_component = 0;
863 unsigned num_components = 0;
864 if (RegisterMask) {
865 while ((RegisterMask & 1) == 0) {
866 ++start_component;
867 RegisterMask >>= 1;
868 }
869 while (RegisterMask) {
870 ++num_components;
871 RegisterMask >>= 1;
872 }
873 assert(start_component < 4);
874 assert(1 <= num_components && num_components <= 4);
875 LOG_UNSUPPORTED(((1 << num_components) - 1) << start_component !=
876 pOutputStreamDecl->RegisterMask);
877 }
878
879 if (pOutputStreamDecl->RegisterIndex == 0xffffffff) {
880 ++num_holes;
881 } else {
882 unsigned idx = i - num_holes;
883 pShader->state.stream_output.output[idx].start_component =
884 start_component;
885 pShader->state.stream_output.output[idx].num_components =
886 num_components;
887 pShader->state.stream_output.output[idx].output_buffer =
888 pOutputStreamDecl->OutputSlot;
889 pShader->state.stream_output.output[idx].register_index =
890 ShaderFindOutputMapping(pShader, pOutputStreamDecl->RegisterIndex);
891 pShader->state.stream_output.output[idx].dst_offset =
892 total_components[pOutputStreamDecl->OutputSlot];
893 if (pOutputStreamDecl->OutputSlot != 0)
894 all_slot_zero = FALSE;
895 }
896 total_components[pOutputStreamDecl->OutputSlot] += num_components;
897 }
898 pShader->state.stream_output.num_outputs = pData->NumEntries - num_holes;
899 for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; ++i) {
900 /* stream_output.stride[i] is in dwords */
901 if (all_slot_zero) {
902 pShader->state.stream_output.stride[i] =
903 pData->StreamOutputStrideInBytes / sizeof(float);
904 } else {
905 pShader->state.stream_output.stride[i] = total_components[i];
906 }
907 }
908
909 pShader->handle = pipe->create_gs_state(pipe, &pShader->state);
910 }
911
912
913 /*
914 * ----------------------------------------------------------------------
915 *
916 * SoSetTargets --
917 *
918 * The SoSetTargets function sets stream output target resources.
919 *
920 * ----------------------------------------------------------------------
921 */
922
923 void APIENTRY
SoSetTargets(D3D10DDI_HDEVICE hDevice,UINT SOTargets,UINT ClearTargets,__in_ecount (SOTargets)const D3D10DDI_HRESOURCE * phResource,__in_ecount (SOTargets)const UINT * pOffsets)924 SoSetTargets(D3D10DDI_HDEVICE hDevice, // IN
925 UINT SOTargets, // IN
926 UINT ClearTargets, // IN
927 __in_ecount (SOTargets) const D3D10DDI_HRESOURCE *phResource, // IN
928 __in_ecount (SOTargets) const UINT *pOffsets) // IN
929 {
930 unsigned i;
931
932 LOG_ENTRYPOINT();
933
934 Device *pDevice = CastDevice(hDevice);
935 struct pipe_context *pipe = pDevice->pipe;
936
937 assert(SOTargets + ClearTargets <= PIPE_MAX_SO_BUFFERS);
938
939 for (i = 0; i < SOTargets; ++i) {
940 Resource *resource = CastResource(phResource[i]);
941 struct pipe_resource *buffer = CastPipeResource(phResource[i]);
942 struct pipe_stream_output_target *so_target =
943 resource ? resource->so_target : NULL;
944
945 if (buffer) {
946 unsigned buffer_size = buffer->width0;
947
948 if (!so_target ||
949 so_target->buffer != buffer ||
950 so_target->buffer_size != buffer_size) {
951 if (so_target) {
952 pipe_so_target_reference(&so_target, NULL);
953 }
954 so_target = pipe->create_stream_output_target(pipe, buffer,
955 0,/*buffer offset*/
956 buffer_size);
957 resource->so_target = so_target;
958 }
959 }
960 pDevice->so_targets[i] = so_target;
961 }
962
963 for (i = 0; i < ClearTargets; ++i) {
964 pDevice->so_targets[SOTargets + i] = NULL;
965 }
966
967 if (!pipe->set_stream_output_targets) {
968 LOG_UNSUPPORTED(pipe->set_stream_output_targets);
969 return;
970 }
971
972 pipe->set_stream_output_targets(pipe, SOTargets, pDevice->so_targets,
973 pOffsets);
974 }
975
976
977 /*
978 * ----------------------------------------------------------------------
979 *
980 * CreatePixelShader --
981 *
982 * The CreatePixelShader function converts pixel shader code into a
983 * hardware-specific format and associates this code with a
984 * shader handle.
985 *
986 * ----------------------------------------------------------------------
987 */
988
989 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)990 CreatePixelShader(D3D10DDI_HDEVICE hDevice, // IN
991 __in_ecount (pShaderCode[1]) const UINT *pShaderCode, // IN
992 D3D10DDI_HSHADER hShader, // IN
993 D3D10DDI_HRTSHADER hRTShader, // IN
994 __in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
995 {
996 LOG_ENTRYPOINT();
997
998 struct pipe_context *pipe = CastPipeContext(hDevice);
999 Shader *pShader = CastShader(hShader);
1000
1001 pShader->type = PIPE_SHADER_FRAGMENT;
1002 pShader->output_resolved = TRUE;
1003
1004 memset(&pShader->state, 0, sizeof pShader->state);
1005 pShader->state.tokens = Shader_tgsi_translate(pShaderCode,
1006 pShader->output_mapping);
1007
1008 pShader->handle = pipe->create_fs_state(pipe, &pShader->state);
1009
1010 }
1011
1012
1013 /*
1014 * ----------------------------------------------------------------------
1015 *
1016 * PsSetShader --
1017 *
1018 * The PsSetShader function sets a pixel shader to be used
1019 * in all drawing operations.
1020 *
1021 * ----------------------------------------------------------------------
1022 */
1023
1024 void APIENTRY
PsSetShader(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADER hShader)1025 PsSetShader(D3D10DDI_HDEVICE hDevice, // IN
1026 D3D10DDI_HSHADER hShader) // IN
1027 {
1028 LOG_ENTRYPOINT();
1029
1030 Device *pDevice = CastDevice(hDevice);
1031 struct pipe_context *pipe = pDevice->pipe;
1032 void *state = CastPipeShader(hShader);
1033
1034 if (!state) {
1035 state = pDevice->empty_fs;
1036 }
1037
1038 pipe->bind_fs_state(pipe, state);
1039 }
1040
1041
1042 /*
1043 * ----------------------------------------------------------------------
1044 *
1045 * PsSetShaderResources --
1046 *
1047 * The PsSetShaderResources function sets resources for a pixel shader.
1048 *
1049 * ----------------------------------------------------------------------
1050 */
1051
1052 void APIENTRY
PsSetShaderResources(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumViews,__in_ecount (NumViews)const D3D10DDI_HSHADERRESOURCEVIEW * phShaderResourceViews)1053 PsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
1054 UINT Offset, // IN
1055 UINT NumViews, // IN
1056 __in_ecount (NumViews)
1057 const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
1058 {
1059 LOG_ENTRYPOINT();
1060
1061 SetShaderResources(PIPE_SHADER_FRAGMENT, hDevice, Offset, NumViews, phShaderResourceViews);
1062 }
1063
1064
1065 /*
1066 * ----------------------------------------------------------------------
1067 *
1068 * PsSetConstantBuffers --
1069 *
1070 * The PsSetConstantBuffers function sets constant buffers for
1071 * a pixel shader.
1072 *
1073 * ----------------------------------------------------------------------
1074 */
1075
1076 void APIENTRY
PsSetConstantBuffers(D3D10DDI_HDEVICE hDevice,UINT StartBuffer,UINT NumBuffers,__in_ecount (NumBuffers)const D3D10DDI_HRESOURCE * phBuffers)1077 PsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
1078 UINT StartBuffer, // IN
1079 UINT NumBuffers, // IN
1080 __in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
1081 {
1082 LOG_ENTRYPOINT();
1083
1084 SetConstantBuffers(PIPE_SHADER_FRAGMENT,
1085 hDevice, StartBuffer, NumBuffers, phBuffers);
1086 }
1087
1088 /*
1089 * ----------------------------------------------------------------------
1090 *
1091 * PsSetSamplers --
1092 *
1093 * The PsSetSamplers function sets samplers for a pixel shader.
1094 *
1095 * ----------------------------------------------------------------------
1096 */
1097
1098 void APIENTRY
PsSetSamplers(D3D10DDI_HDEVICE hDevice,UINT Offset,UINT NumSamplers,__in_ecount (NumSamplers)const D3D10DDI_HSAMPLER * phSamplers)1099 PsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
1100 UINT Offset, // IN
1101 UINT NumSamplers, // IN
1102 __in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
1103 {
1104 LOG_ENTRYPOINT();
1105
1106 SetSamplers(PIPE_SHADER_FRAGMENT, hDevice, Offset, NumSamplers, phSamplers);
1107 }
1108
1109
1110 /*
1111 * ----------------------------------------------------------------------
1112 *
1113 * ShaderResourceViewReadAfterWriteHazard --
1114 *
1115 * The ShaderResourceViewReadAfterWriteHazard function informs
1116 * the usermode display driver that the specified resource was
1117 * used as an output from the graphics processing unit (GPU)
1118 * and that the resource will be used as an input to the GPU.
1119 * A shader resource view is also provided to indicate which
1120 * view caused the hazard.
1121 *
1122 * ----------------------------------------------------------------------
1123 */
1124
1125 void APIENTRY
ShaderResourceViewReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,D3D10DDI_HRESOURCE hResource)1126 ShaderResourceViewReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice, // IN
1127 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
1128 D3D10DDI_HRESOURCE hResource) // IN
1129 {
1130 LOG_ENTRYPOINT();
1131
1132 /* Not actually necessary */
1133 }
1134
1135
1136 /*
1137 * ----------------------------------------------------------------------
1138 *
1139 * CalcPrivateShaderResourceViewSize --
1140 *
1141 * The CalcPrivateShaderResourceViewSize function determines the size
1142 * of the usermode display driver's private region of memory
1143 * (that is, the size of internal driver structures, not the size of
1144 * the resource video memory) for a shader resource view.
1145 *
1146 * ----------------------------------------------------------------------
1147 */
1148
1149 SIZE_T APIENTRY
CalcPrivateShaderResourceViewSize(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATESHADERRESOURCEVIEW * pCreateSRView)1150 CalcPrivateShaderResourceViewSize(
1151 D3D10DDI_HDEVICE hDevice, // IN
1152 __in const D3D10DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView) // IN
1153 {
1154 return sizeof(ShaderResourceView);
1155 }
1156
1157
1158 /*
1159 * ----------------------------------------------------------------------
1160 *
1161 * CalcPrivateShaderResourceViewSize --
1162 *
1163 * The CalcPrivateShaderResourceViewSize function determines the size
1164 * of the usermode display driver's private region of memory
1165 * (that is, the size of internal driver structures, not the size of
1166 * the resource video memory) for a shader resource view.
1167 *
1168 * ----------------------------------------------------------------------
1169 */
1170
1171 SIZE_T APIENTRY
CalcPrivateShaderResourceViewSize1(D3D10DDI_HDEVICE hDevice,__in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW * pCreateSRView)1172 CalcPrivateShaderResourceViewSize1(
1173 D3D10DDI_HDEVICE hDevice, // IN
1174 __in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView) // IN
1175 {
1176 return sizeof(ShaderResourceView);
1177 }
1178
1179
1180 /*
1181 * ----------------------------------------------------------------------
1182 *
1183 * CreateShaderResourceView --
1184 *
1185 * The CreateShaderResourceView function creates a shader
1186 * resource view.
1187 *
1188 * ----------------------------------------------------------------------
1189 */
1190
1191 void APIENTRY
CreateShaderResourceView(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATESHADERRESOURCEVIEW * pCreateSRView,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView)1192 CreateShaderResourceView(
1193 D3D10DDI_HDEVICE hDevice, // IN
1194 __in const D3D10DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView, // IN
1195 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
1196 D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView) // IN
1197 {
1198 LOG_ENTRYPOINT();
1199
1200 struct pipe_context *pipe = CastPipeContext(hDevice);
1201 ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
1202 struct pipe_resource *resource;
1203 enum pipe_format format;
1204
1205 struct pipe_sampler_view desc;
1206 memset(&desc, 0, sizeof desc);
1207 resource = CastPipeResource(pCreateSRView->hDrvResource);
1208 format = FormatTranslate(pCreateSRView->Format, FALSE);
1209
1210 u_sampler_view_default_template(&desc,
1211 resource,
1212 format);
1213
1214 switch (pCreateSRView->ResourceDimension) {
1215 case D3D10DDIRESOURCE_BUFFER: {
1216 const struct util_format_description *fdesc = util_format_description(format);
1217 desc.u.buf.offset = pCreateSRView->Buffer.FirstElement *
1218 (fdesc->block.bits / 8) * fdesc->block.width;
1219 desc.u.buf.size = pCreateSRView->Buffer.NumElements *
1220 (fdesc->block.bits / 8) * fdesc->block.width;
1221 }
1222 break;
1223 case D3D10DDIRESOURCE_TEXTURE1D:
1224 desc.u.tex.first_level = pCreateSRView->Tex1D.MostDetailedMip;
1225 desc.u.tex.last_level = pCreateSRView->Tex1D.MipLevels - 1 + desc.u.tex.first_level;
1226 desc.u.tex.first_layer = pCreateSRView->Tex1D.FirstArraySlice;
1227 desc.u.tex.last_layer = pCreateSRView->Tex1D.ArraySize - 1 + desc.u.tex.first_layer;
1228 assert(pCreateSRView->Tex1D.MipLevels != 0 && pCreateSRView->Tex1D.MipLevels != (UINT)-1);
1229 assert(pCreateSRView->Tex1D.ArraySize != 0 && pCreateSRView->Tex1D.ArraySize != (UINT)-1);
1230 break;
1231 case D3D10DDIRESOURCE_TEXTURE2D:
1232 desc.u.tex.first_level = pCreateSRView->Tex2D.MostDetailedMip;
1233 desc.u.tex.last_level = pCreateSRView->Tex2D.MipLevels - 1 + desc.u.tex.first_level;
1234 desc.u.tex.first_layer = pCreateSRView->Tex2D.FirstArraySlice;
1235 desc.u.tex.last_layer = pCreateSRView->Tex2D.ArraySize - 1 + desc.u.tex.first_layer;
1236 assert(pCreateSRView->Tex2D.MipLevels != 0 && pCreateSRView->Tex2D.MipLevels != (UINT)-1);
1237 assert(pCreateSRView->Tex2D.ArraySize != 0 && pCreateSRView->Tex2D.ArraySize != (UINT)-1);
1238 break;
1239 case D3D10DDIRESOURCE_TEXTURE3D:
1240 desc.u.tex.first_level = pCreateSRView->Tex3D.MostDetailedMip;
1241 desc.u.tex.last_level = pCreateSRView->Tex3D.MipLevels - 1 + desc.u.tex.first_level;
1242 /* layer info filled in by default_template */
1243 assert(pCreateSRView->Tex3D.MipLevels != 0 && pCreateSRView->Tex3D.MipLevels != (UINT)-1);
1244 break;
1245 case D3D10DDIRESOURCE_TEXTURECUBE:
1246 desc.u.tex.first_level = pCreateSRView->TexCube.MostDetailedMip;
1247 desc.u.tex.last_level = pCreateSRView->TexCube.MipLevels - 1 + desc.u.tex.first_level;
1248 /* layer info filled in by default_template */
1249 assert(pCreateSRView->TexCube.MipLevels != 0 && pCreateSRView->TexCube.MipLevels != (UINT)-1);
1250 break;
1251 default:
1252 assert(0);
1253 return;
1254 }
1255
1256 pSRView->handle = pipe->create_sampler_view(pipe, resource, &desc);
1257 }
1258
1259
1260 /*
1261 * ----------------------------------------------------------------------
1262 *
1263 * CreateShaderResourceView1 --
1264 *
1265 * The CreateShaderResourceView function creates a shader
1266 * resource view.
1267 *
1268 * ----------------------------------------------------------------------
1269 */
1270
1271 void APIENTRY
CreateShaderResourceView1(D3D10DDI_HDEVICE hDevice,__in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW * pCreateSRView,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView)1272 CreateShaderResourceView1(
1273 D3D10DDI_HDEVICE hDevice, // IN
1274 __in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView, // IN
1275 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
1276 D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView) // IN
1277 {
1278 LOG_ENTRYPOINT();
1279
1280 struct pipe_context *pipe = CastPipeContext(hDevice);
1281 ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
1282 struct pipe_resource *resource;
1283 enum pipe_format format;
1284
1285 struct pipe_sampler_view desc;
1286 memset(&desc, 0, sizeof desc);
1287 resource = CastPipeResource(pCreateSRView->hDrvResource);
1288 format = FormatTranslate(pCreateSRView->Format, FALSE);
1289
1290 u_sampler_view_default_template(&desc,
1291 resource,
1292 format);
1293
1294 switch (pCreateSRView->ResourceDimension) {
1295 case D3D10DDIRESOURCE_BUFFER: {
1296 const struct util_format_description *fdesc = util_format_description(format);
1297 desc.u.buf.offset = pCreateSRView->Buffer.FirstElement *
1298 (fdesc->block.bits / 8) * fdesc->block.width;
1299 desc.u.buf.size = pCreateSRView->Buffer.NumElements *
1300 (fdesc->block.bits / 8) * fdesc->block.width;
1301 }
1302 break;
1303 case D3D10DDIRESOURCE_TEXTURE1D:
1304 desc.u.tex.first_level = pCreateSRView->Tex1D.MostDetailedMip;
1305 desc.u.tex.last_level = pCreateSRView->Tex1D.MipLevels - 1 + desc.u.tex.first_level;
1306 desc.u.tex.first_layer = pCreateSRView->Tex1D.FirstArraySlice;
1307 desc.u.tex.last_layer = pCreateSRView->Tex1D.ArraySize - 1 + desc.u.tex.first_layer;
1308 assert(pCreateSRView->Tex1D.MipLevels != 0 && pCreateSRView->Tex1D.MipLevels != (UINT)-1);
1309 assert(pCreateSRView->Tex1D.ArraySize != 0 && pCreateSRView->Tex1D.ArraySize != (UINT)-1);
1310 break;
1311 case D3D10DDIRESOURCE_TEXTURE2D:
1312 desc.u.tex.first_level = pCreateSRView->Tex2D.MostDetailedMip;
1313 desc.u.tex.last_level = pCreateSRView->Tex2D.MipLevels - 1 + desc.u.tex.first_level;
1314 desc.u.tex.first_layer = pCreateSRView->Tex2D.FirstArraySlice;
1315 desc.u.tex.last_layer = pCreateSRView->Tex2D.ArraySize - 1 + desc.u.tex.first_layer;
1316 assert(pCreateSRView->Tex2D.MipLevels != 0 && pCreateSRView->Tex2D.MipLevels != (UINT)-1);
1317 assert(pCreateSRView->Tex2D.ArraySize != 0 && pCreateSRView->Tex2D.ArraySize != (UINT)-1);
1318 break;
1319 case D3D10DDIRESOURCE_TEXTURE3D:
1320 desc.u.tex.first_level = pCreateSRView->Tex3D.MostDetailedMip;
1321 desc.u.tex.last_level = pCreateSRView->Tex3D.MipLevels - 1 + desc.u.tex.first_level;
1322 /* layer info filled in by default_template */
1323 assert(pCreateSRView->Tex3D.MipLevels != 0 && pCreateSRView->Tex3D.MipLevels != (UINT)-1);
1324 break;
1325 case D3D10DDIRESOURCE_TEXTURECUBE:
1326 desc.u.tex.first_level = pCreateSRView->TexCube.MostDetailedMip;
1327 desc.u.tex.last_level = pCreateSRView->TexCube.MipLevels - 1 + desc.u.tex.first_level;
1328 desc.u.tex.first_layer = pCreateSRView->TexCube.First2DArrayFace;
1329 desc.u.tex.last_layer = 6*pCreateSRView->TexCube.NumCubes - 1 +
1330 pCreateSRView->TexCube.First2DArrayFace;
1331 assert(pCreateSRView->TexCube.MipLevels != 0 && pCreateSRView->TexCube.MipLevels != (UINT)-1);
1332 break;
1333 default:
1334 assert(0);
1335 return;
1336 }
1337
1338 pSRView->handle = pipe->create_sampler_view(pipe, resource, &desc);
1339 }
1340
1341
1342 /*
1343 * ----------------------------------------------------------------------
1344 *
1345 * DestroyShaderResourceView --
1346 *
1347 * The DestroyShaderResourceView function destroys the specified
1348 * shader resource view object. The shader resource view object
1349 * can be destoyed only if it is not currently bound to a
1350 * display device.
1351 *
1352 * ----------------------------------------------------------------------
1353 */
1354
1355 void APIENTRY
DestroyShaderResourceView(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView)1356 DestroyShaderResourceView(D3D10DDI_HDEVICE hDevice, // IN
1357 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView) // IN
1358 {
1359 LOG_ENTRYPOINT();
1360
1361 ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
1362
1363 pipe_sampler_view_reference(&pSRView->handle, NULL);
1364 }
1365
1366
1367 /*
1368 * ----------------------------------------------------------------------
1369 *
1370 * GenMips --
1371 *
1372 * The GenMips function generates the lower MIP-map levels
1373 * on the specified shader-resource view.
1374 *
1375 * ----------------------------------------------------------------------
1376 */
1377
1378 void APIENTRY
GenMips(D3D10DDI_HDEVICE hDevice,D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView)1379 GenMips(D3D10DDI_HDEVICE hDevice, // IN
1380 D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView) // IN
1381 {
1382 LOG_ENTRYPOINT();
1383
1384 Device *pDevice = CastDevice(hDevice);
1385 if (!CheckPredicate(pDevice)) {
1386 return;
1387 }
1388
1389 struct pipe_context *pipe = pDevice->pipe;
1390 struct pipe_sampler_view *sampler_view = CastPipeShaderResourceView(hShaderResourceView);
1391
1392 util_gen_mipmap(pipe,
1393 sampler_view->texture,
1394 sampler_view->format,
1395 sampler_view->u.tex.first_level,
1396 sampler_view->u.tex.last_level,
1397 sampler_view->u.tex.first_layer,
1398 sampler_view->u.tex.last_layer,
1399 PIPE_TEX_FILTER_LINEAR);
1400 }
1401
1402
1403 unsigned
ShaderFindOutputMapping(Shader * shader,unsigned registerIndex)1404 ShaderFindOutputMapping(Shader *shader, unsigned registerIndex)
1405 {
1406 if (!shader || !shader->state.tokens)
1407 return registerIndex;
1408
1409 for (unsigned i = 0; i < PIPE_MAX_SHADER_OUTPUTS; ++i) {
1410 if (shader->output_mapping[i] == registerIndex)
1411 return i;
1412 }
1413 return registerIndex;
1414 }
1415