#include "quakedef.h" #ifdef D3D11QUAKE #include "shader.h" #include "winquake.h" #define COBJMACROS #include 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->handle[permu].hlsl.vert = NULL; prog->handle[permu].hlsl.frag = NULL; prog->handle[permu].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->handle[permu].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->handle[permu].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->handle[permu].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