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;
|
|
|
|
|
2015-03-03 00:14:43 +00:00
|
|
|
//#include <D3D11Shader.h> //apparently requires win8 sdk, despite being a win7 thing.
|
|
|
|
|
2012-09-30 05:52:03 +00:00
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
#ifndef IID_ID3DBlob
|
|
|
|
//microsoft can be such a pain sometimes.
|
|
|
|
typedef struct _D3D_SHADER_MACRO
|
|
|
|
{
|
|
|
|
LPCSTR Name;
|
|
|
|
LPCSTR Definition;
|
2012-09-30 05:52:03 +00:00
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
} D3D_SHADER_MACRO, *LPD3D_SHADER_MACRO;
|
2012-09-30 05:52:03 +00:00
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
typedef enum _D3D_INCLUDE_TYPE {
|
|
|
|
D3D_INCLUDE_LOCAL = 0,
|
|
|
|
D3D_INCLUDE_SYSTEM = ( D3D_INCLUDE_LOCAL + 1 ),
|
|
|
|
D3D_INCLUDE_FORCE_DWORD = 0x7fffffff
|
|
|
|
} D3D_INCLUDE_TYPE;
|
2012-09-30 05:52:03 +00:00
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
#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;
|
|
|
|
};
|
2012-09-30 05:52:03 +00:00
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
#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;
|
|
|
|
};
|
|
|
|
#undef INTERFACE
|
|
|
|
#endif
|
2013-11-21 23:02:28 +00:00
|
|
|
#define ID3DBlob_GetBufferPointer(b) b->lpVtbl->GetBufferPointer(b)
|
|
|
|
#define ID3DBlob_Release(b) b->lpVtbl->Release(b)
|
|
|
|
#define ID3DBlob_GetBufferSize(b) b->lpVtbl->GetBufferSize(b)
|
2012-09-30 05:52:03 +00:00
|
|
|
|
2015-03-03 00:14:43 +00:00
|
|
|
#define D3D11_SHADER_VARIABLE_DESC void
|
|
|
|
typedef unsigned int D3D_SHADER_INPUT_TYPE;
|
|
|
|
typedef unsigned int D3D_RESOURCE_RETURN_TYPE;
|
|
|
|
typedef unsigned int D3D_SRV_DIMENSION;
|
|
|
|
typedef struct D3D11_SHADER_INPUT_BIND_DESC {
|
|
|
|
LPCSTR Name;
|
|
|
|
D3D_SHADER_INPUT_TYPE Type;
|
|
|
|
UINT BindPoint;
|
|
|
|
UINT BindCount;
|
|
|
|
UINT uFlags;
|
|
|
|
D3D_RESOURCE_RETURN_TYPE ReturnType;
|
|
|
|
D3D_SRV_DIMENSION Dimension;
|
|
|
|
UINT NumSamples;
|
|
|
|
} D3D11_SHADER_INPUT_BIND_DESC;
|
|
|
|
#define ID3D11ShaderReflectionConstantBuffer void
|
|
|
|
#define ID3D11ShaderReflectionType void
|
|
|
|
#define INTERFACE ID3D11ShaderReflectionVariable
|
|
|
|
DECLARE_INTERFACE(ID3D11ShaderReflectionVariable)
|
|
|
|
{
|
|
|
|
STDMETHOD(GetDesc)(THIS_ D3D11_SHADER_VARIABLE_DESC *pDesc) PURE;
|
|
|
|
|
|
|
|
STDMETHOD_(ID3D11ShaderReflectionType*, GetType)(THIS) PURE;
|
|
|
|
STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetBuffer)(THIS) PURE;
|
|
|
|
|
|
|
|
STDMETHOD_(UINT, GetInterfaceSlot)(THIS_ UINT uArrayIndex) PURE;
|
|
|
|
};
|
|
|
|
#undef INTERFACE
|
|
|
|
#define D3D11_SHADER_DESC void
|
|
|
|
#define D3D11_SIGNATURE_PARAMETER_DESC void
|
|
|
|
const GUID IID_ID3D11ShaderReflection = {0x8d536ca1, 0x0cca, 0x4956, 0xa8, 0x37, 0x78, 0x69, 0x63, 0x75, 0x55, 0x84};
|
|
|
|
#define INTERFACE ID3D11ShaderReflection
|
|
|
|
DECLARE_INTERFACE_(INTERFACE, IUnknown)
|
|
|
|
{
|
|
|
|
STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE;
|
|
|
|
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
|
|
|
|
STDMETHOD_(ULONG, Release)(THIS) PURE;
|
|
|
|
|
|
|
|
STDMETHOD(GetDesc)(THIS_ D3D11_SHADER_DESC *pDesc) PURE;
|
|
|
|
|
|
|
|
STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetConstantBufferByIndex)(THIS_ UINT Index) PURE;
|
|
|
|
STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetConstantBufferByName)(THIS_ LPCSTR Name) PURE;
|
|
|
|
|
|
|
|
STDMETHOD(GetResourceBindingDesc)(THIS_ UINT ResourceIndex,
|
|
|
|
D3D11_SHADER_INPUT_BIND_DESC *pDesc) PURE;
|
|
|
|
|
|
|
|
STDMETHOD(GetInputParameterDesc)(THIS_ UINT ParameterIndex,
|
|
|
|
D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
|
|
|
|
STDMETHOD(GetOutputParameterDesc)(THIS_ UINT ParameterIndex,
|
|
|
|
D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
|
|
|
|
STDMETHOD(GetPatchConstantParameterDesc)(THIS_ UINT ParameterIndex,
|
|
|
|
D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
|
|
|
|
|
|
|
|
STDMETHOD_(ID3D11ShaderReflectionVariable*, GetVariableByName)(THIS_ LPCSTR Name) PURE;
|
|
|
|
STDMETHOD(GetResourceBindingDescByName)(THIS_ LPCSTR Name, D3D11_SHADER_INPUT_BIND_DESC *pDesc) PURE;
|
|
|
|
//more stuff
|
|
|
|
};
|
|
|
|
#define ID3D11ShaderReflection_GetVariableByName(r,v) r->lpVtbl->GetVariableByName(r,v)
|
|
|
|
#define ID3D11ShaderReflection_Release IUnknown_Release
|
|
|
|
#undef INTERFACE
|
|
|
|
|
|
|
|
|
2012-09-30 05:52:03 +00:00
|
|
|
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
|
|
|
|
);
|
2015-03-03 00:14:43 +00:00
|
|
|
|
|
|
|
HRESULT (WINAPI *pD3DReflect)(
|
|
|
|
LPCVOID pSrcData,
|
|
|
|
SIZE_T SrcDataSize,
|
|
|
|
REFIID pInterface,
|
|
|
|
void **ppReflector
|
|
|
|
);
|
|
|
|
|
2012-12-04 19:37:57 +00:00
|
|
|
static dllhandle_t *shaderlib;
|
2012-09-30 05:52:03 +00:00
|
|
|
|
|
|
|
|
2013-11-21 23:02:28 +00:00
|
|
|
D3D_FEATURE_LEVEL d3dfeaturelevel;
|
2012-09-30 05:52:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
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"
|
2013-11-21 23:02:28 +00:00
|
|
|
"float4 e_lmscale[4];\n"
|
2012-09-30 05:52:03 +00:00
|
|
|
"};\n"
|
|
|
|
"cbuffer fteviewdefs : register(b1)\n"
|
|
|
|
"{\n"
|
|
|
|
"matrix m_view;\n"
|
|
|
|
"matrix m_projection;\n"
|
|
|
|
"float3 v_eyepos; float v_time;\n"
|
|
|
|
"};\n"
|
2013-11-21 23:02:28 +00:00
|
|
|
"cbuffer ftelightdefs : register(b2)\n"
|
|
|
|
"{\n"
|
|
|
|
"matrix l_cubematrix;\n"
|
|
|
|
"float3 l_lightposition; float padl1;\n"
|
|
|
|
"float3 l_colour; float padl2;\n"
|
|
|
|
"float3 l_lightcolourscale;float l_lightradius;\n"
|
|
|
|
"float4 l_shadowmapproj;\n"
|
|
|
|
"float2 l_shadowmapscale; float2 padl3;\n"
|
|
|
|
"};\n"
|
|
|
|
;
|
|
|
|
*ppData = strdup(defstruct);
|
|
|
|
*pBytes = strlen(*ppData);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
if (!strcmp(pFileName, "sys/skeletal.h"))
|
|
|
|
{
|
|
|
|
static const char *defstruct =
|
|
|
|
""
|
2012-09-30 05:52:03 +00:00
|
|
|
;
|
|
|
|
*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;
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
void D3D11Shader_DeleteProg(program_t *prog, unsigned int permu)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
|
|
|
ID3D11InputLayout *layout;
|
|
|
|
ID3D11PixelShader *frag;
|
|
|
|
ID3D11VertexShader *vert;
|
2014-03-30 08:55:06 +00:00
|
|
|
vert = prog->permu[permu].handle.hlsl.vert;
|
|
|
|
frag = prog->permu[permu].handle.hlsl.frag;
|
|
|
|
layout = prog->permu[permu].handle.hlsl.layout;
|
|
|
|
if (vert)
|
|
|
|
ID3D11VertexShader_Release(vert);
|
|
|
|
if (frag)
|
|
|
|
ID3D11PixelShader_Release(frag);
|
|
|
|
if (layout)
|
|
|
|
ID3D11InputLayout_Release(layout);
|
|
|
|
}
|
|
|
|
|
|
|
|
//create a program from two blobs.
|
|
|
|
static qboolean D3D11Shader_CreateShaders(program_t *prog, const char *name, int permu,
|
|
|
|
void *vblob, size_t vsize,
|
|
|
|
void *hblob, size_t hsize,
|
|
|
|
void *dblob, size_t dsize,
|
2015-07-01 23:15:25 +00:00
|
|
|
void *gblob, size_t gsize,
|
2014-03-30 08:55:06 +00:00
|
|
|
void *fblob, size_t fsize)
|
|
|
|
{
|
|
|
|
qboolean success = true;
|
|
|
|
|
|
|
|
if (FAILED(ID3D11Device_CreateVertexShader(pD3DDev11, vblob, vsize, NULL, (ID3D11VertexShader**)&prog->permu[permu].handle.hlsl.vert)))
|
|
|
|
success = false;
|
|
|
|
|
|
|
|
if (hblob || dblob)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
prog->permu[permu].handle.hlsl.topology = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST;
|
|
|
|
if (FAILED(ID3D11Device_CreateHullShader(pD3DDev11, hblob, hsize, NULL, (ID3D11HullShader**)&prog->permu[permu].handle.hlsl.hull)))
|
|
|
|
success = false;
|
|
|
|
|
|
|
|
if (FAILED(ID3D11Device_CreateDomainShader(pD3DDev11, dblob, dsize, NULL, (ID3D11DomainShader**)&prog->permu[permu].handle.hlsl.domain)))
|
|
|
|
success = false;
|
2013-11-21 23:02:28 +00:00
|
|
|
}
|
2014-03-30 08:55:06 +00:00
|
|
|
else
|
|
|
|
prog->permu[permu].handle.hlsl.topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
|
|
|
|
2015-07-01 23:15:25 +00:00
|
|
|
if (gblob && FAILED(ID3D11Device_CreateGeometryShader(pD3DDev11, gblob, gsize, NULL, (ID3D11GeometryShader**)&prog->permu[permu].handle.hlsl.geom)))
|
|
|
|
success = false;
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
if (FAILED(ID3D11Device_CreatePixelShader(pD3DDev11, fblob, fsize, NULL, (ID3D11PixelShader**)&prog->permu[permu].handle.hlsl.frag)))
|
|
|
|
success = false;
|
|
|
|
|
|
|
|
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, vblob, vsize, (ID3D11InputLayout**)&prog->permu[permu].handle.hlsl.layout)))
|
|
|
|
{
|
|
|
|
Con_Printf("HLSL Shader %s requires unsupported inputs\n", name);
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return success;
|
2013-11-21 23:02:28 +00:00
|
|
|
}
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
static qboolean D3D11Shader_LoadBlob(program_t *prog, const char *name, unsigned int permu, vfsfile_t *blobfile)
|
|
|
|
{
|
|
|
|
qboolean success;
|
2015-07-01 23:15:25 +00:00
|
|
|
char *vblob, *hblob, *dblob, *gblob, *fblob;
|
|
|
|
unsigned int vsz, hsz, dsz, gsz, fsz;
|
2014-03-30 08:55:06 +00:00
|
|
|
|
|
|
|
VFS_READ(blobfile, &vsz, sizeof(vsz));
|
|
|
|
vblob = Z_Malloc(vsz);
|
|
|
|
VFS_READ(blobfile, vblob, vsz);
|
|
|
|
|
|
|
|
VFS_READ(blobfile, &hsz, sizeof(hsz));
|
|
|
|
if (hsz != ~0u)
|
|
|
|
{
|
|
|
|
hblob = Z_Malloc(hsz);
|
|
|
|
VFS_READ(blobfile, hblob, hsz);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
hblob = NULL;
|
|
|
|
|
|
|
|
VFS_READ(blobfile, &dsz, sizeof(dsz));
|
|
|
|
if (dsz != ~0u)
|
|
|
|
{
|
|
|
|
dblob = Z_Malloc(dsz);
|
|
|
|
VFS_READ(blobfile, dblob, dsz);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
dblob = NULL;
|
|
|
|
|
2015-07-01 23:15:25 +00:00
|
|
|
VFS_READ(blobfile, &gsz, sizeof(gsz));
|
|
|
|
if (dsz != ~0u)
|
|
|
|
{
|
|
|
|
gblob = Z_Malloc(gsz);
|
|
|
|
VFS_READ(blobfile, gblob, gsz);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gblob = NULL;
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
VFS_READ(blobfile, &fsz, sizeof(fsz));
|
|
|
|
fblob = Z_Malloc(fsz);
|
|
|
|
VFS_READ(blobfile, fblob, fsz);
|
|
|
|
|
|
|
|
|
2015-07-01 23:15:25 +00:00
|
|
|
success = D3D11Shader_CreateShaders(prog, name, permu, vblob, vsz, hblob, hsz, dblob, dsz, gblob, gsz, fblob, fsz);
|
2014-03-30 08:55:06 +00:00
|
|
|
Z_Free(vblob);
|
|
|
|
Z_Free(hblob);
|
|
|
|
Z_Free(dblob);
|
2015-07-01 23:15:25 +00:00
|
|
|
Z_Free(gblob);
|
2014-03-30 08:55:06 +00:00
|
|
|
Z_Free(fblob);
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2015-07-01 23:15:25 +00:00
|
|
|
qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *hull, const char *domain, const char *geom, const char *frag, qboolean silenterrors, vfsfile_t *blobfile)
|
2012-09-30 05:52:03 +00:00
|
|
|
{
|
2015-03-03 00:14:43 +00:00
|
|
|
static const char *defaultsamplers[] =
|
|
|
|
{
|
|
|
|
"s_diffuse",
|
|
|
|
"s_normalmap",
|
|
|
|
"s_specular",
|
|
|
|
"s_upper",
|
|
|
|
"s_lower",
|
|
|
|
"s_fullbright",
|
|
|
|
"s_paletted",
|
|
|
|
"s_shadowmap",
|
|
|
|
"s_projectionmap",
|
2015-05-03 19:57:46 +00:00
|
|
|
"s_reflectcube",
|
|
|
|
"s_reflectmask",
|
2015-03-03 00:14:43 +00:00
|
|
|
"s_lightmap",
|
|
|
|
"s_deluxmap"
|
|
|
|
#if MAXRLIGHTMAPS > 1
|
|
|
|
,"s_lightmap1"
|
|
|
|
,"s_lightmap2"
|
|
|
|
,"s_lightmap3"
|
|
|
|
,"s_deluxmap1"
|
|
|
|
,"s_deluxmap2"
|
|
|
|
,"s_deluxmap3"
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2013-11-21 23:02:28 +00:00
|
|
|
char *vsformat;
|
2014-03-30 08:55:06 +00:00
|
|
|
char *hsformat = NULL;
|
|
|
|
char *dsformat = NULL;
|
2013-11-21 23:02:28 +00:00
|
|
|
char *fsformat;
|
2015-07-01 23:15:25 +00:00
|
|
|
char *gsformat = NULL;
|
2012-09-30 05:52:03 +00:00
|
|
|
D3D_SHADER_MACRO defines[64];
|
2015-07-01 23:15:25 +00:00
|
|
|
ID3DBlob *vcode = NULL, *hcode = NULL, *dcode = NULL, *gcode = NULL, *fcode = NULL, *errors = NULL;
|
2012-09-30 05:52:03 +00:00
|
|
|
qboolean success = false;
|
2015-03-03 00:14:43 +00:00
|
|
|
ID3D11ShaderReflection *freflect;
|
|
|
|
int i;
|
2012-09-30 05:52:03 +00:00
|
|
|
|
2013-11-21 23:02:28 +00:00
|
|
|
if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_11_0) //and 11.1
|
|
|
|
{
|
|
|
|
vsformat = "vs_5_0";
|
2014-03-30 08:55:06 +00:00
|
|
|
hsformat = "hs_5_0";
|
|
|
|
dsformat = "ds_5_0";
|
2015-07-01 23:15:25 +00:00
|
|
|
gsformat = "gs_5_0";
|
2013-11-21 23:02:28 +00:00
|
|
|
fsformat = "ps_5_0";
|
|
|
|
}
|
|
|
|
else if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_10_1)
|
|
|
|
{
|
|
|
|
vsformat = "vs_4_1";
|
2015-07-01 23:15:25 +00:00
|
|
|
gsformat = "gs_4_1";
|
2013-11-21 23:02:28 +00:00
|
|
|
fsformat = "ps_4_1";
|
|
|
|
}
|
|
|
|
else if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_10_0)
|
|
|
|
{
|
|
|
|
vsformat = "vs_4_0";
|
2015-07-01 23:15:25 +00:00
|
|
|
gsformat = "gs_4_0";
|
2013-11-21 23:02:28 +00:00
|
|
|
fsformat = "ps_4_0";
|
|
|
|
}
|
|
|
|
else if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_9_3)
|
|
|
|
{ //dx10-compatible output for 9.3 hardware
|
|
|
|
vsformat = "vs_4_0_level_9_3";
|
|
|
|
fsformat = "ps_4_0_level_9_3";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ //dx10-compatible output for 9.1|9.2 hardware
|
|
|
|
vsformat = "vs_4_0_level_9_1";
|
|
|
|
fsformat = "ps_4_0_level_9_1";
|
|
|
|
}
|
|
|
|
|
2012-11-27 03:23:19 +00:00
|
|
|
prog->permu[permu].handle.hlsl.vert = NULL;
|
|
|
|
prog->permu[permu].handle.hlsl.frag = NULL;
|
2015-07-01 23:15:25 +00:00
|
|
|
prog->permu[permu].handle.hlsl.hull = NULL;
|
|
|
|
prog->permu[permu].handle.hlsl.domain = NULL;
|
|
|
|
prog->permu[permu].handle.hlsl.geom = NULL;
|
2012-11-27 03:23:19 +00:00
|
|
|
prog->permu[permu].handle.hlsl.layout = NULL;
|
2012-09-30 05:52:03 +00:00
|
|
|
|
|
|
|
if (pD3DCompile)
|
|
|
|
{
|
|
|
|
int consts;
|
2014-03-30 08:55:06 +00:00
|
|
|
for (consts = 0; precompilerconstants[consts]; consts++)
|
2012-09-30 05:52:03 +00:00
|
|
|
;
|
2014-03-30 08:55:06 +00:00
|
|
|
if (consts+3 >= sizeof(defines) / sizeof(defines[0]))
|
2012-09-30 05:52:03 +00:00
|
|
|
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++;
|
|
|
|
|
2013-11-21 23:02:28 +00:00
|
|
|
defines[consts].Name = Z_StrDup("LEVEL");
|
|
|
|
defines[consts].Definition = Z_StrDup(va("0x%x", d3dfeaturelevel));
|
|
|
|
consts++;
|
|
|
|
|
2012-09-30 05:52:03 +00:00
|
|
|
for (; *precompilerconstants; precompilerconstants++)
|
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
const char *t = *precompilerconstants;
|
2013-11-21 23:02:28 +00:00
|
|
|
t = COM_Parse(t);
|
|
|
|
t = COM_Parse(t);
|
|
|
|
defines[consts].Name = Z_StrDup(com_token);
|
|
|
|
defines[consts].Definition = t?Z_StrDup(t):NULL;
|
2012-09-30 05:52:03 +00:00
|
|
|
consts++;
|
|
|
|
}
|
|
|
|
|
|
|
|
defines[consts].Name = NULL;
|
|
|
|
defines[consts].Definition = NULL;
|
|
|
|
|
|
|
|
success = true;
|
|
|
|
|
|
|
|
defines[0].Name = "VERTEX_SHADER";
|
2013-11-21 23:02:28 +00:00
|
|
|
if (FAILED(pD3DCompile(vert, strlen(vert), name, defines, &myd3dinclude, "main", vsformat, 0, 0, &vcode, &errors)))
|
2012-09-30 05:52:03 +00:00
|
|
|
success = false;
|
2014-03-30 08:55:06 +00:00
|
|
|
if (errors && !silenterrors)
|
2012-09-30 05:52:03 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
char *messages = ID3DBlob_GetBufferPointer(errors);
|
|
|
|
Con_Printf("vertex shader %s:\n%s", name, messages);
|
|
|
|
ID3DBlob_Release(errors);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hull)
|
|
|
|
{
|
|
|
|
if (!hsformat)
|
2012-09-30 05:52:03 +00:00
|
|
|
success = false;
|
2014-03-30 08:55:06 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
defines[0].Name = "HULL_SHADER";
|
|
|
|
if (FAILED(pD3DCompile(hull, strlen(hull), name, defines, &myd3dinclude, "main", hsformat, 0, 0, &hcode, &errors)))
|
|
|
|
success = false;
|
|
|
|
if (errors && !silenterrors)
|
|
|
|
{
|
|
|
|
char *messages = ID3DBlob_GetBufferPointer(errors);
|
|
|
|
Con_Printf("hull shader %s:\n%s", name, messages);
|
|
|
|
ID3DBlob_Release(errors);
|
|
|
|
}
|
|
|
|
}
|
2012-09-30 05:52:03 +00:00
|
|
|
}
|
2014-03-30 08:55:06 +00:00
|
|
|
|
|
|
|
if (domain)
|
2012-09-30 05:52:03 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
if (!dsformat)
|
|
|
|
success = false;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
defines[0].Name = "DOMAIN_SHADER";
|
|
|
|
if (FAILED(pD3DCompile(domain, strlen(domain), name, defines, &myd3dinclude, "main", dsformat, 0, 0, &dcode, &errors)))
|
|
|
|
success = false;
|
|
|
|
if (errors && !silenterrors)
|
|
|
|
{
|
|
|
|
char *messages = ID3DBlob_GetBufferPointer(errors);
|
|
|
|
Con_Printf("domain shader %s:\n%s", name, messages);
|
|
|
|
ID3DBlob_Release(errors);
|
|
|
|
}
|
|
|
|
}
|
2012-09-30 05:52:03 +00:00
|
|
|
}
|
|
|
|
|
2015-07-01 23:15:25 +00:00
|
|
|
if (geom)
|
|
|
|
{
|
|
|
|
if (!dsformat)
|
|
|
|
success = false;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
defines[0].Name = "GEOMETRY_SHADER";
|
|
|
|
if (FAILED(pD3DCompile(domain, strlen(domain), name, defines, &myd3dinclude, "main", gsformat, 0, 0, &gcode, &errors)))
|
|
|
|
success = false;
|
|
|
|
if (errors && !silenterrors)
|
|
|
|
{
|
|
|
|
char *messages = ID3DBlob_GetBufferPointer(errors);
|
|
|
|
Con_Printf("geometry shader %s:\n%s", name, messages);
|
|
|
|
ID3DBlob_Release(errors);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-30 05:52:03 +00:00
|
|
|
defines[0].Name = "FRAGMENT_SHADER";
|
2013-11-21 23:02:28 +00:00
|
|
|
if (FAILED(pD3DCompile(frag, strlen(frag), name, defines, &myd3dinclude, "main", fsformat, 0, 0, &fcode, &errors)))
|
2012-09-30 05:52:03 +00:00
|
|
|
success = false;
|
2014-03-30 08:55:06 +00:00
|
|
|
if (errors && !silenterrors)
|
2012-09-30 05:52:03 +00:00
|
|
|
{
|
2013-11-21 23:02:28 +00:00
|
|
|
char *messages = ID3DBlob_GetBufferPointer(errors);
|
2014-03-30 08:55:06 +00:00
|
|
|
Con_Printf("fragment shader %s:\n%s", name, messages);
|
2013-11-21 23:02:28 +00:00
|
|
|
ID3DBlob_Release(errors);
|
2012-09-30 05:52:03 +00:00
|
|
|
}
|
|
|
|
|
2013-11-21 23:02:28 +00:00
|
|
|
while(consts-->2)
|
|
|
|
{
|
|
|
|
Z_Free((void*)defines[consts].Name);
|
|
|
|
Z_Free((void*)defines[consts].Definition);
|
|
|
|
}
|
2012-09-30 05:52:03 +00:00
|
|
|
|
|
|
|
if (success)
|
2014-03-30 08:55:06 +00:00
|
|
|
success = D3D11Shader_CreateShaders(prog, name, permu,
|
|
|
|
ID3DBlob_GetBufferPointer(vcode), ID3DBlob_GetBufferSize(vcode),
|
|
|
|
hcode?ID3DBlob_GetBufferPointer(hcode):NULL, hcode?ID3DBlob_GetBufferSize(hcode):0,
|
|
|
|
dcode?ID3DBlob_GetBufferPointer(dcode):NULL, dcode?ID3DBlob_GetBufferSize(dcode):0,
|
2015-07-01 23:15:25 +00:00
|
|
|
gcode?ID3DBlob_GetBufferPointer(gcode):NULL, gcode?ID3DBlob_GetBufferSize(gcode):0,
|
2014-03-30 08:55:06 +00:00
|
|
|
ID3DBlob_GetBufferPointer(fcode), ID3DBlob_GetBufferSize(fcode));
|
|
|
|
|
|
|
|
if (success && blobfile)
|
2012-09-30 05:52:03 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
unsigned int sz;
|
|
|
|
sz = ID3DBlob_GetBufferSize(vcode);
|
|
|
|
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
|
|
|
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(vcode), sz);
|
2012-09-30 05:52:03 +00:00
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
if (!hcode)
|
2012-09-30 05:52:03 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
sz = ~0u;
|
|
|
|
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
2012-09-30 05:52:03 +00:00
|
|
|
}
|
2014-03-30 08:55:06 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
sz = ID3DBlob_GetBufferSize(hcode);
|
|
|
|
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
|
|
|
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(hcode), sz);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dcode)
|
|
|
|
{
|
|
|
|
sz = ~0u;
|
|
|
|
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sz = ID3DBlob_GetBufferSize(dcode);
|
|
|
|
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
|
|
|
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(dcode), sz);
|
|
|
|
}
|
|
|
|
|
2015-07-01 23:15:25 +00:00
|
|
|
if (!gcode)
|
|
|
|
{
|
|
|
|
sz = ~0u;
|
|
|
|
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sz = ID3DBlob_GetBufferSize(gcode);
|
|
|
|
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
|
|
|
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(gcode), sz);
|
|
|
|
}
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
sz = ID3DBlob_GetBufferSize(fcode);
|
|
|
|
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
|
|
|
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(fcode), sz);
|
2012-09-30 05:52:03 +00:00
|
|
|
}
|
|
|
|
|
2015-03-03 00:14:43 +00:00
|
|
|
|
|
|
|
if (fcode)
|
|
|
|
{
|
|
|
|
pD3DReflect(ID3DBlob_GetBufferPointer(fcode), ID3DBlob_GetBufferSize(fcode), &IID_ID3D11ShaderReflection, (void**)&freflect);
|
|
|
|
if (freflect)
|
|
|
|
{
|
|
|
|
int tmu;
|
|
|
|
D3D11_SHADER_INPUT_BIND_DESC bdesc = {0};
|
2015-05-03 19:57:46 +00:00
|
|
|
for (i = prog->numsamplers; i < be_maxpasses; i++)
|
2015-03-03 00:14:43 +00:00
|
|
|
{
|
2015-07-31 13:23:32 +00:00
|
|
|
if (SUCCEEDED(freflect->lpVtbl->GetResourceBindingDescByName(freflect, va("t_t%i", i), &bdesc)))
|
2015-03-03 00:14:43 +00:00
|
|
|
prog->numsamplers = i+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmu = prog->numsamplers;
|
|
|
|
for (i = 0; i < sizeof(defaultsamplers)/sizeof(defaultsamplers[0]); i++)
|
|
|
|
{
|
|
|
|
// if (prog->defaulttextures & (1u<<i))
|
|
|
|
// continue;
|
|
|
|
if (SUCCEEDED(freflect->lpVtbl->GetResourceBindingDescByName(freflect, va("t%s", defaultsamplers[i]+1), &bdesc)))
|
|
|
|
prog->defaulttextures |= (1u<<i);
|
|
|
|
if (!(prog->defaulttextures & (1u<<i)))
|
|
|
|
continue;
|
|
|
|
tmu++;
|
|
|
|
}
|
|
|
|
ID3D11ShaderReflection_Release(freflect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-30 05:52:03 +00:00
|
|
|
if (vcode)
|
2013-11-21 23:02:28 +00:00
|
|
|
ID3DBlob_Release(vcode);
|
2014-03-30 08:55:06 +00:00
|
|
|
if (hcode)
|
|
|
|
ID3DBlob_Release(hcode);
|
|
|
|
if (dcode)
|
|
|
|
ID3DBlob_Release(dcode);
|
2015-07-01 23:15:25 +00:00
|
|
|
if (gcode)
|
|
|
|
ID3DBlob_Release(gcode);
|
2012-09-30 05:52:03 +00:00
|
|
|
if (fcode)
|
2013-11-21 23:02:28 +00:00
|
|
|
ID3DBlob_Release(fcode);
|
2012-09-30 05:52:03 +00:00
|
|
|
}
|
|
|
|
return success;
|
|
|
|
}
|
2014-03-30 08:55:06 +00:00
|
|
|
|
|
|
|
qboolean D3D11Shader_Init(unsigned int flevel)
|
2012-09-30 05:52:03 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
//FIXME: if the feature level is below 10, make sure the compiler supports all the right targets etc
|
|
|
|
int ver;
|
|
|
|
dllfunction_t funcsold[] =
|
|
|
|
{
|
|
|
|
{(void**)&pD3DCompile, "D3DCompileFromMemory"},
|
2015-03-03 00:14:43 +00:00
|
|
|
{(void**)&pD3DReflect, "D3DReflect"},
|
2014-03-30 08:55:06 +00:00
|
|
|
{NULL,NULL}
|
|
|
|
};
|
|
|
|
dllfunction_t funcsnew[] =
|
|
|
|
{
|
|
|
|
{(void**)&pD3DCompile, "D3DCompile"},
|
2015-03-03 00:14:43 +00:00
|
|
|
{(void**)&pD3DReflect, "D3DReflect"},
|
2014-03-30 08:55:06 +00:00
|
|
|
{NULL,NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
for (ver = 47; ver >= 33; ver--)
|
|
|
|
{
|
|
|
|
shaderlib = Sys_LoadLibrary(va("D3dcompiler_%i.dll", ver), (ver>=40)?funcsnew:funcsold);
|
|
|
|
if (shaderlib)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!shaderlib)
|
|
|
|
{
|
|
|
|
//no shader library available. at least make sure that there's a 2d blob that we can use.
|
|
|
|
if (!COM_FCheckExists("hlsl11/default2d.blob"))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
sh_config.minver = 11;
|
|
|
|
sh_config.maxver = 11;
|
|
|
|
sh_config.blobpath = "hlsl11/%s.blob";
|
|
|
|
sh_config.progpath = shaderlib?"hlsl11/%s.hlsl":NULL;
|
|
|
|
sh_config.shadernamefmt = "%s_hlsl11";
|
|
|
|
|
|
|
|
sh_config.progs_supported = true;
|
|
|
|
sh_config.progs_required = true;
|
|
|
|
|
|
|
|
sh_config.pDeleteProg = D3D11Shader_DeleteProg;
|
|
|
|
sh_config.pLoadBlob = D3D11Shader_LoadBlob;
|
|
|
|
sh_config.pCreateProgram = D3D11Shader_CreateProgram;
|
|
|
|
sh_config.pProgAutoFields = NULL;
|
|
|
|
|
|
|
|
sh_config.tex_env_combine = 1;
|
|
|
|
sh_config.nv_tex_env_combine4 = 1;
|
|
|
|
sh_config.env_add = 1;
|
|
|
|
|
|
|
|
d3dfeaturelevel = flevel;
|
|
|
|
return true;
|
2012-09-30 05:52:03 +00:00
|
|
|
}
|
2014-03-30 08:55:06 +00:00
|
|
|
|
2012-10-13 00:56:31 +00:00
|
|
|
#endif
|
|
|
|
|