• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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