Home | History | Annotate | Line # | Download | only in d3d10umd
      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 *
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    405 translate_min_filter(D3D10_DDI_FILTER Filter)
    406 {
    407    return translate_filter(D3D10_DDI_DECODE_MIN_FILTER(Filter));
    408 }
    409 
    410 static uint
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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