xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/d3d10umd/Shader.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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