fteqw/engine/d3d/d3d11_shader.c

343 lines
9.5 KiB
C

#include "quakedef.h"
#ifdef D3D11QUAKE
#include "shader.h"
#include "winquake.h"
#define COBJMACROS
#include <d3d11.h>
extern ID3D11Device *pD3DDev11;
typedef struct _D3D_SHADER_MACRO
{
LPCSTR Name;
LPCSTR Definition;
} D3D_SHADER_MACRO, *LPD3D_SHADER_MACRO;
typedef enum _D3D_INCLUDE_TYPE {
D3D_INCLUDE_LOCAL = 0,
D3D_INCLUDE_SYSTEM = ( D3D_INCLUDE_LOCAL + 1 ),
D3D_INCLUDE_FORCE_DWORD = 0x7fffffff
} D3D_INCLUDE_TYPE;
#undef INTERFACE
#define INTERFACE ID3DInclude
DECLARE_INTERFACE_(INTERFACE, IUnknown)
{
STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE;
STDMETHOD(Close)(THIS_ LPCVOID pData) PURE;
};
#undef INTERFACE
#define INTERFACE ID3DBlob
DECLARE_INTERFACE_(INTERFACE, IUnknown)
{
STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE;
STDMETHOD_(SIZE_T, GetBufferSize)(THIS) PURE;
};
HRESULT (WINAPI *pD3DCompile) (
LPCVOID pSrcData,
SIZE_T SrcDataSize,
LPCSTR pSourceName,
const D3D_SHADER_MACRO *pDefines,
ID3DInclude *pInclude,
LPCSTR pEntrypoint,
LPCSTR pTarget,
UINT Flags1,
UINT Flags2,
ID3DBlob **ppCode,
ID3DBlob **ppErrorMsgs
);
dllhandle_t *shaderlib;
void D3D11Shader_Init(void)
{
dllfunction_t funcs[] =
{
{(void**)&pD3DCompile, "D3DCompileFromMemory"},
{NULL,NULL}
};
if (!shaderlib)
shaderlib = Sys_LoadLibrary("D3dcompiler_34.dll", funcs);
if (!shaderlib)
return;
}
HRESULT STDMETHODCALLTYPE d3dinclude_Close(ID3DInclude *this, LPCVOID pData)
{
free((void*)pData);
return S_OK;
}
HRESULT STDMETHODCALLTYPE d3dinclude_Open(ID3DInclude *this, D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes)
{
if (IncludeType == D3D_INCLUDE_SYSTEM)
{
if (!strcmp(pFileName, "ftedefs.h"))
{
static const char *defstruct =
"cbuffer ftemodeldefs : register(b0)\n"
"{\n"
"matrix m_model;\n"
"float3 e_eyepos; float e_time;\n"
"float3 e_light_ambient; float pad1;\n"
"float3 e_light_dir; float pad2;\n"
"float3 e_light_mul; float pad3;\n"
"};\n"
"cbuffer fteviewdefs : register(b1)\n"
"{\n"
"matrix m_view;\n"
"matrix m_projection;\n"
"float3 v_eyepos; float v_time;\n"
"};\n"
;
*ppData = strdup(defstruct);
*pBytes = strlen(*ppData);
return S_OK;
}
}
else
{
}
return E_FAIL;
}
ID3DIncludeVtbl myd3dincludetab =
{
d3dinclude_Open,
d3dinclude_Close
};
ID3DInclude myd3dinclude =
{
&myd3dincludetab
};
typedef struct
{
vecV_t coord;
vec2_t tex;
vec2_t lm;
vec3_t ndir;
vec3_t sdir;
vec3_t tdir;
byte_vec4_t colorsb;
} vbovdata_t;
qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, int permu, char **precompilerconstants, char *vert, char *frag)
{
D3D_SHADER_MACRO defines[64];
ID3DBlob *vcode = NULL, *fcode = NULL, *errors = NULL;
qboolean success = false;
prog->permu[permu].handle.hlsl.vert = NULL;
prog->permu[permu].handle.hlsl.frag = NULL;
prog->permu[permu].handle.hlsl.layout = NULL;
if (pD3DCompile)
{
int consts;
for (consts = 2; precompilerconstants[consts]; consts++)
;
if (consts >= sizeof(defines) / sizeof(defines[0]))
return success;
consts = 0;
defines[consts].Name = NULL; /*shader type*/
defines[consts].Definition = "1";
consts++;
defines[consts].Name = "ENGINE_"DISTRIBUTION;
defines[consts].Definition = __DATE__;
consts++;
for (; *precompilerconstants; precompilerconstants++)
{
defines[consts].Name = NULL;
defines[consts].Definition = NULL;
consts++;
}
defines[consts].Name = NULL;
defines[consts].Definition = NULL;
success = true;
defines[0].Name = "VERTEX_SHADER";
if (FAILED(pD3DCompile(vert, strlen(vert), name, defines, &myd3dinclude, "main", "vs_4_0", 0, 0, &vcode, &errors)))
success = false;
else
{
if (FAILED(ID3D11Device_CreateVertexShader(pD3DDev11, vcode->lpVtbl->GetBufferPointer(vcode), vcode->lpVtbl->GetBufferSize(vcode), NULL, (ID3D11VertexShader**)&prog->permu[permu].handle.hlsl.vert)))
success = false;
}
if (errors)
{
char *messages = errors->lpVtbl->GetBufferPointer(errors);
Con_Printf("%s", messages);
errors->lpVtbl->Release(errors);
}
defines[0].Name = "FRAGMENT_SHADER";
if (FAILED(pD3DCompile(frag, strlen(frag), name, defines, &myd3dinclude, "main", "ps_4_0", 0, 0, &fcode, &errors)))
success = false;
else
{
if (FAILED(ID3D11Device_CreatePixelShader(pD3DDev11, fcode->lpVtbl->GetBufferPointer(fcode), fcode->lpVtbl->GetBufferSize(fcode), NULL, (ID3D11PixelShader**)&prog->permu[permu].handle.hlsl.frag)))
success = false;
}
if (errors)
{
char *messages = errors->lpVtbl->GetBufferPointer(errors);
Con_Printf("%s", messages);
errors->lpVtbl->Release(errors);
}
if (success)
{
D3D11_INPUT_ELEMENT_DESC decl[13];
int elements = 0;
vbovdata_t *foo = NULL;
decl[elements].SemanticName = "POSITION";
decl[elements].SemanticIndex = 0;
decl[elements].Format = DXGI_FORMAT_R32G32B32_FLOAT;
decl[elements].InputSlot = 0;
decl[elements].AlignedByteOffset = (char*)&foo->coord[0] - (char*)NULL;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
decl[elements].SemanticName = "TEXCOORD";
decl[elements].SemanticIndex = 0;
decl[elements].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
decl[elements].InputSlot = 0;
decl[elements].AlignedByteOffset = (char*)&foo->tex[0] - (char*)NULL;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
/*
decl[elements].SemanticName = "TEXCOORD";
decl[elements].SemanticIndex = 1;
decl[elements].Format = DXGI_FORMAT_R32G32_FLOAT;
decl[elements].InputSlot = 1;
decl[elements].AlignedByteOffset = (char*)&foo->lm[0] - (char*)NULL;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
*/
decl[elements].SemanticName = "COLOR";
decl[elements].SemanticIndex = 0;
decl[elements].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
decl[elements].InputSlot = 0;
decl[elements].AlignedByteOffset = (char*)&foo->colorsb[0] - (char*)NULL;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
decl[elements].SemanticName = "NORMAL";
decl[elements].SemanticIndex = 0;
decl[elements].Format = DXGI_FORMAT_R32G32B32_FLOAT;
decl[elements].InputSlot = 0;
decl[elements].AlignedByteOffset = (char*)&foo->ndir[0] - (char*)NULL;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
decl[elements].SemanticName = "TANGENT";
decl[elements].SemanticIndex = 0;
decl[elements].Format = DXGI_FORMAT_R32G32B32_FLOAT;
decl[elements].InputSlot = 0;
decl[elements].AlignedByteOffset = (char*)&foo->sdir[0] - (char*)NULL;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
decl[elements].SemanticName = "BINORMAL";
decl[elements].SemanticIndex = 0;
decl[elements].Format = DXGI_FORMAT_R32G32B32_FLOAT;
decl[elements].InputSlot = 0;
decl[elements].AlignedByteOffset = (char*)&foo->tdir[0] - (char*)NULL;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
/*
decl[elements].SemanticName = "BLENDWEIGHT";
decl[elements].SemanticIndex = 0;
decl[elements].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
decl[elements].InputSlot = 0;
decl[elements].AlignedByteOffset = 0;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
decl[elements].SemanticName = "BLENDINDICIES";
decl[elements].SemanticIndex = 0;
decl[elements].Format = DXGI_FORMAT_R8G8B8A8_UINT;
decl[elements].InputSlot = 0;
decl[elements].AlignedByteOffset = 0;
decl[elements].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
decl[elements].InstanceDataStepRate = 0;
elements++;
*/
if (FAILED(ID3D11Device_CreateInputLayout(pD3DDev11, decl, elements, vcode->lpVtbl->GetBufferPointer(vcode), vcode->lpVtbl->GetBufferSize(vcode), (ID3D11InputLayout**)&prog->permu[permu].handle.hlsl.layout)))
{
Con_Printf("HLSL Shader %s requires unsupported inputs\n", name);
success = false;
}
}
if (vcode)
vcode->lpVtbl->Release(vcode);
if (fcode)
fcode->lpVtbl->Release(fcode);
}
return success;
}
/*
static int D3D11Shader_FindUniform_(LPD3DXCONSTANTTABLE ct, char *name)
{
if (ct)
{
UINT dc = 1;
D3DXCONSTANT_DESC d;
if (!FAILED(ct->lpVtbl->GetConstantDesc(ct, name, &d, &dc)))
return d.RegisterIndex;
}
return -1;
}
*/
int D3D11Shader_FindUniform(union programhandle_u *h, int type, char *name)
{
#if 0
int offs;
if (!type || type == 1)
{
offs = D3D11Shader_FindUniform_(h->hlsl.ctabv, name);
if (offs >= 0)
return offs;
}
if (!type || type == 2)
{
offs = D3D11Shader_FindUniform_(h->hlsl.ctabf, name);
if (offs >= 0)
return offs;
}
#endif
return -1;
}
#endif