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 58void * 59CreateEmptyShader(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 120void 121DeleteEmptyShader(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 158static void 159SetConstantBuffers(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 193static void 194SetSamplers(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 223static void 224SetShaderResources(enum pipe_shader_type shader_type, // IN 225 D3D10DDI_HDEVICE hDevice, // IN 226 UINT Offset, // IN 227 UINT NumViews, // IN 228 const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN 229{ 230 Device *pDevice = CastDevice(hDevice); 231 struct pipe_context *pipe = pDevice->pipe; 232 233 assert(Offset + NumViews <= D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT); 234 235 struct pipe_sampler_view **sampler_views = pDevice->sampler_views[shader_type]; 236 for (UINT i = 0; i < NumViews; i++) { 237 struct pipe_sampler_view *sampler_view = 238 CastPipeShaderResourceView(phShaderResourceViews[i]); 239 if (Offset + i < PIPE_MAX_SHADER_SAMPLER_VIEWS) { 240 sampler_views[Offset + i] = sampler_view; 241 } else { 242 if (sampler_view) { 243 LOG_UNSUPPORTED(TRUE); 244 break; 245 } 246 } 247 } 248 249 /* 250 * XXX: Now that the semantics are actually the same in gallium, should 251 * probably think about not updating all always... It should just work. 252 */ 253 pipe->set_sampler_views(pipe, shader_type, 0, PIPE_MAX_SHADER_SAMPLER_VIEWS, 254 0, false, sampler_views); 255} 256 257 258/* 259 * ---------------------------------------------------------------------- 260 * 261 * CalcPrivateShaderSize -- 262 * 263 * The CalcPrivateShaderSize function determines the size of 264 * the user-mode display driver's private region of memory 265 * (that is, the size of internal driver structures, not the 266 * size of the resource video memory) for a shader. 267 * 268 * ---------------------------------------------------------------------- 269 */ 270 271SIZE_T APIENTRY 272CalcPrivateShaderSize(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 292void APIENTRY 293DestroyShader(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 336SIZE_T APIENTRY 337CalcPrivateSamplerSize(D3D10DDI_HDEVICE hDevice, // IN 338 __in const D3D10_DDI_SAMPLER_DESC *pSamplerDesc) // IN 339{ 340 return sizeof(SamplerState); 341} 342 343 344static uint 345translate_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 364static uint 365translate_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 390static uint 391translate_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 404static uint 405translate_min_filter(D3D10_DDI_FILTER Filter) 406{ 407 return translate_filter(D3D10_DDI_DECODE_MIN_FILTER(Filter)); 408} 409 410static uint 411translate_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 */ 419static uint 420translate_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 443void APIENTRY 444CreateSampler(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 514void APIENTRY 515DestroySampler(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 537void APIENTRY 538CreateVertexShader(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 571void APIENTRY 572VsSetShader(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 602void APIENTRY 603VsSetShaderResources(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 627void APIENTRY 628VsSetConstantBuffers(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 650void APIENTRY 651VsSetSamplers(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 673void APIENTRY 674CreateGeometryShader(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 706void APIENTRY 707GsSetShader(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 739void APIENTRY 740GsSetShaderResources(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 763void APIENTRY 764GsSetConstantBuffers(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 786void APIENTRY 787GsSetSamplers(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 811SIZE_T APIENTRY 812CalcPrivateGeometryShaderWithStreamOutput( 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 833void APIENTRY 834CreateGeometryShaderWithStreamOutput( 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 923void APIENTRY 924SoSetTargets(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 989void APIENTRY 990CreatePixelShader(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 1024void APIENTRY 1025PsSetShader(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 1052void APIENTRY 1053PsSetShaderResources(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 1076void APIENTRY 1077PsSetConstantBuffers(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 1098void APIENTRY 1099PsSetSamplers(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 1125void APIENTRY 1126ShaderResourceViewReadAfterWriteHazard(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 1149SIZE_T APIENTRY 1150CalcPrivateShaderResourceViewSize( 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 1171SIZE_T APIENTRY 1172CalcPrivateShaderResourceViewSize1( 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 1191void APIENTRY 1192CreateShaderResourceView( 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 1271void APIENTRY 1272CreateShaderResourceView1( 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 1355void APIENTRY 1356DestroyShaderResourceView(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 1378void APIENTRY 1379GenMips(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 1403unsigned 1404ShaderFindOutputMapping(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