updated ebiten version from 2.7.9 to 2.9.9

This commit is contained in:
2026-06-15 19:06:55 +02:00
parent 21edbc41c4
commit db1b625069
405 changed files with 31913 additions and 12595 deletions
@@ -16,94 +16,232 @@
package directx
// Some functions of ID3D12GraphicsCommandList has additional logics besides the original COM function call.
// Some functions must be called with C++ directly for some reasons.
// Then, instead of calling them by LazyProc.Call, we have to defer this call to the C++ side.
// These functions are chosen based on the DirectX header file's implementation.
//
// These functions should be defined on the C++ side like this:
//
// extern "C" {
// void Ebitengine_ID3D12GraphicsCommandList_ClearDepthStencilView(void* i, uintptr_t depthStencilView, int32_t clearFlags, float depth, uint8_t stencil, uint32_t numRects, void* pRects) {
// static_cast<ID3D12GraphicsCommandList*>(i)->ClearDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE{ depthStencilView }, static_cast<D3D12_CLEAR_FLAGS>(clearFlags), depth, stencil, numRects, static_cast<D3D12_RECT*>(pRects));
// }
// void Ebitengine_ID3D12GraphicsCommandList_ClearRenderTargetView(void* i, uintptr_t pRenderTargetView, void* colorRGBA, uint32_t numRects, void* pRects) {
// static_cast<ID3D12GraphicsCommandList*>(i)->ClearRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE{ pRenderTargetView }, static_cast<FLOAT*>(colorRGBA), numRects, static_cast<D3D12_RECT*>(pRects));
// }
// uintptr_t Ebitengine_ID3D12GraphicsCommandList_Close(void* i) {
// auto r = static_cast<ID3D12GraphicsCommandList*>(i)->Close();
// return uintptr_t(r);
// }
// void Ebitengine_ID3D12GraphicsCommandList_CopyTextureRegion(void* i, void* pDst, uint32_t dstX, uint32_t dstY, uint32_t dstZ, void* pSrc, void* pSrcBox) {
// static_cast<ID3D12GraphicsCommandList*>(i)->CopyTextureRegion(static_cast<D3D12_TEXTURE_COPY_LOCATION*>(pDst), dstX, dstY, dstZ, static_cast<D3D12_TEXTURE_COPY_LOCATION*>(pSrc), static_cast<D3D12_BOX*>(pSrcBox));
// }
// void Ebitengine_ID3D12GraphicsCommandList_DrawIndexedInstanced(void* i, uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) {
// static_cast<ID3D12GraphicsCommandList*>(i)->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
// }
// void Ebitengine_ID3D12GraphicsCommandList_IASetIndexBuffer(void* i, void* pView) {
// static_cast<ID3D12GraphicsCommandList*>(i)->IASetIndexBuffer(static_cast<D3D12_INDEX_BUFFER_VIEW*>(pView));
// }
// void Ebitengine_ID3D12GraphicsCommandList_IASetPrimitiveTopology(void* i, int32_t primitiveTopology) {
// static_cast<ID3D12GraphicsCommandList*>(i)->IASetPrimitiveTopology(static_cast<D3D12_PRIMITIVE_TOPOLOGY>(primitiveTopology));
// }
// void Ebitengine_ID3D12GraphicsCommandList_IASetVertexBuffers(void* i, uint32_t startSlot, uint32_t numViews, void* pViews) {
// static_cast<ID3D12GraphicsCommandList*>(i)->IASetVertexBuffers(startSlot, numViews, static_cast<D3D12_VERTEX_BUFFER_VIEW*>(pViews));
// }
// void Ebitengine_ID3D12GraphicsCommandList_OMSetRenderTargets(void* i, uint32_t numRenderTargetDescriptors, void* pRenderTargetDescriptors, int rtsSingleHandleToDescriptorRange, void* pDepthStencilDescriptor) {
// static_cast<ID3D12GraphicsCommandList*>(i)->OMSetRenderTargets(numRenderTargetDescriptors, static_cast<D3D12_CPU_DESCRIPTOR_HANDLE*>(pRenderTargetDescriptors), static_cast<BOOL>(rtsSingleHandleToDescriptorRange), static_cast<D3D12_CPU_DESCRIPTOR_HANDLE*>(pDepthStencilDescriptor));
// }
// void Ebitengine_ID3D12GraphicsCommandList_OMSetStencilRef(void* i, uint32_t stencilRef) {
// static_cast<ID3D12GraphicsCommandList*>(i)->OMSetStencilRef(stencilRef);
// }
// uint32_t Ebitengine_ID3D12GraphicsCommandList_Release(void* i) {
// return static_cast<uint32_t>(static_cast<ID3D12GraphicsCommandList*>(i)->Release());
// }
// uintptr_t Ebitengine_ID3D12GraphicsCommandList_Reset(void* i, void* pAllocator, void* pInitialState) {
// auto r = static_cast<ID3D12GraphicsCommandList*>(i)->Reset(static_cast<ID3D12CommandAllocator*>(pAllocator), static_cast<ID3D12PipelineState*>(pInitialState));
// return static_cast<uintptr_t>(r);
// }
// void Ebitengine_ID3D12GraphicsCommandList_ResourceBarrier(void* i, uint32_t numBarriers, void* pBarriers) {
// static_cast<ID3D12GraphicsCommandList*>(i)->ResourceBarrier(numBarriers, static_cast<D3D12_RESOURCE_BARRIER*>(pBarriers));
// }
// void Ebitengine_ID3D12GraphicsCommandList_RSSetViewports(void* i, uint32_t numViewports, void* pViewports) {
// static_cast<ID3D12GraphicsCommandList*>(i)->RSSetViewports(numViewports, static_cast<D3D12_VIEWPORT*>(pViewports));
// }
// void Ebitengine_ID3D12GraphicsCommandList_RSSetScissorRects(void* i, uint32_t numRects, void* pRects) {
// static_cast<ID3D12GraphicsCommandList*>(i)->RSSetScissorRects(numRects, static_cast<D3D12_RECT*>(pRects));
// }
// void Ebitengine_ID3D12GraphicsCommandList_SetDescriptorHeaps(void* i, uint32_t numDescriptorHeaps, void* ppDescriptorHeaps) {
// static_cast<ID3D12GraphicsCommandList*>(i)->SetDescriptorHeaps(numDescriptorHeaps, static_cast<ID3D12DescriptorHeap**>(ppDescriptorHeaps));
// }
// void Ebitengine_ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(void* i, uint32_t rootParameterIndex, uint64_t baseDescriptorPtr) {
// static_cast<ID3D12GraphicsCommandList*>(i)->SetGraphicsRootDescriptorTable(rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE{ baseDescriptorPtr });
// }
// void Ebitengine_ID3D12GraphicsCommandList_SetGraphicsRootSignature(void* i, void* pRootSignature) {
// static_cast<ID3D12GraphicsCommandList*>(i)->SetGraphicsRootSignature(static_cast<ID3D12RootSignature*>(pRootSignature));
// }
// void Ebitengine_ID3D12GraphicsCommandList_SetPipelineState(void* i, void* pPipelineState) {
// static_cast<ID3D12GraphicsCommandList*>(i)->SetPipelineState(static_cast<ID3D12PipelineState*>(pPipelineState));
// }
// }
/*
extern "C" {
int32_t Ebitengine_D3D12_RESOURCE_STATE_PRESENT() {
return static_cast<int32_t>(D3D12_RESOURCE_STATE_PRESENT);
}
void Ebitengine_ID3D12CommandQueue_ExecuteCommandLists(void* i, uint32_t numCommandLists, void* ppCommandLists) {
static_cast<ID3D12CommandQueue*>(i)->ExecuteCommandLists(numCommandLists, static_cast<ID3D12CommandList**>(ppCommandLists));
}
uintptr_t Ebitengine_ID3D12CommandQueue_PresentX(void* i, uint32_t planeCount, void* pPlaneParameters, void* pPresentParameters) {
auto r = static_cast<ID3D12CommandQueue*>(i)->PresentX(planeCount, static_cast<D3D12XBOX_PRESENT_PLANE_PARAMETERS*>(pPlaneParameters), static_cast<D3D12XBOX_PRESENT_PARAMETERS*>(pPresentParameters));
return static_cast<uintptr_t>(r);
}
uint32_t Ebitengine_ID3D12CommandQueue_Release(void* i) {
auto r = static_cast<ID3D12CommandQueue*>(i)->Release();
return static_cast<uint32_t>(r);
}
uintptr_t Ebitengine_ID3D12CommandQueue_ResumeX(void* i) {
auto r = static_cast<ID3D12CommandQueue*>(i)->ResumeX();
return static_cast<uintptr_t>(r);
}
uintptr_t Ebitengine_ID3D12CommandQueue_Signal(void* i, void* pFence, uint64_t value) {
auto r = static_cast<ID3D12CommandQueue*>(i)->Signal(static_cast<ID3D12Fence*>(pFence), value);
return static_cast<uintptr_t>(r);
}
uintptr_t Ebitengine_ID3D12CommandQueue_SuspendX(void* i, uint32_t flags) {
auto r = static_cast<ID3D12CommandQueue*>(i)->SuspendX(flags);
return static_cast<uintptr_t>(r);
}
void Ebitengine_ID3D12GraphicsCommandList_ClearDepthStencilView(void* i, uintptr_t depthStencilView, int32_t clearFlags, float depth, uint8_t stencil, uint32_t numRects, void* pRects) {
static_cast<ID3D12GraphicsCommandList*>(i)->ClearDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE{ depthStencilView }, static_cast<D3D12_CLEAR_FLAGS>(clearFlags), depth, stencil, numRects, static_cast<D3D12_RECT*>(pRects));
}
void Ebitengine_ID3D12GraphicsCommandList_ClearRenderTargetView(void* i, uintptr_t pRenderTargetView, void* colorRGBA, uint32_t numRects, void* pRects) {
static_cast<ID3D12GraphicsCommandList*>(i)->ClearRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE{ pRenderTargetView }, static_cast<FLOAT*>(colorRGBA), numRects, static_cast<D3D12_RECT*>(pRects));
}
uintptr_t Ebitengine_ID3D12GraphicsCommandList_Close(void* i) {
auto r = static_cast<ID3D12GraphicsCommandList*>(i)->Close();
return uintptr_t(r);
}
void Ebitengine_ID3D12GraphicsCommandList_CopyTextureRegion(void* i, void* pDst, uint32_t dstX, uint32_t dstY, uint32_t dstZ, void* pSrc, void* pSrcBox) {
static_cast<ID3D12GraphicsCommandList*>(i)->CopyTextureRegion(static_cast<D3D12_TEXTURE_COPY_LOCATION*>(pDst), dstX, dstY, dstZ, static_cast<D3D12_TEXTURE_COPY_LOCATION*>(pSrc), static_cast<D3D12_BOX*>(pSrcBox));
}
void Ebitengine_ID3D12GraphicsCommandList_DrawIndexedInstanced(void* i, uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) {
static_cast<ID3D12GraphicsCommandList*>(i)->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
}
void Ebitengine_ID3D12GraphicsCommandList_IASetIndexBuffer(void* i, void* pView) {
static_cast<ID3D12GraphicsCommandList*>(i)->IASetIndexBuffer(static_cast<D3D12_INDEX_BUFFER_VIEW*>(pView));
}
void Ebitengine_ID3D12GraphicsCommandList_IASetPrimitiveTopology(void* i, int32_t primitiveTopology) {
static_cast<ID3D12GraphicsCommandList*>(i)->IASetPrimitiveTopology(static_cast<D3D12_PRIMITIVE_TOPOLOGY>(primitiveTopology));
}
void Ebitengine_ID3D12GraphicsCommandList_IASetVertexBuffers(void* i, uint32_t startSlot, uint32_t numViews, void* pViews) {
static_cast<ID3D12GraphicsCommandList*>(i)->IASetVertexBuffers(startSlot, numViews, static_cast<D3D12_VERTEX_BUFFER_VIEW*>(pViews));
}
void Ebitengine_ID3D12GraphicsCommandList_OMSetRenderTargets(void* i, uint32_t numRenderTargetDescriptors, void* pRenderTargetDescriptors, int rtsSingleHandleToDescriptorRange, void* pDepthStencilDescriptor) {
static_cast<ID3D12GraphicsCommandList*>(i)->OMSetRenderTargets(numRenderTargetDescriptors, static_cast<D3D12_CPU_DESCRIPTOR_HANDLE*>(pRenderTargetDescriptors), static_cast<BOOL>(rtsSingleHandleToDescriptorRange), static_cast<D3D12_CPU_DESCRIPTOR_HANDLE*>(pDepthStencilDescriptor));
}
void Ebitengine_ID3D12GraphicsCommandList_OMSetStencilRef(void* i, uint32_t stencilRef) {
static_cast<ID3D12GraphicsCommandList*>(i)->OMSetStencilRef(stencilRef);
}
uint32_t Ebitengine_ID3D12GraphicsCommandList_Release(void* i) {
return static_cast<uint32_t>(static_cast<ID3D12GraphicsCommandList*>(i)->Release());
}
uintptr_t Ebitengine_ID3D12GraphicsCommandList_Reset(void* i, void* pAllocator, void* pInitialState) {
auto r = static_cast<ID3D12GraphicsCommandList*>(i)->Reset(static_cast<ID3D12CommandAllocator*>(pAllocator), static_cast<ID3D12PipelineState*>(pInitialState));
return static_cast<uintptr_t>(r);
}
void Ebitengine_ID3D12GraphicsCommandList_ResourceBarrier(void* i, uint32_t numBarriers, void* pBarriers) {
static_cast<ID3D12GraphicsCommandList*>(i)->ResourceBarrier(numBarriers, static_cast<D3D12_RESOURCE_BARRIER*>(pBarriers));
}
void Ebitengine_ID3D12GraphicsCommandList_RSSetViewports(void* i, uint32_t numViewports, void* pViewports) {
static_cast<ID3D12GraphicsCommandList*>(i)->RSSetViewports(numViewports, static_cast<D3D12_VIEWPORT*>(pViewports));
}
void Ebitengine_ID3D12GraphicsCommandList_RSSetScissorRects(void* i, uint32_t numRects, void* pRects) {
static_cast<ID3D12GraphicsCommandList*>(i)->RSSetScissorRects(numRects, static_cast<D3D12_RECT*>(pRects));
}
void Ebitengine_ID3D12GraphicsCommandList_SetDescriptorHeaps(void* i, uint32_t numDescriptorHeaps, void* ppDescriptorHeaps) {
static_cast<ID3D12GraphicsCommandList*>(i)->SetDescriptorHeaps(numDescriptorHeaps, static_cast<ID3D12DescriptorHeap**>(ppDescriptorHeaps));
}
void Ebitengine_ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(void* i, uint32_t rootParameterIndex, uint64_t baseDescriptorPtr) {
static_cast<ID3D12GraphicsCommandList*>(i)->SetGraphicsRootDescriptorTable(rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE{ baseDescriptorPtr });
}
void Ebitengine_ID3D12GraphicsCommandList_SetGraphicsRootSignature(void* i, void* pRootSignature) {
static_cast<ID3D12GraphicsCommandList*>(i)->SetGraphicsRootSignature(static_cast<ID3D12RootSignature*>(pRootSignature));
}
void Ebitengine_ID3D12GraphicsCommandList_SetPipelineState(void* i, void* pPipelineState) {
static_cast<ID3D12GraphicsCommandList*>(i)->SetPipelineState(static_cast<ID3D12PipelineState*>(pPipelineState));
}
}
*/
// #include <stdint.h>
//
// #cgo noescape D3D12_RESOURCE_STATE_PRESENT
// #cgo nocallback D3D12_RESOURCE_STATE_PRESENT
// int32_t Ebitengine_D3D12_RESOURCE_STATE_PRESENT();
//
// #cgo noescape ID3D12CommandQueue_ExecuteCommandLists
// #cgo nocallback ID3D12CommandQueue_ExecuteCommandLists
// void Ebitengine_ID3D12CommandQueue_ExecuteCommandLists(void* i, uint32_t numCommandLists, void* ppCommandLists);
//
// #cgo noescape ID3D12CommandQueue_PresentX
// #cgo nocallback ID3D12CommandQueue_PresentX
// uintptr_t Ebitengine_ID3D12CommandQueue_PresentX(void* i, uint32_t planeCount, void* pPlaneParameters, void* pPresentParameters);
//
// #cgo noescape ID3D12CommandQueue_Release
// #cgo nocallback ID3D12CommandQueue_Release
// uint32_t Ebitengine_ID3D12CommandQueue_Release(void* i);
//
// #cgo noescape ID3D12CommandQueue_ResumeX
// #cgo nocallback ID3D12CommandQueue_ResumeX
// uintptr_t Ebitengine_ID3D12CommandQueue_ResumeX(void* i);
//
// #cgo noescape ID3D12CommandQueue_Signal
// #cgo nocallback ID3D12CommandQueue_Signal
// uintptr_t Ebitengine_ID3D12CommandQueue_Signal(void* i, void* pFence, uint64_t value);
//
// #cgo noescape ID3D12CommandQueue_SuspendX
// #cgo nocallback ID3D12CommandQueue_SuspendX
// uintptr_t Ebitengine_ID3D12CommandQueue_SuspendX(void* i, uint32_t flags);
//
// #cgo noescape ID3D12GraphicsCommandList_ClearDepthStencilView
// #cgo nocallback ID3D12GraphicsCommandList_ClearDepthStencilView
// void Ebitengine_ID3D12GraphicsCommandList_ClearDepthStencilView(void* i, uintptr_t depthStencilView, int32_t clearFlags, float depth, uint8_t stencil, uint32_t numRects, void* pRects);
//
// #cgo noescape ID3D12GraphicsCommandList_ClearRenderTargetView
// #cgo nocallback ID3D12GraphicsCommandList_ClearRenderTargetView
// void Ebitengine_ID3D12GraphicsCommandList_ClearRenderTargetView(void* i, uintptr_t pRenderTargetView, void* colorRGBA, uint32_t numRects, void* pRects);
//
// #cgo noescape ID3D12GraphicsCommandList_Close
// #cgo nocallback ID3D12GraphicsCommandList_Close
// uintptr_t Ebitengine_ID3D12GraphicsCommandList_Close(void* i);
//
// #cgo noescape ID3D12GraphicsCommandList_CopyTextureRegion
// #cgo nocallback ID3D12GraphicsCommandList_CopyTextureRegion
// void Ebitengine_ID3D12GraphicsCommandList_CopyTextureRegion(void* i, void* pDst, uint32_t dstX, uint32_t dstY, uint32_t dstZ, void* pSrc, void* pSrcBox);
//
// #cgo noescape ID3D12GraphicsCommandList_DrawIndexedInstanced
// #cgo nocallback ID3D12GraphicsCommandList_DrawIndexedInstanced
// void Ebitengine_ID3D12GraphicsCommandList_DrawIndexedInstanced(void* i, uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation);
//
// #cgo noescape ID3D12GraphicsCommandList_IASetIndexBuffer
// #cgo nocallback ID3D12GraphicsCommandList_IASetIndexBuffer
// void Ebitengine_ID3D12GraphicsCommandList_IASetIndexBuffer(void* i, void* pView);
//
// #cgo noescape ID3D12GraphicsCommandList_IASetPrimitiveTopology
// #cgo nocallback ID3D12GraphicsCommandList_IASetPrimitiveTopology
// void Ebitengine_ID3D12GraphicsCommandList_IASetPrimitiveTopology(void* i, int32_t primitiveTopology);
//
// #cgo noescape ID3D12GraphicsCommandList_IASetVertexBuffers
// #cgo nocallback ID3D12GraphicsCommandList_IASetVertexBuffers
// void Ebitengine_ID3D12GraphicsCommandList_IASetVertexBuffers(void* i, uint32_t startSlot, uint32_t numViews, void* pViews);
//
// #cgo noescape ID3D12GraphicsCommandList_OMSetRenderTargets
// #cgo nocallback ID3D12GraphicsCommandList_OMSetRenderTargets
// void Ebitengine_ID3D12GraphicsCommandList_OMSetRenderTargets(void* i, uint32_t numRenderTargetDescriptors, void* pRenderTargetDescriptors, int rtsSingleHandleToDescriptorRange, void* pDepthStencilDescriptor);
//
// #cgo noescape ID3D12GraphicsCommandList_OMSetStencilRef
// #cgo nocallback ID3D12GraphicsCommandList_OMSetStencilRef
// void Ebitengine_ID3D12GraphicsCommandList_OMSetStencilRef(void* i, uint32_t stencilRef);
//
// #cgo noescape ID3D12GraphicsCommandList_Release
// #cgo nocallback ID3D12GraphicsCommandList_Release
// uint32_t Ebitengine_ID3D12GraphicsCommandList_Release(void* i);
//
// #cgo noescape ID3D12GraphicsCommandList_Reset
// #cgo nocallback ID3D12GraphicsCommandList_Reset
// uintptr_t Ebitengine_ID3D12GraphicsCommandList_Reset(void* i, void* pAllocator, void* pInitialState);
//
// #cgo noescape ID3D12GraphicsCommandList_ResourceBarrier
// #cgo nocallback ID3D12GraphicsCommandList_ResourceBarrier
// void Ebitengine_ID3D12GraphicsCommandList_ResourceBarrier(void* i, uint32_t numBarriers, void* pBarriers);
//
// #cgo noescape ID3D12GraphicsCommandList_RSSetViewports
// #cgo nocallback ID3D12GraphicsCommandList_RSSetViewports
// void Ebitengine_ID3D12GraphicsCommandList_RSSetViewports(void* i, uint32_t numViewports, void* pViewports);
//
// #cgo noescape ID3D12GraphicsCommandList_RSSetScissorRects
// #cgo nocallback ID3D12GraphicsCommandList_RSSetScissorRects
// void Ebitengine_ID3D12GraphicsCommandList_RSSetScissorRects(void* i, uint32_t numRects, void* pRects);
//
// #cgo noescape ID3D12GraphicsCommandList_SetDescriptorHeaps
// #cgo nocallback ID3D12GraphicsCommandList_SetDescriptorHeaps
// void Ebitengine_ID3D12GraphicsCommandList_SetDescriptorHeaps(void* i, uint32_t numDescriptorHeaps, void* ppDescriptorHeaps);
//
// #cgo noescape ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable
// #cgo nocallback ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable
// void Ebitengine_ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(void* i, uint32_t rootParameterIndex, uint64_t baseDescriptorPtr);
//
// #cgo noescape ID3D12GraphicsCommandList_SetGraphicsRootSignature
// #cgo nocallback ID3D12GraphicsCommandList_SetGraphicsRootSignature
// void Ebitengine_ID3D12GraphicsCommandList_SetGraphicsRootSignature(void* i, void* pRootSignature);
//
// #cgo noescape ID3D12GraphicsCommandList_SetPipelineState
// #cgo nocallback ID3D12GraphicsCommandList_SetPipelineState
// void Ebitengine_ID3D12GraphicsCommandList_SetPipelineState(void* i, void* pPipelineState);
import "C"
@@ -111,6 +249,44 @@ import (
"unsafe"
)
func _D3D12_RESOURCE_STATE_PRESENT() _D3D12_RESOURCE_STATES {
// This value depends on the environment.
return _D3D12_RESOURCE_STATES(C.Ebitengine_D3D12_RESOURCE_STATE_PRESENT())
}
func _ID3D12CommandQueue_ExecuteCommandLists(i *_ID3D12CommandQueue, ppCommandLists []*_ID3D12GraphicsCommandList) {
var ppCommandListsPtr **_ID3D12GraphicsCommandList
if len(ppCommandLists) > 0 {
ppCommandListsPtr = &ppCommandLists[0]
}
C.Ebitengine_ID3D12CommandQueue_ExecuteCommandLists(unsafe.Pointer(i), C.uint32_t(len(ppCommandLists)), unsafe.Pointer(ppCommandListsPtr))
}
func _ID3D12CommandQueue_PresentX(i *_ID3D12CommandQueue, planeCount uint32, pPlaneParameters *_D3D12XBOX_PRESENT_PLANE_PARAMETERS, pPresentParameters *_D3D12XBOX_PRESENT_PARAMETERS) uintptr {
r := C.Ebitengine_ID3D12CommandQueue_PresentX(unsafe.Pointer(i), C.uint32_t(planeCount), unsafe.Pointer(pPlaneParameters), unsafe.Pointer(pPresentParameters))
return uintptr(r)
}
func _ID3D12CommandQueue_Release(i *_ID3D12CommandQueue) uint32 {
r := C.Ebitengine_ID3D12CommandQueue_Release(unsafe.Pointer(i))
return uint32(r)
}
func _ID3D12CommandQueue_ResumeX(i *_ID3D12CommandQueue) uintptr {
r := C.Ebitengine_ID3D12CommandQueue_ResumeX(unsafe.Pointer(i))
return uintptr(r)
}
func _ID3D12CommandQueue_Signal(i *_ID3D12CommandQueue, pFence *_ID3D12Fence, value uint64) uintptr {
r := C.Ebitengine_ID3D12CommandQueue_Signal(unsafe.Pointer(i), unsafe.Pointer(pFence), C.uint64_t(value))
return uintptr(r)
}
func _ID3D12CommandQueue_SuspendX(i *_ID3D12CommandQueue, flags uint32) uintptr {
r := C.Ebitengine_ID3D12CommandQueue_SuspendX(unsafe.Pointer(i), C.uint32_t(flags))
return uintptr(r)
}
func _ID3D12GraphicsCommandList_ClearDepthStencilView(i *_ID3D12GraphicsCommandList, depthStencilView _D3D12_CPU_DESCRIPTOR_HANDLE, clearFlags _D3D12_CLEAR_FLAGS, depth float32, stencil uint8, rects []_D3D12_RECT) {
var pRects *_D3D12_RECT
if len(rects) > 0 {
@@ -20,6 +20,34 @@ import (
"unsafe"
)
func _D3D12_RESOURCE_STATE_PRESENT() _D3D12_RESOURCE_STATES {
return 0
}
func _ID3D12CommandQueue_ExecuteCommandLists(i *_ID3D12CommandQueue, ppCommandLists []*_ID3D12GraphicsCommandList) {
panic("not implemented")
}
func _ID3D12CommandQueue_PresentX(i *_ID3D12CommandQueue, planeCount uint32, pPlaneParameters *_D3D12XBOX_PRESENT_PLANE_PARAMETERS, pPresentParameters *_D3D12XBOX_PRESENT_PARAMETERS) uintptr {
panic("not implemented")
}
func _ID3D12CommandQueue_Release(i *_ID3D12CommandQueue) uint32 {
panic("not implemented")
}
func _ID3D12CommandQueue_ResumeX(i *_ID3D12CommandQueue) uintptr {
panic("not implemented")
}
func _ID3D12CommandQueue_Signal(i *_ID3D12CommandQueue, pFence *_ID3D12Fence, value uint64) uintptr {
panic("not implemented")
}
func _ID3D12CommandQueue_SuspendX(i *_ID3D12CommandQueue, flags uint32) uintptr {
panic("not implemented")
}
func _ID3D12GraphicsCommandList_ClearDepthStencilView(i *_ID3D12GraphicsCommandList, depthStencilView _D3D12_CPU_DESCRIPTOR_HANDLE, clearFlags _D3D12_CLEAR_FLAGS, depth float32, stencil uint8, rects []_D3D12_RECT) {
panic("not implemented")
}
@@ -343,7 +343,6 @@ const (
_D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT _D3D12_RESOURCE_STATES = 0x200
_D3D12_RESOURCE_STATE_COPY_DEST _D3D12_RESOURCE_STATES = 0x400
_D3D12_RESOURCE_STATE_COPY_SOURCE _D3D12_RESOURCE_STATES = 0x800
_D3D12_RESOURCE_STATE_PRESENT _D3D12_RESOURCE_STATES = 0
)
func _D3D12_RESOURCE_STATE_GENERIC_READ() _D3D12_RESOURCE_STATES {
@@ -1066,33 +1065,24 @@ type _ID3D12CommandQueue_Vtbl struct {
Wait uintptr
GetTimestampFrequency uintptr
GetClockCalibration uintptr
GetDesc uintptr // Is this another function for Xbox?
// These members are for Xbox.
_ uintptr
_ uintptr
SuspendX uintptr
ResumeX uintptr
_ uintptr
_ uintptr
_ uintptr
_ uintptr // Is this GetDesc for Xbox?
_ uintptr
_ uintptr
_ uintptr
PresentX uintptr
_ uintptr
_ uintptr
GetDesc uintptr
}
func (i *_ID3D12CommandQueue) ExecuteCommandLists(ppCommandLists []*_ID3D12GraphicsCommandList) {
_, _, _ = syscall.Syscall(i.vtbl.ExecuteCommandLists, 3, uintptr(unsafe.Pointer(i)),
uintptr(len(ppCommandLists)), uintptr(unsafe.Pointer(&ppCommandLists[0])))
if microsoftgdk.IsXbox() {
_ID3D12CommandQueue_ExecuteCommandLists(i, ppCommandLists)
} else {
_, _, _ = syscall.Syscall(i.vtbl.ExecuteCommandLists, 3, uintptr(unsafe.Pointer(i)),
uintptr(len(ppCommandLists)), uintptr(unsafe.Pointer(&ppCommandLists[0])))
}
runtime.KeepAlive(ppCommandLists)
}
func (i *_ID3D12CommandQueue) PresentX(planeCount uint32, pPlaneParameters *_D3D12XBOX_PRESENT_PLANE_PARAMETERS, pPresentParameters *_D3D12XBOX_PRESENT_PARAMETERS) error {
r, _, _ := syscall.Syscall6(i.vtbl.PresentX, 4, uintptr(unsafe.Pointer(i)), uintptr(planeCount), uintptr(unsafe.Pointer(pPlaneParameters)), uintptr(unsafe.Pointer(pPresentParameters)), 0, 0)
if !microsoftgdk.IsXbox() {
panic("directx: ID3D12CommandQueue::PresentX is only available on Xbox")
}
r := _ID3D12CommandQueue_PresentX(i, planeCount, pPlaneParameters, pPresentParameters)
runtime.KeepAlive(pPlaneParameters)
runtime.KeepAlive(pPresentParameters)
if uint32(r) != uint32(windows.S_OK) {
@@ -1102,12 +1092,18 @@ func (i *_ID3D12CommandQueue) PresentX(planeCount uint32, pPlaneParameters *_D3D
}
func (i *_ID3D12CommandQueue) Release() uint32 {
if microsoftgdk.IsXbox() {
return _ID3D12CommandQueue_Release(i)
}
r, _, _ := syscall.Syscall(i.vtbl.Release, 1, uintptr(unsafe.Pointer(i)), 0, 0)
return uint32(r)
}
func (i *_ID3D12CommandQueue) ResumeX() error {
if r, _, _ := syscall.Syscall(i.vtbl.ResumeX, 1, uintptr(unsafe.Pointer(i)), 0, 0); uint32(r) != uint32(windows.S_OK) {
if !microsoftgdk.IsXbox() {
panic("directx: ID3D12CommandQueue::ResumeX is only available on Xbox")
}
if r := _ID3D12CommandQueue_ResumeX(i); uint32(r) != uint32(windows.S_OK) {
return fmt.Errorf("directx: ID3D12CommandQueue::ResumeX failed: %w", handleError(windows.Handle(uint32(r))))
}
return nil
@@ -1115,7 +1111,9 @@ func (i *_ID3D12CommandQueue) ResumeX() error {
func (i *_ID3D12CommandQueue) Signal(signal *_ID3D12Fence, value uint64) error {
var r uintptr
if is64bit {
if microsoftgdk.IsXbox() {
r = _ID3D12CommandQueue_Signal(i, signal, value)
} else if is64bit {
r, _, _ = syscall.Syscall(i.vtbl.Signal, 3, uintptr(unsafe.Pointer(i)),
uintptr(unsafe.Pointer(signal)), uintptr(value))
} else {
@@ -1130,7 +1128,10 @@ func (i *_ID3D12CommandQueue) Signal(signal *_ID3D12Fence, value uint64) error {
}
func (i *_ID3D12CommandQueue) SuspendX(flags uint32) error {
if r, _, _ := syscall.Syscall(i.vtbl.SuspendX, 2, uintptr(unsafe.Pointer(i)), uintptr(flags), 0); uint32(r) != uint32(windows.S_OK) {
if !microsoftgdk.IsXbox() {
panic("directx: ID3D12CommandQueue::SuspendX is only available on Xbox")
}
if r := _ID3D12CommandQueue_SuspendX(i, flags); uint32(r) != uint32(windows.S_OK) {
return fmt.Errorf("directx: ID3D12CommandQueue::SuspendX failed: %w", handleError(windows.Handle(uint32(r))))
}
return nil
@@ -71,7 +71,8 @@ const (
)
var (
procD3DCompile *windows.LazyProc
procD3DCompile *windows.LazyProc
procD3DCreateBlob *windows.LazyProc
)
func init() {
@@ -93,6 +94,7 @@ func init() {
}
procD3DCompile = d3dcompiler.NewProc("D3DCompile")
procD3DCreateBlob = d3dcompiler.NewProc("D3DCreateBlob")
}
func isD3DCompilerDLLAvailable() bool {
@@ -135,6 +137,19 @@ func _D3DCompile(srcData []byte, sourceName string, pDefines []_D3D_SHADER_MACRO
return code, nil
}
func _D3DCreateBlob(size uint) (*_ID3DBlob, error) {
if !isD3DCompilerDLLAvailable() {
return nil, fmt.Errorf("directx: d3dcompiler_*.dll is missing in this environment")
}
var blob *_ID3DBlob
r, _, _ := procD3DCreateBlob.Call(uintptr(size), uintptr(unsafe.Pointer(&blob)))
if uint32(r) != uint32(windows.S_OK) {
return nil, fmt.Errorf("directx: D3DCreateBlob failed: %w", handleError(windows.Handle(uint32(r))))
}
return blob, nil
}
type _D3D_SHADER_MACRO struct {
Name *byte
Definition *byte
@@ -27,34 +27,56 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl"
)
var inputElementDescsForDX11 = []_D3D11_INPUT_ELEMENT_DESC{
{
SemanticName: &([]byte("POSITION\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
{
SemanticName: &([]byte("TEXCOORD\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
{
SemanticName: &([]byte("COLOR\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
var inputElementDescsForDX11 []_D3D11_INPUT_ELEMENT_DESC
func init() {
inputElementDescsForDX11 = []_D3D11_INPUT_ELEMENT_DESC{
{
SemanticName: &([]byte("POSITION\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
{
SemanticName: &([]byte("TEXCOORD\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
{
SemanticName: &([]byte("COLOR\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
}
diff := graphics.VertexFloatCount - 8
if diff == 0 {
return
}
if diff%4 != 0 {
panic("directx: unexpected attribute layout")
}
for i := 0; i < diff/4; i++ {
inputElementDescsForDX11 = append(inputElementDescsForDX11, _D3D11_INPUT_ELEMENT_DESC{
SemanticName: &([]byte("COLOR\000"))[0],
SemanticIndex: uint32(i) + 1,
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
})
}
}
func blendFactorToBlend11(f graphicsdriver.BlendFactor, alpha bool) _D3D11_BLEND {
@@ -482,8 +504,7 @@ func (g *graphics11) MaxImageSize() int {
}
func (g *graphics11) NewShader(program *shaderir.Program) (graphicsdriver.Shader, error) {
vs, ps, offsets := hlsl.Compile(program)
vsh, psh, err := compileShader(vs, ps)
vsh, psh, err := compileShader(program)
if err != nil {
return nil, err
}
@@ -492,7 +513,7 @@ func (g *graphics11) NewShader(program *shaderir.Program) (graphicsdriver.Shader
graphics: g,
id: g.genNextShaderID(),
uniformTypes: program.Uniforms,
uniformOffsets: offsets,
uniformOffsets: hlsl.UniformVariableOffsetsInDwords(program),
vertexShaderBlob: vsh,
pixelShaderBlob: psh,
}
@@ -515,14 +536,14 @@ func (g *graphics11) removeShader(s *shader11) {
delete(g.shaders, s.id)
}
func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
// Remove bound textures first. This is needed to avoid warnings on the debugger.
g.deviceContext.OMSetRenderTargets([]*_ID3D11RenderTargetView{nil}, nil)
srvs := [graphics.ShaderImageCount]*_ID3D11ShaderResourceView{}
srvs := [graphics.ShaderSrcImageCount]*_ID3D11ShaderResourceView{}
g.deviceContext.PSSetShaderResources(0, srvs[:])
dst := g.images[dstID]
var srcs [graphics.ShaderImageCount]*image11
var srcs [graphics.ShaderSrcImageCount]*image11
for i, id := range srcIDs {
img := g.images[id]
if img == nil {
@@ -543,7 +564,7 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
},
})
if err := dst.setAsRenderTarget(fillRule != graphicsdriver.FillAll); err != nil {
if err := dst.setAsRenderTarget(fillRule != graphicsdriver.FillRuleFillAll); err != nil {
return err
}
@@ -553,7 +574,7 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
return err
}
if fillRule == graphicsdriver.FillAll {
if fillRule == graphicsdriver.FillRuleFillAll {
bs, err := g.blendState(blend, noStencil)
if err != nil {
return err
@@ -578,9 +599,9 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
})
switch fillRule {
case graphicsdriver.FillAll:
case graphicsdriver.FillRuleFillAll:
g.deviceContext.DrawIndexed(uint32(dstRegion.IndexCount), uint32(indexOffset), 0)
case graphicsdriver.NonZero:
case graphicsdriver.FillRuleNonZero:
bs, err := g.blendState(blend, incrementStencil)
if err != nil {
return err
@@ -592,7 +613,7 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
}
g.deviceContext.OMSetDepthStencilState(dss, 0)
g.deviceContext.DrawIndexed(uint32(dstRegion.IndexCount), uint32(indexOffset), 0)
case graphicsdriver.EvenOdd:
case graphicsdriver.FillRuleEvenOdd:
bs, err := g.blendState(blend, invertStencil)
if err != nil {
return err
@@ -606,7 +627,7 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
g.deviceContext.DrawIndexed(uint32(dstRegion.IndexCount), uint32(indexOffset), 0)
}
if fillRule != graphicsdriver.FillAll {
if fillRule != graphicsdriver.FillRuleFillAll {
bs, err := g.blendState(blend, drawWithStencil)
if err != nil {
return err
@@ -17,6 +17,7 @@ package directx
import (
"errors"
"fmt"
"runtime"
"unsafe"
"golang.org/x/sys/windows"
@@ -48,7 +49,7 @@ type graphics12 struct {
renderTargets [frameCount]*_ID3D12Resource
framePipelineToken _D3D12XBOX_FRAME_PIPELINE_TOKEN
fence *_ID3D12Fence
fences [frameCount]*_ID3D12Fence
fenceValues [frameCount]uint64
fenceWaitEvent windows.Handle
@@ -93,6 +94,7 @@ type graphics12 struct {
shaders map[graphicsdriver.ShaderID]*shader12
nextShaderID graphicsdriver.ShaderID
disposedShaders [frameCount][]*shader12
tmpUniforms []uint32
vsyncEnabled bool
@@ -208,7 +210,7 @@ func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, feature
}
g.device = (*_ID3D12Device)(d)
if err := g.initializeMembers(g.frameIndex); err != nil {
if err := g.initializeMembers(); err != nil {
return err
}
@@ -224,8 +226,6 @@ func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, feature
}
func (g *graphics12) initializeXbox(useWARP bool, useDebugLayer bool) (ferr error) {
g = &graphics12{}
if err := d3d12x.Load(); err != nil {
return err
}
@@ -245,7 +245,7 @@ func (g *graphics12) initializeXbox(useWARP bool, useDebugLayer bool) (ferr erro
}
g.device = (*_ID3D12Device)(d)
if err := g.initializeMembers(g.frameIndex); err != nil {
if err := g.initializeMembers(); err != nil {
return err
}
@@ -302,7 +302,7 @@ func (g *graphics12) registerFrameEventForXbox() error {
return nil
}
func (g *graphics12) initializeMembers(frameIndex int) (ferr error) {
func (g *graphics12) initializeMembers() (ferr error) {
// Create an event for a fence.
e, err := windows.CreateEventEx(nil, nil, 0, windows.EVENT_MODIFY_STATE|windows.SYNCHRONIZE)
if err != nil {
@@ -355,18 +355,19 @@ func (g *graphics12) initializeMembers(frameIndex int) (ferr error) {
}
// Create a frame fence.
f, err := g.device.CreateFence(0, _D3D12_FENCE_FLAG_NONE)
if err != nil {
return err
}
g.fence = f
defer func() {
if ferr != nil {
g.fence.Release()
g.fence = nil
for i := range frameCount {
f, err := g.device.CreateFence(0, _D3D12_FENCE_FLAG_NONE)
if err != nil {
return err
}
}()
g.fenceValues[frameIndex]++
g.fences[i] = f
defer func() {
if ferr != nil {
g.fences[i].Release()
g.fences[i] = nil
}
}()
}
// Create command lists.
dcl, err := g.device.CreateCommandList(0, _D3D12_COMMAND_LIST_TYPE_DIRECT, g.drawCommandAllocators[0], nil)
@@ -537,7 +538,7 @@ func (g *graphics12) initSwapChainXbox(width, height int) (ferr error) {
},
Layout: _D3D12_TEXTURE_LAYOUT_UNKNOWN,
Flags: _D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET,
}, _D3D12_RESOURCE_STATE_PRESENT, &_D3D12_CLEAR_VALUE{
}, _D3D12_RESOURCE_STATE_PRESENT(), &_D3D12_CLEAR_VALUE{
Format: _DXGI_FORMAT_B8G8R8A8_UNORM,
})
if err != nil {
@@ -569,10 +570,6 @@ func (g *graphics12) resizeSwapChainDesktop(width, height int) error {
}
g.releaseResources(g.frameIndex)
for i := 0; i < frameCount; i++ {
g.fenceValues[i] = g.fenceValues[g.frameIndex]
}
for _, r := range g.renderTargets {
r.Release()
}
@@ -676,7 +673,7 @@ func (g *graphics12) End(present bool) error {
// screenImage can be nil in tests.
if present && g.screenImage != nil {
if rb, ok := g.screenImage.transiteState(_D3D12_RESOURCE_STATE_PRESENT); ok {
if rb, ok := g.screenImage.transiteState(_D3D12_RESOURCE_STATE_PRESENT()); ok {
g.drawCommandList.ResourceBarrier([]_D3D12_RESOURCE_BARRIER_Transition{rb})
}
}
@@ -738,6 +735,9 @@ func (g *graphics12) presentDesktop() error {
}
func (g *graphics12) presentXbox() error {
var pinner runtime.Pinner
pinner.Pin(&g.renderTargets[g.frameIndex])
defer pinner.Unpin()
return g.commandQueue.PresentX(1, &_D3D12XBOX_PRESENT_PLANE_PARAMETERS{
Token: g.framePipelineToken,
ResourceCount: 1,
@@ -746,8 +746,9 @@ func (g *graphics12) presentXbox() error {
}
func (g *graphics12) moveToNextFrame() error {
g.fenceValues[g.frameIndex]++
fv := g.fenceValues[g.frameIndex]
if err := g.commandQueue.Signal(g.fence, fv); err != nil {
if err := g.commandQueue.Signal(g.fences[g.frameIndex], fv); err != nil {
return err
}
@@ -762,15 +763,14 @@ func (g *graphics12) moveToNextFrame() error {
g.frameIndex = idx
}
if g.fence.GetCompletedValue() < g.fenceValues[g.frameIndex] {
if err := g.fence.SetEventOnCompletion(g.fenceValues[g.frameIndex], g.fenceWaitEvent); err != nil {
if g.fences[g.frameIndex].GetCompletedValue() < g.fenceValues[g.frameIndex] {
if err := g.fences[g.frameIndex].SetEventOnCompletion(g.fenceValues[g.frameIndex], g.fenceWaitEvent); err != nil {
return err
}
if _, err := windows.WaitForSingleObject(g.fenceWaitEvent, windows.INFINITE); err != nil {
return err
}
}
g.fenceValues[g.frameIndex] = fv + 1
return nil
}
@@ -858,17 +858,17 @@ func (g *graphics12) flushCommandList(commandList *_ID3D12GraphicsCommandList) e
}
func (g *graphics12) waitForCommandQueue() error {
g.fenceValues[g.frameIndex]++
fv := g.fenceValues[g.frameIndex]
if err := g.commandQueue.Signal(g.fence, fv); err != nil {
if err := g.commandQueue.Signal(g.fences[g.frameIndex], fv); err != nil {
return err
}
if err := g.fence.SetEventOnCompletion(fv, g.fenceWaitEvent); err != nil {
if err := g.fences[g.frameIndex].SetEventOnCompletion(fv, g.fenceWaitEvent); err != nil {
return err
}
if _, err := windows.WaitForSingleObject(g.fenceWaitEvent, windows.INFINITE); err != nil {
return err
}
g.fenceValues[g.frameIndex]++
return nil
}
@@ -1064,8 +1064,7 @@ func (g *graphics12) MaxImageSize() int {
}
func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader, error) {
vs, ps, offsets := hlsl.Compile(program)
vsh, psh, err := compileShader(vs, ps)
vsh, psh, err := compileShader(program)
if err != nil {
return nil, err
}
@@ -1074,7 +1073,7 @@ func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader
graphics: g,
id: g.genNextShaderID(),
uniformTypes: program.Uniforms,
uniformOffsets: offsets,
uniformOffsets: hlsl.UniformVariableOffsetsInDwords(program),
vertexShader: vsh,
pixelShader: psh,
}
@@ -1082,7 +1081,7 @@ func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader
return s, nil
}
func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
if shaderID == graphicsdriver.InvalidShaderID {
return fmt.Errorf("directx: shader ID is invalid")
}
@@ -1093,7 +1092,7 @@ func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.
// Release constant buffers when too many ones will be created.
numPipelines := 1
if fillRule != graphicsdriver.FillAll {
if fillRule != graphicsdriver.FillRuleFillAll {
numPipelines = 2
}
if len(g.pipelineStates.constantBuffers[g.frameIndex])+numPipelines > numDescriptorsPerFrame {
@@ -1109,7 +1108,7 @@ func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.
resourceBarriers = append(resourceBarriers, rb)
}
var srcImages [graphics.ShaderImageCount]*image12
var srcImages [graphics.ShaderSrcImageCount]*image12
for i, srcID := range srcs {
src := g.images[srcID]
if src == nil {
@@ -1125,12 +1124,12 @@ func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.
g.drawCommandList.ResourceBarrier(resourceBarriers)
}
if err := dst.setAsRenderTarget(g.drawCommandList, g.device, fillRule != graphicsdriver.FillAll); err != nil {
if err := dst.setAsRenderTarget(g.drawCommandList, g.device, fillRule != graphicsdriver.FillRuleFillAll); err != nil {
return err
}
shader := g.shaders[shaderID]
adjustedUniforms := adjustUniforms(shader.uniformTypes, shader.uniformOffsets, uniforms)
g.tmpUniforms = appendAdjustedUniforms(g.tmpUniforms[:0], shader.uniformTypes, shader.uniformOffsets, uniforms)
w, h := dst.internalSize()
g.needFlushDrawCommandList = true
@@ -1158,7 +1157,7 @@ func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.
Format: _DXGI_FORMAT_R32_UINT,
})
if err := g.pipelineStates.drawTriangles(g.device, g.drawCommandList, g.frameIndex, dst.screen, srcImages, shader, dstRegions, adjustedUniforms, blend, indexOffset, fillRule); err != nil {
if err := g.pipelineStates.drawTriangles(g.device, g.drawCommandList, g.frameIndex, dst.screen, srcImages, shader, dstRegions, g.tmpUniforms, blend, indexOffset, fillRule); err != nil {
return err
}
@@ -147,9 +147,7 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
}
type graphicsInfra struct {
factory *_IDXGIFactory
swapChain *_IDXGISwapChain
swapChain4 *_IDXGISwapChain4
*graphicsInfraResources
allowTearing bool
@@ -160,14 +158,24 @@ type graphicsInfra struct {
lastTime time.Time
bufferCount int
cleanup runtime.Cleanup
}
type graphicsInfraResources struct {
factory *_IDXGIFactory
swapChain *_IDXGISwapChain
swapChain4 *_IDXGISwapChain4
}
// newGraphicsInfra takes the ownership of the given factory.
func newGraphicsInfra(factory *_IDXGIFactory) (*graphicsInfra, error) {
g := &graphicsInfra{
factory: factory,
graphicsInfraResources: &graphicsInfraResources{
factory: factory,
},
}
runtime.SetFinalizer(g, (*graphicsInfra).release)
g.cleanup = runtime.AddCleanup(g, (*graphicsInfraResources).releaseResources, g.graphicsInfraResources)
if f, err := g.factory.QueryInterface(&_IID_IDXGIFactory5); err == nil && f != nil {
factory := (*_IDXGIFactory5)(f)
@@ -183,6 +191,11 @@ func newGraphicsInfra(factory *_IDXGIFactory) (*graphicsInfra, error) {
}
func (g *graphicsInfra) release() {
g.releaseResources()
g.cleanup.Stop()
}
func (g *graphicsInfraResources) releaseResources() {
if g.factory != nil {
g.factory.Release()
g.factory = nil
@@ -23,34 +23,56 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
)
var inputElementDescsForDX12 = []_D3D12_INPUT_ELEMENT_DESC{
{
SemanticName: &([]byte("POSITION\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
{
SemanticName: &([]byte("TEXCOORD\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
{
SemanticName: &([]byte("COLOR\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
var inputElementDescsForDX12 []_D3D12_INPUT_ELEMENT_DESC
func init() {
inputElementDescsForDX12 = []_D3D12_INPUT_ELEMENT_DESC{
{
SemanticName: &([]byte("POSITION\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
{
SemanticName: &([]byte("TEXCOORD\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
{
SemanticName: &([]byte("COLOR\000"))[0],
SemanticIndex: 0,
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
}
diff := graphics.VertexFloatCount - 8
if diff == 0 {
return
}
if diff%4 != 0 {
panic("directx: unexpected attribute layout")
}
for i := 0; i < diff/4; i++ {
inputElementDescsForDX12 = append(inputElementDescsForDX12, _D3D12_INPUT_ELEMENT_DESC{
SemanticName: &([]byte("COLOR\000"))[0],
SemanticIndex: uint32(i) + 1,
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
})
}
}
const numDescriptorsPerFrame = 32
@@ -128,7 +150,7 @@ type pipelineStates struct {
constantBufferMaps [frameCount][]uintptr
}
const numConstantBufferAndSourceTextures = 1 + graphics.ShaderImageCount
const numConstantBufferAndSourceTextures = 1 + graphics.ShaderSrcImageCount
func (p *pipelineStates) initialize(device *_ID3D12Device) (ferr error) {
// Create a CBV/SRV/UAV descriptor heap.
@@ -180,7 +202,7 @@ func (p *pipelineStates) initialize(device *_ID3D12Device) (ferr error) {
return nil
}
func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D12GraphicsCommandList, frameIndex int, screen bool, srcs [graphics.ShaderImageCount]*image12, shader *shader12, dstRegions []graphicsdriver.DstRegion, uniforms []uint32, blend graphicsdriver.Blend, indexOffset int, fillRule graphicsdriver.FillRule) error {
func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D12GraphicsCommandList, frameIndex int, screen bool, srcs [graphics.ShaderSrcImageCount]*image12, shader *shader12, dstRegions []graphicsdriver.DstRegion, uniforms []uint32, blend graphicsdriver.Blend, indexOffset int, fillRule graphicsdriver.FillRule) error {
idx := len(p.constantBuffers[frameIndex])
if idx >= numDescriptorsPerFrame {
return fmt.Errorf("directx: too many constant buffers")
@@ -289,7 +311,7 @@ func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D
}
commandList.SetGraphicsRootDescriptorTable(2, sh)
if fillRule == graphicsdriver.FillAll {
if fillRule == graphicsdriver.FillRuleFillAll {
s, err := shader.pipelineState(blend, noStencil, screen)
if err != nil {
return err
@@ -307,16 +329,16 @@ func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D
},
})
switch fillRule {
case graphicsdriver.FillAll:
case graphicsdriver.FillRuleFillAll:
commandList.DrawIndexedInstanced(uint32(dstRegion.IndexCount), 1, uint32(indexOffset), 0, 0)
case graphicsdriver.NonZero:
case graphicsdriver.FillRuleNonZero:
s, err := shader.pipelineState(blend, incrementStencil, screen)
if err != nil {
return err
}
commandList.SetPipelineState(s)
commandList.DrawIndexedInstanced(uint32(dstRegion.IndexCount), 1, uint32(indexOffset), 0, 0)
case graphicsdriver.EvenOdd:
case graphicsdriver.FillRuleEvenOdd:
s, err := shader.pipelineState(blend, invertStencil, screen)
if err != nil {
return err
@@ -325,7 +347,7 @@ func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D
commandList.DrawIndexedInstanced(uint32(dstRegion.IndexCount), 1, uint32(indexOffset), 0, 0)
}
if fillRule != graphicsdriver.FillAll {
if fillRule != graphicsdriver.FillRuleFillAll {
s, err := shader.pipelineState(blend, drawWithStencil, screen)
if err != nil {
return err
@@ -354,7 +376,7 @@ func (p *pipelineStates) ensureRootSignature(device *_ID3D12Device) (rootSignatu
}
srv := _D3D12_DESCRIPTOR_RANGE{
RangeType: _D3D12_DESCRIPTOR_RANGE_TYPE_SRV, // t0
NumDescriptors: graphics.ShaderImageCount,
NumDescriptors: graphics.ShaderSrcImageCount,
BaseShaderRegister: 0,
RegisterSpace: 0,
OffsetInDescriptorsFromTableStart: 1,
@@ -29,6 +29,7 @@ type shader11 struct {
uniformOffsets []int
vertexShaderBlob *_ID3DBlob
pixelShaderBlob *_ID3DBlob
tmpUniforms []uint32
inputLayout *_ID3D11InputLayout
vertexShader *_ID3D11VertexShader
@@ -78,7 +79,7 @@ func (s *shader11) disposeImpl() {
}
}
func (s *shader11) use(uniforms []uint32, srcs [graphics.ShaderImageCount]*image11) error {
func (s *shader11) use(uniforms []uint32, srcs [graphics.ShaderSrcImageCount]*image11) error {
vs, err := s.ensureVertexShader()
if err != nil {
return err
@@ -105,16 +106,16 @@ func (s *shader11) use(uniforms []uint32, srcs [graphics.ShaderImageCount]*image
s.graphics.deviceContext.PSSetConstantBuffers(0, []*_ID3D11Buffer{cb})
// Send the constant buffer data.
uniforms = adjustUniforms(s.uniformTypes, s.uniformOffsets, uniforms)
s.tmpUniforms = appendAdjustedUniforms(s.tmpUniforms[:0], s.uniformTypes, s.uniformOffsets, uniforms)
var mapped _D3D11_MAPPED_SUBRESOURCE
if err := s.graphics.deviceContext.Map(unsafe.Pointer(cb), 0, _D3D11_MAP_WRITE_DISCARD, 0, &mapped); err != nil {
return err
}
copy(unsafe.Slice((*uint32)(mapped.pData), len(uniforms)), uniforms)
copy(unsafe.Slice((*uint32)(mapped.pData), len(s.tmpUniforms)), s.tmpUniforms)
s.graphics.deviceContext.Unmap(unsafe.Pointer(cb), 0)
// Set the render sources.
var srvs [graphics.ShaderImageCount]*_ID3D11ShaderResourceView
var srvs [graphics.ShaderSrcImageCount]*_ID3D11ShaderResourceView
for i, src := range srcs {
if src == nil {
continue
@@ -16,18 +16,67 @@ package directx
import (
"fmt"
"sync"
"unsafe"
"golang.org/x/sync/errgroup"
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl"
)
const (
VertexShaderProfile = "vs_4_0"
PixelShaderProfile = "ps_4_0"
VertexShaderEntryPoint = "VSMain"
PixelShaderEntryPoint = "PSMain"
)
type fxcPair struct {
vertex []byte
pixel []byte
}
type precompiledFXCs struct {
binaries map[shaderir.SourceHash]fxcPair
m sync.Mutex
}
func (c *precompiledFXCs) put(hash shaderir.SourceHash, vertex, pixel []byte) {
c.m.Lock()
defer c.m.Unlock()
if c.binaries == nil {
c.binaries = map[shaderir.SourceHash]fxcPair{}
}
if _, ok := c.binaries[hash]; ok {
panic(fmt.Sprintf("directx: the precompiled library for the hash %s is already registered", hash.String()))
}
c.binaries[hash] = fxcPair{
vertex: vertex,
pixel: pixel,
}
}
func (c *precompiledFXCs) get(hash shaderir.SourceHash) ([]byte, []byte) {
c.m.Lock()
defer c.m.Unlock()
f := c.binaries[hash]
return f.vertex, f.pixel
}
var thePrecompiledFXCs precompiledFXCs
func RegisterPrecompiledFXCs(source []byte, vertex, pixel []byte) {
thePrecompiledFXCs.put(shaderir.CalcSourceHash(source), vertex, pixel)
}
var vertexShaderCache = map[string]*_ID3DBlob{}
func compileShader(vs, ps string) (vsh, psh *_ID3DBlob, ferr error) {
var flag uint32 = uint32(_D3DCOMPILE_OPTIMIZATION_LEVEL3)
func compileShader(program *shaderir.Program) (vsh, psh *_ID3DBlob, ferr error) {
defer func() {
if ferr == nil {
return
@@ -40,6 +89,22 @@ func compileShader(vs, ps string) (vsh, psh *_ID3DBlob, ferr error) {
}
}()
if vshBin, pshBin := thePrecompiledFXCs.get(program.SourceHash); vshBin != nil && pshBin != nil {
var err error
if vsh, err = _D3DCreateBlob(uint(len(vshBin))); err != nil {
return nil, nil, err
}
if psh, err = _D3DCreateBlob(uint(len(pshBin))); err != nil {
return nil, nil, err
}
copy(unsafe.Slice((*byte)(vsh.GetBufferPointer()), vsh.GetBufferSize()), vshBin)
copy(unsafe.Slice((*byte)(psh.GetBufferPointer()), psh.GetBufferSize()), pshBin)
return vsh, psh, nil
}
vs, ps, _, _ := hlsl.Compile(program)
var flag uint32 = uint32(_D3DCOMPILE_OPTIMIZATION_LEVEL3)
var wg errgroup.Group
// Vertex shaders are likely the same. If so, reuse the same _ID3DBlob.
@@ -56,7 +121,7 @@ func compileShader(vs, ps string) (vsh, psh *_ID3DBlob, ferr error) {
}
}()
wg.Go(func() error {
v, err := _D3DCompile([]byte(vs), "shader", nil, nil, "VSMain", "vs_4_0", flag, 0)
v, err := _D3DCompile([]byte(vs), "shader", nil, nil, VertexShaderEntryPoint, VertexShaderProfile, flag, 0)
if err != nil {
return fmt.Errorf("directx: D3DCompile for VSMain failed, original source: %s, %w", vs, err)
}
@@ -65,7 +130,7 @@ func compileShader(vs, ps string) (vsh, psh *_ID3DBlob, ferr error) {
})
}
wg.Go(func() error {
p, err := _D3DCompile([]byte(ps), "shader", nil, nil, "PSMain", "ps_4_0", flag, 0)
p, err := _D3DCompile([]byte(ps), "shader", nil, nil, PixelShaderEntryPoint, PixelShaderProfile, flag, 0)
if err != nil {
return fmt.Errorf("directx: D3DCompile for PSMain failed, original source: %s, %w", ps, err)
}
@@ -77,17 +142,20 @@ func compileShader(vs, ps string) (vsh, psh *_ID3DBlob, ferr error) {
return nil, nil, err
}
return
return vsh, psh, nil
}
func constantBufferSize(uniformTypes []shaderir.Type, uniformOffsets []int) int {
var size int
for i, typ := range uniformTypes {
if size < uniformOffsets[i]/4 {
size = uniformOffsets[i] / 4
if size < uniformOffsets[i] {
size = uniformOffsets[i]
}
switch typ.Main {
case shaderir.Bool:
// Bool is 4 bytes in HLSL.
size += 1
case shaderir.Float:
size += 1
case shaderir.Int:
@@ -107,6 +175,8 @@ func constantBufferSize(uniformTypes []shaderir.Type, uniformOffsets []int) int
case shaderir.Array:
// Each element is aligned to the boundary.
switch typ.Sub[0].Main {
case shaderir.Bool:
size += 4*(typ.Length-1) + 1
case shaderir.Float:
size += 4*(typ.Length-1) + 1
case shaderir.Int:
@@ -133,33 +203,39 @@ func constantBufferSize(uniformTypes []shaderir.Type, uniformOffsets []int) int
return size
}
func adjustUniforms(uniformTypes []shaderir.Type, uniformOffsets []int, uniforms []uint32) []uint32 {
var fs []uint32
func appendAdjustedUniforms(dst []uint32, uniformTypes []shaderir.Type, uniformOffsets []int, uniforms []uint32) []uint32 {
// Note that HLSL's matrices are row-major, while GLSL and MSL are column-major.
// Transpose matrices so that users can access matrix indices in the same way as GLSL and MSL.
// For packing rule, see https://github.com/microsoft/DirectXShaderCompiler/wiki/Buffer-Packing
var idx int
for i, typ := range uniformTypes {
if len(fs) < uniformOffsets[i]/4 {
fs = append(fs, make([]uint32, uniformOffsets[i]/4-len(fs))...)
if len(dst) < uniformOffsets[i] {
dst = append(dst, make([]uint32, uniformOffsets[i]-len(dst))...)
}
n := typ.Uint32Count()
n := typ.DwordCount()
switch typ.Main {
case shaderir.Bool:
// Bool is 4 bytes in HLSL.
dst = append(dst, uniforms[idx:idx+1]...)
case shaderir.Float:
fs = append(fs, uniforms[idx:idx+1]...)
dst = append(dst, uniforms[idx:idx+1]...)
case shaderir.Int:
fs = append(fs, uniforms[idx:idx+1]...)
dst = append(dst, uniforms[idx:idx+1]...)
case shaderir.Vec2, shaderir.IVec2:
fs = append(fs, uniforms[idx:idx+2]...)
dst = append(dst, uniforms[idx:idx+2]...)
case shaderir.Vec3, shaderir.IVec3:
fs = append(fs, uniforms[idx:idx+3]...)
dst = append(dst, uniforms[idx:idx+3]...)
case shaderir.Vec4, shaderir.IVec4:
fs = append(fs, uniforms[idx:idx+4]...)
dst = append(dst, uniforms[idx:idx+4]...)
case shaderir.Mat2:
fs = append(fs,
dst = append(dst,
uniforms[idx+0], uniforms[idx+2], 0, 0,
uniforms[idx+1], uniforms[idx+3],
)
case shaderir.Mat3:
fs = append(fs,
dst = append(dst,
uniforms[idx+0], uniforms[idx+3], uniforms[idx+6], 0,
uniforms[idx+1], uniforms[idx+4], uniforms[idx+7], 0,
uniforms[idx+2], uniforms[idx+5], uniforms[idx+8],
@@ -169,14 +245,14 @@ func adjustUniforms(uniformTypes []shaderir.Type, uniformOffsets []int, uniforms
// In DirectX, the NDC's Y direction (upward) and the framebuffer's Y direction (downward) don't
// match. Then, the Y direction must be inverted.
// Invert the sign bits as float32 values.
fs = append(fs,
dst = append(dst,
uniforms[idx+0], uniforms[idx+4], uniforms[idx+8], uniforms[idx+12],
uniforms[idx+1]^(1<<31), uniforms[idx+5]^(1<<31), uniforms[idx+9]^(1<<31), uniforms[idx+13]^(1<<31),
uniforms[idx+2], uniforms[idx+6], uniforms[idx+10], uniforms[idx+14],
uniforms[idx+3], uniforms[idx+7], uniforms[idx+11], uniforms[idx+15],
)
} else {
fs = append(fs,
dst = append(dst,
uniforms[idx+0], uniforms[idx+4], uniforms[idx+8], uniforms[idx+12],
uniforms[idx+1], uniforms[idx+5], uniforms[idx+9], uniforms[idx+13],
uniforms[idx+2], uniforms[idx+6], uniforms[idx+10], uniforms[idx+14],
@@ -186,63 +262,70 @@ func adjustUniforms(uniformTypes []shaderir.Type, uniformOffsets []int, uniforms
case shaderir.Array:
// Each element is aligned to the boundary.
switch typ.Sub[0].Main {
case shaderir.Bool:
for j := 0; j < typ.Length; j++ {
dst = append(dst, uniforms[idx+j])
if j < typ.Length-1 {
dst = append(dst, 0, 0, 0)
}
}
case shaderir.Float:
for j := 0; j < typ.Length; j++ {
fs = append(fs, uniforms[idx+j])
dst = append(dst, uniforms[idx+j])
if j < typ.Length-1 {
fs = append(fs, 0, 0, 0)
dst = append(dst, 0, 0, 0)
}
}
case shaderir.Int:
for j := 0; j < typ.Length; j++ {
fs = append(fs, uniforms[idx+j])
dst = append(dst, uniforms[idx+j])
if j < typ.Length-1 {
fs = append(fs, 0, 0, 0)
dst = append(dst, 0, 0, 0)
}
}
case shaderir.Vec2, shaderir.IVec2:
for j := 0; j < typ.Length; j++ {
fs = append(fs, uniforms[idx+2*j:idx+2*(j+1)]...)
dst = append(dst, uniforms[idx+2*j:idx+2*(j+1)]...)
if j < typ.Length-1 {
fs = append(fs, 0, 0)
dst = append(dst, 0, 0)
}
}
case shaderir.Vec3, shaderir.IVec3:
for j := 0; j < typ.Length; j++ {
fs = append(fs, uniforms[idx+3*j:idx+3*(j+1)]...)
dst = append(dst, uniforms[idx+3*j:idx+3*(j+1)]...)
if j < typ.Length-1 {
fs = append(fs, 0)
dst = append(dst, 0)
}
}
case shaderir.Vec4, shaderir.IVec4:
fs = append(fs, uniforms[idx:idx+4*typ.Length]...)
dst = append(dst, uniforms[idx:idx+4*typ.Length]...)
case shaderir.Mat2:
for j := 0; j < typ.Length; j++ {
u := uniforms[idx+4*j : idx+4*(j+1)]
fs = append(fs,
dst = append(dst,
u[0], u[2], 0, 0,
u[1], u[3], 0, 0,
u[1], u[3],
)
}
if typ.Length > 0 {
fs = fs[:len(fs)-2]
if j < typ.Length-1 {
dst = append(dst, 0, 0)
}
}
case shaderir.Mat3:
for j := 0; j < typ.Length; j++ {
u := uniforms[idx+9*j : idx+9*(j+1)]
fs = append(fs,
dst = append(dst,
u[0], u[3], u[6], 0,
u[1], u[4], u[7], 0,
u[2], u[5], u[8], 0,
u[2], u[5], u[8],
)
}
if typ.Length > 0 {
fs = fs[:len(fs)-1]
if j < typ.Length-1 {
dst = append(dst, 0)
}
}
case shaderir.Mat4:
for j := 0; j < typ.Length; j++ {
u := uniforms[idx+16*j : idx+16*(j+1)]
fs = append(fs,
dst = append(dst,
u[0], u[4], u[8], u[12],
u[1], u[5], u[9], u[13],
u[2], u[6], u[10], u[14],
@@ -258,5 +341,5 @@ func adjustUniforms(uniformTypes []shaderir.Type, uniformOffsets []int, uniforms
idx += n
}
return fs
return dst
}