mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-25 00:58:30 -05:00
D3D12: Initial commit.
This commit is contained in:
parent
5f466bd576
commit
b702dcdf3c
10 changed files with 9142 additions and 2 deletions
|
@ -17,4 +17,7 @@
|
|||
#include "renderer_null.cpp"
|
||||
#include "renderer_gl.cpp"
|
||||
#include "renderer_vk.cpp"
|
||||
#include "shader_dxbc.cpp"
|
||||
#include "shader_dx9bc.cpp"
|
||||
#include "shader_spirv.cpp"
|
||||
#include "vertexdecl.cpp"
|
||||
|
|
|
@ -140,11 +140,13 @@ namespace bgfx
|
|||
# include <tinystl/string.h>
|
||||
# include <tinystl/unordered_map.h>
|
||||
# include <tinystl/unordered_set.h>
|
||||
# include <tinystl/vector.h>
|
||||
namespace stl = tinystl;
|
||||
#else
|
||||
# include <string>
|
||||
# include <unordered_map>
|
||||
# include <unordered_set>
|
||||
# include <vector>
|
||||
namespace stl
|
||||
{
|
||||
using namespace std;
|
||||
|
|
File diff suppressed because it is too large
Load diff
430
src/renderer_d3d12.h
Normal file
430
src/renderer_d3d12.h
Normal file
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* Copyright 2011-2015 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef BGFX_RENDERER_D3D12_H_HEADER_GUARD
|
||||
#define BGFX_RENDERER_D3D12_H_HEADER_GUARD
|
||||
|
||||
#define USE_D3D12_DYNAMIC_LIB 1
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <d3dx12.h>
|
||||
#include <dxgidebug.h>
|
||||
|
||||
#include "renderer.h"
|
||||
#include "renderer_d3d.h"
|
||||
#include "shader_dxbc.h"
|
||||
|
||||
namespace bgfx { namespace d3d12
|
||||
{
|
||||
struct Rdt
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Sampler,
|
||||
SRV,
|
||||
CBV,
|
||||
UAV,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
class ScratchBufferD3D12
|
||||
{
|
||||
public:
|
||||
ScratchBufferD3D12()
|
||||
{
|
||||
}
|
||||
|
||||
~ScratchBufferD3D12()
|
||||
{
|
||||
}
|
||||
|
||||
void create(uint32_t _size, uint32_t _maxDescriptors);
|
||||
void destroy();
|
||||
void reset(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle);
|
||||
void* alloc(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, uint32_t _size);
|
||||
void alloc(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, struct TextureD3D12& _texture);
|
||||
void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, struct TextureD3D12& _texture);
|
||||
|
||||
void alloc(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, struct BufferD3D12& _buffer);
|
||||
void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, struct BufferD3D12& _buffer);
|
||||
|
||||
ID3D12DescriptorHeap* getHeap()
|
||||
{
|
||||
return m_heap;
|
||||
}
|
||||
|
||||
private:
|
||||
ID3D12DescriptorHeap* m_heap;
|
||||
ID3D12Resource* m_upload;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE m_cpuHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE m_gpuHandle;
|
||||
uint32_t m_incrementSize;
|
||||
uint8_t* m_data;
|
||||
uint32_t m_size;
|
||||
uint32_t m_pos;
|
||||
};
|
||||
|
||||
class DescriptorAllocator
|
||||
{
|
||||
public:
|
||||
DescriptorAllocator()
|
||||
: m_numDescriptorsPerBlock(1)
|
||||
{
|
||||
}
|
||||
|
||||
~DescriptorAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
void create(D3D12_DESCRIPTOR_HEAP_TYPE _type, uint32_t _maxDescriptors, uint16_t _numDescriptorsPerBlock = 1);
|
||||
void destroy();
|
||||
|
||||
uint16_t alloc(ID3D12Resource* _ptr, const D3D12_SHADER_RESOURCE_VIEW_DESC* _desc);
|
||||
uint16_t alloc(const uint32_t* _flags, uint32_t _num = BGFX_CONFIG_MAX_TEXTURE_SAMPLERS);
|
||||
void free(uint16_t _handle);
|
||||
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE get(uint16_t _handle);
|
||||
|
||||
ID3D12DescriptorHeap* getHeap()
|
||||
{
|
||||
return m_heap;
|
||||
}
|
||||
|
||||
private:
|
||||
ID3D12DescriptorHeap* m_heap;
|
||||
bx::HandleAlloc* m_handleAlloc;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE m_cpuHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE m_gpuHandle;
|
||||
uint32_t m_incrementSize;
|
||||
uint16_t m_numDescriptorsPerBlock;
|
||||
};
|
||||
|
||||
struct BufferD3D12
|
||||
{
|
||||
BufferD3D12()
|
||||
: m_ptr(NULL)
|
||||
, m_staging(NULL)
|
||||
, m_state(D3D12_RESOURCE_STATE_COMMON)
|
||||
, m_size(0)
|
||||
, m_flags(BGFX_BUFFER_NONE)
|
||||
, m_dynamic(false)
|
||||
{
|
||||
}
|
||||
|
||||
void create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex);
|
||||
void update(ID3D12GraphicsCommandList* _commandList, uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (NULL != m_ptr)
|
||||
{
|
||||
DX_RELEASE(m_ptr, 0);
|
||||
DX_RELEASE(m_staging, 0);
|
||||
m_dynamic = false;
|
||||
}
|
||||
}
|
||||
|
||||
void setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC m_srvd;
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd;
|
||||
ID3D12Resource* m_ptr;
|
||||
ID3D12Resource* m_staging;
|
||||
D3D12_RESOURCE_STATES m_state;
|
||||
uint32_t m_size;
|
||||
uint16_t m_flags;
|
||||
bool m_dynamic;
|
||||
};
|
||||
|
||||
struct VertexBufferD3D12 : public BufferD3D12
|
||||
{
|
||||
void create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags);
|
||||
|
||||
VertexDeclHandle m_decl;
|
||||
};
|
||||
|
||||
struct ShaderD3D12
|
||||
{
|
||||
ShaderD3D12()
|
||||
: m_code(NULL)
|
||||
, m_constantBuffer(NULL)
|
||||
, m_hash(0)
|
||||
, m_numUniforms(0)
|
||||
, m_numPredefined(0)
|
||||
{
|
||||
}
|
||||
|
||||
void create(const Memory* _mem);
|
||||
DWORD* getShaderCode(uint8_t _fragmentBit, const Memory* _mem);
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (NULL != m_constantBuffer)
|
||||
{
|
||||
ConstantBuffer::destroy(m_constantBuffer);
|
||||
m_constantBuffer = NULL;
|
||||
}
|
||||
|
||||
m_numPredefined = 0;
|
||||
|
||||
if (NULL != m_code)
|
||||
{
|
||||
release(m_code);
|
||||
m_code = NULL;
|
||||
m_hash = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const Memory* m_code;
|
||||
ConstantBuffer* m_constantBuffer;
|
||||
|
||||
PredefinedUniform m_predefined[PredefinedUniform::Count];
|
||||
uint8_t m_attrMask[Attrib::Count];
|
||||
|
||||
uint32_t m_hash;
|
||||
uint16_t m_numUniforms;
|
||||
uint16_t m_size;
|
||||
uint8_t m_numPredefined;
|
||||
};
|
||||
|
||||
struct ProgramD3D12
|
||||
{
|
||||
ProgramD3D12()
|
||||
: m_vsh(NULL)
|
||||
, m_fsh(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void create(const ShaderD3D12* _vsh, const ShaderD3D12* _fsh)
|
||||
{
|
||||
BX_CHECK(NULL != _vsh->m_code, "Vertex shader doesn't exist.");
|
||||
m_vsh = _vsh;
|
||||
memcpy(&m_predefined[0], _vsh->m_predefined, _vsh->m_numPredefined*sizeof(PredefinedUniform));
|
||||
m_numPredefined = _vsh->m_numPredefined;
|
||||
|
||||
if (NULL != _fsh)
|
||||
{
|
||||
BX_CHECK(NULL != _fsh->m_code, "Fragment shader doesn't exist.");
|
||||
m_fsh = _fsh;
|
||||
memcpy(&m_predefined[m_numPredefined], _fsh->m_predefined, _fsh->m_numPredefined*sizeof(PredefinedUniform));
|
||||
m_numPredefined += _fsh->m_numPredefined;
|
||||
}
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
m_numPredefined = 0;
|
||||
m_vsh = NULL;
|
||||
m_fsh = NULL;
|
||||
}
|
||||
|
||||
const ShaderD3D12* m_vsh;
|
||||
const ShaderD3D12* m_fsh;
|
||||
|
||||
PredefinedUniform m_predefined[PredefinedUniform::Count * 2];
|
||||
uint8_t m_numPredefined;
|
||||
};
|
||||
|
||||
struct TextureD3D12
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Texture2D,
|
||||
Texture3D,
|
||||
TextureCube,
|
||||
};
|
||||
|
||||
TextureD3D12()
|
||||
: m_ptr(NULL)
|
||||
, m_staging(NULL)
|
||||
, m_state(D3D12_RESOURCE_STATE_COMMON)
|
||||
, m_numMips(0)
|
||||
{
|
||||
}
|
||||
|
||||
void create(const Memory* _mem, uint32_t _flags, uint8_t _skip);
|
||||
void destroy();
|
||||
void update(ID3D12GraphicsCommandList* _commandList, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
|
||||
void commit(uint8_t _stage, uint32_t _flags = BGFX_SAMPLER_DEFAULT_FLAGS);
|
||||
void resolve();
|
||||
void setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC m_srvd;
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd;
|
||||
ID3D12Resource* m_ptr;
|
||||
ID3D12Resource* m_staging;
|
||||
D3D12_RESOURCE_STATES m_state;
|
||||
uint32_t m_flags;
|
||||
uint16_t m_samplerIdx;
|
||||
uint8_t m_type;
|
||||
uint8_t m_requestedFormat;
|
||||
uint8_t m_textureFormat;
|
||||
uint8_t m_numMips;
|
||||
};
|
||||
|
||||
struct FrameBufferD3D12
|
||||
{
|
||||
FrameBufferD3D12()
|
||||
: m_swapChain(NULL)
|
||||
, m_denseIdx(UINT16_MAX)
|
||||
, m_num(0)
|
||||
, m_numTh(0)
|
||||
{
|
||||
m_depth.idx = bgfx::invalidHandle;
|
||||
}
|
||||
|
||||
void create(uint8_t _num, const TextureHandle* _handles);
|
||||
void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
|
||||
uint16_t destroy();
|
||||
void preReset();
|
||||
void postReset();
|
||||
void resolve();
|
||||
void clear(ID3D12GraphicsCommandList* _commandList, const Clear& _clear, const float _palette[][4], const D3D12_RECT* _rect = NULL, uint32_t _num = 0);
|
||||
|
||||
TextureHandle m_texture[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
|
||||
TextureHandle m_depth;
|
||||
IDXGISwapChain* m_swapChain;
|
||||
uint16_t m_denseIdx;
|
||||
uint8_t m_num;
|
||||
uint8_t m_numTh;
|
||||
TextureHandle m_th[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
|
||||
};
|
||||
|
||||
struct CommandQueue
|
||||
{
|
||||
CommandQueue()
|
||||
: m_control(BX_COUNTOF(m_commandList) )
|
||||
{
|
||||
}
|
||||
|
||||
void init(ID3D12Device* _device)
|
||||
{
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc;
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
queueDesc.Priority = 0;
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.NodeMask = 1;
|
||||
DX_CHECK(_device->CreateCommandQueue(&queueDesc
|
||||
, __uuidof(ID3D12CommandQueue)
|
||||
, (void**)&m_commandQueue
|
||||
) );
|
||||
|
||||
m_currentFence = 0;
|
||||
DX_CHECK(_device->CreateFence(0
|
||||
, D3D12_FENCE_FLAG_NONE
|
||||
, __uuidof(ID3D12Fence)
|
||||
, (void**)&m_fence
|
||||
) );
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_commandList); ++ii)
|
||||
{
|
||||
DX_CHECK(_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT
|
||||
, __uuidof(ID3D12CommandAllocator)
|
||||
, (void**)&m_commandList[ii].m_commandAllocator
|
||||
) );
|
||||
|
||||
DX_CHECK(_device->CreateCommandList(0
|
||||
, D3D12_COMMAND_LIST_TYPE_DIRECT
|
||||
, m_commandList[ii].m_commandAllocator
|
||||
, NULL
|
||||
, __uuidof(ID3D12GraphicsCommandList)
|
||||
, (void**)&m_commandList[ii].m_commandList
|
||||
) );
|
||||
|
||||
DX_CHECK(m_commandList[ii].m_commandList->Close() );
|
||||
}
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
finish();
|
||||
|
||||
DX_RELEASE(m_fence, 0);
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_commandList); ++ii)
|
||||
{
|
||||
DX_RELEASE(m_commandList[ii].m_commandAllocator, 0);
|
||||
DX_RELEASE(m_commandList[ii].m_commandList, 0);
|
||||
}
|
||||
|
||||
DX_RELEASE(m_commandQueue, 0);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* alloc()
|
||||
{
|
||||
while (0 == m_control.reserve(1) )
|
||||
{
|
||||
CommandList& commandList = m_commandList[m_control.m_read];
|
||||
WaitForSingleObject(commandList.m_event, INFINITE);
|
||||
CloseHandle(commandList.m_event);
|
||||
|
||||
m_control.consume(1);
|
||||
}
|
||||
|
||||
CommandList& commandList = m_commandList[m_control.m_current];
|
||||
DX_CHECK(commandList.m_commandList->Reset(commandList.m_commandAllocator, NULL) );
|
||||
return commandList.m_commandList;
|
||||
}
|
||||
|
||||
uint64_t kick()
|
||||
{
|
||||
CommandList& commandList = m_commandList[m_control.m_current];
|
||||
DX_CHECK(commandList.m_commandList->Close() );
|
||||
|
||||
ID3D12CommandList* commandLists[] = { commandList.m_commandList };
|
||||
m_commandQueue->ExecuteCommandLists(BX_COUNTOF(commandLists), commandLists);
|
||||
|
||||
commandList.m_event = CreateEventExA(NULL, NULL, 0, EVENT_ALL_ACCESS);
|
||||
const uint64_t fence = m_currentFence++;
|
||||
m_commandQueue->Signal(m_fence, fence);
|
||||
m_fence->SetEventOnCompletion(fence, commandList.m_event);
|
||||
|
||||
m_control.commit(1);
|
||||
|
||||
return fence;
|
||||
}
|
||||
|
||||
void finish(uint64_t _waitFence = UINT64_MAX)
|
||||
{
|
||||
while (0 < m_control.available() )
|
||||
{
|
||||
CommandList& commandList = m_commandList[m_control.m_read];
|
||||
WaitForSingleObject(commandList.m_event, INFINITE);
|
||||
CloseHandle(commandList.m_event);
|
||||
commandList.m_event = NULL;
|
||||
m_completedFence = m_fence->GetCompletedValue();
|
||||
m_commandQueue->Wait(m_fence, m_completedFence);
|
||||
|
||||
m_control.consume(1);
|
||||
|
||||
if (_waitFence <= m_completedFence)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BX_CHECK(0 == m_control.available(), "");
|
||||
}
|
||||
|
||||
struct CommandList
|
||||
{
|
||||
ID3D12GraphicsCommandList* m_commandList;
|
||||
ID3D12CommandAllocator* m_commandAllocator;
|
||||
HANDLE m_event;
|
||||
};
|
||||
|
||||
ID3D12CommandQueue* m_commandQueue;
|
||||
uint64_t m_currentFence;
|
||||
uint64_t m_completedFence;
|
||||
ID3D12Fence* m_fence;
|
||||
CommandList m_commandList[4];
|
||||
bx::RingBufferControl m_control;
|
||||
};
|
||||
|
||||
} /* namespace d3d12 */ } // namespace bgfx
|
||||
|
||||
#endif // BGFX_RENDERER_D3D12_H_HEADER_GUARD
|
748
src/shader_dx9bc.cpp
Normal file
748
src/shader_dx9bc.cpp
Normal file
|
@ -0,0 +1,748 @@
|
|||
/*
|
||||
* Copyright 2011-2015 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "bgfx_p.h"
|
||||
#include "shader_dx9bc.h"
|
||||
|
||||
BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wunused-parameter");
|
||||
BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunneeded-internal-declaration");
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
struct Dx9bcOpcodeInfo
|
||||
{
|
||||
uint8_t numOperands;
|
||||
uint8_t numValues;
|
||||
};
|
||||
|
||||
static const Dx9bcOpcodeInfo s_dx9bcOpcodeInfo[] =
|
||||
{
|
||||
{ 0, 0 }, // NOP
|
||||
{ 2, 0 }, // MOV
|
||||
{ 3, 0 }, // ADD
|
||||
{ 1, 0 }, // SUB
|
||||
{ 4, 0 }, // MAD
|
||||
{ 3, 0 }, // MUL
|
||||
{ 2, 0 }, // RCP
|
||||
{ 2, 0 }, // RSQ
|
||||
{ 3, 0 }, // DP3
|
||||
{ 3, 0 }, // DP4
|
||||
{ 3, 0 }, // MIN
|
||||
{ 3, 0 }, // MAX
|
||||
{ 3, 0 }, // SLT
|
||||
{ 3, 0 }, // SGE
|
||||
{ 2, 0 }, // EXP
|
||||
{ 2, 0 }, // LOG
|
||||
{ 1, 0 }, // LIT
|
||||
{ 1, 0 }, // DST
|
||||
{ 4, 0 }, // LRP
|
||||
{ 2, 0 }, // FRC
|
||||
{ 1, 0 }, // M4X4
|
||||
{ 1, 0 }, // M4X3
|
||||
{ 1, 0 }, // M3X4
|
||||
{ 1, 0 }, // M3X3
|
||||
{ 1, 0 }, // M3X2
|
||||
{ 0, 0 }, // CALL
|
||||
{ 0, 0 }, // CALLNZ
|
||||
{ 0, 0 }, // LOOP
|
||||
{ 0, 0 }, // RET
|
||||
{ 0, 0 }, // ENDLOOP
|
||||
{ 0, 0 }, // LABEL
|
||||
{ 1, 1 }, // DCL
|
||||
{ 3, 0 }, // POW
|
||||
{ 1, 0 }, // CRS
|
||||
{ 1, 0 }, // SGN
|
||||
{ 1, 0 }, // ABS
|
||||
{ 2, 0 }, // NRM
|
||||
{ 4, 0 }, // SINCOS
|
||||
{ 1, 0 }, // REP
|
||||
{ 0, 0 }, // ENDREP
|
||||
{ 1, 0 }, // IF
|
||||
{ 2, 0 }, // IFC
|
||||
{ 0, 0 }, // ELSE
|
||||
{ 0, 0 }, // ENDIF
|
||||
{ 0, 0 }, // BREAK
|
||||
{ 2, 0 }, // BREAKC
|
||||
{ 2, 0 }, // MOVA
|
||||
{ 1, 4 }, // DEFB
|
||||
{ 1, 4 }, // DEFI
|
||||
{ 0, 0 }, // 0
|
||||
{ 0, 0 }, // 1
|
||||
{ 0, 0 }, // 2
|
||||
{ 0, 0 }, // 3
|
||||
{ 0, 0 }, // 4
|
||||
{ 0, 0 }, // 5
|
||||
{ 0, 0 }, // 6
|
||||
{ 0, 0 }, // 7
|
||||
{ 0, 0 }, // 8
|
||||
{ 0, 0 }, // 9
|
||||
{ 0, 0 }, // 10
|
||||
{ 0, 0 }, // 11
|
||||
{ 0, 0 }, // 12
|
||||
{ 0, 0 }, // 13
|
||||
{ 0, 0 }, // 14
|
||||
{ 1, 0 }, // TEXCOORD
|
||||
{ 1, 0 }, // TEXKILL
|
||||
{ 3, 0 }, // TEX
|
||||
{ 1, 0 }, // TEXBEM
|
||||
{ 1, 0 }, // TEXBEM1
|
||||
{ 1, 0 }, // TEXREG2AR
|
||||
{ 1, 0 }, // TEXREG2GB
|
||||
{ 1, 0 }, // TEXM3X2PAD
|
||||
{ 1, 0 }, // TEXM3X2TEX
|
||||
{ 1, 0 }, // TEXM3X3PAD
|
||||
{ 1, 0 }, // TEXM3X3TEX
|
||||
{ 1, 0 }, // TEXM3X3DIFF
|
||||
{ 1, 0 }, // TEXM3X3SPEC
|
||||
{ 1, 0 }, // TEXM3X3VSPEC
|
||||
{ 2, 0 }, // EXPP
|
||||
{ 2, 0 }, // LOGP
|
||||
{ 4, 0 }, // CND
|
||||
{ 1, 4 }, // DEF
|
||||
{ 1, 0 }, // TEXREG2RGB
|
||||
{ 1, 0 }, // TEXDP3TEX
|
||||
{ 1, 0 }, // TEXM3X2DEPTH
|
||||
{ 1, 0 }, // TEXDP3
|
||||
{ 1, 0 }, // TEXM3X3
|
||||
{ 1, 0 }, // TEXDEPTH
|
||||
{ 4, 0 }, // CMP
|
||||
{ 1, 0 }, // BEM
|
||||
{ 4, 0 }, // DP2ADD
|
||||
{ 2, 0 }, // DSX
|
||||
{ 2, 0 }, // DSY
|
||||
{ 5, 0 }, // TEXLDD
|
||||
{ 1, 0 }, // SETP
|
||||
{ 3, 0 }, // TEXLDL
|
||||
{ 0, 0 }, // BREAKP
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_dx9bcOpcodeInfo) == Dx9bcOpcode::Count);
|
||||
|
||||
static const char* s_dx9bcOpcode[] =
|
||||
{
|
||||
"nop",
|
||||
"mov",
|
||||
"add",
|
||||
"sub",
|
||||
"mad",
|
||||
"mul",
|
||||
"rcp",
|
||||
"rsq",
|
||||
"dp3",
|
||||
"dp4",
|
||||
"min",
|
||||
"max",
|
||||
"slt",
|
||||
"sge",
|
||||
"exp",
|
||||
"log",
|
||||
"lit",
|
||||
"dst",
|
||||
"lrp",
|
||||
"frc",
|
||||
"m4x4",
|
||||
"m4x3",
|
||||
"m3x4",
|
||||
"m3x3",
|
||||
"m3x2",
|
||||
"call",
|
||||
"callnz",
|
||||
"loop",
|
||||
"ret",
|
||||
"endloop",
|
||||
"label",
|
||||
"dcl",
|
||||
"pow",
|
||||
"crs",
|
||||
"sgn",
|
||||
"abs",
|
||||
"nrm",
|
||||
"sincos",
|
||||
"rep",
|
||||
"endrep",
|
||||
"if",
|
||||
"ifc",
|
||||
"else",
|
||||
"endif",
|
||||
"break",
|
||||
"breakc",
|
||||
"mova",
|
||||
"defb",
|
||||
"defi",
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
"texcoord",
|
||||
"texkill",
|
||||
"tex",
|
||||
"texbem",
|
||||
"texbem1",
|
||||
"texreg2ar",
|
||||
"texreg2gb",
|
||||
"texm3x2pad",
|
||||
"texm3x2tex",
|
||||
"texm3x3pad",
|
||||
"texm3x3tex",
|
||||
"texm3x3diff",
|
||||
"texm3x3spec",
|
||||
"texm3x3vspec",
|
||||
"expp",
|
||||
"logp",
|
||||
"cnd",
|
||||
"def",
|
||||
"texreg2rgb",
|
||||
"texdp3tex",
|
||||
"texm3x2depth",
|
||||
"texdp3",
|
||||
"texm3x3",
|
||||
"texdepth",
|
||||
"cmp",
|
||||
"bem",
|
||||
"dp2add",
|
||||
"dsx",
|
||||
"dsy",
|
||||
"texldd",
|
||||
"setp",
|
||||
"texldl",
|
||||
"breakp",
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_dx9bcOpcode) == Dx9bcOpcode::Count);
|
||||
|
||||
const char* getName(Dx9bcOpcode::Enum _opcode)
|
||||
{
|
||||
BX_CHECK(_opcode < Dx9bcOpcode::Count, "Unknown opcode id %d (%x).", _opcode, _opcode);
|
||||
return s_dx9bcOpcode[_opcode];
|
||||
}
|
||||
|
||||
static const char* s_dx9bcOperandType[] =
|
||||
{
|
||||
"r", // Temporary Register File
|
||||
"v", // Input Register File
|
||||
"c", // Constant Register File
|
||||
"t", // Texture Register File (PS)
|
||||
"oPos", // Rasterizer Register File
|
||||
"oD", // Attribute Output Register File
|
||||
"oT", // Texture Coordinate Output Register File
|
||||
"output", // Output register file for VS3.0+
|
||||
"i", // Constant Integer Vector Register File
|
||||
"oColor", // Color Output Register File
|
||||
"oDepth", // Depth Output Register File
|
||||
"s", // Sampler State Register File
|
||||
"c", // Constant Register File 2048 - 4095
|
||||
"c", // Constant Register File 4096 - 6143
|
||||
"c", // Constant Register File 6144 - 8191
|
||||
"b", // Constant Boolean register file
|
||||
"aL", // Loop counter register file
|
||||
"tempfloat16", // 16-bit float temp register file
|
||||
"misctype", // Miscellaneous (single) registers.
|
||||
"label", // Label
|
||||
"p", // Predicate register
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_dx9bcOperandType) == Dx9bcOperandType::Count);
|
||||
|
||||
static const char* s_dx9bcDeclUsage[] =
|
||||
{
|
||||
"position",
|
||||
"blendweight",
|
||||
"blendindices",
|
||||
"normal",
|
||||
"psize",
|
||||
"texcoord",
|
||||
"tangent",
|
||||
"binormal",
|
||||
"tessfactor",
|
||||
"positiont",
|
||||
"color",
|
||||
"fog",
|
||||
"depth",
|
||||
"sample",
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_dx9bcDeclUsage) == Dx9bcDeclUsage::Count);
|
||||
|
||||
int32_t read(bx::ReaderI* _reader, Dx9bcSubOperand& _subOperand)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uint32_t token;
|
||||
size += bx::read(_reader, token);
|
||||
|
||||
_subOperand.type = Dx9bcOperandType::Enum( ( (token & UINT32_C(0x70000000) ) >> 28)
|
||||
| ( (token & UINT32_C(0x00001800) ) >> 8) );
|
||||
_subOperand.regIndex = (token & UINT32_C(0x000007ff) );
|
||||
_subOperand.swizzleBits = ( (token & UINT32_C(0x00ff0000) ) >> 16);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t write(bx::WriterI* _writer, const Dx9bcSubOperand& _subOperand)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uint32_t token = 0;
|
||||
token |= (_subOperand.type << 28) & UINT32_C(0x70000000);
|
||||
token |= (_subOperand.type << 8) & UINT32_C(0x00001800);
|
||||
token |= _subOperand.regIndex & UINT32_C(0x000007ff);
|
||||
token |= (_subOperand.swizzleBits << 16) & UINT32_C(0x00ff0000);
|
||||
size += bx::write(_writer, token);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t read(bx::ReaderI* _reader, Dx9bcOperand& _operand)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uint32_t token;
|
||||
size += bx::read(_reader, token);
|
||||
|
||||
_operand.type = Dx9bcOperandType::Enum( ( (token & UINT32_C(0x70000000) ) >> 28)
|
||||
| ( (token & UINT32_C(0x00001800) ) >> 8) );
|
||||
_operand.regIndex = (token & UINT32_C(0x000007ff) );
|
||||
_operand.addrMode = Dx9bcOperandAddrMode::Enum( (token & UINT32_C(0x00002000) ) >> 13);
|
||||
|
||||
if (_operand.destination)
|
||||
{
|
||||
// Destination Parameter Token
|
||||
// https://msdn.microsoft.com/en-us/library/ff552738.aspx
|
||||
|
||||
_operand.writeMask = ( (token & UINT32_C(0x000f0000) ) >> 16);
|
||||
_operand.saturate = 0 != (token & UINT32_C(0x00100000) );
|
||||
_operand.partialPrecision = 0 != (token & UINT32_C(0x00200000) );
|
||||
_operand.centroid = 0 != (token & UINT32_C(0x00400000) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Source Parameter Token
|
||||
// https://msdn.microsoft.com/en-us/library/ff569716%28v=vs.85%29.aspx
|
||||
|
||||
_operand.writeMask = 0;
|
||||
_operand.saturate = false;
|
||||
_operand.partialPrecision = false;
|
||||
_operand.centroid = false;
|
||||
_operand.swizzleBits = ( (token & UINT32_C(0x00ff0000) ) >> 16);
|
||||
}
|
||||
|
||||
if (Dx9bcOperandAddrMode::Relative == _operand.addrMode)
|
||||
{
|
||||
size += read(_reader, _operand.subOperand);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t write(bx::WriterI* _writer, const Dx9bcOperand& _operand)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uint32_t token = 0;
|
||||
token |= (_operand.type << 28) & UINT32_C(0x70000000);
|
||||
token |= (_operand.type << 8) & UINT32_C(0x00001800);
|
||||
token |= _operand.regIndex & UINT32_C(0x000007ff);
|
||||
token |= (_operand.addrMode << 13) & UINT32_C(0x00002000);
|
||||
size += bx::write(_writer, token);
|
||||
|
||||
if (Dx9bcOperandAddrMode::Relative == _operand.addrMode)
|
||||
{
|
||||
size += write(_writer, _operand.subOperand);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t read(bx::ReaderI* _reader, Dx9bcInstruction& _instruction)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uint32_t token;
|
||||
size += bx::read(_reader, token);
|
||||
|
||||
_instruction.opcode = Dx9bcOpcode::Enum( (token & UINT32_C(0x0000ffff) ) );
|
||||
|
||||
if (Dx9bcOpcode::Comment == _instruction.opcode)
|
||||
{
|
||||
_instruction.specific = 0;
|
||||
_instruction.length = uint16_t( (token & UINT32_C(0x7fff0000) ) >> 16) + 1;
|
||||
_instruction.predicated = false;
|
||||
_instruction.coissue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_instruction.specific = uint8_t( (token & UINT32_C(0x00ff0000) ) >> 16);
|
||||
_instruction.length = uint8_t( (token & UINT32_C(0x0f000000) ) >> 24) + 1;
|
||||
_instruction.predicated = 0 != (token & UINT32_C(0x10000000) );
|
||||
_instruction.coissue = 0 != (token & UINT32_C(0x40000000) );
|
||||
}
|
||||
|
||||
if (Dx9bcOpcode::Count <= _instruction.opcode)
|
||||
{
|
||||
if (Dx9bcOpcode::Comment == _instruction.opcode)
|
||||
{
|
||||
for (int32_t ii = 0, num = _instruction.length-1; ii < num; ++ii)
|
||||
{
|
||||
uint32_t tmp;
|
||||
size += bx::read(_reader, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t currOp = 0;
|
||||
|
||||
const Dx9bcOpcodeInfo& info = s_dx9bcOpcodeInfo[bx::uint32_min(_instruction.opcode, Dx9bcOpcode::Count)];
|
||||
_instruction.numOperands = info.numOperands;
|
||||
_instruction.numValues = info.numValues;
|
||||
|
||||
switch (_instruction.opcode)
|
||||
{
|
||||
case Dx9bcOpcode::SINCOS:
|
||||
if (5 > _instruction.length)
|
||||
{
|
||||
_instruction.numOperands = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
//BX_TRACE("%d (%d), %d, %d, 0x%08x"
|
||||
// , _instruction.opcode
|
||||
// , bx::uint32_min(_instruction.opcode, Dx9bcOpcode::Count)
|
||||
// , _instruction.length
|
||||
// , _instruction.numOperands
|
||||
// , token
|
||||
// );
|
||||
|
||||
const bool valuesBeforeOpcode = false
|
||||
|| Dx9bcOpcode::DCL == _instruction.opcode
|
||||
;
|
||||
|
||||
if (valuesBeforeOpcode
|
||||
&& 0 < info.numValues)
|
||||
{
|
||||
size += read(_reader, _instruction.value, info.numValues*sizeof(uint32_t) );
|
||||
}
|
||||
|
||||
_instruction.operand[0].destination = true;
|
||||
|
||||
switch (_instruction.numOperands)
|
||||
{
|
||||
case 6: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 5: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 4: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 3: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 2: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 1: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 0:
|
||||
if (!valuesBeforeOpcode
|
||||
&& 0 < info.numValues)
|
||||
{
|
||||
size += read(_reader, _instruction.value, info.numValues*sizeof(uint32_t) );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BX_CHECK(false, "Instruction %s with invalid number of operands %d (numValues %d)."
|
||||
, getName(_instruction.opcode)
|
||||
, _instruction.numOperands
|
||||
, info.numValues
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t write(bx::WriterI* _writer, const Dx9bcInstruction& _instruction)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uint32_t token = 0;
|
||||
token |= _instruction.opcode & UINT32_C(0x0000ffff);
|
||||
token |= (_instruction.specific << 16) & UINT32_C(0x00ff0000);
|
||||
token |= ( (_instruction.length - 1) << 24) & UINT32_C(0x0f000000);
|
||||
size += bx::write(_writer, token);
|
||||
|
||||
uint32_t currOp = 0;
|
||||
switch (_instruction.numOperands)
|
||||
{
|
||||
case 6: size += write(_writer, _instruction.operand[currOp++]);
|
||||
case 5: size += write(_writer, _instruction.operand[currOp++]);
|
||||
case 4: size += write(_writer, _instruction.operand[currOp++]);
|
||||
case 3: size += write(_writer, _instruction.operand[currOp++]);
|
||||
case 2: size += write(_writer, _instruction.operand[currOp++]);
|
||||
case 1: size += write(_writer, _instruction.operand[currOp++]);
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t toString(char* _out, int32_t _size, const Dx9bcInstruction& _instruction)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
if (Dx9bcOpcode::Comment == _instruction.opcode
|
||||
|| Dx9bcOpcode::Phase == _instruction.opcode)
|
||||
{
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "// %x"
|
||||
, _instruction.opcode
|
||||
);
|
||||
return size;
|
||||
}
|
||||
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "%2d %s"
|
||||
, _instruction.opcode
|
||||
, getName(_instruction.opcode)
|
||||
);
|
||||
|
||||
switch (_instruction.opcode)
|
||||
{
|
||||
case Dx9bcOpcode::DCL:
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "_%s%d (%d, %d, %d, %d)"
|
||||
, s_dx9bcDeclUsage[_instruction.value[0] & UINT32_C(0x0000000f)]
|
||||
, (_instruction.value[0] & UINT32_C(0x000f0000) )>>16
|
||||
, (_instruction.value[0] & UINT32_C(0x08000000) )>>27 // ?
|
||||
, (_instruction.value[0] & UINT32_C(0x10000000) )>>28 // texture2d
|
||||
, (_instruction.value[0] & UINT32_C(0x20000000) )>>29 // textureCube
|
||||
, (_instruction.value[0] & UINT32_C(0x40000000) )>>30 // texture3d
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32_t ii = 0; ii < _instruction.numOperands; ++ii)
|
||||
{
|
||||
const Dx9bcOperand& operand = _instruction.operand[ii];
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "%s%s%d"
|
||||
, 0 == ii ? " " : ", "
|
||||
, s_dx9bcOperandType[operand.type]
|
||||
, operand.regIndex
|
||||
);
|
||||
|
||||
if (operand.destination)
|
||||
{
|
||||
if (0xf > operand.writeMask
|
||||
&& 0 < operand.writeMask)
|
||||
{
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, ".%s%s%s%s"
|
||||
, 0 == (operand.writeMask & 1) ? "" : "x"
|
||||
, 0 == (operand.writeMask & 2) ? "" : "y"
|
||||
, 0 == (operand.writeMask & 4) ? "" : "z"
|
||||
, 0 == (operand.writeMask & 8) ? "" : "w"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Dx9bcOperandAddrMode::Relative == operand.addrMode)
|
||||
{
|
||||
const bool array = true;
|
||||
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "["
|
||||
);
|
||||
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "%s%d"
|
||||
, s_dx9bcOperandType[operand.subOperand.type]
|
||||
, operand.subOperand.regIndex
|
||||
);
|
||||
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "%s"
|
||||
, array ? "]" : ""
|
||||
);
|
||||
}
|
||||
|
||||
if (0xe4 != operand.swizzleBits)
|
||||
{
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, ".%c%c%c%c"
|
||||
, "xyzw"[(operand.swizzleBits )&0x3]
|
||||
, "xyzw"[(operand.swizzleBits>>2)&0x3]
|
||||
, "xyzw"[(operand.swizzleBits>>4)&0x3]
|
||||
, "xyzw"[(operand.swizzleBits>>6)&0x3]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (_instruction.opcode)
|
||||
{
|
||||
case Dx9bcOpcode::DEF:
|
||||
for (uint32_t jj = 0; jj < _instruction.numValues; ++jj)
|
||||
{
|
||||
union { int32_t i; float f; } cast = { _instruction.value[jj] };
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "%s%f%s"
|
||||
, 0 == jj ? " (" : ", "
|
||||
, cast.f
|
||||
, uint32_t(_instruction.numValues-1) == jj ? ")" : ""
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case Dx9bcOpcode::DEFI:
|
||||
for (uint32_t jj = 0; jj < _instruction.numValues; ++jj)
|
||||
{
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "%s%d%s"
|
||||
, 0 == jj ? " (" : ", "
|
||||
, _instruction.value[jj]
|
||||
, uint32_t(_instruction.numValues-1) == jj ? ")" : ""
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, Dx9bcShader& _shader)
|
||||
{
|
||||
int32_t size = 0;
|
||||
int64_t offset = bx::seek(_reader);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Dx9bcInstruction instruction;
|
||||
int32_t length = read(_reader, instruction);
|
||||
size += length;
|
||||
|
||||
if (Dx9bcOpcode::Count > instruction.opcode)
|
||||
{
|
||||
char temp[512];
|
||||
toString(temp, 512, instruction);
|
||||
|
||||
BX_CHECK(length/4 == instruction.length
|
||||
, "%s\nread %d, expected %d"
|
||||
, temp
|
||||
, length/4
|
||||
, instruction.length
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Dx9bcOpcode::End == instruction.opcode)
|
||||
{
|
||||
size -= length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bx::seek(_reader, offset, bx::Whence::Begin);
|
||||
|
||||
_shader.byteCode.resize(size);
|
||||
bx::read(_reader, _shader.byteCode.data(), size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t write(bx::WriterI* _writer, const Dx9bcShader& _shader)
|
||||
{
|
||||
BX_UNUSED(_writer, _shader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, Dx9bc& _bc)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
size += bx::read(_reader, _bc.version);
|
||||
|
||||
bool pixelShader = (0xffff0000 == (_bc.version & 0xffff0000) );
|
||||
uint32_t versionMajor = (_bc.version>>8)&0xff;
|
||||
uint32_t versionMinor = _bc.version&0xff;
|
||||
BX_TRACE("%s shader %d.%d"
|
||||
, pixelShader ? "pixel" : "vertex"
|
||||
, versionMajor
|
||||
, versionMinor
|
||||
);
|
||||
|
||||
size += read(_reader, _bc.shader);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t write(bx::WriterSeekerI* _writer, const Dx9bc& _dxbc)
|
||||
{
|
||||
BX_UNUSED(_writer, _dxbc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void parse(const Dx9bcShader& _src, Dx9bcParseFn _fn, void* _userData)
|
||||
{
|
||||
bx::MemoryReader reader(_src.byteCode.data(), uint32_t(_src.byteCode.size() ) );
|
||||
|
||||
//BX_TRACE("parse %d", _src.byteCode.size());
|
||||
|
||||
for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
|
||||
{
|
||||
Dx9bcInstruction instruction;
|
||||
uint32_t size = read(&reader, instruction);
|
||||
|
||||
BX_CHECK(size/4 == instruction.length, "read %d, expected %d", size/4, instruction.length);
|
||||
|
||||
_fn(token * sizeof(uint32_t), instruction, _userData);
|
||||
|
||||
token += instruction.length;
|
||||
}
|
||||
}
|
||||
|
||||
void filter(Dx9bcShader& _dst, const Dx9bcShader& _src, Dx9bcFilterFn _fn, void* _userData)
|
||||
{
|
||||
bx::MemoryReader reader(_src.byteCode.data(), uint32_t(_src.byteCode.size() ) );
|
||||
|
||||
bx::CrtAllocator r;
|
||||
bx::MemoryBlock mb(&r);
|
||||
bx::MemoryWriter writer(&mb);
|
||||
|
||||
for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
|
||||
{
|
||||
Dx9bcInstruction instruction;
|
||||
uint32_t size = read(&reader, instruction);
|
||||
BX_CHECK(size/4 == instruction.length, "read %d, expected %d", size/4, instruction.length);
|
||||
|
||||
_fn(instruction, _userData);
|
||||
|
||||
write(&writer, instruction);
|
||||
|
||||
token += instruction.length;
|
||||
}
|
||||
|
||||
uint8_t* data = (uint8_t*)mb.more();
|
||||
uint32_t size = uint32_t(bx::getSize(&writer) );
|
||||
_dst.byteCode.reserve(size);
|
||||
memcpy(_dst.byteCode.data(), data, size);
|
||||
}
|
||||
|
||||
} // namespace bgfx
|
258
src/shader_dx9bc.h
Normal file
258
src/shader_dx9bc.h
Normal file
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Copyright 2011-2015 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef BGFX_SHADER_DX9BC_H
|
||||
#define BGFX_SHADER_DX9BC_H
|
||||
|
||||
#include <bx/readerwriter.h>
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
struct Dx9bcOpcode
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
NOP,
|
||||
MOV,
|
||||
ADD,
|
||||
SUB,
|
||||
MAD,
|
||||
MUL,
|
||||
RCP,
|
||||
RSQ,
|
||||
DP3,
|
||||
DP4,
|
||||
MIN,
|
||||
MAX,
|
||||
SLT,
|
||||
SGE,
|
||||
EXP,
|
||||
LOG,
|
||||
LIT,
|
||||
DST,
|
||||
LRP,
|
||||
FRC,
|
||||
M4X4,
|
||||
M4X3,
|
||||
M3X4,
|
||||
M3X3,
|
||||
M3X2,
|
||||
CALL,
|
||||
CALLNZ,
|
||||
LOOP,
|
||||
RET,
|
||||
ENDLOOP,
|
||||
LABEL,
|
||||
DCL,
|
||||
POW,
|
||||
CRS,
|
||||
SGN,
|
||||
ABS,
|
||||
NRM,
|
||||
SINCOS,
|
||||
REP,
|
||||
ENDREP,
|
||||
IF,
|
||||
IFC,
|
||||
ELSE,
|
||||
ENDIF,
|
||||
BREAK,
|
||||
BREAKC,
|
||||
MOVA,
|
||||
DEFB,
|
||||
DEFI,
|
||||
|
||||
Unknown = 63,
|
||||
TEXCOORD,
|
||||
TEXKILL,
|
||||
TEX,
|
||||
TEXBEM,
|
||||
TEXBEM1,
|
||||
TEXREG2AR,
|
||||
TEXREG2GB,
|
||||
TEXM3X2PAD,
|
||||
TEXM3X2TEX,
|
||||
TEXM3X3PAD,
|
||||
TEXM3X3TEX,
|
||||
TEXM3X3DIFF,
|
||||
TEXM3X3SPEC,
|
||||
TEXM3X3VSPEC,
|
||||
EXPP,
|
||||
LOGP,
|
||||
CND,
|
||||
DEF,
|
||||
TEXREG2RGB,
|
||||
TEXDP3TEX,
|
||||
TEXM3X2DEPTH,
|
||||
TEXDP3,
|
||||
TEXM3X3,
|
||||
TEXDEPTH,
|
||||
CMP,
|
||||
BEM,
|
||||
DP2ADD,
|
||||
DSX,
|
||||
DSY,
|
||||
TEXLDD,
|
||||
SETP,
|
||||
TEXLDL,
|
||||
BREAKP,
|
||||
|
||||
Count,
|
||||
|
||||
Phase = 0xfffd,
|
||||
Comment = 0xfffe,
|
||||
End = 0xffff
|
||||
};
|
||||
};
|
||||
|
||||
const char* getName(Dx9bcOpcode::Enum _opcode);
|
||||
|
||||
struct Dx9bcResourceDim
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown,
|
||||
Texture1D,
|
||||
Texture2D,
|
||||
TextureCube,
|
||||
Texture3D,
|
||||
};
|
||||
};
|
||||
|
||||
struct Dx9bcOperandType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Temp,
|
||||
Input,
|
||||
Const,
|
||||
Texture,
|
||||
RastOut,
|
||||
AttrOut,
|
||||
TexCrdOut,
|
||||
Output,
|
||||
ConstInt,
|
||||
ColorOut,
|
||||
DepthOut,
|
||||
Sampler,
|
||||
Const2,
|
||||
Const3,
|
||||
Const4,
|
||||
ConstBool,
|
||||
Loop,
|
||||
TempFloat16,
|
||||
MiscType,
|
||||
Label,
|
||||
Predicate,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct Dx9bcDeclUsage
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Position,
|
||||
BlendWeight,
|
||||
BlendIndices,
|
||||
Normal,
|
||||
Psize,
|
||||
Texcoord,
|
||||
Tangent,
|
||||
Binormal,
|
||||
TessFactor,
|
||||
PositionT,
|
||||
Color,
|
||||
Fog,
|
||||
Depth,
|
||||
Sample,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct Dx9bcOperandAddrMode
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Absolute,
|
||||
Relative,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct Dx9bcSubOperand
|
||||
{
|
||||
Dx9bcOperandType::Enum type;
|
||||
uint32_t regIndex;
|
||||
uint8_t swizzleBits;
|
||||
};
|
||||
|
||||
struct Dx9bcOperand
|
||||
{
|
||||
Dx9bcOperandType::Enum type;
|
||||
uint32_t regIndex;
|
||||
|
||||
bool destination;
|
||||
|
||||
// Destination
|
||||
uint8_t writeMask;
|
||||
bool saturate;
|
||||
bool partialPrecision;
|
||||
bool centroid;
|
||||
|
||||
// Source
|
||||
uint8_t swizzleBits;
|
||||
|
||||
Dx9bcOperandAddrMode::Enum addrMode;
|
||||
Dx9bcSubOperand subOperand;
|
||||
};
|
||||
|
||||
struct Dx9bcInstruction
|
||||
{
|
||||
Dx9bcOpcode::Enum opcode;
|
||||
uint16_t length;
|
||||
uint8_t numOperands;
|
||||
uint8_t numValues;
|
||||
uint8_t specific;
|
||||
bool predicated;
|
||||
bool coissue;
|
||||
|
||||
Dx9bcOperand operand[6];
|
||||
int32_t value[4];
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderI* _reader, Dx9bcInstruction& _instruction);
|
||||
int32_t write(bx::WriterI* _writer, const Dx9bcInstruction& _instruction);
|
||||
int32_t toString(char* _out, int32_t _size, const Dx9bcInstruction& _instruction);
|
||||
|
||||
struct Dx9bcShader
|
||||
{
|
||||
stl::vector<uint8_t> byteCode;
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, Dx9bcShader& _shader);
|
||||
int32_t write(bx::WriterI* _writer, const Dx9bcShader& _shader);
|
||||
|
||||
struct Dx9bc
|
||||
{
|
||||
uint32_t version;
|
||||
Dx9bcShader shader;
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, Dx9bc& _dx9bc);
|
||||
int32_t write(bx::WriterSeekerI* _writer, const Dx9bc& _dx9bc);
|
||||
|
||||
typedef void (*Dx9bcParseFn)(uint32_t _offset, const Dx9bcInstruction& _instruction, void* _userData);
|
||||
void parse(const Dx9bcShader& _src, Dx9bcParseFn _fn, void* _userData);
|
||||
|
||||
typedef void (*Dx9bcFilterFn)(Dx9bcInstruction& _instruction, void* _userData);
|
||||
void filter(Dx9bcShader& _dst, const Dx9bcShader& _src, Dx9bcFilterFn _fn, void* _userData);
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
#endif // BGFX_SHADER_DX9BC_H
|
1851
src/shader_dxbc.cpp
Normal file
1851
src/shader_dxbc.cpp
Normal file
File diff suppressed because it is too large
Load diff
608
src/shader_dxbc.h
Normal file
608
src/shader_dxbc.h
Normal file
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* Copyright 2011-2015 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef BGFX_SHADER_DXBC_H
|
||||
#define BGFX_SHADER_DXBC_H
|
||||
|
||||
#include <bx/readerwriter.h>
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
struct DxbcOpcode
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
ADD,
|
||||
AND,
|
||||
BREAK,
|
||||
BREAKC,
|
||||
CALL,
|
||||
CALLC,
|
||||
CASE,
|
||||
CONTINUE,
|
||||
CONTINUEC,
|
||||
CUT,
|
||||
DEFAULT,
|
||||
DERIV_RTX,
|
||||
DERIV_RTY,
|
||||
DISCARD,
|
||||
DIV,
|
||||
DP2,
|
||||
DP3,
|
||||
DP4,
|
||||
ELSE,
|
||||
EMIT,
|
||||
EMITTHENCUT,
|
||||
ENDIF,
|
||||
ENDLOOP,
|
||||
ENDSWITCH,
|
||||
EQ,
|
||||
EXP,
|
||||
FRC,
|
||||
FTOI,
|
||||
FTOU,
|
||||
GE,
|
||||
IADD,
|
||||
IF,
|
||||
IEQ,
|
||||
IGE,
|
||||
ILT,
|
||||
IMAD,
|
||||
IMAX,
|
||||
IMIN,
|
||||
IMUL,
|
||||
INE,
|
||||
INEG,
|
||||
ISHL,
|
||||
ISHR,
|
||||
ITOF,
|
||||
LABEL,
|
||||
LD,
|
||||
LD_MS,
|
||||
LOG,
|
||||
LOOP,
|
||||
LT,
|
||||
MAD,
|
||||
MIN,
|
||||
MAX,
|
||||
CUSTOMDATA,
|
||||
MOV,
|
||||
MOVC,
|
||||
MUL,
|
||||
NE,
|
||||
NOP,
|
||||
NOT,
|
||||
OR,
|
||||
RESINFO,
|
||||
RET,
|
||||
RETC,
|
||||
ROUND_NE,
|
||||
ROUND_NI,
|
||||
ROUND_PI,
|
||||
ROUND_Z,
|
||||
RSQ,
|
||||
SAMPLE,
|
||||
SAMPLE_C,
|
||||
SAMPLE_C_LZ,
|
||||
SAMPLE_L,
|
||||
SAMPLE_D,
|
||||
SAMPLE_B,
|
||||
SQRT,
|
||||
SWITCH,
|
||||
SINCOS,
|
||||
UDIV,
|
||||
ULT,
|
||||
UGE,
|
||||
UMUL,
|
||||
UMAD,
|
||||
UMAX,
|
||||
UMIN,
|
||||
USHR,
|
||||
UTOF,
|
||||
XOR,
|
||||
DCL_RESOURCE,
|
||||
DCL_CONSTANT_BUFFER,
|
||||
DCL_SAMPLER,
|
||||
DCL_INDEX_RANGE,
|
||||
DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY,
|
||||
DCL_GS_INPUT_PRIMITIVE,
|
||||
DCL_MAX_OUTPUT_VERTEX_COUNT,
|
||||
DCL_INPUT,
|
||||
DCL_INPUT_SGV,
|
||||
DCL_INPUT_SIV,
|
||||
DCL_INPUT_PS,
|
||||
DCL_INPUT_PS_SGV,
|
||||
DCL_INPUT_PS_SIV,
|
||||
DCL_OUTPUT,
|
||||
DCL_OUTPUT_SGV,
|
||||
DCL_OUTPUT_SIV,
|
||||
DCL_TEMPS,
|
||||
DCL_INDEXABLE_TEMP,
|
||||
DCL_GLOBAL_FLAGS,
|
||||
|
||||
UnknownD3D10,
|
||||
LOD,
|
||||
GATHER4,
|
||||
SAMPLE_POS,
|
||||
SAMPLE_INFO,
|
||||
|
||||
UnknownD3D10_1,
|
||||
HS_DECLS,
|
||||
HS_CONTROL_POINT_PHASE,
|
||||
HS_FORK_PHASE,
|
||||
HS_JOIN_PHASE,
|
||||
EMIT_STREAM,
|
||||
CUT_STREAM,
|
||||
EMITTHENCUT_STREAM,
|
||||
INTERFACE_CALL,
|
||||
BUFINFO,
|
||||
DERIV_RTX_COARSE,
|
||||
DERIV_RTX_FINE,
|
||||
DERIV_RTY_COARSE,
|
||||
DERIV_RTY_FINE,
|
||||
GATHER4_C,
|
||||
GATHER4_PO,
|
||||
GATHER4_PO_C,
|
||||
RCP,
|
||||
F32TOF16,
|
||||
F16TOF32,
|
||||
UADDC,
|
||||
USUBB,
|
||||
COUNTBITS,
|
||||
FIRSTBIT_HI,
|
||||
FIRSTBIT_LO,
|
||||
FIRSTBIT_SHI,
|
||||
UBFE,
|
||||
IBFE,
|
||||
BFI,
|
||||
BFREV,
|
||||
SWAPC,
|
||||
DCL_STREAM,
|
||||
DCL_FUNCTION_BODY,
|
||||
DCL_FUNCTION_TABLE,
|
||||
DCL_INTERFACE,
|
||||
DCL_INPUT_CONTROL_POINT_COUNT,
|
||||
DCL_OUTPUT_CONTROL_POINT_COUNT,
|
||||
DCL_TESS_DOMAIN,
|
||||
DCL_TESS_PARTITIONING,
|
||||
DCL_TESS_OUTPUT_PRIMITIVE,
|
||||
DCL_HS_MAX_TESSFACTOR,
|
||||
DCL_HS_FORK_PHASE_INSTANCE_COUNT,
|
||||
DCL_HS_JOIN_PHASE_INSTANCE_COUNT,
|
||||
DCL_THREAD_GROUP,
|
||||
DCL_UNORDERED_ACCESS_VIEW_TYPED,
|
||||
DCL_UNORDERED_ACCESS_VIEW_RAW,
|
||||
DCL_UNORDERED_ACCESS_VIEW_STRUCTURED,
|
||||
DCL_THREAD_GROUP_SHARED_MEMORY_RAW,
|
||||
DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED,
|
||||
DCL_RESOURCE_RAW,
|
||||
DCL_RESOURCE_STRUCTURED,
|
||||
LD_UAV_TYPED,
|
||||
STORE_UAV_TYPED,
|
||||
LD_RAW,
|
||||
STORE_RAW,
|
||||
LD_STRUCTURED,
|
||||
STORE_STRUCTURED,
|
||||
ATOMIC_AND,
|
||||
ATOMIC_OR,
|
||||
ATOMIC_XOR,
|
||||
ATOMIC_CMP_STORE,
|
||||
ATOMIC_IADD,
|
||||
ATOMIC_IMAX,
|
||||
ATOMIC_IMIN,
|
||||
ATOMIC_UMAX,
|
||||
ATOMIC_UMIN,
|
||||
IMM_ATOMIC_ALLOC,
|
||||
IMM_ATOMIC_CONSUME,
|
||||
IMM_ATOMIC_IADD,
|
||||
IMM_ATOMIC_AND,
|
||||
IMM_ATOMIC_OR,
|
||||
IMM_ATOMIC_XOR,
|
||||
IMM_ATOMIC_EXCH,
|
||||
IMM_ATOMIC_CMP_EXCH,
|
||||
IMM_ATOMIC_IMAX,
|
||||
IMM_ATOMIC_IMIN,
|
||||
IMM_ATOMIC_UMAX,
|
||||
IMM_ATOMIC_UMIN,
|
||||
SYNC,
|
||||
DADD,
|
||||
DMAX,
|
||||
DMIN,
|
||||
DMUL,
|
||||
DEQ,
|
||||
DGE,
|
||||
DLT,
|
||||
DNE,
|
||||
DMOV,
|
||||
DMOVC,
|
||||
DTOF,
|
||||
FTOD,
|
||||
EVAL_SNAPPED,
|
||||
EVAL_SAMPLE_INDEX,
|
||||
EVAL_CENTROID,
|
||||
DCL_GS_INSTANCE_COUNT,
|
||||
ABORT,
|
||||
DEBUG_BREAK,
|
||||
|
||||
UnknownD3D11,
|
||||
DDIV,
|
||||
DFMA,
|
||||
DRCP,
|
||||
MSAD,
|
||||
DTOI,
|
||||
DTOU,
|
||||
ITOD,
|
||||
UTOD,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
const char* getName(DxbcOpcode::Enum _opcode);
|
||||
|
||||
struct DxbcBuiltin
|
||||
{
|
||||
// D3D_NAME
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff728724%28v=vs.85%29.aspx
|
||||
// mesa/src/gallium/state_trackers/d3d1x/d3d1xshader/defs/svs.txt
|
||||
enum Enum
|
||||
{
|
||||
Undefined,
|
||||
Position,
|
||||
ClipDistance,
|
||||
CullDistance,
|
||||
RenderTargetArrayIndex,
|
||||
ViewportArrayIndex,
|
||||
VertexId,
|
||||
PrimitiveId,
|
||||
InstanceId,
|
||||
IsFrontFace,
|
||||
SampleIndex,
|
||||
FinalQuadUEq0EdgeTessFactor,
|
||||
FinalQuadVEq0EdgeTessFactor,
|
||||
FinalQuadUEq1EdgeTessFactor,
|
||||
FinalQuadVEq1EdgeTessFactor,
|
||||
FinalQuadUInsideTessFactor,
|
||||
FinalQuadVInsideTessFactor,
|
||||
FinalTriUEq0EdgeTessFactor,
|
||||
FinalTriVEq0EdgeTessFactor,
|
||||
FinalTriWEq0EdgeTessFactor,
|
||||
FinalTriInsideTessFactor,
|
||||
FinalLineDetailTessFactor,
|
||||
FinalLineDensityTessFactor,
|
||||
Target = 64,
|
||||
Depth,
|
||||
Coverage,
|
||||
DepthGreaterEqual,
|
||||
DepthLessEqual,
|
||||
StencilRef,
|
||||
InnerCoverage,
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcResourceDim
|
||||
{
|
||||
// D3D_SRV_DIMENSION
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff728736%28v=vs.85%29.aspx
|
||||
// mesa/src/gallium/state_trackers/d3d1x/d3d1xshader/defs/targets.txt
|
||||
enum Enum
|
||||
{
|
||||
Unknown,
|
||||
Buffer,
|
||||
Texture1D,
|
||||
Texture2D,
|
||||
Texture2DMS,
|
||||
Texture3D,
|
||||
TextureCube,
|
||||
Texture1DArray,
|
||||
Texture2DArray,
|
||||
Texture2DMSArray,
|
||||
TextureCubearray,
|
||||
RawBuffer,
|
||||
StructuredBuffer,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcInterpolation
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown,
|
||||
Constant,
|
||||
Linear,
|
||||
LinearCentroid,
|
||||
LinearNoPerspective,
|
||||
LinearNoPerspectiveCentroid,
|
||||
LinearSample,
|
||||
LinearNoPerspectiveSample,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcResourceReturnType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unorm,
|
||||
Snorm,
|
||||
Sint,
|
||||
Uint,
|
||||
Float,
|
||||
Mixed,
|
||||
Double,
|
||||
Continued,
|
||||
Unused,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcComponentType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown,
|
||||
Uint32,
|
||||
Int32,
|
||||
Float,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcPrecision
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Default,
|
||||
Half,
|
||||
Float2_8,
|
||||
Reserved,
|
||||
Int16,
|
||||
Uint16,
|
||||
Any16 = 0xf0,
|
||||
Any10 = 0xf1,
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcOperandType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Temp,
|
||||
Input,
|
||||
Output,
|
||||
TempArray,
|
||||
Imm32,
|
||||
Imm64,
|
||||
Sampler,
|
||||
Resource,
|
||||
ConstantBuffer,
|
||||
ImmConstantBuffer,
|
||||
Label,
|
||||
PrimitiveID,
|
||||
OutputDepth,
|
||||
Null,
|
||||
Rasterizer,
|
||||
CoverageMask,
|
||||
Stream,
|
||||
FunctionBody,
|
||||
FunctionTable,
|
||||
Interface,
|
||||
FunctionInput,
|
||||
FunctionOutput,
|
||||
OutputControlPointId,
|
||||
InputForkInstanceId,
|
||||
InputJoinInstanceId,
|
||||
InputControlPoint,
|
||||
OutputControlPoint,
|
||||
InputPatchConstant,
|
||||
InputDomainPoint,
|
||||
ThisPointer,
|
||||
UnorderedAccessView,
|
||||
ThreadGroupSharedMemory,
|
||||
InputThreadId,
|
||||
InputThreadGroupId,
|
||||
InputThreadIdInGroup,
|
||||
InputCoverageMask,
|
||||
InputThreadIdInGroupFlattened,
|
||||
InputGsInstanceId,
|
||||
OutputDepthGreaterEqual,
|
||||
OutputDepthLessEqual,
|
||||
CycleCounter,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcOperandAddrMode
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Imm32,
|
||||
Imm64,
|
||||
Reg,
|
||||
RegImm32,
|
||||
RegImm64,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcOperandMode
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Mask,
|
||||
Swizzle,
|
||||
Scalar,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct DxbcSubOperand
|
||||
{
|
||||
DxbcOperandType::Enum type;
|
||||
uint8_t mode;
|
||||
uint8_t modeBits;
|
||||
uint8_t num;
|
||||
uint8_t numAddrModes;
|
||||
uint8_t addrMode;
|
||||
uint32_t regIndex;
|
||||
};
|
||||
|
||||
struct DxbcOperand
|
||||
{
|
||||
DxbcOperandType::Enum type;
|
||||
DxbcOperandMode::Enum mode;
|
||||
uint8_t modeBits;
|
||||
uint8_t num;
|
||||
bool extended;
|
||||
uint32_t extBits;
|
||||
|
||||
uint8_t numAddrModes;
|
||||
uint8_t addrMode[3];
|
||||
uint32_t regIndex[3];
|
||||
DxbcSubOperand subOperand[3];
|
||||
|
||||
union
|
||||
{
|
||||
uint32_t imm32[4];
|
||||
uint64_t imm64[4];
|
||||
} un;
|
||||
};
|
||||
|
||||
struct DxbcInstruction
|
||||
{
|
||||
struct ExtendedType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Empty,
|
||||
SampleControls,
|
||||
ResourceDim,
|
||||
ResourceReturnType,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
DxbcOpcode::Enum opcode;
|
||||
uint32_t value[3];
|
||||
uint32_t length;
|
||||
uint8_t numOperands;
|
||||
ExtendedType::Enum extended[3];
|
||||
|
||||
//
|
||||
DxbcResourceDim::Enum srv;
|
||||
uint8_t samples;
|
||||
|
||||
//
|
||||
DxbcInterpolation::Enum interpolation;
|
||||
|
||||
//
|
||||
bool shadow;
|
||||
bool mono;
|
||||
|
||||
//
|
||||
bool allowRefactoring;
|
||||
bool fp64;
|
||||
bool earlyDepth;
|
||||
bool enableBuffers;
|
||||
bool skipOptimization;
|
||||
bool enableMinPrecision;
|
||||
bool enableDoubleExtensions;
|
||||
bool enableShaderExtensions;
|
||||
|
||||
//
|
||||
bool threadsInGroup;
|
||||
bool sharedMemory;
|
||||
bool uavGroup;
|
||||
bool uavGlobal;
|
||||
|
||||
//
|
||||
DxbcResourceReturnType::Enum retType;
|
||||
bool saturate;
|
||||
uint8_t testNZ;
|
||||
|
||||
//
|
||||
uint8_t sampleOffsets[3];
|
||||
uint8_t resourceTarget;
|
||||
uint8_t resourceStride;
|
||||
DxbcResourceReturnType::Enum resourceReturnTypes[4];
|
||||
|
||||
DxbcOperand operand[6];
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderI* _reader, DxbcInstruction& _instruction);
|
||||
int32_t write(bx::WriterI* _writer, const DxbcInstruction& _instruction);
|
||||
int32_t toString(char* _out, int32_t _size, const DxbcInstruction& _instruction);
|
||||
|
||||
struct DxbcSignature
|
||||
{
|
||||
struct Element
|
||||
{
|
||||
stl::string name;
|
||||
uint32_t semanticIndex;
|
||||
DxbcBuiltin::Enum valueType;
|
||||
DxbcComponentType::Enum componentType;
|
||||
uint32_t registerIndex;
|
||||
uint8_t mask;
|
||||
uint8_t readWriteMask;
|
||||
uint8_t stream;
|
||||
};
|
||||
|
||||
uint32_t key;
|
||||
stl::vector<Element> elements;
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, DxbcSignature& _signature);
|
||||
int32_t write(bx::WriterI* _writer, const DxbcSignature& _signature);
|
||||
|
||||
struct DxbcShader
|
||||
{
|
||||
uint32_t version;
|
||||
stl::vector<uint8_t> byteCode;
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, DxbcShader& _shader);
|
||||
int32_t write(bx::WriterI* _writer, const DxbcShader& _shader);
|
||||
|
||||
typedef void (*DxbcParseFn)(uint32_t _offset, const DxbcInstruction& _instruction, void* _userData);
|
||||
void parse(const DxbcShader& _src, DxbcParseFn _fn, void* _userData);
|
||||
|
||||
typedef void (*DxbcFilterFn)(DxbcInstruction& _instruction, void* _userData);
|
||||
void filter(DxbcShader& _dst, const DxbcShader& _src, DxbcFilterFn _fn, void* _userData);
|
||||
|
||||
struct DxbcContext
|
||||
{
|
||||
struct Header
|
||||
{
|
||||
uint32_t magic;
|
||||
uint8_t hash[16];
|
||||
uint32_t version;
|
||||
uint32_t size;
|
||||
uint32_t numChunks;
|
||||
};
|
||||
|
||||
Header header;
|
||||
DxbcSignature inputSignature;
|
||||
DxbcSignature outputSignature;
|
||||
DxbcShader shader;
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, DxbcContext& _dxbc);
|
||||
int32_t write(bx::WriterSeekerI* _writer, const DxbcContext& _dxbc);
|
||||
|
||||
/// Calculate DXBC hash from data.
|
||||
void dxbcHash(const void* _data, uint32_t _size, void* _digest);
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
#endif // BGFX_SHADER_DXBC_H
|
732
src/shader_spirv.cpp
Normal file
732
src/shader_spirv.cpp
Normal file
|
@ -0,0 +1,732 @@
|
|||
/*
|
||||
* Copyright 2011-2015 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "bgfx_p.h"
|
||||
#include "shader_spirv.h"
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
struct SpirvOpcodeInfo
|
||||
{
|
||||
uint8_t numOperands;
|
||||
uint8_t numValues;
|
||||
bool hasVariable;
|
||||
};
|
||||
|
||||
static const SpirvOpcodeInfo s_sprivOpcodeInfo[] =
|
||||
{
|
||||
{ 0, 0, false }, // Nop,
|
||||
{ 0, 0, true }, // Source
|
||||
{ 0, 0, true }, // SourceExtension
|
||||
{ 0, 0, false }, // Extension
|
||||
{ 0, 1, true }, // ExtInstImport
|
||||
{ 0, 2, false }, // MemoryModel
|
||||
{ 0, 2, false }, // EntryPoint
|
||||
{ 0, 0, false }, // ExecutionMode
|
||||
{ 0, 1, false }, // TypeVoid
|
||||
{ 0, 1, false }, // TypeBool
|
||||
{ 0, 3, false }, // TypeInt
|
||||
{ 0, 2, false }, // TypeFloat
|
||||
{ 0, 3, false }, // TypeVector
|
||||
{ 0, 3, false }, // TypeMatrix
|
||||
{ 1, 7, false }, // TypeSampler
|
||||
{ 0, 0, false }, // TypeFilter
|
||||
{ 0, 0, false }, // TypeArray
|
||||
{ 0, 0, false }, // TypeRuntimeArray
|
||||
{ 0, 0, false }, // TypeStruct
|
||||
{ 0, 0, false }, // TypeOpaque
|
||||
{ 0, 3, false }, // TypePointer
|
||||
{ 0, 2, true }, // TypeFunction
|
||||
{ 0, 0, false }, // TypeEvent
|
||||
{ 0, 0, false }, // TypeDeviceEvent
|
||||
{ 0, 0, false }, // TypeReserveId
|
||||
{ 0, 0, false }, // TypeQueue
|
||||
{ 0, 0, false }, // TypePipe
|
||||
{ 0, 0, false }, // ConstantTrue
|
||||
{ 0, 0, false }, // ConstantFalse
|
||||
{ 0, 2, true }, // Constant
|
||||
{ 0, 2, true }, // ConstantComposite
|
||||
{ 0, 0, false }, // ConstantSampler
|
||||
{ 0, 0, false }, // ConstantNullPointer
|
||||
{ 0, 0, false }, // ConstantNullObject
|
||||
{ 0, 0, false }, // SpecConstantTrue
|
||||
{ 0, 0, false }, // SpecConstantFalse
|
||||
{ 0, 0, false }, // SpecConstant
|
||||
{ 0, 0, false }, // SpecConstantComposite
|
||||
{ 0, 3, true }, // Variable
|
||||
{ 0, 0, false }, // VariableArray
|
||||
{ 0, 4, false }, // Function
|
||||
{ 0, 0, false }, // FunctionParameter
|
||||
{ 0, 0, false }, // FunctionEnd
|
||||
{ 0, 0, false }, // FunctionCall
|
||||
{ 0, 0, false }, // ExtInst
|
||||
{ 0, 0, false }, // Undef
|
||||
{ 0, 0, false }, // Load
|
||||
{ 0, 2, true }, // Store
|
||||
{ 0, 0, false }, // Phi
|
||||
{ 0, 0, false }, // DecorationGroup
|
||||
{ 0, 2, true }, // Decorate
|
||||
{ 0, 0, false }, // MemberDecorate
|
||||
{ 0, 0, false }, // GroupDecorate
|
||||
{ 0, 0, false }, // GroupMemberDecorate
|
||||
{ 0, 1, true }, // Name
|
||||
{ 0, 1, true }, // MemberName
|
||||
{ 0, 0, false }, // String
|
||||
{ 0, 0, false }, // Line
|
||||
{ 0, 0, false }, // VectorExtractDynamic
|
||||
{ 0, 0, false }, // VectorInsertDynamic
|
||||
{ 0, 0, false }, // VectorShuffle
|
||||
{ 0, 0, false }, // CompositeConstruct
|
||||
{ 0, 0, false }, // CompositeExtract
|
||||
{ 0, 0, false }, // CompositeInsert
|
||||
{ 0, 0, false }, // CopyObject
|
||||
{ 0, 0, false }, // CopyMemory
|
||||
{ 0, 0, false }, // CopyMemorySized
|
||||
{ 0, 0, false }, // Sampler
|
||||
{ 0, 0, false }, // TextureSample
|
||||
{ 0, 0, false }, // TextureSampleDref
|
||||
{ 0, 0, false }, // TextureSampleLod
|
||||
{ 0, 0, false }, // TextureSampleProj
|
||||
{ 0, 0, false }, // TextureSampleGrad
|
||||
{ 0, 0, false }, // TextureSampleOffset
|
||||
{ 0, 0, false }, // TextureSampleProjLod
|
||||
{ 0, 0, false }, // TextureSampleProjGrad
|
||||
{ 0, 0, false }, // TextureSampleLodOffset
|
||||
{ 0, 0, false }, // TextureSampleProjOffset
|
||||
{ 0, 0, false }, // TextureSampleGradOffset
|
||||
{ 0, 0, false }, // TextureSampleProjLodOffset
|
||||
{ 0, 0, false }, // TextureSampleProjGradOffset
|
||||
{ 0, 0, false }, // TextureFetchTexelLod
|
||||
{ 0, 0, false }, // TextureFetchTexelOffset
|
||||
{ 0, 0, false }, // TextureFetchSample
|
||||
{ 0, 0, false }, // TextureFetchTexel
|
||||
{ 0, 0, false }, // TextureGather
|
||||
{ 0, 0, false }, // TextureGatherOffset
|
||||
{ 0, 0, false }, // TextureGatherOffsets
|
||||
{ 0, 0, false }, // TextureQuerySizeLod
|
||||
{ 0, 0, false }, // TextureQuerySize
|
||||
{ 0, 0, false }, // TextureQueryLod
|
||||
{ 0, 0, false }, // TextureQueryLevels
|
||||
{ 0, 0, false }, // TextureQuerySamples
|
||||
{ 0, 0, false }, // AccessChain
|
||||
{ 0, 0, false }, // InBoundsAccessChain
|
||||
{ 0, 0, false }, // SNegate
|
||||
{ 0, 0, false }, // FNegate
|
||||
{ 0, 0, false }, // Not
|
||||
{ 0, 0, false }, // Any
|
||||
{ 0, 0, false }, // All
|
||||
{ 0, 0, false }, // ConvertFToU
|
||||
{ 0, 0, false }, // ConvertFToS
|
||||
{ 0, 0, false }, // ConvertSToF
|
||||
{ 0, 0, false }, // ConvertUToF
|
||||
{ 0, 0, false }, // UConvert
|
||||
{ 0, 0, false }, // SConvert
|
||||
{ 0, 0, false }, // FConvert
|
||||
{ 0, 0, false }, // ConvertPtrToU
|
||||
{ 0, 0, false }, // ConvertUToPtr
|
||||
{ 0, 0, false }, // PtrCastToGeneric
|
||||
{ 0, 0, false }, // GenericCastToPtr
|
||||
{ 0, 0, false }, // Bitcast
|
||||
{ 0, 0, false }, // Transpose
|
||||
{ 0, 0, false }, // IsNan
|
||||
{ 0, 0, false }, // IsInf
|
||||
{ 0, 0, false }, // IsFinite
|
||||
{ 0, 0, false }, // IsNormal
|
||||
{ 0, 0, false }, // SignBitSet
|
||||
{ 0, 0, false }, // LessOrGreater
|
||||
{ 0, 0, false }, // Ordered
|
||||
{ 0, 0, false }, // Unordered
|
||||
{ 0, 0, false }, // ArrayLength
|
||||
{ 0, 0, false }, // IAdd
|
||||
{ 0, 0, false }, // FAdd
|
||||
{ 0, 0, false }, // ISub
|
||||
{ 0, 0, false }, // FSub
|
||||
{ 0, 0, false }, // IMul
|
||||
{ 0, 0, false }, // FMul
|
||||
{ 0, 0, false }, // UDiv
|
||||
{ 0, 0, false }, // SDiv
|
||||
{ 0, 0, false }, // FDiv
|
||||
{ 0, 0, false }, // UMod
|
||||
{ 0, 0, false }, // SRem
|
||||
{ 0, 0, false }, // SMod
|
||||
{ 0, 0, false }, // FRem
|
||||
{ 0, 0, false }, // FMod
|
||||
{ 0, 0, false }, // VectorTimesScalar
|
||||
{ 0, 0, false }, // MatrixTimesScalar
|
||||
{ 0, 0, false }, // VectorTimesMatrix
|
||||
{ 0, 0, false }, // MatrixTimesVector
|
||||
{ 0, 0, false }, // MatrixTimesMatrix
|
||||
{ 0, 0, false }, // OuterProduct
|
||||
{ 0, 0, false }, // Dot
|
||||
{ 0, 0, false }, // ShiftRightLogical
|
||||
{ 0, 0, false }, // ShiftRightArithmetic
|
||||
{ 0, 0, false }, // ShiftLeftLogical
|
||||
{ 0, 0, false }, // LogicalOr
|
||||
{ 0, 0, false }, // LogicalXor
|
||||
{ 0, 0, false }, // LogicalAnd
|
||||
{ 0, 0, false }, // BitwiseOr
|
||||
{ 0, 0, false }, // BitwiseXor
|
||||
{ 0, 0, false }, // BitwiseAnd
|
||||
{ 0, 0, false }, // Select
|
||||
{ 0, 0, false }, // IEqual
|
||||
{ 0, 0, false }, // FOrdEqual
|
||||
{ 0, 0, false }, // FUnordEqual
|
||||
{ 0, 0, false }, // INotEqual
|
||||
{ 0, 0, false }, // FOrdNotEqual
|
||||
{ 0, 0, false }, // FUnordNotEqual
|
||||
{ 0, 0, false }, // ULessThan
|
||||
{ 0, 0, false }, // SLessThan
|
||||
{ 0, 0, false }, // FOrdLessThan
|
||||
{ 0, 0, false }, // FUnordLessThan
|
||||
{ 0, 0, false }, // UGreaterThan
|
||||
{ 0, 0, false }, // SGreaterThan
|
||||
{ 0, 0, false }, // FOrdGreaterThan
|
||||
{ 0, 0, false }, // FUnordGreaterThan
|
||||
{ 0, 0, false }, // ULessThanEqual
|
||||
{ 0, 0, false }, // SLessThanEqual
|
||||
{ 0, 0, false }, // FOrdLessThanEqual
|
||||
{ 0, 0, false }, // FUnordLessThanEqual
|
||||
{ 0, 0, false }, // UGreaterThanEqual
|
||||
{ 0, 0, false }, // SGreaterThanEqual
|
||||
{ 0, 0, false }, // FOrdGreaterThanEqual
|
||||
{ 0, 0, false }, // FUnordGreaterThanEqual
|
||||
{ 0, 0, false }, // DPdx
|
||||
{ 0, 0, false }, // DPdy
|
||||
{ 0, 0, false }, // Fwidth
|
||||
{ 0, 0, false }, // DPdxFine
|
||||
{ 0, 0, false }, // DPdyFine
|
||||
{ 0, 0, false }, // FwidthFine
|
||||
{ 0, 0, false }, // DPdxCoarse
|
||||
{ 0, 0, false }, // DPdyCoarse
|
||||
{ 0, 0, false }, // FwidthCoarse
|
||||
{ 0, 0, false }, // EmitVertex
|
||||
{ 0, 0, false }, // EndPrimitive
|
||||
{ 0, 0, false }, // EmitStreamVertex
|
||||
{ 0, 0, false }, // EndStreamPrimitive
|
||||
{ 0, 0, false }, // ControlBarrier
|
||||
{ 0, 0, false }, // MemoryBarrier
|
||||
{ 0, 0, false }, // ImagePointer
|
||||
{ 0, 0, false }, // AtomicInit
|
||||
{ 0, 0, false }, // AtomicLoad
|
||||
{ 0, 0, false }, // AtomicStore
|
||||
{ 0, 0, false }, // AtomicExchange
|
||||
{ 0, 0, false }, // AtomicCompareExchange
|
||||
{ 0, 0, false }, // AtomicCompareExchangeWeak
|
||||
{ 0, 0, false }, // AtomicIIncrement
|
||||
{ 0, 0, false }, // AtomicIDecrement
|
||||
{ 0, 0, false }, // AtomicIAdd
|
||||
{ 0, 0, false }, // AtomicISub
|
||||
{ 0, 0, false }, // AtomicUMin
|
||||
{ 0, 0, false }, // AtomicUMax
|
||||
{ 0, 0, false }, // AtomicAnd
|
||||
{ 0, 0, false }, // AtomicOr
|
||||
{ 0, 0, false }, // AtomicXor
|
||||
{ 0, 0, false }, // LoopMerge
|
||||
{ 0, 0, false }, // SelectionMerge
|
||||
{ 0, 1, false }, // Label
|
||||
{ 0, 1, false }, // Branch
|
||||
{ 0, 0, false }, // BranchConditional
|
||||
{ 0, 0, false }, // Switch
|
||||
{ 0, 0, false }, // Kill
|
||||
{ 0, 0, false }, // Return
|
||||
{ 0, 0, false }, // ReturnValue
|
||||
{ 0, 0, false }, // Unreachable
|
||||
{ 0, 0, false }, // LifetimeStart
|
||||
{ 0, 0, false }, // LifetimeStop
|
||||
{ 0, 0, false }, // CompileFlag
|
||||
{ 0, 0, false }, // AsyncGroupCopy
|
||||
{ 0, 0, false }, // WaitGroupEvents
|
||||
{ 0, 0, false }, // GroupAll
|
||||
{ 0, 0, false }, // GroupAny
|
||||
{ 0, 0, false }, // GroupBroadcast
|
||||
{ 0, 0, false }, // GroupIAdd
|
||||
{ 0, 0, false }, // GroupFAdd
|
||||
{ 0, 0, false }, // GroupFMin
|
||||
{ 0, 0, false }, // GroupUMin
|
||||
{ 0, 0, false }, // GroupSMin
|
||||
{ 0, 0, false }, // GroupFMax
|
||||
{ 0, 0, false }, // GroupUMax
|
||||
{ 0, 0, false }, // GroupSMax
|
||||
{ 0, 0, false }, // GenericCastToPtrExplicit
|
||||
{ 0, 0, false }, // GenericPtrMemSemantics
|
||||
{ 0, 0, false }, // ReadPipe
|
||||
{ 0, 0, false }, // WritePipe
|
||||
{ 0, 0, false }, // ReservedReadPipe
|
||||
{ 0, 0, false }, // ReservedWritePipe
|
||||
{ 0, 0, false }, // ReserveReadPipePackets
|
||||
{ 0, 0, false }, // ReserveWritePipePackets
|
||||
{ 0, 0, false }, // CommitReadPipe
|
||||
{ 0, 0, false }, // CommitWritePipe
|
||||
{ 0, 0, false }, // IsValidReserveId
|
||||
{ 0, 0, false }, // GetNumPipePackets
|
||||
{ 0, 0, false }, // GetMaxPipePackets
|
||||
{ 0, 0, false }, // GroupReserveReadPipePackets
|
||||
{ 0, 0, false }, // GroupReserveWritePipePackets
|
||||
{ 0, 0, false }, // GroupCommitReadPipe
|
||||
{ 0, 0, false }, // GroupCommitWritePipe
|
||||
{ 0, 0, false }, // EnqueueMarker
|
||||
{ 0, 0, false }, // EnqueueKernel
|
||||
{ 0, 0, false }, // GetKernelNDrangeSubGroupCount
|
||||
{ 0, 0, false }, // GetKernelNDrangeMaxSubGroupSize
|
||||
{ 0, 0, false }, // GetKernelWorkGroupSize
|
||||
{ 0, 0, false }, // GetKernelPreferredWorkGroupSizeMultiple
|
||||
{ 0, 0, false }, // RetainEvent
|
||||
{ 0, 0, false }, // ReleaseEvent
|
||||
{ 0, 0, false }, // CreateUserEvent
|
||||
{ 0, 0, false }, // IsValidEvent
|
||||
{ 0, 0, false }, // SetUserEventStatus
|
||||
{ 0, 0, false }, // CaptureEventProfilingInfo
|
||||
{ 0, 0, false }, // GetDefaultQueue
|
||||
{ 0, 0, false }, // BuildNDRange
|
||||
{ 0, 0, false }, // SatConvertSToU
|
||||
{ 0, 0, false }, // SatConvertUToS
|
||||
{ 0, 0, false }, // AtomicIMin
|
||||
{ 0, 0, false }, // AtomicIMax
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_sprivOpcodeInfo) == SpirvOpcode::Count);
|
||||
|
||||
const char* s_spirvOpcode[] =
|
||||
{
|
||||
"Nop",
|
||||
"Source",
|
||||
"SourceExtension",
|
||||
"Extension",
|
||||
"ExtInstImport",
|
||||
"MemoryModel",
|
||||
"EntryPoint",
|
||||
"ExecutionMode",
|
||||
"TypeVoid",
|
||||
"TypeBool",
|
||||
"TypeInt",
|
||||
"TypeFloat",
|
||||
"TypeVector",
|
||||
"TypeMatrix",
|
||||
"TypeSampler",
|
||||
"TypeFilter",
|
||||
"TypeArray",
|
||||
"TypeRuntimeArray",
|
||||
"TypeStruct",
|
||||
"TypeOpaque",
|
||||
"TypePointer",
|
||||
"TypeFunction",
|
||||
"TypeEvent",
|
||||
"TypeDeviceEvent",
|
||||
"TypeReserveId",
|
||||
"TypeQueue",
|
||||
"TypePipe",
|
||||
"ConstantTrue",
|
||||
"ConstantFalse",
|
||||
"Constant",
|
||||
"ConstantComposite",
|
||||
"ConstantSampler",
|
||||
"ConstantNullPointer",
|
||||
"ConstantNullObject",
|
||||
"SpecConstantTrue",
|
||||
"SpecConstantFalse",
|
||||
"SpecConstant",
|
||||
"SpecConstantComposite",
|
||||
"Variable",
|
||||
"VariableArray",
|
||||
"Function",
|
||||
"FunctionParameter",
|
||||
"FunctionEnd",
|
||||
"FunctionCall",
|
||||
"ExtInst",
|
||||
"Undef",
|
||||
"Load",
|
||||
"Store",
|
||||
"Phi",
|
||||
"DecorationGroup",
|
||||
"Decorate",
|
||||
"MemberDecorate",
|
||||
"GroupDecorate",
|
||||
"GroupMemberDecorate",
|
||||
"Name",
|
||||
"MemberName",
|
||||
"String",
|
||||
"Line",
|
||||
"VectorExtractDynamic",
|
||||
"VectorInsertDynamic",
|
||||
"VectorShuffle",
|
||||
"CompositeConstruct",
|
||||
"CompositeExtract",
|
||||
"CompositeInsert",
|
||||
"CopyObject",
|
||||
"CopyMemory",
|
||||
"CopyMemorySized",
|
||||
"Sampler",
|
||||
"TextureSample",
|
||||
"TextureSampleDref",
|
||||
"TextureSampleLod",
|
||||
"TextureSampleProj",
|
||||
"TextureSampleGrad",
|
||||
"TextureSampleOffset",
|
||||
"TextureSampleProjLod",
|
||||
"TextureSampleProjGrad",
|
||||
"TextureSampleLodOffset",
|
||||
"TextureSampleProjOffset",
|
||||
"TextureSampleGradOffset",
|
||||
"TextureSampleProjLodOffset",
|
||||
"TextureSampleProjGradOffset",
|
||||
"TextureFetchTexelLod",
|
||||
"TextureFetchTexelOffset",
|
||||
"TextureFetchSample",
|
||||
"TextureFetchTexel",
|
||||
"TextureGather",
|
||||
"TextureGatherOffset",
|
||||
"TextureGatherOffsets",
|
||||
"TextureQuerySizeLod",
|
||||
"TextureQuerySize",
|
||||
"TextureQueryLod",
|
||||
"TextureQueryLevels",
|
||||
"TextureQuerySamples",
|
||||
"AccessChain",
|
||||
"InBoundsAccessChain",
|
||||
"SNegate",
|
||||
"FNegate",
|
||||
"Not",
|
||||
"Any",
|
||||
"All",
|
||||
"ConvertFToU",
|
||||
"ConvertFToS",
|
||||
"ConvertSToF",
|
||||
"ConvertUToF",
|
||||
"UConvert",
|
||||
"SConvert",
|
||||
"FConvert",
|
||||
"ConvertPtrToU",
|
||||
"ConvertUToPtr",
|
||||
"PtrCastToGeneric",
|
||||
"GenericCastToPtr",
|
||||
"Bitcast",
|
||||
"Transpose",
|
||||
"IsNan",
|
||||
"IsInf",
|
||||
"IsFinite",
|
||||
"IsNormal",
|
||||
"SignBitSet",
|
||||
"LessOrGreater",
|
||||
"Ordered",
|
||||
"Unordered",
|
||||
"ArrayLength",
|
||||
"IAdd",
|
||||
"FAdd",
|
||||
"ISub",
|
||||
"FSub",
|
||||
"IMul",
|
||||
"FMul",
|
||||
"UDiv",
|
||||
"SDiv",
|
||||
"FDiv",
|
||||
"UMod",
|
||||
"SRem",
|
||||
"SMod",
|
||||
"FRem",
|
||||
"FMod",
|
||||
"VectorTimesScalar",
|
||||
"MatrixTimesScalar",
|
||||
"VectorTimesMatrix",
|
||||
"MatrixTimesVector",
|
||||
"MatrixTimesMatrix",
|
||||
"OuterProduct",
|
||||
"Dot",
|
||||
"ShiftRightLogical",
|
||||
"ShiftRightArithmetic",
|
||||
"ShiftLeftLogical",
|
||||
"LogicalOr",
|
||||
"LogicalXor",
|
||||
"LogicalAnd",
|
||||
"BitwiseOr",
|
||||
"BitwiseXor",
|
||||
"BitwiseAnd",
|
||||
"Select",
|
||||
"IEqual",
|
||||
"FOrdEqual",
|
||||
"FUnordEqual",
|
||||
"INotEqual",
|
||||
"FOrdNotEqual",
|
||||
"FUnordNotEqual",
|
||||
"ULessThan",
|
||||
"SLessThan",
|
||||
"FOrdLessThan",
|
||||
"FUnordLessThan",
|
||||
"UGreaterThan",
|
||||
"SGreaterThan",
|
||||
"FOrdGreaterThan",
|
||||
"FUnordGreaterThan",
|
||||
"ULessThanEqual",
|
||||
"SLessThanEqual",
|
||||
"FOrdLessThanEqual",
|
||||
"FUnordLessThanEqual",
|
||||
"UGreaterThanEqual",
|
||||
"SGreaterThanEqual",
|
||||
"FOrdGreaterThanEqual",
|
||||
"FUnordGreaterThanEqual",
|
||||
"DPdx",
|
||||
"DPdy",
|
||||
"Fwidth",
|
||||
"DPdxFine",
|
||||
"DPdyFine",
|
||||
"FwidthFine",
|
||||
"DPdxCoarse",
|
||||
"DPdyCoarse",
|
||||
"FwidthCoarse",
|
||||
"EmitVertex",
|
||||
"EndPrimitive",
|
||||
"EmitStreamVertex",
|
||||
"EndStreamPrimitive",
|
||||
"ControlBarrier",
|
||||
"MemoryBarrier",
|
||||
"ImagePointer",
|
||||
"AtomicInit",
|
||||
"AtomicLoad",
|
||||
"AtomicStore",
|
||||
"AtomicExchange",
|
||||
"AtomicCompareExchange",
|
||||
"AtomicCompareExchangeWeak",
|
||||
"AtomicIIncrement",
|
||||
"AtomicIDecrement",
|
||||
"AtomicIAdd",
|
||||
"AtomicISub",
|
||||
"AtomicUMin",
|
||||
"AtomicUMax",
|
||||
"AtomicAnd",
|
||||
"AtomicOr",
|
||||
"AtomicXor",
|
||||
"LoopMerge",
|
||||
"SelectionMerge",
|
||||
"Label",
|
||||
"Branch",
|
||||
"BranchConditional",
|
||||
"Switch",
|
||||
"Kill",
|
||||
"Return",
|
||||
"ReturnValue",
|
||||
"Unreachable",
|
||||
"LifetimeStart",
|
||||
"LifetimeStop",
|
||||
"CompileFlag",
|
||||
"AsyncGroupCopy",
|
||||
"WaitGroupEvents",
|
||||
"GroupAll",
|
||||
"GroupAny",
|
||||
"GroupBroadcast",
|
||||
"GroupIAdd",
|
||||
"GroupFAdd",
|
||||
"GroupFMin",
|
||||
"GroupUMin",
|
||||
"GroupSMin",
|
||||
"GroupFMax",
|
||||
"GroupUMax",
|
||||
"GroupSMax",
|
||||
"GenericCastToPtrExplicit",
|
||||
"GenericPtrMemSemantics",
|
||||
"ReadPipe",
|
||||
"WritePipe",
|
||||
"ReservedReadPipe",
|
||||
"ReservedWritePipe",
|
||||
"ReserveReadPipePackets",
|
||||
"ReserveWritePipePackets",
|
||||
"CommitReadPipe",
|
||||
"CommitWritePipe",
|
||||
"IsValidReserveId",
|
||||
"GetNumPipePackets",
|
||||
"GetMaxPipePackets",
|
||||
"GroupReserveReadPipePackets",
|
||||
"GroupReserveWritePipePackets",
|
||||
"GroupCommitReadPipe",
|
||||
"GroupCommitWritePipe",
|
||||
"EnqueueMarker",
|
||||
"EnqueueKernel",
|
||||
"GetKernelNDrangeSubGroupCount",
|
||||
"GetKernelNDrangeMaxSubGroupSize",
|
||||
"GetKernelWorkGroupSize",
|
||||
"GetKernelPreferredWorkGroupSizeMultiple",
|
||||
"RetainEvent",
|
||||
"ReleaseEvent",
|
||||
"CreateUserEvent",
|
||||
"IsValidEvent",
|
||||
"SetUserEventStatus",
|
||||
"CaptureEventProfilingInfo",
|
||||
"GetDefaultQueue",
|
||||
"BuildNDRange",
|
||||
"SatConvertSToU",
|
||||
"SatConvertUToS",
|
||||
"AtomicIMin",
|
||||
"AtomicIMax",
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_spirvOpcode) == SpirvOpcode::Count);
|
||||
|
||||
const char* getName(SpirvOpcode::Enum _opcode)
|
||||
{
|
||||
BX_CHECK(_opcode < SpirvOpcode::Count, "Unknown opcode id %d.", _opcode);
|
||||
return s_spirvOpcode[_opcode];
|
||||
}
|
||||
|
||||
int32_t read(bx::ReaderI* _reader, SpirvOperand& _operand)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
BX_UNUSED(_operand);
|
||||
uint32_t token;
|
||||
size += bx::read(_reader, token);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t read(bx::ReaderI* _reader, SpirvInstruction& _instruction)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uint32_t token;
|
||||
size += bx::read(_reader, token);
|
||||
|
||||
_instruction.opcode = SpirvOpcode::Enum( (token & UINT32_C(0x0000ffff) ) );
|
||||
_instruction.length = uint16_t( (token & UINT32_C(0xffff0000) ) >> 16);
|
||||
|
||||
uint32_t currOp = 0;
|
||||
|
||||
const SpirvOpcodeInfo& info = s_sprivOpcodeInfo[_instruction.opcode];
|
||||
|
||||
if (0 < info.numValues)
|
||||
{
|
||||
size += read(_reader, _instruction.un.value, info.numValues*sizeof(uint32_t) );
|
||||
}
|
||||
|
||||
if (info.hasVariable)
|
||||
{
|
||||
while (size/4 != _instruction.length)
|
||||
{
|
||||
uint32_t tmp;
|
||||
size += bx::read(_reader, tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_instruction.numOperands = info.numOperands;
|
||||
switch (info.numOperands)
|
||||
{
|
||||
case 6: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 5: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 4: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 3: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 2: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 1: size += read(_reader, _instruction.operand[currOp++]);
|
||||
case 0:
|
||||
break;
|
||||
|
||||
default:
|
||||
BX_WARN(false, "Instruction %s with invalid number of operands %d (numValues %d)."
|
||||
, getName(_instruction.opcode)
|
||||
, info.numOperands
|
||||
, info.numValues
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
BX_WARN(size/4 == _instruction.length, "read %d, expected %d, %s"
|
||||
, size/4
|
||||
, _instruction.length
|
||||
, getName(_instruction.opcode)
|
||||
);
|
||||
while (size/4 != _instruction.length)
|
||||
{
|
||||
uint32_t tmp;
|
||||
size += bx::read(_reader, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t write(bx::WriterI* _writer, const SpirvInstruction& _instruction)
|
||||
{
|
||||
int32_t size = 0;
|
||||
BX_UNUSED(_writer, _instruction);
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t toString(char* _out, int32_t _size, const SpirvInstruction& _instruction)
|
||||
{
|
||||
int32_t size = 0;
|
||||
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
|
||||
, "%s %d (%d, %d)"
|
||||
, getName(_instruction.opcode)
|
||||
, _instruction.numOperands
|
||||
, _instruction.un.value[0]
|
||||
, _instruction.un.value[1]
|
||||
);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, SpirvShader& _shader)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uint32_t len = uint32_t(bx::getSize(_reader) - bx::seek(_reader) );
|
||||
_shader.byteCode.resize(len);
|
||||
size += bx::read(_reader, _shader.byteCode.data(), len);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t write(bx::WriterI* _writer, const SpirvShader& _shader)
|
||||
{
|
||||
int32_t size = 0;
|
||||
BX_UNUSED(_writer, _shader);
|
||||
return size;
|
||||
}
|
||||
|
||||
#define SPIRV_MAGIC 0x07230203
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, Spirv& _spirv)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
size += bx::read(_reader, _spirv.header);
|
||||
|
||||
if (size != sizeof(Spirv::Header)
|
||||
|| _spirv.header.magic != SPIRV_MAGIC
|
||||
)
|
||||
{
|
||||
// error
|
||||
return -size;
|
||||
}
|
||||
|
||||
size += read(_reader, _spirv.shader);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t write(bx::WriterSeekerI* _writer, const Spirv& _spirv)
|
||||
{
|
||||
int32_t size = 0;
|
||||
BX_UNUSED(_writer, _spirv);
|
||||
return size;
|
||||
}
|
||||
|
||||
void parse(const SpirvShader& _src, SpirvParseFn _fn, void* _userData)
|
||||
{
|
||||
bx::MemoryReader reader(_src.byteCode.data(), uint32_t(_src.byteCode.size() ) );
|
||||
|
||||
for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
|
||||
{
|
||||
SpirvInstruction instruction;
|
||||
uint32_t size = read(&reader, instruction);
|
||||
|
||||
BX_CHECK(size/4 == instruction.length, "read %d, expected %d, %s"
|
||||
, size/4
|
||||
, instruction.length
|
||||
, getName(instruction.opcode)
|
||||
);
|
||||
|
||||
_fn(token * sizeof(uint32_t), instruction, _userData);
|
||||
|
||||
token += instruction.length;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace bgfx
|
520
src/shader_spirv.h
Normal file
520
src/shader_spirv.h
Normal file
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
* Copyright 2011-2015 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef BGFX_SHADER_SPIRV_H
|
||||
#define BGFX_SHADER_SPIRV_H
|
||||
|
||||
#include <bx/readerwriter.h>
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
// Reference: https://www.khronos.org/registry/spir-v/specs/1.0/SPIRV.html
|
||||
|
||||
struct SpirvOpcode
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Nop,
|
||||
Source,
|
||||
SourceExtension,
|
||||
Extension,
|
||||
ExtInstImport,
|
||||
MemoryModel,
|
||||
EntryPoint,
|
||||
ExecutionMode,
|
||||
TypeVoid,
|
||||
TypeBool,
|
||||
TypeInt,
|
||||
TypeFloat,
|
||||
TypeVector,
|
||||
TypeMatrix,
|
||||
TypeSampler,
|
||||
TypeFilter,
|
||||
TypeArray,
|
||||
TypeRuntimeArray,
|
||||
TypeStruct,
|
||||
TypeOpaque,
|
||||
TypePointer,
|
||||
TypeFunction,
|
||||
TypeEvent,
|
||||
TypeDeviceEvent,
|
||||
TypeReserveId,
|
||||
TypeQueue,
|
||||
TypePipe,
|
||||
ConstantTrue,
|
||||
ConstantFalse,
|
||||
Constant,
|
||||
ConstantComposite,
|
||||
ConstantSampler,
|
||||
ConstantNullPointer,
|
||||
ConstantNullObject,
|
||||
SpecConstantTrue,
|
||||
SpecConstantFalse,
|
||||
SpecConstant,
|
||||
SpecConstantComposite,
|
||||
Variable,
|
||||
VariableArray,
|
||||
Function,
|
||||
FunctionParameter,
|
||||
FunctionEnd,
|
||||
FunctionCall,
|
||||
ExtInst,
|
||||
Undef,
|
||||
Load,
|
||||
Store,
|
||||
Phi,
|
||||
DecorationGroup,
|
||||
Decorate,
|
||||
MemberDecorate,
|
||||
GroupDecorate,
|
||||
GroupMemberDecorate,
|
||||
Name,
|
||||
MemberName,
|
||||
String,
|
||||
Line,
|
||||
VectorExtractDynamic,
|
||||
VectorInsertDynamic,
|
||||
VectorShuffle,
|
||||
CompositeConstruct,
|
||||
CompositeExtract,
|
||||
CompositeInsert,
|
||||
CopyObject,
|
||||
CopyMemory,
|
||||
CopyMemorySized,
|
||||
Sampler,
|
||||
TextureSample,
|
||||
TextureSampleDref,
|
||||
TextureSampleLod,
|
||||
TextureSampleProj,
|
||||
TextureSampleGrad,
|
||||
TextureSampleOffset,
|
||||
TextureSampleProjLod,
|
||||
TextureSampleProjGrad,
|
||||
TextureSampleLodOffset,
|
||||
TextureSampleProjOffset,
|
||||
TextureSampleGradOffset,
|
||||
TextureSampleProjLodOffset,
|
||||
TextureSampleProjGradOffset,
|
||||
TextureFetchTexelLod,
|
||||
TextureFetchTexelOffset,
|
||||
TextureFetchSample,
|
||||
TextureFetchTexel,
|
||||
TextureGather,
|
||||
TextureGatherOffset,
|
||||
TextureGatherOffsets,
|
||||
TextureQuerySizeLod,
|
||||
TextureQuerySize,
|
||||
TextureQueryLod,
|
||||
TextureQueryLevels,
|
||||
TextureQuerySamples,
|
||||
AccessChain,
|
||||
InBoundsAccessChain,
|
||||
SNegate,
|
||||
FNegate,
|
||||
Not,
|
||||
Any,
|
||||
All,
|
||||
ConvertFToU,
|
||||
ConvertFToS,
|
||||
ConvertSToF,
|
||||
ConvertUToF,
|
||||
UConvert,
|
||||
SConvert,
|
||||
FConvert,
|
||||
ConvertPtrToU,
|
||||
ConvertUToPtr,
|
||||
PtrCastToGeneric,
|
||||
GenericCastToPtr,
|
||||
Bitcast,
|
||||
Transpose,
|
||||
IsNan,
|
||||
IsInf,
|
||||
IsFinite,
|
||||
IsNormal,
|
||||
SignBitSet,
|
||||
LessOrGreater,
|
||||
Ordered,
|
||||
Unordered,
|
||||
ArrayLength,
|
||||
IAdd,
|
||||
FAdd,
|
||||
ISub,
|
||||
FSub,
|
||||
IMul,
|
||||
FMul,
|
||||
UDiv,
|
||||
SDiv,
|
||||
FDiv,
|
||||
UMod,
|
||||
SRem,
|
||||
SMod,
|
||||
FRem,
|
||||
FMod,
|
||||
VectorTimesScalar,
|
||||
MatrixTimesScalar,
|
||||
VectorTimesMatrix,
|
||||
MatrixTimesVector,
|
||||
MatrixTimesMatrix,
|
||||
OuterProduct,
|
||||
Dot,
|
||||
ShiftRightLogical,
|
||||
ShiftRightArithmetic,
|
||||
ShiftLeftLogical,
|
||||
LogicalOr,
|
||||
LogicalXor,
|
||||
LogicalAnd,
|
||||
BitwiseOr,
|
||||
BitwiseXor,
|
||||
BitwiseAnd,
|
||||
Select,
|
||||
IEqual,
|
||||
FOrdEqual,
|
||||
FUnordEqual,
|
||||
INotEqual,
|
||||
FOrdNotEqual,
|
||||
FUnordNotEqual,
|
||||
ULessThan,
|
||||
SLessThan,
|
||||
FOrdLessThan,
|
||||
FUnordLessThan,
|
||||
UGreaterThan,
|
||||
SGreaterThan,
|
||||
FOrdGreaterThan,
|
||||
FUnordGreaterThan,
|
||||
ULessThanEqual,
|
||||
SLessThanEqual,
|
||||
FOrdLessThanEqual,
|
||||
FUnordLessThanEqual,
|
||||
UGreaterThanEqual,
|
||||
SGreaterThanEqual,
|
||||
FOrdGreaterThanEqual,
|
||||
FUnordGreaterThanEqual,
|
||||
DPdx,
|
||||
DPdy,
|
||||
Fwidth,
|
||||
DPdxFine,
|
||||
DPdyFine,
|
||||
FwidthFine,
|
||||
DPdxCoarse,
|
||||
DPdyCoarse,
|
||||
FwidthCoarse,
|
||||
EmitVertex,
|
||||
EndPrimitive,
|
||||
EmitStreamVertex,
|
||||
EndStreamPrimitive,
|
||||
ControlBarrier,
|
||||
MemoryBarrier,
|
||||
ImagePointer,
|
||||
AtomicInit,
|
||||
AtomicLoad,
|
||||
AtomicStore,
|
||||
AtomicExchange,
|
||||
AtomicCompareExchange,
|
||||
AtomicCompareExchangeWeak,
|
||||
AtomicIIncrement,
|
||||
AtomicIDecrement,
|
||||
AtomicIAdd,
|
||||
AtomicISub,
|
||||
AtomicUMin,
|
||||
AtomicUMax,
|
||||
AtomicAnd,
|
||||
AtomicOr,
|
||||
AtomicXor,
|
||||
LoopMerge,
|
||||
SelectionMerge,
|
||||
Label,
|
||||
Branch,
|
||||
BranchConditional,
|
||||
Switch,
|
||||
Kill,
|
||||
Return,
|
||||
ReturnValue,
|
||||
Unreachable,
|
||||
LifetimeStart,
|
||||
LifetimeStop,
|
||||
CompileFlag,
|
||||
AsyncGroupCopy,
|
||||
WaitGroupEvents,
|
||||
GroupAll,
|
||||
GroupAny,
|
||||
GroupBroadcast,
|
||||
GroupIAdd,
|
||||
GroupFAdd,
|
||||
GroupFMin,
|
||||
GroupUMin,
|
||||
GroupSMin,
|
||||
GroupFMax,
|
||||
GroupUMax,
|
||||
GroupSMax,
|
||||
GenericCastToPtrExplicit,
|
||||
GenericPtrMemSemantics,
|
||||
ReadPipe,
|
||||
WritePipe,
|
||||
ReservedReadPipe,
|
||||
ReservedWritePipe,
|
||||
ReserveReadPipePackets,
|
||||
ReserveWritePipePackets,
|
||||
CommitReadPipe,
|
||||
CommitWritePipe,
|
||||
IsValidReserveId,
|
||||
GetNumPipePackets,
|
||||
GetMaxPipePackets,
|
||||
GroupReserveReadPipePackets,
|
||||
GroupReserveWritePipePackets,
|
||||
GroupCommitReadPipe,
|
||||
GroupCommitWritePipe,
|
||||
EnqueueMarker,
|
||||
EnqueueKernel,
|
||||
GetKernelNDrangeSubGroupCount,
|
||||
GetKernelNDrangeMaxSubGroupSize,
|
||||
GetKernelWorkGroupSize,
|
||||
GetKernelPreferredWorkGroupSizeMultiple,
|
||||
RetainEvent,
|
||||
ReleaseEvent,
|
||||
CreateUserEvent,
|
||||
IsValidEvent,
|
||||
SetUserEventStatus,
|
||||
CaptureEventProfilingInfo,
|
||||
GetDefaultQueue,
|
||||
BuildNDRange,
|
||||
SatConvertSToU,
|
||||
SatConvertUToS,
|
||||
AtomicIMin,
|
||||
AtomicIMax,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct SpirvBuiltin
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Position,
|
||||
PointSize,
|
||||
ClipVertex,
|
||||
ClipDistance,
|
||||
CullDistance,
|
||||
VertexId,
|
||||
InstanceId,
|
||||
BuiltInPrimitiveId,
|
||||
InvocationId,
|
||||
Layer,
|
||||
ViewportIndex,
|
||||
TessLevelOuter,
|
||||
TessLevelInner,
|
||||
TessCoord,
|
||||
PatchVertices,
|
||||
FragCoord,
|
||||
PointCoord,
|
||||
FrontFacing,
|
||||
SampleId,
|
||||
SamplePosition,
|
||||
SampleMask,
|
||||
FragColor,
|
||||
FragDepth,
|
||||
HelperInvocation,
|
||||
NumWorkgroups,
|
||||
WorkgroupSize,
|
||||
WorkgroupId,
|
||||
LocalInvocationId,
|
||||
GlobalInvocationId,
|
||||
LocalInvocationIndex,
|
||||
WorkDim,
|
||||
GlobalSize,
|
||||
EnqueuedWorkgroupSize,
|
||||
GlobalOffset,
|
||||
GlobalLinearId,
|
||||
WorkgroupLinearId,
|
||||
SubgroupSize,
|
||||
SubgroupMaxSize,
|
||||
NumSubgroups,
|
||||
NumEnqueuedSubgroups,
|
||||
SubgroupId,
|
||||
SubgroupLocalInvocationId,
|
||||
};
|
||||
};
|
||||
|
||||
struct SpirvExecutionModel
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Vertex,
|
||||
TessellationControl,
|
||||
TessellationEvaluation,
|
||||
Geometry,
|
||||
Fragment,
|
||||
GLCompute,
|
||||
Kernel,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct SpirvMemoryModel
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Simple,
|
||||
GLSL450,
|
||||
OpenCL12,
|
||||
OpenCL20,
|
||||
OpenCL21,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct SpirvStorageClass
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
UniformConstant,
|
||||
Input,
|
||||
Uniform,
|
||||
Output,
|
||||
WorkgroupLocal,
|
||||
WorkgroupGlobal,
|
||||
PrivateGlobal,
|
||||
Function,
|
||||
Generic,
|
||||
Private,
|
||||
AtomicCounter,
|
||||
};
|
||||
};
|
||||
|
||||
struct SpirvResourceDim
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Texture1D,
|
||||
Texture2D,
|
||||
Texture3D,
|
||||
TextureCube,
|
||||
TextureRect,
|
||||
Buffer,
|
||||
};
|
||||
};
|
||||
|
||||
struct SpirvDecoration
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
PrecisionLow,
|
||||
PrecisionMedium,
|
||||
PrecisionHigh,
|
||||
Block,
|
||||
BufferBlock,
|
||||
RowMajor,
|
||||
ColMajor,
|
||||
GLSLShared,
|
||||
GLSLStd140,
|
||||
GLSLStd430,
|
||||
GLSLPacked,
|
||||
Smooth,
|
||||
Noperspective,
|
||||
Flat,
|
||||
Patch,
|
||||
Centroid,
|
||||
Sample,
|
||||
Invariant,
|
||||
Restrict,
|
||||
Aliased,
|
||||
Volatile,
|
||||
Constant,
|
||||
Coherent,
|
||||
Nonwritable,
|
||||
Nonreadable,
|
||||
Uniform,
|
||||
NoStaticUse,
|
||||
CPacked,
|
||||
SaturatedConversion,
|
||||
Stream,
|
||||
Location,
|
||||
Component,
|
||||
Index,
|
||||
Binding,
|
||||
DescriptorSet,
|
||||
Offset,
|
||||
Alignment,
|
||||
XfbBuffer,
|
||||
Stride,
|
||||
BuiltIn,
|
||||
FuncParamAttr,
|
||||
FPRoundingMode,
|
||||
FPFastMathMode,
|
||||
LinkageAttributes,
|
||||
SpecId,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
struct SpirvOperand
|
||||
{
|
||||
};
|
||||
|
||||
struct SpirvInstruction
|
||||
{
|
||||
SpirvOpcode::Enum opcode;
|
||||
uint16_t length;
|
||||
|
||||
uint8_t numOperands;
|
||||
SpirvOperand operand[6];
|
||||
|
||||
union
|
||||
{
|
||||
struct ResultTypeId
|
||||
{
|
||||
uint32_t resultType;
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
ResultTypeId constant;
|
||||
ResultTypeId constantComposite;
|
||||
|
||||
uint32_t value[8];
|
||||
} un;
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderI* _reader, SpirvInstruction& _instruction);
|
||||
int32_t write(bx::WriterI* _writer, const SpirvInstruction& _instruction);
|
||||
int32_t toString(char* _out, int32_t _size, const SpirvInstruction& _instruction);
|
||||
|
||||
struct SpirvShader
|
||||
{
|
||||
stl::vector<uint8_t> byteCode;
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, SpirvShader& _shader);
|
||||
int32_t write(bx::WriterI* _writer, const SpirvShader& _shader);
|
||||
|
||||
typedef void (*SpirvParseFn)(uint32_t _offset, const SpirvInstruction& _instruction, void* _userData);
|
||||
void parse(const SpirvShader& _src, SpirvParseFn _fn, void* _userData);
|
||||
|
||||
typedef void (*SpirvFilterFn)(SpirvInstruction& _instruction, void* _userData);
|
||||
void filter(SpirvShader& _dst, const SpirvShader& _src, SpirvFilterFn _fn, void* _userData);
|
||||
|
||||
struct Spirv
|
||||
{
|
||||
struct Header
|
||||
{
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint32_t generator;
|
||||
uint32_t bound;
|
||||
uint32_t schema;
|
||||
};
|
||||
|
||||
Header header;
|
||||
SpirvShader shader;
|
||||
};
|
||||
|
||||
int32_t read(bx::ReaderSeekerI* _reader, Spirv& _spirv);
|
||||
int32_t write(bx::WriterSeekerI* _writer, const Spirv& _spirv);
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
#endif // BGFX_SHADER_SPIRV_H
|
Loading…
Reference in a new issue