2012-09-30 05:52:03 +00:00
|
|
|
#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;
|
|
|
|
|
2012-11-27 03:23:19 +00:00
|
|
|
prog->permu[permu].handle.hlsl.vert = NULL;
|
|
|
|
prog->permu[permu].handle.hlsl.frag = NULL;
|
|
|
|
prog->permu[permu].handle.hlsl.layout = NULL;
|
2012-09-30 05:52:03 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2012-11-27 03:23:19 +00:00
|
|
|
if (FAILED(ID3D11Device_CreateVertexShader(pD3DDev11, vcode->lpVtbl->GetBufferPointer(vcode), vcode->lpVtbl->GetBufferSize(vcode), NULL, (ID3D11VertexShader**)&prog->permu[permu].handle.hlsl.vert)))
|
2012-09-30 05:52:03 +00:00
|
|
|
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
|
|
|
|
{
|
2012-11-27 03:23:19 +00:00
|
|
|
if (FAILED(ID3D11Device_CreatePixelShader(pD3DDev11, fcode->lpVtbl->GetBufferPointer(fcode), fcode->lpVtbl->GetBufferSize(fcode), NULL, (ID3D11PixelShader**)&prog->permu[permu].handle.hlsl.frag)))
|
2012-09-30 05:52:03 +00:00
|
|
|
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++;
|
|
|
|
*/
|
2012-11-27 03:23:19 +00:00
|
|
|
if (FAILED(ID3D11Device_CreateInputLayout(pD3DDev11, decl, elements, vcode->lpVtbl->GetBufferPointer(vcode), vcode->lpVtbl->GetBufferSize(vcode), (ID3D11InputLayout**)&prog->permu[permu].handle.hlsl.layout)))
|
2012-09-30 05:52:03 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2012-10-13 00:56:31 +00:00
|
|
|
#endif
|
|
|
|
|