From 1362acb85a2360b0ebf4d82f8e381583c715baea Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 28 Aug 2021 10:18:03 +0200 Subject: [PATCH] gpu/internal/d3d11,internal/d3d11: add DirectCompute support This change implements support for compute programs in the Direct3D 11 driver. The compute renderer doesn't work for me yet; my NVIDIA GTX 970 and Intel GPUs both display corrupted output and hangs. Signed-off-by: Elias Naur --- go.mod | 2 +- go.sum | 4 +- gpu/internal/d3d11/d3d11_windows.go | 204 +++++++++++++++++++++++----- internal/d3d11/d3d11_windows.go | 159 ++++++++++++++++++++-- 4 files changed, 327 insertions(+), 42 deletions(-) diff --git a/go.mod b/go.mod index 1e16c4c1..5ecbd217 100644 --- a/go.mod +++ b/go.mod @@ -10,5 +10,5 @@ require ( require ( gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 - gioui.org/shader v1.0.1 + gioui.org/shader v1.0.2 ) diff --git a/go.sum b/go.sum index c274c198..94f4933e 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7 gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 h1:AGDDxsJE1RpcXTAxPG2B4jrwVUJGFDjINIPi1jtO6pc= gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= -gioui.org/shader v1.0.1 h1:xDrtlW/NiAQORPPR9UPjP33AguOIT1lAuQ3xb7ubgq8= -gioui.org/shader v1.0.1/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM= +gioui.org/shader v1.0.2 h1:5JrtNdOqmY+tQzBKKVFqf0YIziUK38OEw8mxxEbXdc8= +gioui.org/shader v1.0.2/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= diff --git a/gpu/internal/d3d11/d3d11_windows.go b/gpu/internal/d3d11/d3d11_windows.go index 97d3da73..57c989f2 100644 --- a/gpu/internal/d3d11/d3d11_windows.go +++ b/gpu/internal/d3d11/d3d11_windows.go @@ -31,6 +31,8 @@ type Backend struct { offset int } + program *Program + caps driver.Caps // fbo is the currently bound fbo. @@ -54,6 +56,7 @@ type Texture struct { tex *d3d11.Texture2D sampler *d3d11.SamplerState resView *d3d11.ShaderResourceView + uaView *d3d11.UnorderedAccessView width int height int } @@ -69,6 +72,11 @@ type FragmentShader struct { shader *d3d11.PixelShader } +type Program struct { + backend *Backend + shader *d3d11.ComputeShader +} + type Framebuffer struct { dev *d3d11.Device ctx *d3d11.DeviceContext @@ -82,7 +90,9 @@ type Buffer struct { backend *Backend bind uint32 buf *d3d11.Buffer - size int + resView *d3d11.ShaderResourceView + uaView *d3d11.UnorderedAccessView + size int immutable bool } @@ -120,14 +130,14 @@ func newDirect3D11Device(api driver.Direct3D11) (driver.Device, error) { }, } featLvl := dev.GetFeatureLevel() - if featLvl < d3d11.FEATURE_LEVEL_9_1 { + switch { + case featLvl < d3d11.FEATURE_LEVEL_9_1: d3d11.IUnknownRelease(unsafe.Pointer(dev), dev.Vtbl.Release) d3d11.IUnknownRelease(unsafe.Pointer(b.ctx), b.ctx.Vtbl.Release) return nil, fmt.Errorf("d3d11: feature level too low: %d", featLvl) - } - switch { case featLvl >= d3d11.FEATURE_LEVEL_11_0: b.caps.MaxTextureSize = 16384 + b.caps.Features |= driver.FeatureCompute case featLvl >= d3d11.FEATURE_LEVEL_9_3: b.caps.MaxTextureSize = 4096 } @@ -159,15 +169,31 @@ func (b *Backend) BeginFrame(target driver.RenderTarget, clear bool, viewport im case *Framebuffer: renderTarget = t.renderTarget default: - panic(fmt.Errorf("opengl: invalid render target type: %T", target)) + panic(fmt.Errorf("d3d11: invalid render target type: %T", target)) } } b.ctx.OMSetRenderTargets(renderTarget, nil) return &Framebuffer{ctx: b.ctx, dev: b.dev, renderTarget: renderTarget, foreign: true} } -func (b *Backend) CopyTexture(dst driver.Texture, dstOrigin image.Point, src driver.Framebuffer, srcRect image.Rectangle) { - panic("not implemented") +func (b *Backend) CopyTexture(dstTex driver.Texture, dstOrigin image.Point, srcFBO driver.Framebuffer, srcRect image.Rectangle) { + dst := (*d3d11.Resource)(unsafe.Pointer(dstTex.(*Texture).tex)) + src := srcFBO.(*Framebuffer).resource + b.ctx.CopySubresourceRegion( + dst, + 0, // Destination subresource. + uint32(dstOrigin.X), uint32(dstOrigin.Y), 0, // Destination coordinates (x, y, z). + src, + 0, // Source subresource. + &d3d11.BOX{ + Left: uint32(srcRect.Min.X), + Top: uint32(srcRect.Min.Y), + Right: uint32(srcRect.Max.X), + Bottom: uint32(srcRect.Max.Y), + Front: 0, + Back: 1, + }, + ) } func (b *Backend) EndFrame() { @@ -197,6 +223,8 @@ func (b *Backend) NewTexture(format driver.TextureFormat, width, height int, min d3dfmt = b.floatFormat case driver.TextureFormatSRGBA: d3dfmt = d3d11.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB + case driver.TextureFormatRGBA8: + d3dfmt = d3d11.DXGI_FORMAT_R8G8B8A8_UNORM default: return nil, fmt.Errorf("unsupported texture format %d", format) } @@ -218,6 +246,7 @@ func (b *Backend) NewTexture(format driver.TextureFormat, width, height int, min var ( sampler *d3d11.SamplerState resView *d3d11.ShaderResourceView + uaView *d3d11.UnorderedAccessView ) if bindings&driver.BufferBindingTexture != 0 { var filter uint32 @@ -244,9 +273,9 @@ func (b *Backend) NewTexture(format driver.TextureFormat, width, height int, min d3d11.IUnknownRelease(unsafe.Pointer(tex), tex.Vtbl.Release) return nil, err } - resView, err = b.dev.CreateShaderResourceViewTEX2D( + resView, err = b.dev.CreateShaderResourceView( (*d3d11.Resource)(unsafe.Pointer(tex)), - &d3d11.SHADER_RESOURCE_VIEW_DESC_TEX2D{ + unsafe.Pointer(&d3d11.SHADER_RESOURCE_VIEW_DESC_TEX2D{ SHADER_RESOURCE_VIEW_DESC: d3d11.SHADER_RESOURCE_VIEW_DESC{ Format: d3dfmt, ViewDimension: d3d11.SRV_DIMENSION_TEXTURE2D, @@ -255,7 +284,7 @@ func (b *Backend) NewTexture(format driver.TextureFormat, width, height int, min MostDetailedMip: 0, MipLevels: ^uint32(0), }, - }, + }), ) if err != nil { d3d11.IUnknownRelease(unsafe.Pointer(tex), tex.Vtbl.Release) @@ -263,7 +292,31 @@ func (b *Backend) NewTexture(format driver.TextureFormat, width, height int, min return nil, err } } - return &Texture{backend: b, format: d3dfmt, tex: tex, sampler: sampler, resView: resView, bindings: bindings, width: width, height: height}, nil + if bindings&driver.BufferBindingShaderStorageWrite != 0 { + uaView, err = b.dev.CreateUnorderedAccessView( + (*d3d11.Resource)(unsafe.Pointer(tex)), + unsafe.Pointer(&d3d11.UNORDERED_ACCESS_VIEW_DESC_TEX2D{ + UNORDERED_ACCESS_VIEW_DESC: d3d11.UNORDERED_ACCESS_VIEW_DESC{ + Format: d3dfmt, + ViewDimension: d3d11.UAV_DIMENSION_TEXTURE2D, + }, + Texture2D: d3d11.TEX2D_UAV{ + MipSlice: 0, + }, + }), + ) + if err != nil { + if sampler != nil { + d3d11.IUnknownRelease(unsafe.Pointer(sampler), sampler.Vtbl.Release) + } + if resView != nil { + d3d11.IUnknownRelease(unsafe.Pointer(resView), resView.Vtbl.Release) + } + d3d11.IUnknownRelease(unsafe.Pointer(tex), tex.Vtbl.Release) + return nil, err + } + } + return &Texture{backend: b, format: d3dfmt, tex: tex, sampler: sampler, resView: resView, uaView: uaView, bindings: bindings, width: width, height: height}, nil } func (b *Backend) NewFramebuffer(tex driver.Texture) (driver.Framebuffer, error) { @@ -346,23 +399,78 @@ func (b *Backend) newBuffer(typ driver.BufferBinding, size int, data []byte, imm } } bind := convBufferBinding(typ) - var usage uint32 + var usage, miscFlags, cpuFlags uint32 if immutable { usage = d3d11.USAGE_IMMUTABLE } + if typ&driver.BufferBindingShaderStorageWrite != 0 { + cpuFlags = d3d11.CPU_ACCESS_READ + } + if typ&(driver.BufferBindingShaderStorageRead|driver.BufferBindingShaderStorageWrite) != 0 { + miscFlags |= d3d11.RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS + } buf, err := b.dev.CreateBuffer(&d3d11.BUFFER_DESC{ - ByteWidth: uint32(size), - Usage: usage, - BindFlags: bind, + ByteWidth: uint32(size), + Usage: usage, + BindFlags: bind, + CPUAccessFlags: cpuFlags, + MiscFlags: miscFlags, }, data) if err != nil { return nil, err } - return &Buffer{backend: b, buf: buf, bind: bind, size: size, immutable: immutable}, nil + var ( + resView *d3d11.ShaderResourceView + uaView *d3d11.UnorderedAccessView + ) + if typ&driver.BufferBindingShaderStorageWrite != 0 { + uaView, err = b.dev.CreateUnorderedAccessView( + (*d3d11.Resource)(unsafe.Pointer(buf)), + unsafe.Pointer(&d3d11.UNORDERED_ACCESS_VIEW_DESC_BUFFER{ + UNORDERED_ACCESS_VIEW_DESC: d3d11.UNORDERED_ACCESS_VIEW_DESC{ + Format: d3d11.DXGI_FORMAT_R32_TYPELESS, + ViewDimension: d3d11.UAV_DIMENSION_BUFFER, + }, + Buffer: d3d11.BUFFER_UAV{ + FirstElement: 0, + NumElements: uint32(size / 4), + Flags: d3d11.BUFFER_UAV_FLAG_RAW, + }, + }), + ) + if err != nil { + d3d11.IUnknownRelease(unsafe.Pointer(buf), buf.Vtbl.Release) + return nil, err + } + } else if typ&driver.BufferBindingShaderStorageRead != 0 { + resView, err = b.dev.CreateShaderResourceView( + (*d3d11.Resource)(unsafe.Pointer(buf)), + unsafe.Pointer(&d3d11.SHADER_RESOURCE_VIEW_DESC_BUFFEREX{ + SHADER_RESOURCE_VIEW_DESC: d3d11.SHADER_RESOURCE_VIEW_DESC{ + Format: d3d11.DXGI_FORMAT_R32_TYPELESS, + ViewDimension: d3d11.SRV_DIMENSION_BUFFEREX, + }, + Buffer: d3d11.BUFFEREX_SRV{ + FirstElement: 0, + NumElements: uint32(size / 4), + Flags: d3d11.BUFFEREX_SRV_FLAG_RAW, + }, + }), + ) + if err != nil { + d3d11.IUnknownRelease(unsafe.Pointer(buf), buf.Vtbl.Release) + return nil, err + } + } + return &Buffer{backend: b, buf: buf, bind: bind, size: size, resView: resView, uaView: uaView, immutable: immutable}, nil } func (b *Backend) NewComputeProgram(shader shader.Sources) (driver.Program, error) { - panic("not implemented") + cs, err := b.dev.CreateComputeShader([]byte(shader.DXBC)) + if err != nil { + return nil, err + } + return &Program{backend: b, shader: cs}, nil } func (b *Backend) NewPipeline(desc driver.PipelineDesc) (driver.Pipeline, error) { @@ -476,15 +584,19 @@ func (b *Backend) prepareDraw(mode driver.DrawMode) { } func (b *Backend) BindImageTexture(unit int, tex driver.Texture, access driver.AccessBits, f driver.TextureFormat) { - panic("not implemented") + t := tex.(*Texture) + if access&driver.AccessWrite == 0 { + b.ctx.CSSetShaderResources(uint32(unit), t.resView) + } else { + b.ctx.CSSetUnorderedAccessViews(uint32(unit), t.uaView) + } } -func (b *Backend) MemoryBarrier() { - panic("not implemented") -} +func (b *Backend) MemoryBarrier() {} func (b *Backend) DispatchCompute(x, y, z int) { - panic("not implemented") + b.ctx.CSSetShader(b.program.shader) + b.ctx.Dispatch(uint32(x), uint32(y), uint32(z)) } func (t *Texture) Upload(offset, size image.Point, pixels []byte, stride int) { @@ -504,16 +616,17 @@ func (t *Texture) Upload(offset, size image.Point, pixels []byte, stride int) { } func (t *Texture) Release() { - d3d11.IUnknownRelease(unsafe.Pointer(t.tex), t.tex.Vtbl.Release) - t.tex = nil if t.sampler != nil { d3d11.IUnknownRelease(unsafe.Pointer(t.sampler), t.sampler.Vtbl.Release) - t.sampler = nil } if t.resView != nil { d3d11.IUnknownRelease(unsafe.Pointer(t.resView), t.resView.Vtbl.Release) - t.resView = nil } + if t.uaView != nil { + d3d11.IUnknownRelease(unsafe.Pointer(t.uaView), t.uaView.Vtbl.Release) + } + d3d11.IUnknownRelease(unsafe.Pointer(t.tex), t.tex.Vtbl.Release) + *t = Texture{} } func (b *Backend) BindTexture(unit int, tex driver.Texture) { @@ -527,7 +640,7 @@ func (b *Backend) BindPipeline(pipe driver.Pipeline) { } func (b *Backend) BindProgram(prog driver.Program) { - panic("not implemented") + b.program = prog.(*Program) } func (s *VertexShader) Release() { @@ -540,6 +653,11 @@ func (s *FragmentShader) Release() { *s = FragmentShader{} } +func (s *Program) Release() { + d3d11.IUnknownRelease(unsafe.Pointer(s.shader), s.shader.Vtbl.Release) + *s = Program{} +} + func (p *Pipeline) Release() { d3d11.IUnknownRelease(unsafe.Pointer(p.vert), p.vert.Vtbl.Release) d3d11.IUnknownRelease(unsafe.Pointer(p.frag), p.frag.Vtbl.Release) @@ -551,7 +669,12 @@ func (p *Pipeline) Release() { } func (b *Backend) BindStorageBuffer(binding int, buffer driver.Buffer) { - panic("not implemented") + buf := buffer.(*Buffer) + if buf.resView != nil { + b.ctx.CSSetShaderResources(uint32(binding), buf.resView) + } else { + b.ctx.CSSetUnorderedAccessViews(uint32(binding), buf.uaView) + } } func (b *Backend) BindVertexUniforms(buffer driver.Buffer) { @@ -573,8 +696,16 @@ func (b *Backend) BindIndexBuffer(buf driver.Buffer) { b.ctx.IASetIndexBuffer(buf.(*Buffer).buf, d3d11.DXGI_FORMAT_R16_UINT, 0) } -func (b *Buffer) Download(data []byte) error { - panic("not implemented") +func (b *Buffer) Download(dst []byte) error { + res := (*d3d11.Resource)(unsafe.Pointer(b.buf)) + resMap, err := b.backend.ctx.Map(res, 0, d3d11.MAP_READ, 0) + if err != nil { + return fmt.Errorf("d3d11: %v", err) + } + defer b.backend.ctx.Unmap(res, 0) + data := sliceOf(resMap.PData, len(dst)) + copy(dst, data) + return nil } func (b *Buffer) Upload(data []byte) { @@ -593,8 +724,14 @@ func (b *Buffer) Upload(data []byte) { } func (b *Buffer) Release() { + if b.resView != nil { + d3d11.IUnknownRelease(unsafe.Pointer(b.resView), b.resView.Vtbl.Release) + } + if b.uaView != nil { + d3d11.IUnknownRelease(unsafe.Pointer(b.uaView), b.uaView.Vtbl.Release) + } d3d11.IUnknownRelease(unsafe.Pointer(b.buf), b.buf.Vtbl.Release) - b.buf = nil + *b = Buffer{} } func (f *Framebuffer) ReadPixels(src image.Rectangle, pixels []byte, stride int) error { @@ -691,6 +828,11 @@ func convBufferBinding(typ driver.BufferBinding) uint32 { if typ&driver.BufferBindingFramebuffer != 0 { bindings |= d3d11.BIND_RENDER_TARGET } + if typ&driver.BufferBindingShaderStorageWrite != 0 { + bindings |= d3d11.BIND_UNORDERED_ACCESS + } else if typ&driver.BufferBindingShaderStorageRead != 0 { + bindings |= d3d11.BIND_SHADER_RESOURCE + } return bindings } diff --git a/internal/d3d11/d3d11_windows.go b/internal/d3d11/d3d11_windows.go index 4d26611b..450fde1a 100644 --- a/internal/d3d11/d3d11_windows.go +++ b/internal/d3d11/d3d11_windows.go @@ -74,16 +74,52 @@ type SHADER_RESOURCE_VIEW_DESC_TEX2D struct { Texture2D TEX2D_SRV } +type SHADER_RESOURCE_VIEW_DESC_BUFFEREX struct { + SHADER_RESOURCE_VIEW_DESC + Buffer BUFFEREX_SRV +} + +type UNORDERED_ACCESS_VIEW_DESC_TEX2D struct { + UNORDERED_ACCESS_VIEW_DESC + Texture2D TEX2D_UAV +} + +type UNORDERED_ACCESS_VIEW_DESC_BUFFER struct { + UNORDERED_ACCESS_VIEW_DESC + Buffer BUFFER_UAV +} + type SHADER_RESOURCE_VIEW_DESC struct { Format uint32 ViewDimension uint32 } +type UNORDERED_ACCESS_VIEW_DESC struct { + Format uint32 + ViewDimension uint32 +} + type TEX2D_SRV struct { MostDetailedMip uint32 MipLevels uint32 } +type BUFFEREX_SRV struct { + FirstElement uint32 + NumElements uint32 + Flags uint32 +} + +type TEX2D_UAV struct { + MipSlice uint32 +} + +type BUFFER_UAV struct { + FirstElement uint32 + NumElements uint32 + Flags uint32 +} + type INPUT_ELEMENT_DESC struct { SemanticName *byte SemanticIndex uint32 @@ -336,6 +372,12 @@ type ShaderResourceView struct { } } +type UnorderedAccessView struct { + Vtbl *struct { + _IUnknownVTbl + } +} + type DepthStencilView struct { Vtbl *struct { _IUnknownVTbl @@ -360,6 +402,12 @@ type VertexShader struct { } } +type ComputeShader struct { + Vtbl *struct { + _IUnknownVTbl + } +} + type RasterizerState struct { Vtbl *struct { _IUnknownVTbl @@ -590,9 +638,11 @@ const ( DXGI_FORMAT_UNKNOWN = 0 DXGI_FORMAT_R16_FLOAT = 54 DXGI_FORMAT_R32_FLOAT = 41 + DXGI_FORMAT_R32_TYPELESS = 39 DXGI_FORMAT_R32G32_FLOAT = 16 DXGI_FORMAT_R32G32B32_FLOAT = 6 DXGI_FORMAT_R32G32B32A32_FLOAT = 2 + DXGI_FORMAT_R8G8B8A8_UNORM = 28 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29 DXGI_FORMAT_R16_SINT = 59 DXGI_FORMAT_R16G16_SINT = 38 @@ -623,12 +673,13 @@ const ( USAGE_IMMUTABLE = 1 USAGE_STAGING = 3 - BIND_VERTEX_BUFFER = 0x1 - BIND_INDEX_BUFFER = 0x2 - BIND_CONSTANT_BUFFER = 0x4 - BIND_SHADER_RESOURCE = 0x8 - BIND_RENDER_TARGET = 0x20 - BIND_DEPTH_STENCIL = 0x40 + BIND_VERTEX_BUFFER = 0x1 + BIND_INDEX_BUFFER = 0x2 + BIND_CONSTANT_BUFFER = 0x4 + BIND_SHADER_RESOURCE = 0x8 + BIND_RENDER_TARGET = 0x20 + BIND_DEPTH_STENCIL = 0x40 + BIND_UNORDERED_ACCESS = 0x80 PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4 PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5 @@ -640,7 +691,16 @@ const ( TEXTURE_ADDRESS_CLAMP = 3 TEXTURE_ADDRESS_WRAP = 1 + SRV_DIMENSION_BUFFER = 1 + UAV_DIMENSION_BUFFER = 1 + SRV_DIMENSION_BUFFEREX = 11 SRV_DIMENSION_TEXTURE2D = 4 + UAV_DIMENSION_TEXTURE2D = 4 + + BUFFER_UAV_FLAG_RAW = 0x1 + BUFFEREX_SRV_FLAG_RAW = 0x1 + + RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS = 0x20 CREATE_DEVICE_DEBUG = 0x2 @@ -855,14 +915,32 @@ func (d *Device) CreateVertexShader(bytecode []byte) (*VertexShader, error) { return shader, nil } -func (d *Device) CreateShaderResourceViewTEX2D(res *Resource, desc *SHADER_RESOURCE_VIEW_DESC_TEX2D) (*ShaderResourceView, error) { +func (d *Device) CreateComputeShader(bytecode []byte) (*ComputeShader, error) { + var shader *ComputeShader + r, _, _ := syscall.Syscall6( + d.Vtbl.CreateComputeShader, + 5, + uintptr(unsafe.Pointer(d)), + uintptr(unsafe.Pointer(&bytecode[0])), + uintptr(len(bytecode)), + 0, // pClassLinkage + uintptr(unsafe.Pointer(&shader)), + 0, + ) + if r != 0 { + return nil, ErrorCode{Name: "DeviceCreateComputeShader", Code: uint32(r)} + } + return shader, nil +} + +func (d *Device) CreateShaderResourceView(res *Resource, desc unsafe.Pointer) (*ShaderResourceView, error) { var resView *ShaderResourceView r, _, _ := syscall.Syscall6( d.Vtbl.CreateShaderResourceView, 4, uintptr(unsafe.Pointer(d)), uintptr(unsafe.Pointer(res)), - uintptr(unsafe.Pointer(desc)), + uintptr(desc), uintptr(unsafe.Pointer(&resView)), 0, 0, ) @@ -872,6 +950,23 @@ func (d *Device) CreateShaderResourceViewTEX2D(res *Resource, desc *SHADER_RESOU return resView, nil } +func (d *Device) CreateUnorderedAccessView(res *Resource, desc unsafe.Pointer) (*UnorderedAccessView, error) { + var uaView *UnorderedAccessView + r, _, _ := syscall.Syscall6( + d.Vtbl.CreateUnorderedAccessView, + 4, + uintptr(unsafe.Pointer(d)), + uintptr(unsafe.Pointer(res)), + uintptr(desc), + uintptr(unsafe.Pointer(&uaView)), + 0, 0, + ) + if r != 0 { + return nil, ErrorCode{Name: "DeviceCreateUnorderedAccessView", Code: uint32(r)} + } + return uaView, nil +} + func (d *Device) CreateRasterizerState(desc *RASTERIZER_DESC) (*RasterizerState, error) { var state *RasterizerState r, _, _ := syscall.Syscall( @@ -1162,6 +1257,42 @@ func (c *DeviceContext) ClearRenderTargetView(target *RenderTargetView, color *[ ) } +func (c *DeviceContext) CSSetShaderResources(startSlot uint32, s *ShaderResourceView) { + syscall.Syscall6( + c.Vtbl.CSSetShaderResources, + 4, + uintptr(unsafe.Pointer(c)), + uintptr(startSlot), + 1, // NumViews + uintptr(unsafe.Pointer(&s)), + 0, 0, + ) +} + +func (c *DeviceContext) CSSetUnorderedAccessViews(startSlot uint32, v *UnorderedAccessView) { + syscall.Syscall6( + c.Vtbl.CSSetUnorderedAccessViews, + 4, + uintptr(unsafe.Pointer(c)), + uintptr(startSlot), + 1, // NumViews + uintptr(unsafe.Pointer(&v)), + 0, 0, + ) +} + +func (c *DeviceContext) CSSetShader(s *ComputeShader) { + syscall.Syscall6( + c.Vtbl.CSSetShader, + 4, + uintptr(unsafe.Pointer(c)), + uintptr(unsafe.Pointer(s)), + 0, // ppClassInstances + 0, // NumClassInstances + 0, 0, + ) +} + func (c *DeviceContext) RSSetViewports(viewport *VIEWPORT) { syscall.Syscall( c.Vtbl.RSSetViewports, @@ -1365,6 +1496,18 @@ func (c *DeviceContext) DrawIndexed(count, start uint32, base int32) { ) } +func (c *DeviceContext) Dispatch(x, y, z uint32) { + syscall.Syscall6( + c.Vtbl.Dispatch, + 4, + uintptr(unsafe.Pointer(c)), + uintptr(x), + uintptr(y), + uintptr(z), + 0, 0, + ) +} + func (c *DeviceContext) OMSetBlendState(state *BlendState, factor *f32color.RGBA, sampleMask uint32) { syscall.Syscall6( c.Vtbl.OMSetBlendState,