github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/internal/d3d11/d3d11_windows.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package d3d11
     4  
     5  import (
     6  	"fmt"
     7  	"math"
     8  	"syscall"
     9  	"unsafe"
    10  
    11  	"github.com/cybriq/giocore/internal/f32color"
    12  
    13  	"golang.org/x/sys/windows"
    14  )
    15  
    16  type DXGI_SWAP_CHAIN_DESC struct {
    17  	BufferDesc   DXGI_MODE_DESC
    18  	SampleDesc   DXGI_SAMPLE_DESC
    19  	BufferUsage  uint32
    20  	BufferCount  uint32
    21  	OutputWindow windows.Handle
    22  	Windowed     uint32
    23  	SwapEffect   uint32
    24  	Flags        uint32
    25  }
    26  
    27  type DXGI_SAMPLE_DESC struct {
    28  	Count   uint32
    29  	Quality uint32
    30  }
    31  
    32  type DXGI_MODE_DESC struct {
    33  	Width            uint32
    34  	Height           uint32
    35  	RefreshRate      DXGI_RATIONAL
    36  	Format           uint32
    37  	ScanlineOrdering uint32
    38  	Scaling          uint32
    39  }
    40  
    41  type DXGI_RATIONAL struct {
    42  	Numerator   uint32
    43  	Denominator uint32
    44  }
    45  
    46  type TEXTURE2D_DESC struct {
    47  	Width          uint32
    48  	Height         uint32
    49  	MipLevels      uint32
    50  	ArraySize      uint32
    51  	Format         uint32
    52  	SampleDesc     DXGI_SAMPLE_DESC
    53  	Usage          uint32
    54  	BindFlags      uint32
    55  	CPUAccessFlags uint32
    56  	MiscFlags      uint32
    57  }
    58  
    59  type SAMPLER_DESC struct {
    60  	Filter         uint32
    61  	AddressU       uint32
    62  	AddressV       uint32
    63  	AddressW       uint32
    64  	MipLODBias     float32
    65  	MaxAnisotropy  uint32
    66  	ComparisonFunc uint32
    67  	BorderColor    [4]float32
    68  	MinLOD         float32
    69  	MaxLOD         float32
    70  }
    71  
    72  type SHADER_RESOURCE_VIEW_DESC_TEX2D struct {
    73  	SHADER_RESOURCE_VIEW_DESC
    74  	Texture2D TEX2D_SRV
    75  }
    76  
    77  type SHADER_RESOURCE_VIEW_DESC struct {
    78  	Format        uint32
    79  	ViewDimension uint32
    80  }
    81  
    82  type TEX2D_SRV struct {
    83  	MostDetailedMip uint32
    84  	MipLevels       uint32
    85  }
    86  
    87  type INPUT_ELEMENT_DESC struct {
    88  	SemanticName         *byte
    89  	SemanticIndex        uint32
    90  	Format               uint32
    91  	InputSlot            uint32
    92  	AlignedByteOffset    uint32
    93  	InputSlotClass       uint32
    94  	InstanceDataStepRate uint32
    95  }
    96  
    97  type IDXGISwapChain struct {
    98  	Vtbl *struct {
    99  		_IUnknownVTbl
   100  		SetPrivateData          uintptr
   101  		SetPrivateDataInterface uintptr
   102  		GetPrivateData          uintptr
   103  		GetParent               uintptr
   104  		GetDevice               uintptr
   105  		Present                 uintptr
   106  		GetBuffer               uintptr
   107  		SetFullscreenState      uintptr
   108  		GetFullscreenState      uintptr
   109  		GetDesc                 uintptr
   110  		ResizeBuffers           uintptr
   111  		ResizeTarget            uintptr
   112  		GetContainingOutput     uintptr
   113  		GetFrameStatistics      uintptr
   114  		GetLastPresentCount     uintptr
   115  	}
   116  }
   117  
   118  type Device struct {
   119  	Vtbl *struct {
   120  		_IUnknownVTbl
   121  		CreateBuffer                         uintptr
   122  		CreateTexture1D                      uintptr
   123  		CreateTexture2D                      uintptr
   124  		CreateTexture3D                      uintptr
   125  		CreateShaderResourceView             uintptr
   126  		CreateUnorderedAccessView            uintptr
   127  		CreateRenderTargetView               uintptr
   128  		CreateDepthStencilView               uintptr
   129  		CreateInputLayout                    uintptr
   130  		CreateVertexShader                   uintptr
   131  		CreateGeometryShader                 uintptr
   132  		CreateGeometryShaderWithStreamOutput uintptr
   133  		CreatePixelShader                    uintptr
   134  		CreateHullShader                     uintptr
   135  		CreateDomainShader                   uintptr
   136  		CreateComputeShader                  uintptr
   137  		CreateClassLinkage                   uintptr
   138  		CreateBlendState                     uintptr
   139  		CreateDepthStencilState              uintptr
   140  		CreateRasterizerState                uintptr
   141  		CreateSamplerState                   uintptr
   142  		CreateQuery                          uintptr
   143  		CreatePredicate                      uintptr
   144  		CreateCounter                        uintptr
   145  		CreateDeferredContext                uintptr
   146  		OpenSharedResource                   uintptr
   147  		CheckFormatSupport                   uintptr
   148  		CheckMultisampleQualityLevels        uintptr
   149  		CheckCounterInfo                     uintptr
   150  		CheckCounter                         uintptr
   151  		CheckFeatureSupport                  uintptr
   152  		GetPrivateData                       uintptr
   153  		SetPrivateData                       uintptr
   154  		SetPrivateDataInterface              uintptr
   155  		GetFeatureLevel                      uintptr
   156  		GetCreationFlags                     uintptr
   157  		GetDeviceRemovedReason               uintptr
   158  		GetImmediateContext                  uintptr
   159  		SetExceptionMode                     uintptr
   160  		GetExceptionMode                     uintptr
   161  	}
   162  }
   163  
   164  type DeviceContext struct {
   165  	Vtbl *struct {
   166  		_IUnknownVTbl
   167  		GetDevice                                 uintptr
   168  		GetPrivateData                            uintptr
   169  		SetPrivateData                            uintptr
   170  		SetPrivateDataInterface                   uintptr
   171  		VSSetConstantBuffers                      uintptr
   172  		PSSetShaderResources                      uintptr
   173  		PSSetShader                               uintptr
   174  		PSSetSamplers                             uintptr
   175  		VSSetShader                               uintptr
   176  		DrawIndexed                               uintptr
   177  		Draw                                      uintptr
   178  		Map                                       uintptr
   179  		Unmap                                     uintptr
   180  		PSSetConstantBuffers                      uintptr
   181  		IASetInputLayout                          uintptr
   182  		IASetVertexBuffers                        uintptr
   183  		IASetIndexBuffer                          uintptr
   184  		DrawIndexedInstanced                      uintptr
   185  		DrawInstanced                             uintptr
   186  		GSSetConstantBuffers                      uintptr
   187  		GSSetShader                               uintptr
   188  		IASetPrimitiveTopology                    uintptr
   189  		VSSetShaderResources                      uintptr
   190  		VSSetSamplers                             uintptr
   191  		Begin                                     uintptr
   192  		End                                       uintptr
   193  		GetData                                   uintptr
   194  		SetPredication                            uintptr
   195  		GSSetShaderResources                      uintptr
   196  		GSSetSamplers                             uintptr
   197  		OMSetRenderTargets                        uintptr
   198  		OMSetRenderTargetsAndUnorderedAccessViews uintptr
   199  		OMSetBlendState                           uintptr
   200  		OMSetDepthStencilState                    uintptr
   201  		SOSetTargets                              uintptr
   202  		DrawAuto                                  uintptr
   203  		DrawIndexedInstancedIndirect              uintptr
   204  		DrawInstancedIndirect                     uintptr
   205  		Dispatch                                  uintptr
   206  		DispatchIndirect                          uintptr
   207  		RSSetState                                uintptr
   208  		RSSetViewports                            uintptr
   209  		RSSetScissorRects                         uintptr
   210  		CopySubresourceRegion                     uintptr
   211  		CopyResource                              uintptr
   212  		UpdateSubresource                         uintptr
   213  		CopyStructureCount                        uintptr
   214  		ClearRenderTargetView                     uintptr
   215  		ClearUnorderedAccessViewUint              uintptr
   216  		ClearUnorderedAccessViewFloat             uintptr
   217  		ClearDepthStencilView                     uintptr
   218  		GenerateMips                              uintptr
   219  		SetResourceMinLOD                         uintptr
   220  		GetResourceMinLOD                         uintptr
   221  		ResolveSubresource                        uintptr
   222  		ExecuteCommandList                        uintptr
   223  		HSSetShaderResources                      uintptr
   224  		HSSetShader                               uintptr
   225  		HSSetSamplers                             uintptr
   226  		HSSetConstantBuffers                      uintptr
   227  		DSSetShaderResources                      uintptr
   228  		DSSetShader                               uintptr
   229  		DSSetSamplers                             uintptr
   230  		DSSetConstantBuffers                      uintptr
   231  		CSSetShaderResources                      uintptr
   232  		CSSetUnorderedAccessViews                 uintptr
   233  		CSSetShader                               uintptr
   234  		CSSetSamplers                             uintptr
   235  		CSSetConstantBuffers                      uintptr
   236  		VSGetConstantBuffers                      uintptr
   237  		PSGetShaderResources                      uintptr
   238  		PSGetShader                               uintptr
   239  		PSGetSamplers                             uintptr
   240  		VSGetShader                               uintptr
   241  		PSGetConstantBuffers                      uintptr
   242  		IAGetInputLayout                          uintptr
   243  		IAGetVertexBuffers                        uintptr
   244  		IAGetIndexBuffer                          uintptr
   245  		GSGetConstantBuffers                      uintptr
   246  		GSGetShader                               uintptr
   247  		IAGetPrimitiveTopology                    uintptr
   248  		VSGetShaderResources                      uintptr
   249  		VSGetSamplers                             uintptr
   250  		GetPredication                            uintptr
   251  		GSGetShaderResources                      uintptr
   252  		GSGetSamplers                             uintptr
   253  		OMGetRenderTargets                        uintptr
   254  		OMGetRenderTargetsAndUnorderedAccessViews uintptr
   255  		OMGetBlendState                           uintptr
   256  		OMGetDepthStencilState                    uintptr
   257  		SOGetTargets                              uintptr
   258  		RSGetState                                uintptr
   259  		RSGetViewports                            uintptr
   260  		RSGetScissorRects                         uintptr
   261  		HSGetShaderResources                      uintptr
   262  		HSGetShader                               uintptr
   263  		HSGetSamplers                             uintptr
   264  		HSGetConstantBuffers                      uintptr
   265  		DSGetShaderResources                      uintptr
   266  		DSGetShader                               uintptr
   267  		DSGetSamplers                             uintptr
   268  		DSGetConstantBuffers                      uintptr
   269  		CSGetShaderResources                      uintptr
   270  		CSGetUnorderedAccessViews                 uintptr
   271  		CSGetShader                               uintptr
   272  		CSGetSamplers                             uintptr
   273  		CSGetConstantBuffers                      uintptr
   274  		ClearState                                uintptr
   275  		Flush                                     uintptr
   276  		GetType                                   uintptr
   277  		GetContextFlags                           uintptr
   278  		FinishCommandList                         uintptr
   279  	}
   280  }
   281  
   282  type RenderTargetView struct {
   283  	Vtbl *struct {
   284  		_IUnknownVTbl
   285  	}
   286  }
   287  
   288  type Resource struct {
   289  	Vtbl *struct {
   290  		_IUnknownVTbl
   291  	}
   292  }
   293  
   294  type Texture2D struct {
   295  	Vtbl *struct {
   296  		_IUnknownVTbl
   297  	}
   298  }
   299  
   300  type Buffer struct {
   301  	Vtbl *struct {
   302  		_IUnknownVTbl
   303  	}
   304  }
   305  
   306  type SamplerState struct {
   307  	Vtbl *struct {
   308  		_IUnknownVTbl
   309  	}
   310  }
   311  
   312  type PixelShader struct {
   313  	Vtbl *struct {
   314  		_IUnknownVTbl
   315  	}
   316  }
   317  
   318  type ShaderResourceView struct {
   319  	Vtbl *struct {
   320  		_IUnknownVTbl
   321  	}
   322  }
   323  
   324  type DepthStencilView struct {
   325  	Vtbl *struct {
   326  		_IUnknownVTbl
   327  	}
   328  }
   329  
   330  type BlendState struct {
   331  	Vtbl *struct {
   332  		_IUnknownVTbl
   333  	}
   334  }
   335  
   336  type DepthStencilState struct {
   337  	Vtbl *struct {
   338  		_IUnknownVTbl
   339  	}
   340  }
   341  
   342  type VertexShader struct {
   343  	Vtbl *struct {
   344  		_IUnknownVTbl
   345  	}
   346  }
   347  
   348  type RasterizerState struct {
   349  	Vtbl *struct {
   350  		_IUnknownVTbl
   351  	}
   352  }
   353  
   354  type InputLayout struct {
   355  	Vtbl *struct {
   356  		_IUnknownVTbl
   357  		GetBufferPointer uintptr
   358  		GetBufferSize    uintptr
   359  	}
   360  }
   361  
   362  type DEPTH_STENCIL_DESC struct {
   363  	DepthEnable      uint32
   364  	DepthWriteMask   uint32
   365  	DepthFunc        uint32
   366  	StencilEnable    uint32
   367  	StencilReadMask  uint8
   368  	StencilWriteMask uint8
   369  	FrontFace        DEPTH_STENCILOP_DESC
   370  	BackFace         DEPTH_STENCILOP_DESC
   371  }
   372  
   373  type DEPTH_STENCILOP_DESC struct {
   374  	StencilFailOp      uint32
   375  	StencilDepthFailOp uint32
   376  	StencilPassOp      uint32
   377  	StencilFunc        uint32
   378  }
   379  
   380  type DEPTH_STENCIL_VIEW_DESC_TEX2D struct {
   381  	Format        uint32
   382  	ViewDimension uint32
   383  	Flags         uint32
   384  	Texture2D     TEX2D_DSV
   385  }
   386  
   387  type TEX2D_DSV struct {
   388  	MipSlice uint32
   389  }
   390  
   391  type BLEND_DESC struct {
   392  	AlphaToCoverageEnable  uint32
   393  	IndependentBlendEnable uint32
   394  	RenderTarget           [8]RENDER_TARGET_BLEND_DESC
   395  }
   396  
   397  type RENDER_TARGET_BLEND_DESC struct {
   398  	BlendEnable           uint32
   399  	SrcBlend              uint32
   400  	DestBlend             uint32
   401  	BlendOp               uint32
   402  	SrcBlendAlpha         uint32
   403  	DestBlendAlpha        uint32
   404  	BlendOpAlpha          uint32
   405  	RenderTargetWriteMask uint8
   406  }
   407  
   408  type IDXGIObject struct {
   409  	Vtbl *struct {
   410  		_IUnknownVTbl
   411  		SetPrivateData          uintptr
   412  		SetPrivateDataInterface uintptr
   413  		GetPrivateData          uintptr
   414  		GetParent               uintptr
   415  	}
   416  }
   417  
   418  type IDXGIAdapter struct {
   419  	Vtbl *struct {
   420  		_IUnknownVTbl
   421  		SetPrivateData          uintptr
   422  		SetPrivateDataInterface uintptr
   423  		GetPrivateData          uintptr
   424  		GetParent               uintptr
   425  		EnumOutputs             uintptr
   426  		GetDesc                 uintptr
   427  		CheckInterfaceSupport   uintptr
   428  		GetDesc1                uintptr
   429  	}
   430  }
   431  
   432  type IDXGIFactory struct {
   433  	Vtbl *struct {
   434  		_IUnknownVTbl
   435  		SetPrivateData          uintptr
   436  		SetPrivateDataInterface uintptr
   437  		GetPrivateData          uintptr
   438  		GetParent               uintptr
   439  		EnumAdapters            uintptr
   440  		MakeWindowAssociation   uintptr
   441  		GetWindowAssociation    uintptr
   442  		CreateSwapChain         uintptr
   443  		CreateSoftwareAdapter   uintptr
   444  	}
   445  }
   446  
   447  type IDXGIDevice struct {
   448  	Vtbl *struct {
   449  		_IUnknownVTbl
   450  		SetPrivateData          uintptr
   451  		SetPrivateDataInterface uintptr
   452  		GetPrivateData          uintptr
   453  		GetParent               uintptr
   454  		GetAdapter              uintptr
   455  		CreateSurface           uintptr
   456  		QueryResourceResidency  uintptr
   457  		SetGPUThreadPriority    uintptr
   458  		GetGPUThreadPriority    uintptr
   459  	}
   460  }
   461  
   462  type IUnknown struct {
   463  	Vtbl *struct {
   464  		_IUnknownVTbl
   465  	}
   466  }
   467  
   468  type _IUnknownVTbl struct {
   469  	QueryInterface uintptr
   470  	AddRef         uintptr
   471  	Release        uintptr
   472  }
   473  
   474  type BUFFER_DESC struct {
   475  	ByteWidth           uint32
   476  	Usage               uint32
   477  	BindFlags           uint32
   478  	CPUAccessFlags      uint32
   479  	MiscFlags           uint32
   480  	StructureByteStride uint32
   481  }
   482  
   483  type GUID struct {
   484  	Data1   uint32
   485  	Data2   uint16
   486  	Data3   uint16
   487  	Data4_0 uint8
   488  	Data4_1 uint8
   489  	Data4_2 uint8
   490  	Data4_3 uint8
   491  	Data4_4 uint8
   492  	Data4_5 uint8
   493  	Data4_6 uint8
   494  	Data4_7 uint8
   495  }
   496  
   497  type VIEWPORT struct {
   498  	TopLeftX float32
   499  	TopLeftY float32
   500  	Width    float32
   501  	Height   float32
   502  	MinDepth float32
   503  	MaxDepth float32
   504  }
   505  
   506  type SUBRESOURCE_DATA struct {
   507  	pSysMem *byte
   508  }
   509  
   510  type BOX struct {
   511  	Left   uint32
   512  	Top    uint32
   513  	Front  uint32
   514  	Right  uint32
   515  	Bottom uint32
   516  	Back   uint32
   517  }
   518  
   519  type MAPPED_SUBRESOURCE struct {
   520  	PData      uintptr
   521  	RowPitch   uint32
   522  	DepthPitch uint32
   523  }
   524  
   525  type ErrorCode struct {
   526  	Name string
   527  	Code uint32
   528  }
   529  
   530  type RASTERIZER_DESC struct {
   531  	FillMode              uint32
   532  	CullMode              uint32
   533  	FrontCounterClockwise uint32
   534  	DepthBias             int32
   535  	DepthBiasClamp        float32
   536  	SlopeScaledDepthBias  float32
   537  	DepthClipEnable       uint32
   538  	ScissorEnable         uint32
   539  	MultisampleEnable     uint32
   540  	AntialiasedLineEnable uint32
   541  }
   542  
   543  var (
   544  	IID_Texture2D    = GUID{0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c}
   545  	IID_IDXGIDevice  = GUID{0x54ec77fa, 0x1377, 0x44e6, 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c}
   546  	IID_IDXGIFactory = GUID{0x7b7166ec, 0x21c7, 0x44ae, 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69}
   547  )
   548  
   549  var (
   550  	d3d11 = windows.NewLazySystemDLL("d3d11.dll")
   551  
   552  	_D3D11CreateDevice             = d3d11.NewProc("D3D11CreateDevice")
   553  	_D3D11CreateDeviceAndSwapChain = d3d11.NewProc("D3D11CreateDeviceAndSwapChain")
   554  )
   555  
   556  const (
   557  	SDK_VERSION          = 7
   558  	DRIVER_TYPE_HARDWARE = 1
   559  
   560  	DXGI_FORMAT_UNKNOWN             = 0
   561  	DXGI_FORMAT_R16_FLOAT           = 54
   562  	DXGI_FORMAT_R32_FLOAT           = 41
   563  	DXGI_FORMAT_R32G32_FLOAT        = 16
   564  	DXGI_FORMAT_R32G32B32_FLOAT     = 6
   565  	DXGI_FORMAT_R32G32B32A32_FLOAT  = 2
   566  	DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29
   567  	DXGI_FORMAT_R16_SINT            = 59
   568  	DXGI_FORMAT_R16G16_SINT         = 38
   569  	DXGI_FORMAT_R16_UINT            = 57
   570  	DXGI_FORMAT_D24_UNORM_S8_UINT   = 45
   571  	DXGI_FORMAT_R16G16_FLOAT        = 34
   572  	DXGI_FORMAT_R16G16B16A16_FLOAT  = 10
   573  
   574  	FORMAT_SUPPORT_TEXTURE2D     = 0x20
   575  	FORMAT_SUPPORT_RENDER_TARGET = 0x4000
   576  
   577  	DXGI_USAGE_RENDER_TARGET_OUTPUT = 1 << (1 + 4)
   578  
   579  	CPU_ACCESS_READ = 0x20000
   580  
   581  	MAP_READ = 1
   582  
   583  	DXGI_SWAP_EFFECT_DISCARD = 0
   584  
   585  	FEATURE_LEVEL_9_1  = 0x9100
   586  	FEATURE_LEVEL_9_3  = 0x9300
   587  	FEATURE_LEVEL_11_0 = 0xb000
   588  
   589  	USAGE_IMMUTABLE = 1
   590  	USAGE_STAGING   = 3
   591  
   592  	BIND_VERTEX_BUFFER   = 0x1
   593  	BIND_INDEX_BUFFER    = 0x2
   594  	BIND_CONSTANT_BUFFER = 0x4
   595  	BIND_SHADER_RESOURCE = 0x8
   596  	BIND_RENDER_TARGET   = 0x20
   597  	BIND_DEPTH_STENCIL   = 0x40
   598  
   599  	PRIMITIVE_TOPOLOGY_TRIANGLELIST  = 4
   600  	PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5
   601  
   602  	FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14
   603  	FILTER_MIN_MAG_MIP_POINT        = 0
   604  
   605  	TEXTURE_ADDRESS_MIRROR = 2
   606  	TEXTURE_ADDRESS_CLAMP  = 3
   607  	TEXTURE_ADDRESS_WRAP   = 1
   608  
   609  	SRV_DIMENSION_TEXTURE2D = 4
   610  
   611  	CREATE_DEVICE_DEBUG = 0x2
   612  
   613  	FILL_SOLID = 3
   614  
   615  	CULL_NONE = 1
   616  
   617  	CLEAR_DEPTH   = 0x1
   618  	CLEAR_STENCIL = 0x2
   619  
   620  	DSV_DIMENSION_TEXTURE2D = 3
   621  
   622  	DEPTH_WRITE_MASK_ALL = 1
   623  
   624  	COMPARISON_GREATER       = 5
   625  	COMPARISON_GREATER_EQUAL = 7
   626  
   627  	BLEND_OP_ADD        = 1
   628  	BLEND_ONE           = 2
   629  	BLEND_INV_SRC_ALPHA = 6
   630  	BLEND_ZERO          = 1
   631  	BLEND_DEST_COLOR    = 9
   632  	BLEND_DEST_ALPHA    = 7
   633  
   634  	COLOR_WRITE_ENABLE_ALL = 1 | 2 | 4 | 8
   635  
   636  	DXGI_STATUS_OCCLUDED      = 0x087A0001
   637  	DXGI_ERROR_DEVICE_RESET   = 0x887A0007
   638  	DXGI_ERROR_DEVICE_REMOVED = 0x887A0005
   639  	D3DDDIERR_DEVICEREMOVED   = 1<<31 | 0x876<<16 | 2160
   640  )
   641  
   642  func CreateDevice(driverType uint32, flags uint32) (*Device, *DeviceContext, uint32, error) {
   643  	var (
   644  		dev     *Device
   645  		ctx     *DeviceContext
   646  		featLvl uint32
   647  	)
   648  	r, _, _ := _D3D11CreateDevice.Call(
   649  		0,                                 // pAdapter
   650  		uintptr(driverType),               // driverType
   651  		0,                                 // Software
   652  		uintptr(flags),                    // Flags
   653  		0,                                 // pFeatureLevels
   654  		0,                                 // FeatureLevels
   655  		SDK_VERSION,                       // SDKVersion
   656  		uintptr(unsafe.Pointer(&dev)),     // ppDevice
   657  		uintptr(unsafe.Pointer(&featLvl)), // pFeatureLevel
   658  		uintptr(unsafe.Pointer(&ctx)),     // ppImmediateContext
   659  	)
   660  	if r != 0 {
   661  		return nil, nil, 0, ErrorCode{Name: "D3D11CreateDevice", Code: uint32(r)}
   662  	}
   663  	return dev, ctx, featLvl, nil
   664  }
   665  
   666  func CreateDeviceAndSwapChain(driverType uint32, flags uint32, swapDesc *DXGI_SWAP_CHAIN_DESC) (*Device, *DeviceContext, *IDXGISwapChain, uint32, error) {
   667  	var (
   668  		dev     *Device
   669  		ctx     *DeviceContext
   670  		swchain *IDXGISwapChain
   671  		featLvl uint32
   672  	)
   673  	r, _, _ := _D3D11CreateDeviceAndSwapChain.Call(
   674  		0,                                 // pAdapter
   675  		uintptr(driverType),               // driverType
   676  		0,                                 // Software
   677  		uintptr(flags),                    // Flags
   678  		0,                                 // pFeatureLevels
   679  		0,                                 // FeatureLevels
   680  		SDK_VERSION,                       // SDKVersion
   681  		uintptr(unsafe.Pointer(swapDesc)), // pSwapChainDesc
   682  		uintptr(unsafe.Pointer(&swchain)), // ppSwapChain
   683  		uintptr(unsafe.Pointer(&dev)),     // ppDevice
   684  		uintptr(unsafe.Pointer(&featLvl)), // pFeatureLevel
   685  		uintptr(unsafe.Pointer(&ctx)),     // ppImmediateContext
   686  	)
   687  	if r != 0 {
   688  		return nil, nil, nil, 0, ErrorCode{Name: "D3D11CreateDeviceAndSwapChain", Code: uint32(r)}
   689  	}
   690  	return dev, ctx, swchain, featLvl, nil
   691  }
   692  
   693  func (d *Device) CheckFormatSupport(format uint32) (uint32, error) {
   694  	var support uint32
   695  	r, _, _ := syscall.Syscall(
   696  		d.Vtbl.CheckFormatSupport,
   697  		3,
   698  		uintptr(unsafe.Pointer(d)),
   699  		uintptr(format),
   700  		uintptr(unsafe.Pointer(&support)),
   701  	)
   702  	if r != 0 {
   703  		return 0, ErrorCode{Name: "DeviceCheckFormatSupport", Code: uint32(r)}
   704  	}
   705  	return support, nil
   706  }
   707  
   708  func (d *Device) CreateBuffer(desc *BUFFER_DESC, data []byte) (*Buffer, error) {
   709  	var dataDesc *SUBRESOURCE_DATA
   710  	if len(data) > 0 {
   711  		dataDesc = &SUBRESOURCE_DATA{
   712  			pSysMem: &data[0],
   713  		}
   714  	}
   715  	var buf *Buffer
   716  	r, _, _ := syscall.Syscall6(
   717  		d.Vtbl.CreateBuffer,
   718  		4,
   719  		uintptr(unsafe.Pointer(d)),
   720  		uintptr(unsafe.Pointer(desc)),
   721  		uintptr(unsafe.Pointer(dataDesc)),
   722  		uintptr(unsafe.Pointer(&buf)),
   723  		0, 0,
   724  	)
   725  	if r != 0 {
   726  		return nil, ErrorCode{Name: "DeviceCreateBuffer", Code: uint32(r)}
   727  	}
   728  	return buf, nil
   729  }
   730  
   731  func (d *Device) CreateDepthStencilViewTEX2D(res *Resource, desc *DEPTH_STENCIL_VIEW_DESC_TEX2D) (*DepthStencilView, error) {
   732  	var view *DepthStencilView
   733  	r, _, _ := syscall.Syscall6(
   734  		d.Vtbl.CreateDepthStencilView,
   735  		4,
   736  		uintptr(unsafe.Pointer(d)),
   737  		uintptr(unsafe.Pointer(res)),
   738  		uintptr(unsafe.Pointer(desc)),
   739  		uintptr(unsafe.Pointer(&view)),
   740  		0, 0,
   741  	)
   742  	if r != 0 {
   743  		return nil, ErrorCode{Name: "DeviceCreateDepthStencilView", Code: uint32(r)}
   744  	}
   745  	return view, nil
   746  }
   747  
   748  func (d *Device) CreatePixelShader(bytecode []byte) (*PixelShader, error) {
   749  	var shader *PixelShader
   750  	r, _, _ := syscall.Syscall6(
   751  		d.Vtbl.CreatePixelShader,
   752  		5,
   753  		uintptr(unsafe.Pointer(d)),
   754  		uintptr(unsafe.Pointer(&bytecode[0])),
   755  		uintptr(len(bytecode)),
   756  		0, // pClassLinkage
   757  		uintptr(unsafe.Pointer(&shader)),
   758  		0,
   759  	)
   760  	if r != 0 {
   761  		return nil, ErrorCode{Name: "DeviceCreatePixelShader", Code: uint32(r)}
   762  	}
   763  	return shader, nil
   764  }
   765  
   766  func (d *Device) CreateVertexShader(bytecode []byte) (*VertexShader, error) {
   767  	var shader *VertexShader
   768  	r, _, _ := syscall.Syscall6(
   769  		d.Vtbl.CreateVertexShader,
   770  		5,
   771  		uintptr(unsafe.Pointer(d)),
   772  		uintptr(unsafe.Pointer(&bytecode[0])),
   773  		uintptr(len(bytecode)),
   774  		0, // pClassLinkage
   775  		uintptr(unsafe.Pointer(&shader)),
   776  		0,
   777  	)
   778  	if r != 0 {
   779  		return nil, ErrorCode{Name: "DeviceCreateVertexShader", Code: uint32(r)}
   780  	}
   781  	return shader, nil
   782  }
   783  
   784  func (d *Device) CreateShaderResourceViewTEX2D(res *Resource, desc *SHADER_RESOURCE_VIEW_DESC_TEX2D) (*ShaderResourceView, error) {
   785  	var resView *ShaderResourceView
   786  	r, _, _ := syscall.Syscall6(
   787  		d.Vtbl.CreateShaderResourceView,
   788  		4,
   789  		uintptr(unsafe.Pointer(d)),
   790  		uintptr(unsafe.Pointer(res)),
   791  		uintptr(unsafe.Pointer(desc)),
   792  		uintptr(unsafe.Pointer(&resView)),
   793  		0, 0,
   794  	)
   795  	if r != 0 {
   796  		return nil, ErrorCode{Name: "DeviceCreateShaderResourceView", Code: uint32(r)}
   797  	}
   798  	return resView, nil
   799  }
   800  
   801  func (d *Device) CreateRasterizerState(desc *RASTERIZER_DESC) (*RasterizerState, error) {
   802  	var state *RasterizerState
   803  	r, _, _ := syscall.Syscall(
   804  		d.Vtbl.CreateRasterizerState,
   805  		3,
   806  		uintptr(unsafe.Pointer(d)),
   807  		uintptr(unsafe.Pointer(desc)),
   808  		uintptr(unsafe.Pointer(&state)),
   809  	)
   810  	if r != 0 {
   811  		return nil, ErrorCode{Name: "DeviceCreateRasterizerState", Code: uint32(r)}
   812  	}
   813  	return state, nil
   814  }
   815  
   816  func (d *Device) CreateInputLayout(descs []INPUT_ELEMENT_DESC, bytecode []byte) (*InputLayout, error) {
   817  	var pdesc *INPUT_ELEMENT_DESC
   818  	if len(descs) > 0 {
   819  		pdesc = &descs[0]
   820  	}
   821  	var layout *InputLayout
   822  	r, _, _ := syscall.Syscall6(
   823  		d.Vtbl.CreateInputLayout,
   824  		6,
   825  		uintptr(unsafe.Pointer(d)),
   826  		uintptr(unsafe.Pointer(pdesc)),
   827  		uintptr(len(descs)),
   828  		uintptr(unsafe.Pointer(&bytecode[0])),
   829  		uintptr(len(bytecode)),
   830  		uintptr(unsafe.Pointer(&layout)),
   831  	)
   832  	if r != 0 {
   833  		return nil, ErrorCode{Name: "DeviceCreateInputLayout", Code: uint32(r)}
   834  	}
   835  	return layout, nil
   836  }
   837  
   838  func (d *Device) CreateSamplerState(desc *SAMPLER_DESC) (*SamplerState, error) {
   839  	var sampler *SamplerState
   840  	r, _, _ := syscall.Syscall(
   841  		d.Vtbl.CreateSamplerState,
   842  		3,
   843  		uintptr(unsafe.Pointer(d)),
   844  		uintptr(unsafe.Pointer(desc)),
   845  		uintptr(unsafe.Pointer(&sampler)),
   846  	)
   847  	if r != 0 {
   848  		return nil, ErrorCode{Name: "DeviceCreateSamplerState", Code: uint32(r)}
   849  	}
   850  	return sampler, nil
   851  }
   852  
   853  func (d *Device) CreateTexture2D(desc *TEXTURE2D_DESC) (*Texture2D, error) {
   854  	var tex *Texture2D
   855  	r, _, _ := syscall.Syscall6(
   856  		d.Vtbl.CreateTexture2D,
   857  		4,
   858  		uintptr(unsafe.Pointer(d)),
   859  		uintptr(unsafe.Pointer(desc)),
   860  		0, // pInitialData
   861  		uintptr(unsafe.Pointer(&tex)),
   862  		0, 0,
   863  	)
   864  	if r != 0 {
   865  		return nil, ErrorCode{Name: "CreateTexture2D", Code: uint32(r)}
   866  	}
   867  	return tex, nil
   868  }
   869  
   870  func (d *Device) CreateRenderTargetView(res *Resource) (*RenderTargetView, error) {
   871  	var target *RenderTargetView
   872  	r, _, _ := syscall.Syscall6(
   873  		d.Vtbl.CreateRenderTargetView,
   874  		4,
   875  		uintptr(unsafe.Pointer(d)),
   876  		uintptr(unsafe.Pointer(res)),
   877  		0, // pDesc
   878  		uintptr(unsafe.Pointer(&target)),
   879  		0, 0,
   880  	)
   881  	if r != 0 {
   882  		return nil, ErrorCode{Name: "DeviceCreateRenderTargetView", Code: uint32(r)}
   883  	}
   884  	return target, nil
   885  }
   886  
   887  func (d *Device) CreateBlendState(desc *BLEND_DESC) (*BlendState, error) {
   888  	var state *BlendState
   889  	r, _, _ := syscall.Syscall(
   890  		d.Vtbl.CreateBlendState,
   891  		3,
   892  		uintptr(unsafe.Pointer(d)),
   893  		uintptr(unsafe.Pointer(desc)),
   894  		uintptr(unsafe.Pointer(&state)),
   895  	)
   896  	if r != 0 {
   897  		return nil, ErrorCode{Name: "DeviceCreateBlendState", Code: uint32(r)}
   898  	}
   899  	return state, nil
   900  }
   901  
   902  func (d *Device) CreateDepthStencilState(desc *DEPTH_STENCIL_DESC) (*DepthStencilState, error) {
   903  	var state *DepthStencilState
   904  	r, _, _ := syscall.Syscall(
   905  		d.Vtbl.CreateDepthStencilState,
   906  		3,
   907  		uintptr(unsafe.Pointer(d)),
   908  		uintptr(unsafe.Pointer(desc)),
   909  		uintptr(unsafe.Pointer(&state)),
   910  	)
   911  	if r != 0 {
   912  		return nil, ErrorCode{Name: "DeviceCreateDepthStencilState", Code: uint32(r)}
   913  	}
   914  	return state, nil
   915  }
   916  
   917  func (d *Device) GetFeatureLevel() int {
   918  	lvl, _, _ := syscall.Syscall(
   919  		d.Vtbl.GetFeatureLevel,
   920  		1,
   921  		uintptr(unsafe.Pointer(d)),
   922  		0, 0,
   923  	)
   924  	return int(lvl)
   925  }
   926  
   927  func (d *Device) GetImmediateContext() *DeviceContext {
   928  	var ctx *DeviceContext
   929  	syscall.Syscall(
   930  		d.Vtbl.GetImmediateContext,
   931  		2,
   932  		uintptr(unsafe.Pointer(d)),
   933  		uintptr(unsafe.Pointer(&ctx)),
   934  		0,
   935  	)
   936  	return ctx
   937  }
   938  
   939  func (s *IDXGISwapChain) GetDesc() (DXGI_SWAP_CHAIN_DESC, error) {
   940  	var desc DXGI_SWAP_CHAIN_DESC
   941  	r, _, _ := syscall.Syscall(
   942  		s.Vtbl.GetDesc,
   943  		2,
   944  		uintptr(unsafe.Pointer(s)),
   945  		uintptr(unsafe.Pointer(&desc)),
   946  		0,
   947  	)
   948  	if r != 0 {
   949  		return DXGI_SWAP_CHAIN_DESC{}, ErrorCode{Name: "IDXGISwapChainGetDesc", Code: uint32(r)}
   950  	}
   951  	return desc, nil
   952  }
   953  
   954  func (s *IDXGISwapChain) ResizeBuffers(buffers, width, height, newFormat, flags uint32) error {
   955  	r, _, _ := syscall.Syscall6(
   956  		s.Vtbl.ResizeBuffers,
   957  		6,
   958  		uintptr(unsafe.Pointer(s)),
   959  		uintptr(buffers),
   960  		uintptr(width),
   961  		uintptr(height),
   962  		uintptr(newFormat),
   963  		uintptr(flags),
   964  	)
   965  	if r != 0 {
   966  		return ErrorCode{Name: "IDXGISwapChainResizeBuffers", Code: uint32(r)}
   967  	}
   968  	return nil
   969  }
   970  
   971  func (s *IDXGISwapChain) Present(SyncInterval int, Flags uint32) error {
   972  	r, _, _ := syscall.Syscall(
   973  		s.Vtbl.Present,
   974  		3,
   975  		uintptr(unsafe.Pointer(s)),
   976  		uintptr(SyncInterval),
   977  		uintptr(Flags),
   978  	)
   979  	if r != 0 {
   980  		return ErrorCode{Name: "IDXGISwapChainPresent", Code: uint32(r)}
   981  	}
   982  	return nil
   983  }
   984  
   985  func (s *IDXGISwapChain) GetBuffer(index int, riid *GUID) (*IUnknown, error) {
   986  	var buf *IUnknown
   987  	r, _, _ := syscall.Syscall6(
   988  		s.Vtbl.GetBuffer,
   989  		4,
   990  		uintptr(unsafe.Pointer(s)),
   991  		uintptr(index),
   992  		uintptr(unsafe.Pointer(riid)),
   993  		uintptr(unsafe.Pointer(&buf)),
   994  		0,
   995  		0,
   996  	)
   997  	if r != 0 {
   998  		return nil, ErrorCode{Name: "IDXGISwapChainGetBuffer", Code: uint32(r)}
   999  	}
  1000  	return buf, nil
  1001  }
  1002  
  1003  func (c *DeviceContext) Unmap(resource *Resource, subResource uint32) {
  1004  	syscall.Syscall(
  1005  		c.Vtbl.Unmap,
  1006  		3,
  1007  		uintptr(unsafe.Pointer(c)),
  1008  		uintptr(unsafe.Pointer(resource)),
  1009  		uintptr(subResource),
  1010  	)
  1011  }
  1012  
  1013  func (c *DeviceContext) Map(resource *Resource, subResource, mapType, mapFlags uint32) (MAPPED_SUBRESOURCE, error) {
  1014  	var resMap MAPPED_SUBRESOURCE
  1015  	r, _, _ := syscall.Syscall6(
  1016  		c.Vtbl.Map,
  1017  		6,
  1018  		uintptr(unsafe.Pointer(c)),
  1019  		uintptr(unsafe.Pointer(resource)),
  1020  		uintptr(subResource),
  1021  		uintptr(mapType),
  1022  		uintptr(mapFlags),
  1023  		uintptr(unsafe.Pointer(&resMap)),
  1024  	)
  1025  	if r != 0 {
  1026  		return resMap, ErrorCode{Name: "DeviceContextMap", Code: uint32(r)}
  1027  	}
  1028  	return resMap, nil
  1029  }
  1030  
  1031  func (c *DeviceContext) CopySubresourceRegion(dst *Resource, dstSubresource, dstX, dstY, dstZ uint32, src *Resource, srcSubresource uint32, srcBox *BOX) {
  1032  	syscall.Syscall9(
  1033  		c.Vtbl.CopySubresourceRegion,
  1034  		9,
  1035  		uintptr(unsafe.Pointer(c)),
  1036  		uintptr(unsafe.Pointer(dst)),
  1037  		uintptr(dstSubresource),
  1038  		uintptr(dstX),
  1039  		uintptr(dstY),
  1040  		uintptr(dstZ),
  1041  		uintptr(unsafe.Pointer(src)),
  1042  		uintptr(srcSubresource),
  1043  		uintptr(unsafe.Pointer(srcBox)),
  1044  	)
  1045  }
  1046  
  1047  func (c *DeviceContext) ClearDepthStencilView(target *DepthStencilView, flags uint32, depth float32, stencil uint8) {
  1048  	syscall.Syscall6(
  1049  		c.Vtbl.ClearDepthStencilView,
  1050  		5,
  1051  		uintptr(unsafe.Pointer(c)),
  1052  		uintptr(unsafe.Pointer(target)),
  1053  		uintptr(flags),
  1054  		uintptr(math.Float32bits(depth)),
  1055  		uintptr(stencil),
  1056  		0,
  1057  	)
  1058  }
  1059  
  1060  func (c *DeviceContext) ClearRenderTargetView(target *RenderTargetView, color *[4]float32) {
  1061  	syscall.Syscall(
  1062  		c.Vtbl.ClearRenderTargetView,
  1063  		3,
  1064  		uintptr(unsafe.Pointer(c)),
  1065  		uintptr(unsafe.Pointer(target)),
  1066  		uintptr(unsafe.Pointer(color)),
  1067  	)
  1068  }
  1069  
  1070  func (c *DeviceContext) RSSetViewports(viewport *VIEWPORT) {
  1071  	syscall.Syscall(
  1072  		c.Vtbl.RSSetViewports,
  1073  		3,
  1074  		uintptr(unsafe.Pointer(c)),
  1075  		1, // NumViewports
  1076  		uintptr(unsafe.Pointer(viewport)),
  1077  	)
  1078  }
  1079  
  1080  func (c *DeviceContext) VSSetShader(s *VertexShader) {
  1081  	syscall.Syscall6(
  1082  		c.Vtbl.VSSetShader,
  1083  		4,
  1084  		uintptr(unsafe.Pointer(c)),
  1085  		uintptr(unsafe.Pointer(s)),
  1086  		0, // ppClassInstances
  1087  		0, // NumClassInstances
  1088  		0, 0,
  1089  	)
  1090  }
  1091  
  1092  func (c *DeviceContext) VSSetConstantBuffers(b *Buffer) {
  1093  	syscall.Syscall6(
  1094  		c.Vtbl.VSSetConstantBuffers,
  1095  		4,
  1096  		uintptr(unsafe.Pointer(c)),
  1097  		0, // StartSlot
  1098  		1, // NumBuffers
  1099  		uintptr(unsafe.Pointer(&b)),
  1100  		0, 0,
  1101  	)
  1102  }
  1103  
  1104  func (c *DeviceContext) PSSetConstantBuffers(b *Buffer) {
  1105  	syscall.Syscall6(
  1106  		c.Vtbl.PSSetConstantBuffers,
  1107  		4,
  1108  		uintptr(unsafe.Pointer(c)),
  1109  		0, // StartSlot
  1110  		1, // NumBuffers
  1111  		uintptr(unsafe.Pointer(&b)),
  1112  		0, 0,
  1113  	)
  1114  }
  1115  
  1116  func (c *DeviceContext) PSSetShaderResources(startSlot uint32, s *ShaderResourceView) {
  1117  	syscall.Syscall6(
  1118  		c.Vtbl.PSSetShaderResources,
  1119  		4,
  1120  		uintptr(unsafe.Pointer(c)),
  1121  		uintptr(startSlot),
  1122  		1, // NumViews
  1123  		uintptr(unsafe.Pointer(&s)),
  1124  		0, 0,
  1125  	)
  1126  }
  1127  
  1128  func (c *DeviceContext) PSSetSamplers(startSlot uint32, s *SamplerState) {
  1129  	syscall.Syscall6(
  1130  		c.Vtbl.PSSetSamplers,
  1131  		4,
  1132  		uintptr(unsafe.Pointer(c)),
  1133  		uintptr(startSlot),
  1134  		1, // NumSamplers
  1135  		uintptr(unsafe.Pointer(&s)),
  1136  		0, 0,
  1137  	)
  1138  }
  1139  
  1140  func (c *DeviceContext) PSSetShader(s *PixelShader) {
  1141  	syscall.Syscall6(
  1142  		c.Vtbl.PSSetShader,
  1143  		4,
  1144  		uintptr(unsafe.Pointer(c)),
  1145  		uintptr(unsafe.Pointer(s)),
  1146  		0, // ppClassInstances
  1147  		0, // NumClassInstances
  1148  		0, 0,
  1149  	)
  1150  }
  1151  
  1152  func (c *DeviceContext) UpdateSubresource(res *Resource, dstBox *BOX, rowPitch, depthPitch uint32, data []byte) {
  1153  	syscall.Syscall9(
  1154  		c.Vtbl.UpdateSubresource,
  1155  		7,
  1156  		uintptr(unsafe.Pointer(c)),
  1157  		uintptr(unsafe.Pointer(res)),
  1158  		0, // DstSubresource
  1159  		uintptr(unsafe.Pointer(dstBox)),
  1160  		uintptr(unsafe.Pointer(&data[0])),
  1161  		uintptr(rowPitch),
  1162  		uintptr(depthPitch),
  1163  		0, 0,
  1164  	)
  1165  }
  1166  
  1167  func (c *DeviceContext) RSSetState(state *RasterizerState) {
  1168  	syscall.Syscall(
  1169  		c.Vtbl.RSSetState,
  1170  		2,
  1171  		uintptr(unsafe.Pointer(c)),
  1172  		uintptr(unsafe.Pointer(state)),
  1173  		0,
  1174  	)
  1175  }
  1176  
  1177  func (c *DeviceContext) IASetInputLayout(layout *InputLayout) {
  1178  	syscall.Syscall(
  1179  		c.Vtbl.IASetInputLayout,
  1180  		2,
  1181  		uintptr(unsafe.Pointer(c)),
  1182  		uintptr(unsafe.Pointer(layout)),
  1183  		0,
  1184  	)
  1185  }
  1186  
  1187  func (c *DeviceContext) IASetIndexBuffer(buf *Buffer, format, offset uint32) {
  1188  	syscall.Syscall6(
  1189  		c.Vtbl.IASetIndexBuffer,
  1190  		4,
  1191  		uintptr(unsafe.Pointer(c)),
  1192  		uintptr(unsafe.Pointer(buf)),
  1193  		uintptr(format),
  1194  		uintptr(offset),
  1195  		0, 0,
  1196  	)
  1197  }
  1198  
  1199  func (c *DeviceContext) IASetVertexBuffers(buf *Buffer, stride, offset uint32) {
  1200  	syscall.Syscall6(
  1201  		c.Vtbl.IASetVertexBuffers,
  1202  		6,
  1203  		uintptr(unsafe.Pointer(c)),
  1204  		0, // StartSlot
  1205  		1, // NumBuffers,
  1206  		uintptr(unsafe.Pointer(&buf)),
  1207  		uintptr(unsafe.Pointer(&stride)),
  1208  		uintptr(unsafe.Pointer(&offset)),
  1209  	)
  1210  }
  1211  
  1212  func (c *DeviceContext) IASetPrimitiveTopology(mode uint32) {
  1213  	syscall.Syscall(
  1214  		c.Vtbl.IASetPrimitiveTopology,
  1215  		2,
  1216  		uintptr(unsafe.Pointer(c)),
  1217  		uintptr(mode),
  1218  		0,
  1219  	)
  1220  }
  1221  
  1222  func (c *DeviceContext) OMGetRenderTargets() (*RenderTargetView, *DepthStencilView) {
  1223  	var (
  1224  		target           *RenderTargetView
  1225  		depthStencilView *DepthStencilView
  1226  	)
  1227  	syscall.Syscall6(
  1228  		c.Vtbl.OMGetRenderTargets,
  1229  		4,
  1230  		uintptr(unsafe.Pointer(c)),
  1231  		1, // NumViews
  1232  		uintptr(unsafe.Pointer(&target)),
  1233  		uintptr(unsafe.Pointer(&depthStencilView)),
  1234  		0, 0,
  1235  	)
  1236  	return target, depthStencilView
  1237  }
  1238  
  1239  func (c *DeviceContext) OMSetRenderTargets(target *RenderTargetView, depthStencil *DepthStencilView) {
  1240  	syscall.Syscall6(
  1241  		c.Vtbl.OMSetRenderTargets,
  1242  		4,
  1243  		uintptr(unsafe.Pointer(c)),
  1244  		1, // NumViews
  1245  		uintptr(unsafe.Pointer(&target)),
  1246  		uintptr(unsafe.Pointer(depthStencil)),
  1247  		0, 0,
  1248  	)
  1249  }
  1250  
  1251  func (c *DeviceContext) Draw(count, start uint32) {
  1252  	syscall.Syscall(
  1253  		c.Vtbl.Draw,
  1254  		3,
  1255  		uintptr(unsafe.Pointer(c)),
  1256  		uintptr(count),
  1257  		uintptr(start),
  1258  	)
  1259  }
  1260  
  1261  func (c *DeviceContext) DrawIndexed(count, start uint32, base int32) {
  1262  	syscall.Syscall6(
  1263  		c.Vtbl.DrawIndexed,
  1264  		4,
  1265  		uintptr(unsafe.Pointer(c)),
  1266  		uintptr(count),
  1267  		uintptr(start),
  1268  		uintptr(base),
  1269  		0, 0,
  1270  	)
  1271  }
  1272  
  1273  func (c *DeviceContext) OMSetBlendState(state *BlendState, factor *f32color.RGBA, sampleMask uint32) {
  1274  	syscall.Syscall6(
  1275  		c.Vtbl.OMSetBlendState,
  1276  		4,
  1277  		uintptr(unsafe.Pointer(c)),
  1278  		uintptr(unsafe.Pointer(state)),
  1279  		uintptr(unsafe.Pointer(factor)),
  1280  		uintptr(sampleMask),
  1281  		0, 0,
  1282  	)
  1283  }
  1284  
  1285  func (c *DeviceContext) OMSetDepthStencilState(state *DepthStencilState, stencilRef uint32) {
  1286  	syscall.Syscall(
  1287  		c.Vtbl.OMSetDepthStencilState,
  1288  		3,
  1289  		uintptr(unsafe.Pointer(c)),
  1290  		uintptr(unsafe.Pointer(state)),
  1291  		uintptr(stencilRef),
  1292  	)
  1293  }
  1294  
  1295  func (d *IDXGIObject) GetParent(guid *GUID) (*IDXGIObject, error) {
  1296  	var parent *IDXGIObject
  1297  	r, _, _ := syscall.Syscall(
  1298  		d.Vtbl.GetParent,
  1299  		3,
  1300  		uintptr(unsafe.Pointer(d)),
  1301  		uintptr(unsafe.Pointer(guid)),
  1302  		uintptr(unsafe.Pointer(&parent)),
  1303  	)
  1304  	if r != 0 {
  1305  		return nil, ErrorCode{Name: "IDXGIObjectGetParent", Code: uint32(r)}
  1306  	}
  1307  	return parent, nil
  1308  }
  1309  
  1310  func (d *IDXGIFactory) CreateSwapChain(device *IUnknown, desc *DXGI_SWAP_CHAIN_DESC) (*IDXGISwapChain, error) {
  1311  	var swchain *IDXGISwapChain
  1312  	r, _, _ := syscall.Syscall6(
  1313  		d.Vtbl.CreateSwapChain,
  1314  		4,
  1315  		uintptr(unsafe.Pointer(d)),
  1316  		uintptr(unsafe.Pointer(device)),
  1317  		uintptr(unsafe.Pointer(desc)),
  1318  		uintptr(unsafe.Pointer(&swchain)),
  1319  		0, 0,
  1320  	)
  1321  	if r != 0 {
  1322  		return nil, ErrorCode{Name: "IDXGIFactory", Code: uint32(r)}
  1323  	}
  1324  	return swchain, nil
  1325  }
  1326  
  1327  func (d *IDXGIDevice) GetAdapter() (*IDXGIAdapter, error) {
  1328  	var adapter *IDXGIAdapter
  1329  	r, _, _ := syscall.Syscall(
  1330  		d.Vtbl.GetAdapter,
  1331  		2,
  1332  		uintptr(unsafe.Pointer(d)),
  1333  		uintptr(unsafe.Pointer(&adapter)),
  1334  		0,
  1335  	)
  1336  	if r != 0 {
  1337  		return nil, ErrorCode{Name: "IDXGIDeviceGetAdapter", Code: uint32(r)}
  1338  	}
  1339  	return adapter, nil
  1340  }
  1341  
  1342  func IUnknownQueryInterface(obj unsafe.Pointer, queryInterfaceMethod uintptr, guid *GUID) (*IUnknown, error) {
  1343  	var ref *IUnknown
  1344  	r, _, _ := syscall.Syscall(
  1345  		queryInterfaceMethod,
  1346  		3,
  1347  		uintptr(obj),
  1348  		uintptr(unsafe.Pointer(guid)),
  1349  		uintptr(unsafe.Pointer(&ref)),
  1350  	)
  1351  	if r != 0 {
  1352  		return nil, ErrorCode{Name: "IUnknownQueryInterface", Code: uint32(r)}
  1353  	}
  1354  	return ref, nil
  1355  }
  1356  
  1357  func IUnknownRelease(obj unsafe.Pointer, releaseMethod uintptr) {
  1358  	syscall.Syscall(
  1359  		releaseMethod,
  1360  		1,
  1361  		uintptr(obj),
  1362  		0,
  1363  		0,
  1364  	)
  1365  }
  1366  
  1367  func (e ErrorCode) Error() string {
  1368  	return fmt.Sprintf("%s: %#x", e.Name, e.Code)
  1369  }
  1370  
  1371  func CreateSwapChain(dev *Device, hwnd windows.Handle) (*IDXGISwapChain, error) {
  1372  	dxgiDev, err := IUnknownQueryInterface(unsafe.Pointer(dev), dev.Vtbl.QueryInterface, &IID_IDXGIDevice)
  1373  	if err != nil {
  1374  		return nil, fmt.Errorf("NewContext: %v", err)
  1375  	}
  1376  	adapter, err := (*IDXGIDevice)(unsafe.Pointer(dxgiDev)).GetAdapter()
  1377  	IUnknownRelease(unsafe.Pointer(dxgiDev), dxgiDev.Vtbl.Release)
  1378  	if err != nil {
  1379  		return nil, fmt.Errorf("NewContext: %v", err)
  1380  	}
  1381  	dxgiFactory, err := (*IDXGIObject)(unsafe.Pointer(adapter)).GetParent(&IID_IDXGIFactory)
  1382  	IUnknownRelease(unsafe.Pointer(adapter), adapter.Vtbl.Release)
  1383  	if err != nil {
  1384  		return nil, fmt.Errorf("NewContext: %v", err)
  1385  	}
  1386  	swchain, err := (*IDXGIFactory)(unsafe.Pointer(dxgiFactory)).CreateSwapChain(
  1387  		(*IUnknown)(unsafe.Pointer(dev)),
  1388  		&DXGI_SWAP_CHAIN_DESC{
  1389  			BufferDesc: DXGI_MODE_DESC{
  1390  				Format: DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
  1391  			},
  1392  			SampleDesc: DXGI_SAMPLE_DESC{
  1393  				Count: 1,
  1394  			},
  1395  			BufferUsage:  DXGI_USAGE_RENDER_TARGET_OUTPUT,
  1396  			BufferCount:  1,
  1397  			OutputWindow: hwnd,
  1398  			Windowed:     1,
  1399  			SwapEffect:   DXGI_SWAP_EFFECT_DISCARD,
  1400  		},
  1401  	)
  1402  	IUnknownRelease(unsafe.Pointer(dxgiFactory), dxgiFactory.Vtbl.Release)
  1403  	if err != nil {
  1404  		return nil, fmt.Errorf("NewContext: %v", err)
  1405  	}
  1406  	return swchain, nil
  1407  }
  1408  
  1409  func CreateDepthView(d *Device, width, height, depthBits int) (*DepthStencilView, error) {
  1410  	depthTex, err := d.CreateTexture2D(&TEXTURE2D_DESC{
  1411  		Width:     uint32(width),
  1412  		Height:    uint32(height),
  1413  		MipLevels: 1,
  1414  		ArraySize: 1,
  1415  		Format:    DXGI_FORMAT_D24_UNORM_S8_UINT,
  1416  		SampleDesc: DXGI_SAMPLE_DESC{
  1417  			Count:   1,
  1418  			Quality: 0,
  1419  		},
  1420  		BindFlags: BIND_DEPTH_STENCIL,
  1421  	})
  1422  	if err != nil {
  1423  		return nil, err
  1424  	}
  1425  	depthView, err := d.CreateDepthStencilViewTEX2D(
  1426  		(*Resource)(unsafe.Pointer(depthTex)),
  1427  		&DEPTH_STENCIL_VIEW_DESC_TEX2D{
  1428  			Format:        DXGI_FORMAT_D24_UNORM_S8_UINT,
  1429  			ViewDimension: DSV_DIMENSION_TEXTURE2D,
  1430  		},
  1431  	)
  1432  	IUnknownRelease(unsafe.Pointer(depthTex), depthTex.Vtbl.Release)
  1433  	return depthView, err
  1434  }