mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-12-22 16:30:23 +00:00
merge gfx updates from sm64-port
This commit is contained in:
parent
3178c165c2
commit
765a08c846
23 changed files with 1405 additions and 6907 deletions
5
Makefile
5
Makefile
|
@ -487,10 +487,7 @@ SDL2_USED := 0
|
|||
# for now, it's either SDL+GL or DXGI+DirectX, so choose based on WAPI
|
||||
ifeq ($(WINDOW_API),DXGI)
|
||||
DXBITS := `cat $(ENDIAN_BITWIDTH) | tr ' ' '\n' | tail -1`
|
||||
ifeq ($(RENDER_API),D3D11)
|
||||
BACKEND_LDFLAGS += -ld3d11
|
||||
else ifeq ($(RENDER_API),D3D12)
|
||||
BACKEND_LDFLAGS += -ld3d12
|
||||
ifeq ($(RENDER_API),D3D12)
|
||||
BACKEND_CFLAGS += -Iinclude/dxsdk
|
||||
endif
|
||||
BACKEND_LDFLAGS += -ld3dcompiler -ldxgi -ldxguid
|
||||
|
|
|
@ -1,459 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// File: D3D12Shader.h
|
||||
// Content: D3D12 Shader Types and APIs
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __D3D12SHADER_H__
|
||||
#define __D3D12SHADER_H__
|
||||
|
||||
#include "d3dcommon.h"
|
||||
|
||||
typedef enum D3D12_SHADER_VERSION_TYPE
|
||||
{
|
||||
D3D12_SHVER_PIXEL_SHADER = 0,
|
||||
D3D12_SHVER_VERTEX_SHADER = 1,
|
||||
D3D12_SHVER_GEOMETRY_SHADER = 2,
|
||||
|
||||
// D3D11 Shaders
|
||||
D3D12_SHVER_HULL_SHADER = 3,
|
||||
D3D12_SHVER_DOMAIN_SHADER = 4,
|
||||
D3D12_SHVER_COMPUTE_SHADER = 5,
|
||||
|
||||
D3D12_SHVER_RESERVED0 = 0xFFF0,
|
||||
} D3D12_SHADER_VERSION_TYPE;
|
||||
|
||||
#define D3D12_SHVER_GET_TYPE(_Version) \
|
||||
(((_Version) >> 16) & 0xffff)
|
||||
#define D3D12_SHVER_GET_MAJOR(_Version) \
|
||||
(((_Version) >> 4) & 0xf)
|
||||
#define D3D12_SHVER_GET_MINOR(_Version) \
|
||||
(((_Version) >> 0) & 0xf)
|
||||
|
||||
// Slot ID for library function return
|
||||
#define D3D_RETURN_PARAMETER_INDEX (-1)
|
||||
|
||||
typedef D3D_RESOURCE_RETURN_TYPE D3D12_RESOURCE_RETURN_TYPE;
|
||||
|
||||
typedef D3D_CBUFFER_TYPE D3D12_CBUFFER_TYPE;
|
||||
|
||||
|
||||
typedef struct _D3D12_SIGNATURE_PARAMETER_DESC
|
||||
{
|
||||
LPCSTR SemanticName; // Name of the semantic
|
||||
UINT SemanticIndex; // Index of the semantic
|
||||
UINT Register; // Number of member variables
|
||||
D3D_NAME SystemValueType;// A predefined system value, or D3D_NAME_UNDEFINED if not applicable
|
||||
D3D_REGISTER_COMPONENT_TYPE ComponentType; // Scalar type (e.g. uint, float, etc.)
|
||||
BYTE Mask; // Mask to indicate which components of the register
|
||||
// are used (combination of D3D10_COMPONENT_MASK values)
|
||||
BYTE ReadWriteMask; // Mask to indicate whether a given component is
|
||||
// never written (if this is an output signature) or
|
||||
// always read (if this is an input signature).
|
||||
// (combination of D3D_MASK_* values)
|
||||
UINT Stream; // Stream index
|
||||
D3D_MIN_PRECISION MinPrecision; // Minimum desired interpolation precision
|
||||
} D3D12_SIGNATURE_PARAMETER_DESC;
|
||||
|
||||
typedef struct _D3D12_SHADER_BUFFER_DESC
|
||||
{
|
||||
LPCSTR Name; // Name of the constant buffer
|
||||
D3D_CBUFFER_TYPE Type; // Indicates type of buffer content
|
||||
UINT Variables; // Number of member variables
|
||||
UINT Size; // Size of CB (in bytes)
|
||||
UINT uFlags; // Buffer description flags
|
||||
} D3D12_SHADER_BUFFER_DESC;
|
||||
|
||||
typedef struct _D3D12_SHADER_VARIABLE_DESC
|
||||
{
|
||||
LPCSTR Name; // Name of the variable
|
||||
UINT StartOffset; // Offset in constant buffer's backing store
|
||||
UINT Size; // Size of variable (in bytes)
|
||||
UINT uFlags; // Variable flags
|
||||
LPVOID DefaultValue; // Raw pointer to default value
|
||||
UINT StartTexture; // First texture index (or -1 if no textures used)
|
||||
UINT TextureSize; // Number of texture slots possibly used.
|
||||
UINT StartSampler; // First sampler index (or -1 if no textures used)
|
||||
UINT SamplerSize; // Number of sampler slots possibly used.
|
||||
} D3D12_SHADER_VARIABLE_DESC;
|
||||
|
||||
typedef struct _D3D12_SHADER_TYPE_DESC
|
||||
{
|
||||
D3D_SHADER_VARIABLE_CLASS Class; // Variable class (e.g. object, matrix, etc.)
|
||||
D3D_SHADER_VARIABLE_TYPE Type; // Variable type (e.g. float, sampler, etc.)
|
||||
UINT Rows; // Number of rows (for matrices, 1 for other numeric, 0 if not applicable)
|
||||
UINT Columns; // Number of columns (for vectors & matrices, 1 for other numeric, 0 if not applicable)
|
||||
UINT Elements; // Number of elements (0 if not an array)
|
||||
UINT Members; // Number of members (0 if not a structure)
|
||||
UINT Offset; // Offset from the start of structure (0 if not a structure member)
|
||||
LPCSTR Name; // Name of type, can be NULL
|
||||
} D3D12_SHADER_TYPE_DESC;
|
||||
|
||||
typedef D3D_TESSELLATOR_DOMAIN D3D12_TESSELLATOR_DOMAIN;
|
||||
|
||||
typedef D3D_TESSELLATOR_PARTITIONING D3D12_TESSELLATOR_PARTITIONING;
|
||||
|
||||
typedef D3D_TESSELLATOR_OUTPUT_PRIMITIVE D3D12_TESSELLATOR_OUTPUT_PRIMITIVE;
|
||||
|
||||
typedef struct _D3D12_SHADER_DESC
|
||||
{
|
||||
UINT Version; // Shader version
|
||||
LPCSTR Creator; // Creator string
|
||||
UINT Flags; // Shader compilation/parse flags
|
||||
|
||||
UINT ConstantBuffers; // Number of constant buffers
|
||||
UINT BoundResources; // Number of bound resources
|
||||
UINT InputParameters; // Number of parameters in the input signature
|
||||
UINT OutputParameters; // Number of parameters in the output signature
|
||||
|
||||
UINT InstructionCount; // Number of emitted instructions
|
||||
UINT TempRegisterCount; // Number of temporary registers used
|
||||
UINT TempArrayCount; // Number of temporary arrays used
|
||||
UINT DefCount; // Number of constant defines
|
||||
UINT DclCount; // Number of declarations (input + output)
|
||||
UINT TextureNormalInstructions; // Number of non-categorized texture instructions
|
||||
UINT TextureLoadInstructions; // Number of texture load instructions
|
||||
UINT TextureCompInstructions; // Number of texture comparison instructions
|
||||
UINT TextureBiasInstructions; // Number of texture bias instructions
|
||||
UINT TextureGradientInstructions; // Number of texture gradient instructions
|
||||
UINT FloatInstructionCount; // Number of floating point arithmetic instructions used
|
||||
UINT IntInstructionCount; // Number of signed integer arithmetic instructions used
|
||||
UINT UintInstructionCount; // Number of unsigned integer arithmetic instructions used
|
||||
UINT StaticFlowControlCount; // Number of static flow control instructions used
|
||||
UINT DynamicFlowControlCount; // Number of dynamic flow control instructions used
|
||||
UINT MacroInstructionCount; // Number of macro instructions used
|
||||
UINT ArrayInstructionCount; // Number of array instructions used
|
||||
UINT CutInstructionCount; // Number of cut instructions used
|
||||
UINT EmitInstructionCount; // Number of emit instructions used
|
||||
D3D_PRIMITIVE_TOPOLOGY GSOutputTopology; // Geometry shader output topology
|
||||
UINT GSMaxOutputVertexCount; // Geometry shader maximum output vertex count
|
||||
D3D_PRIMITIVE InputPrimitive; // GS/HS input primitive
|
||||
UINT PatchConstantParameters; // Number of parameters in the patch constant signature
|
||||
UINT cGSInstanceCount; // Number of Geometry shader instances
|
||||
UINT cControlPoints; // Number of control points in the HS->DS stage
|
||||
D3D_TESSELLATOR_OUTPUT_PRIMITIVE HSOutputPrimitive; // Primitive output by the tessellator
|
||||
D3D_TESSELLATOR_PARTITIONING HSPartitioning; // Partitioning mode of the tessellator
|
||||
D3D_TESSELLATOR_DOMAIN TessellatorDomain; // Domain of the tessellator (quad, tri, isoline)
|
||||
// instruction counts
|
||||
UINT cBarrierInstructions; // Number of barrier instructions in a compute shader
|
||||
UINT cInterlockedInstructions; // Number of interlocked instructions
|
||||
UINT cTextureStoreInstructions; // Number of texture writes
|
||||
} D3D12_SHADER_DESC;
|
||||
|
||||
typedef struct _D3D12_SHADER_INPUT_BIND_DESC
|
||||
{
|
||||
LPCSTR Name; // Name of the resource
|
||||
D3D_SHADER_INPUT_TYPE Type; // Type of resource (e.g. texture, cbuffer, etc.)
|
||||
UINT BindPoint; // Starting bind point
|
||||
UINT BindCount; // Number of contiguous bind points (for arrays)
|
||||
|
||||
UINT uFlags; // Input binding flags
|
||||
D3D_RESOURCE_RETURN_TYPE ReturnType; // Return type (if texture)
|
||||
D3D_SRV_DIMENSION Dimension; // Dimension (if texture)
|
||||
UINT NumSamples; // Number of samples (0 if not MS texture)
|
||||
UINT Space; // Register space
|
||||
UINT uID; // Range ID in the bytecode
|
||||
} D3D12_SHADER_INPUT_BIND_DESC;
|
||||
|
||||
#define D3D_SHADER_REQUIRES_DOUBLES 0x00000001
|
||||
#define D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL 0x00000002
|
||||
#define D3D_SHADER_REQUIRES_UAVS_AT_EVERY_STAGE 0x00000004
|
||||
#define D3D_SHADER_REQUIRES_64_UAVS 0x00000008
|
||||
#define D3D_SHADER_REQUIRES_MINIMUM_PRECISION 0x00000010
|
||||
#define D3D_SHADER_REQUIRES_11_1_DOUBLE_EXTENSIONS 0x00000020
|
||||
#define D3D_SHADER_REQUIRES_11_1_SHADER_EXTENSIONS 0x00000040
|
||||
#define D3D_SHADER_REQUIRES_LEVEL_9_COMPARISON_FILTERING 0x00000080
|
||||
#define D3D_SHADER_REQUIRES_TILED_RESOURCES 0x00000100
|
||||
#define D3D_SHADER_REQUIRES_STENCIL_REF 0x00000200
|
||||
#define D3D_SHADER_REQUIRES_INNER_COVERAGE 0x00000400
|
||||
#define D3D_SHADER_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS 0x00000800
|
||||
#define D3D_SHADER_REQUIRES_ROVS 0x00001000
|
||||
#define D3D_SHADER_REQUIRES_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER 0x00002000
|
||||
|
||||
|
||||
typedef struct _D3D12_LIBRARY_DESC
|
||||
{
|
||||
LPCSTR Creator; // The name of the originator of the library.
|
||||
UINT Flags; // Compilation flags.
|
||||
UINT FunctionCount; // Number of functions exported from the library.
|
||||
} D3D12_LIBRARY_DESC;
|
||||
|
||||
typedef struct _D3D12_FUNCTION_DESC
|
||||
{
|
||||
UINT Version; // Shader version
|
||||
LPCSTR Creator; // Creator string
|
||||
UINT Flags; // Shader compilation/parse flags
|
||||
|
||||
UINT ConstantBuffers; // Number of constant buffers
|
||||
UINT BoundResources; // Number of bound resources
|
||||
|
||||
UINT InstructionCount; // Number of emitted instructions
|
||||
UINT TempRegisterCount; // Number of temporary registers used
|
||||
UINT TempArrayCount; // Number of temporary arrays used
|
||||
UINT DefCount; // Number of constant defines
|
||||
UINT DclCount; // Number of declarations (input + output)
|
||||
UINT TextureNormalInstructions; // Number of non-categorized texture instructions
|
||||
UINT TextureLoadInstructions; // Number of texture load instructions
|
||||
UINT TextureCompInstructions; // Number of texture comparison instructions
|
||||
UINT TextureBiasInstructions; // Number of texture bias instructions
|
||||
UINT TextureGradientInstructions; // Number of texture gradient instructions
|
||||
UINT FloatInstructionCount; // Number of floating point arithmetic instructions used
|
||||
UINT IntInstructionCount; // Number of signed integer arithmetic instructions used
|
||||
UINT UintInstructionCount; // Number of unsigned integer arithmetic instructions used
|
||||
UINT StaticFlowControlCount; // Number of static flow control instructions used
|
||||
UINT DynamicFlowControlCount; // Number of dynamic flow control instructions used
|
||||
UINT MacroInstructionCount; // Number of macro instructions used
|
||||
UINT ArrayInstructionCount; // Number of array instructions used
|
||||
UINT MovInstructionCount; // Number of mov instructions used
|
||||
UINT MovcInstructionCount; // Number of movc instructions used
|
||||
UINT ConversionInstructionCount; // Number of type conversion instructions used
|
||||
UINT BitwiseInstructionCount; // Number of bitwise arithmetic instructions used
|
||||
D3D_FEATURE_LEVEL MinFeatureLevel; // Min target of the function byte code
|
||||
UINT64 RequiredFeatureFlags; // Required feature flags
|
||||
|
||||
LPCSTR Name; // Function name
|
||||
INT FunctionParameterCount; // Number of logical parameters in the function signature (not including return)
|
||||
BOOL HasReturn; // TRUE, if function returns a value, false - it is a subroutine
|
||||
BOOL Has10Level9VertexShader; // TRUE, if there is a 10L9 VS blob
|
||||
BOOL Has10Level9PixelShader; // TRUE, if there is a 10L9 PS blob
|
||||
} D3D12_FUNCTION_DESC;
|
||||
|
||||
typedef struct _D3D12_PARAMETER_DESC
|
||||
{
|
||||
LPCSTR Name; // Parameter name.
|
||||
LPCSTR SemanticName; // Parameter semantic name (+index).
|
||||
D3D_SHADER_VARIABLE_TYPE Type; // Element type.
|
||||
D3D_SHADER_VARIABLE_CLASS Class; // Scalar/Vector/Matrix.
|
||||
UINT Rows; // Rows are for matrix parameters.
|
||||
UINT Columns; // Components or Columns in matrix.
|
||||
D3D_INTERPOLATION_MODE InterpolationMode; // Interpolation mode.
|
||||
D3D_PARAMETER_FLAGS Flags; // Parameter modifiers.
|
||||
|
||||
UINT FirstInRegister; // The first input register for this parameter.
|
||||
UINT FirstInComponent; // The first input register component for this parameter.
|
||||
UINT FirstOutRegister; // The first output register for this parameter.
|
||||
UINT FirstOutComponent; // The first output register component for this parameter.
|
||||
} D3D12_PARAMETER_DESC;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Interfaces ////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef interface ID3D12ShaderReflectionType ID3D12ShaderReflectionType;
|
||||
typedef interface ID3D12ShaderReflectionType *LPD3D12SHADERREFLECTIONTYPE;
|
||||
|
||||
typedef interface ID3D12ShaderReflectionVariable ID3D12ShaderReflectionVariable;
|
||||
typedef interface ID3D12ShaderReflectionVariable *LPD3D12SHADERREFLECTIONVARIABLE;
|
||||
|
||||
typedef interface ID3D12ShaderReflectionConstantBuffer ID3D12ShaderReflectionConstantBuffer;
|
||||
typedef interface ID3D12ShaderReflectionConstantBuffer *LPD3D12SHADERREFLECTIONCONSTANTBUFFER;
|
||||
|
||||
typedef interface ID3D12ShaderReflection ID3D12ShaderReflection;
|
||||
typedef interface ID3D12ShaderReflection *LPD3D12SHADERREFLECTION;
|
||||
|
||||
typedef interface ID3D12LibraryReflection ID3D12LibraryReflection;
|
||||
typedef interface ID3D12LibraryReflection *LPD3D12LIBRARYREFLECTION;
|
||||
|
||||
typedef interface ID3D12FunctionReflection ID3D12FunctionReflection;
|
||||
typedef interface ID3D12FunctionReflection *LPD3D12FUNCTIONREFLECTION;
|
||||
|
||||
typedef interface ID3D12FunctionParameterReflection ID3D12FunctionParameterReflection;
|
||||
typedef interface ID3D12FunctionParameterReflection *LPD3D12FUNCTIONPARAMETERREFLECTION;
|
||||
|
||||
|
||||
// {E913C351-783D-48CA-A1D1-4F306284AD56}
|
||||
interface DECLSPEC_UUID("E913C351-783D-48CA-A1D1-4F306284AD56") ID3D12ShaderReflectionType;
|
||||
DEFINE_GUID(IID_ID3D12ShaderReflectionType,
|
||||
0xe913c351, 0x783d, 0x48ca, 0xa1, 0xd1, 0x4f, 0x30, 0x62, 0x84, 0xad, 0x56);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ID3D12ShaderReflectionType
|
||||
|
||||
DECLARE_INTERFACE(ID3D12ShaderReflectionType)
|
||||
{
|
||||
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_TYPE_DESC *pDesc) PURE;
|
||||
|
||||
STDMETHOD_(ID3D12ShaderReflectionType*, GetMemberTypeByIndex)(THIS_ _In_ UINT Index) PURE;
|
||||
STDMETHOD_(ID3D12ShaderReflectionType*, GetMemberTypeByName)(THIS_ _In_ LPCSTR Name) PURE;
|
||||
STDMETHOD_(LPCSTR, GetMemberTypeName)(THIS_ _In_ UINT Index) PURE;
|
||||
|
||||
STDMETHOD(IsEqual)(THIS_ _In_ ID3D12ShaderReflectionType* pType) PURE;
|
||||
STDMETHOD_(ID3D12ShaderReflectionType*, GetSubType)(THIS) PURE;
|
||||
STDMETHOD_(ID3D12ShaderReflectionType*, GetBaseClass)(THIS) PURE;
|
||||
STDMETHOD_(UINT, GetNumInterfaces)(THIS) PURE;
|
||||
STDMETHOD_(ID3D12ShaderReflectionType*, GetInterfaceByIndex)(THIS_ _In_ UINT uIndex) PURE;
|
||||
STDMETHOD(IsOfType)(THIS_ _In_ ID3D12ShaderReflectionType* pType) PURE;
|
||||
STDMETHOD(ImplementsInterface)(THIS_ _In_ ID3D12ShaderReflectionType* pBase) PURE;
|
||||
};
|
||||
|
||||
// {8337A8A6-A216-444A-B2F4-314733A73AEA}
|
||||
interface DECLSPEC_UUID("8337A8A6-A216-444A-B2F4-314733A73AEA") ID3D12ShaderReflectionVariable;
|
||||
DEFINE_GUID(IID_ID3D12ShaderReflectionVariable,
|
||||
0x8337a8a6, 0xa216, 0x444a, 0xb2, 0xf4, 0x31, 0x47, 0x33, 0xa7, 0x3a, 0xea);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ID3D12ShaderReflectionVariable
|
||||
|
||||
DECLARE_INTERFACE(ID3D12ShaderReflectionVariable)
|
||||
{
|
||||
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_VARIABLE_DESC *pDesc) PURE;
|
||||
|
||||
STDMETHOD_(ID3D12ShaderReflectionType*, GetType)(THIS) PURE;
|
||||
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetBuffer)(THIS) PURE;
|
||||
|
||||
STDMETHOD_(UINT, GetInterfaceSlot)(THIS_ _In_ UINT uArrayIndex) PURE;
|
||||
};
|
||||
|
||||
// {C59598B4-48B3-4869-B9B1-B1618B14A8B7}
|
||||
interface DECLSPEC_UUID("C59598B4-48B3-4869-B9B1-B1618B14A8B7") ID3D12ShaderReflectionConstantBuffer;
|
||||
DEFINE_GUID(IID_ID3D12ShaderReflectionConstantBuffer,
|
||||
0xc59598b4, 0x48b3, 0x4869, 0xb9, 0xb1, 0xb1, 0x61, 0x8b, 0x14, 0xa8, 0xb7);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ID3D12ShaderReflectionConstantBuffer
|
||||
|
||||
DECLARE_INTERFACE(ID3D12ShaderReflectionConstantBuffer)
|
||||
{
|
||||
STDMETHOD(GetDesc)(THIS_ D3D12_SHADER_BUFFER_DESC *pDesc) PURE;
|
||||
|
||||
STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByIndex)(THIS_ _In_ UINT Index) PURE;
|
||||
STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
|
||||
};
|
||||
|
||||
// The ID3D12ShaderReflection IID may change from SDK version to SDK version
|
||||
// if the reflection API changes. This prevents new code with the new API
|
||||
// from working with an old binary. Recompiling with the new header
|
||||
// will pick up the new IID.
|
||||
|
||||
// {5A58797D-A72C-478D-8BA2-EFC6B0EFE88E}
|
||||
interface DECLSPEC_UUID("5A58797D-A72C-478D-8BA2-EFC6B0EFE88E") ID3D12ShaderReflection;
|
||||
DEFINE_GUID(IID_ID3D12ShaderReflection,
|
||||
0x5a58797d, 0xa72c, 0x478d, 0x8b, 0xa2, 0xef, 0xc6, 0xb0, 0xef, 0xe8, 0x8e);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ID3D12ShaderReflection
|
||||
|
||||
DECLARE_INTERFACE_(ID3D12ShaderReflection, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ _In_ REFIID iid,
|
||||
_Out_ LPVOID *ppv) PURE;
|
||||
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG, Release)(THIS) PURE;
|
||||
|
||||
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_DESC *pDesc) PURE;
|
||||
|
||||
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetConstantBufferByIndex)(THIS_ _In_ UINT Index) PURE;
|
||||
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetConstantBufferByName)(THIS_ _In_ LPCSTR Name) PURE;
|
||||
|
||||
STDMETHOD(GetResourceBindingDesc)(THIS_ _In_ UINT ResourceIndex,
|
||||
_Out_ D3D12_SHADER_INPUT_BIND_DESC *pDesc) PURE;
|
||||
|
||||
STDMETHOD(GetInputParameterDesc)(THIS_ _In_ UINT ParameterIndex,
|
||||
_Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
|
||||
STDMETHOD(GetOutputParameterDesc)(THIS_ _In_ UINT ParameterIndex,
|
||||
_Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
|
||||
STDMETHOD(GetPatchConstantParameterDesc)(THIS_ _In_ UINT ParameterIndex,
|
||||
_Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
|
||||
|
||||
STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
|
||||
|
||||
STDMETHOD(GetResourceBindingDescByName)(THIS_ _In_ LPCSTR Name,
|
||||
_Out_ D3D12_SHADER_INPUT_BIND_DESC *pDesc) PURE;
|
||||
|
||||
STDMETHOD_(UINT, GetMovInstructionCount)(THIS) PURE;
|
||||
STDMETHOD_(UINT, GetMovcInstructionCount)(THIS) PURE;
|
||||
STDMETHOD_(UINT, GetConversionInstructionCount)(THIS) PURE;
|
||||
STDMETHOD_(UINT, GetBitwiseInstructionCount)(THIS) PURE;
|
||||
|
||||
STDMETHOD_(D3D_PRIMITIVE, GetGSInputPrimitive)(THIS) PURE;
|
||||
STDMETHOD_(BOOL, IsSampleFrequencyShader)(THIS) PURE;
|
||||
|
||||
STDMETHOD_(UINT, GetNumInterfaceSlots)(THIS) PURE;
|
||||
STDMETHOD(GetMinFeatureLevel)(THIS_ _Out_ enum D3D_FEATURE_LEVEL* pLevel) PURE;
|
||||
|
||||
STDMETHOD_(UINT, GetThreadGroupSize)(THIS_
|
||||
_Out_opt_ UINT* pSizeX,
|
||||
_Out_opt_ UINT* pSizeY,
|
||||
_Out_opt_ UINT* pSizeZ) PURE;
|
||||
|
||||
STDMETHOD_(UINT64, GetRequiresFlags)(THIS) PURE;
|
||||
};
|
||||
|
||||
// {8E349D19-54DB-4A56-9DC9-119D87BDB804}
|
||||
interface DECLSPEC_UUID("8E349D19-54DB-4A56-9DC9-119D87BDB804") ID3D12LibraryReflection;
|
||||
DEFINE_GUID(IID_ID3D12LibraryReflection,
|
||||
0x8e349d19, 0x54db, 0x4a56, 0x9d, 0xc9, 0x11, 0x9d, 0x87, 0xbd, 0xb8, 0x4);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ID3D12LibraryReflection
|
||||
|
||||
DECLARE_INTERFACE_(ID3D12LibraryReflection, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ _In_ REFIID iid, _Out_ LPVOID * ppv) PURE;
|
||||
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG, Release)(THIS) PURE;
|
||||
|
||||
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_LIBRARY_DESC * pDesc) PURE;
|
||||
|
||||
STDMETHOD_(ID3D12FunctionReflection *, GetFunctionByIndex)(THIS_ _In_ INT FunctionIndex) PURE;
|
||||
};
|
||||
|
||||
// {1108795C-2772-4BA9-B2A8-D464DC7E2799}
|
||||
interface DECLSPEC_UUID("1108795C-2772-4BA9-B2A8-D464DC7E2799") ID3D12FunctionReflection;
|
||||
DEFINE_GUID(IID_ID3D12FunctionReflection,
|
||||
0x1108795c, 0x2772, 0x4ba9, 0xb2, 0xa8, 0xd4, 0x64, 0xdc, 0x7e, 0x27, 0x99);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ID3D12FunctionReflection
|
||||
|
||||
DECLARE_INTERFACE(ID3D12FunctionReflection)
|
||||
{
|
||||
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_FUNCTION_DESC * pDesc) PURE;
|
||||
|
||||
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer *, GetConstantBufferByIndex)(THIS_ _In_ UINT BufferIndex) PURE;
|
||||
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer *, GetConstantBufferByName)(THIS_ _In_ LPCSTR Name) PURE;
|
||||
|
||||
STDMETHOD(GetResourceBindingDesc)(THIS_ _In_ UINT ResourceIndex,
|
||||
_Out_ D3D12_SHADER_INPUT_BIND_DESC * pDesc) PURE;
|
||||
|
||||
STDMETHOD_(ID3D12ShaderReflectionVariable *, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
|
||||
|
||||
STDMETHOD(GetResourceBindingDescByName)(THIS_ _In_ LPCSTR Name,
|
||||
_Out_ D3D12_SHADER_INPUT_BIND_DESC * pDesc) PURE;
|
||||
|
||||
// Use D3D_RETURN_PARAMETER_INDEX to get description of the return value.
|
||||
STDMETHOD_(ID3D12FunctionParameterReflection *, GetFunctionParameter)(THIS_ _In_ INT ParameterIndex) PURE;
|
||||
};
|
||||
|
||||
// {EC25F42D-7006-4F2B-B33E-02CC3375733F}
|
||||
interface DECLSPEC_UUID("EC25F42D-7006-4F2B-B33E-02CC3375733F") ID3D12FunctionParameterReflection;
|
||||
DEFINE_GUID(IID_ID3D12FunctionParameterReflection,
|
||||
0xec25f42d, 0x7006, 0x4f2b, 0xb3, 0x3e, 0x2, 0xcc, 0x33, 0x75, 0x73, 0x3f);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ID3D12FunctionParameterReflection
|
||||
|
||||
DECLARE_INTERFACE(ID3D12FunctionParameterReflection)
|
||||
{
|
||||
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_PARAMETER_DESC * pDesc) PURE;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// APIs //////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif //__D3D12SHADER_H__
|
||||
|
|
@ -1,586 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// File: D3DCompiler.h
|
||||
// Content: D3D Compilation Types and APIs
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __D3DCOMPILER_H__
|
||||
#define __D3DCOMPILER_H__
|
||||
|
||||
#include <winapifamily.h>
|
||||
|
||||
// Current name of the DLL shipped in the same SDK as this header.
|
||||
|
||||
|
||||
|
||||
#define D3DCOMPILER_DLL_W L"d3dcompiler_47.dll"
|
||||
#define D3DCOMPILER_DLL_A "d3dcompiler_47.dll"
|
||||
|
||||
// Current HLSL compiler version.
|
||||
|
||||
#define D3D_COMPILER_VERSION 47
|
||||
|
||||
#ifdef UNICODE
|
||||
#define D3DCOMPILER_DLL D3DCOMPILER_DLL_W
|
||||
#else
|
||||
#define D3DCOMPILER_DLL D3DCOMPILER_DLL_A
|
||||
#endif
|
||||
|
||||
#include "d3d11shader.h"
|
||||
#include "d3d12shader.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// APIs //////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
|
||||
#pragma region Application Family
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DReadFileToBlob:
|
||||
// -----------------
|
||||
// Simple helper routine to read a file on disk into memory
|
||||
// for passing to other routines in this API.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DReadFileToBlob(_In_ LPCWSTR pFileName,
|
||||
_Out_ ID3DBlob** ppContents);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DWriteBlobToFile:
|
||||
// ------------------
|
||||
// Simple helper routine to write a memory blob to a file on disk.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DWriteBlobToFile(_In_ ID3DBlob* pBlob,
|
||||
_In_ LPCWSTR pFileName,
|
||||
_In_ BOOL bOverwrite);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DCOMPILE flags:
|
||||
// -----------------
|
||||
// D3DCOMPILE_DEBUG
|
||||
// Insert debug file/line/type/symbol information.
|
||||
//
|
||||
// D3DCOMPILE_SKIP_VALIDATION
|
||||
// Do not validate the generated code against known capabilities and
|
||||
// constraints. This option is only recommended when compiling shaders
|
||||
// you KNOW will work. (ie. have compiled before without this option.)
|
||||
// Shaders are always validated by D3D before they are set to the device.
|
||||
//
|
||||
// D3DCOMPILE_SKIP_OPTIMIZATION
|
||||
// Instructs the compiler to skip optimization steps during code generation.
|
||||
// Unless you are trying to isolate a problem in your code using this option
|
||||
// is not recommended.
|
||||
//
|
||||
// D3DCOMPILE_PACK_MATRIX_ROW_MAJOR
|
||||
// Unless explicitly specified, matrices will be packed in row-major order
|
||||
// on input and output from the shader.
|
||||
//
|
||||
// D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR
|
||||
// Unless explicitly specified, matrices will be packed in column-major
|
||||
// order on input and output from the shader. This is generally more
|
||||
// efficient, since it allows vector-matrix multiplication to be performed
|
||||
// using a series of dot-products.
|
||||
//
|
||||
// D3DCOMPILE_PARTIAL_PRECISION
|
||||
// Force all computations in resulting shader to occur at partial precision.
|
||||
// This may result in faster evaluation of shaders on some hardware.
|
||||
//
|
||||
// D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT
|
||||
// Force compiler to compile against the next highest available software
|
||||
// target for vertex shaders. This flag also turns optimizations off,
|
||||
// and debugging on.
|
||||
//
|
||||
// D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT
|
||||
// Force compiler to compile against the next highest available software
|
||||
// target for pixel shaders. This flag also turns optimizations off,
|
||||
// and debugging on.
|
||||
//
|
||||
// D3DCOMPILE_NO_PRESHADER
|
||||
// Disables Preshaders. Using this flag will cause the compiler to not
|
||||
// pull out static expression for evaluation on the host cpu
|
||||
//
|
||||
// D3DCOMPILE_AVOID_FLOW_CONTROL
|
||||
// Hint compiler to avoid flow-control constructs where possible.
|
||||
//
|
||||
// D3DCOMPILE_PREFER_FLOW_CONTROL
|
||||
// Hint compiler to prefer flow-control constructs where possible.
|
||||
//
|
||||
// D3DCOMPILE_ENABLE_STRICTNESS
|
||||
// By default, the HLSL/Effect compilers are not strict on deprecated syntax.
|
||||
// Specifying this flag enables the strict mode. Deprecated syntax may be
|
||||
// removed in a future release, and enabling syntax is a good way to make
|
||||
// sure your shaders comply to the latest spec.
|
||||
//
|
||||
// D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY
|
||||
// This enables older shaders to compile to 4_0 targets.
|
||||
//
|
||||
// D3DCOMPILE_DEBUG_NAME_FOR_SOURCE
|
||||
// This enables a debug name to be generated based on source information.
|
||||
// It requires D3DCOMPILE_DEBUG to be set, and is exclusive with
|
||||
// D3DCOMPILE_DEBUG_NAME_FOR_BINARY.
|
||||
//
|
||||
// D3DCOMPILE_DEBUG_NAME_FOR_BINARY
|
||||
// This enables a debug name to be generated based on compiled information.
|
||||
// It requires D3DCOMPILE_DEBUG to be set, and is exclusive with
|
||||
// D3DCOMPILE_DEBUG_NAME_FOR_SOURCE.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define D3DCOMPILE_DEBUG (1 << 0)
|
||||
#define D3DCOMPILE_SKIP_VALIDATION (1 << 1)
|
||||
#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2)
|
||||
#define D3DCOMPILE_PACK_MATRIX_ROW_MAJOR (1 << 3)
|
||||
#define D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR (1 << 4)
|
||||
#define D3DCOMPILE_PARTIAL_PRECISION (1 << 5)
|
||||
#define D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT (1 << 6)
|
||||
#define D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT (1 << 7)
|
||||
#define D3DCOMPILE_NO_PRESHADER (1 << 8)
|
||||
#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9)
|
||||
#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10)
|
||||
#define D3DCOMPILE_ENABLE_STRICTNESS (1 << 11)
|
||||
#define D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY (1 << 12)
|
||||
#define D3DCOMPILE_IEEE_STRICTNESS (1 << 13)
|
||||
#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14)
|
||||
#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0
|
||||
#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15))
|
||||
#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15)
|
||||
#define D3DCOMPILE_RESERVED16 (1 << 16)
|
||||
#define D3DCOMPILE_RESERVED17 (1 << 17)
|
||||
#define D3DCOMPILE_WARNINGS_ARE_ERRORS (1 << 18)
|
||||
#define D3DCOMPILE_RESOURCES_MAY_ALIAS (1 << 19)
|
||||
#define D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES (1 << 20)
|
||||
#define D3DCOMPILE_ALL_RESOURCES_BOUND (1 << 21)
|
||||
#define D3DCOMPILE_DEBUG_NAME_FOR_SOURCE (1 << 22)
|
||||
#define D3DCOMPILE_DEBUG_NAME_FOR_BINARY (1 << 23)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DCOMPILE_EFFECT flags:
|
||||
// -------------------------------------
|
||||
// These flags are passed in when creating an effect, and affect
|
||||
// either compilation behavior or runtime effect behavior
|
||||
//
|
||||
// D3DCOMPILE_EFFECT_CHILD_EFFECT
|
||||
// Compile this .fx file to a child effect. Child effects have no
|
||||
// initializers for any shared values as these are initialied in the
|
||||
// master effect (pool).
|
||||
//
|
||||
// D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS
|
||||
// By default, performance mode is enabled. Performance mode
|
||||
// disallows mutable state objects by preventing non-literal
|
||||
// expressions from appearing in state object definitions.
|
||||
// Specifying this flag will disable the mode and allow for mutable
|
||||
// state objects.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define D3DCOMPILE_EFFECT_CHILD_EFFECT (1 << 0)
|
||||
#define D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS (1 << 1)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DCOMPILE Flags2:
|
||||
// -----------------
|
||||
// Root signature flags. (passed in Flags2)
|
||||
#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_LATEST 0
|
||||
#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_0 (1 << 4)
|
||||
#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_1 (1 << 5)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DCompile:
|
||||
// ----------
|
||||
// Compile source text into bytecode appropriate for the given target.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// D3D_COMPILE_STANDARD_FILE_INCLUDE can be passed for pInclude in any
|
||||
// API and indicates that a simple default include handler should be
|
||||
// used. The include handler will include files relative to the
|
||||
// current directory and files relative to the directory of the initial source
|
||||
// file. When used with APIs like D3DCompile pSourceName must be a
|
||||
// file name and the initial relative directory will be derived from it.
|
||||
#define D3D_COMPILE_STANDARD_FILE_INCLUDE ((ID3DInclude*)(UINT_PTR)1)
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DCompile(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_opt_ LPCSTR pSourceName,
|
||||
_In_reads_opt_(_Inexpressible_(pDefines->Name != NULL)) CONST D3D_SHADER_MACRO* pDefines,
|
||||
_In_opt_ ID3DInclude* pInclude,
|
||||
_In_opt_ LPCSTR pEntrypoint,
|
||||
_In_ LPCSTR pTarget,
|
||||
_In_ UINT Flags1,
|
||||
_In_ UINT Flags2,
|
||||
_Out_ ID3DBlob** ppCode,
|
||||
_Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorMsgs);
|
||||
|
||||
typedef HRESULT (WINAPI *pD3DCompile)
|
||||
(LPCVOID pSrcData,
|
||||
SIZE_T SrcDataSize,
|
||||
LPCSTR pFileName,
|
||||
CONST D3D_SHADER_MACRO* pDefines,
|
||||
ID3DInclude* pInclude,
|
||||
LPCSTR pEntrypoint,
|
||||
LPCSTR pTarget,
|
||||
UINT Flags1,
|
||||
UINT Flags2,
|
||||
ID3DBlob** ppCode,
|
||||
ID3DBlob** ppErrorMsgs);
|
||||
|
||||
#define D3DCOMPILE_SECDATA_MERGE_UAV_SLOTS 0x00000001
|
||||
#define D3DCOMPILE_SECDATA_PRESERVE_TEMPLATE_SLOTS 0x00000002
|
||||
#define D3DCOMPILE_SECDATA_REQUIRE_TEMPLATE_MATCH 0x00000004
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DCompile2(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_opt_ LPCSTR pSourceName,
|
||||
_In_reads_opt_(_Inexpressible_(pDefines->Name != NULL)) CONST D3D_SHADER_MACRO* pDefines,
|
||||
_In_opt_ ID3DInclude* pInclude,
|
||||
_In_ LPCSTR pEntrypoint,
|
||||
_In_ LPCSTR pTarget,
|
||||
_In_ UINT Flags1,
|
||||
_In_ UINT Flags2,
|
||||
_In_ UINT SecondaryDataFlags,
|
||||
_In_reads_bytes_opt_(SecondaryDataSize) LPCVOID pSecondaryData,
|
||||
_In_ SIZE_T SecondaryDataSize,
|
||||
_Out_ ID3DBlob** ppCode,
|
||||
_Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorMsgs);
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DCompileFromFile(_In_ LPCWSTR pFileName,
|
||||
_In_reads_opt_(_Inexpressible_(pDefines->Name != NULL)) CONST D3D_SHADER_MACRO* pDefines,
|
||||
_In_opt_ ID3DInclude* pInclude,
|
||||
_In_ LPCSTR pEntrypoint,
|
||||
_In_ LPCSTR pTarget,
|
||||
_In_ UINT Flags1,
|
||||
_In_ UINT Flags2,
|
||||
_Out_ ID3DBlob** ppCode,
|
||||
_Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorMsgs);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DPreprocess:
|
||||
// -------------
|
||||
// Process source text with the compiler's preprocessor and return
|
||||
// the resulting text.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DPreprocess(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_opt_ LPCSTR pSourceName,
|
||||
_In_opt_ CONST D3D_SHADER_MACRO* pDefines,
|
||||
_In_opt_ ID3DInclude* pInclude,
|
||||
_Out_ ID3DBlob** ppCodeText,
|
||||
_Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorMsgs);
|
||||
|
||||
typedef HRESULT (WINAPI *pD3DPreprocess)
|
||||
(LPCVOID pSrcData,
|
||||
SIZE_T SrcDataSize,
|
||||
LPCSTR pFileName,
|
||||
CONST D3D_SHADER_MACRO* pDefines,
|
||||
ID3DInclude* pInclude,
|
||||
ID3DBlob** ppCodeText,
|
||||
ID3DBlob** ppErrorMsgs);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DGetDebugInfo:
|
||||
// -----------------------
|
||||
// Gets shader debug info. Debug info is generated by D3DCompile and is
|
||||
// embedded in the body of the shader.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DGetDebugInfo(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_Out_ ID3DBlob** ppDebugInfo);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DReflect:
|
||||
// ----------
|
||||
// Shader code contains metadata that can be inspected via the
|
||||
// reflection APIs.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DReflect(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_ REFIID pInterface,
|
||||
_Out_ void** ppReflector);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DReflectLibrary:
|
||||
// ----------
|
||||
// Library code contains metadata that can be inspected via the library
|
||||
// reflection APIs.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DReflectLibrary(__in_bcount(SrcDataSize) LPCVOID pSrcData,
|
||||
__in SIZE_T SrcDataSize,
|
||||
__in REFIID riid,
|
||||
__out LPVOID * ppReflector);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DDisassemble:
|
||||
// ----------------------
|
||||
// Takes a binary shader and returns a buffer containing text assembly.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define D3D_DISASM_ENABLE_COLOR_CODE 0x00000001
|
||||
#define D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS 0x00000002
|
||||
#define D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING 0x00000004
|
||||
#define D3D_DISASM_ENABLE_INSTRUCTION_CYCLE 0x00000008
|
||||
#define D3D_DISASM_DISABLE_DEBUG_INFO 0x00000010
|
||||
#define D3D_DISASM_ENABLE_INSTRUCTION_OFFSET 0x00000020
|
||||
#define D3D_DISASM_INSTRUCTION_ONLY 0x00000040
|
||||
#define D3D_DISASM_PRINT_HEX_LITERALS 0x00000080
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DDisassemble(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_ UINT Flags,
|
||||
_In_opt_ LPCSTR szComments,
|
||||
_Out_ ID3DBlob** ppDisassembly);
|
||||
|
||||
typedef HRESULT (WINAPI *pD3DDisassemble)
|
||||
(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_ UINT Flags,
|
||||
_In_opt_ LPCSTR szComments,
|
||||
_Out_ ID3DBlob** ppDisassembly);
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DDisassembleRegion(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_ UINT Flags,
|
||||
_In_opt_ LPCSTR szComments,
|
||||
_In_ SIZE_T StartByteOffset,
|
||||
_In_ SIZE_T NumInsts,
|
||||
_Out_opt_ SIZE_T* pFinishByteOffset,
|
||||
_Out_ ID3DBlob** ppDisassembly);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Shader linking and Function Linking Graph (FLG) APIs
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT WINAPI
|
||||
D3DCreateLinker(__out interface ID3D11Linker ** ppLinker);
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DLoadModule(_In_ LPCVOID pSrcData,
|
||||
_In_ SIZE_T cbSrcDataSize,
|
||||
_Out_ interface ID3D11Module ** ppModule);
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DCreateFunctionLinkingGraph(_In_ UINT uFlags,
|
||||
_Out_ interface ID3D11FunctionLinkingGraph ** ppFunctionLinkingGraph);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DGetTraceInstructionOffsets:
|
||||
// -----------------------
|
||||
// Determines byte offsets for instructions within a shader blob.
|
||||
// This information is useful for going between trace instruction
|
||||
// indices and byte offsets that are used in debug information.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define D3D_GET_INST_OFFSETS_INCLUDE_NON_EXECUTABLE 0x00000001
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DGetTraceInstructionOffsets(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_ UINT Flags,
|
||||
_In_ SIZE_T StartInstIndex,
|
||||
_In_ SIZE_T NumInsts,
|
||||
_Out_writes_to_opt_(NumInsts, min(NumInsts, *pTotalInsts)) SIZE_T* pOffsets,
|
||||
_Out_opt_ SIZE_T* pTotalInsts);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DGetInputSignatureBlob:
|
||||
// -----------------------
|
||||
// Retrieve the input signature from a compilation result.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DGetInputSignatureBlob(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_Out_ ID3DBlob** ppSignatureBlob);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DGetOutputSignatureBlob:
|
||||
// -----------------------
|
||||
// Retrieve the output signature from a compilation result.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DGetOutputSignatureBlob(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_Out_ ID3DBlob** ppSignatureBlob);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DGetInputAndOutputSignatureBlob:
|
||||
// -----------------------
|
||||
// Retrieve the input and output signatures from a compilation result.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DGetInputAndOutputSignatureBlob(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_Out_ ID3DBlob** ppSignatureBlob);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DStripShader:
|
||||
// -----------------------
|
||||
// Removes unwanted blobs from a compilation result
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
typedef enum D3DCOMPILER_STRIP_FLAGS
|
||||
{
|
||||
D3DCOMPILER_STRIP_REFLECTION_DATA = 0x00000001,
|
||||
D3DCOMPILER_STRIP_DEBUG_INFO = 0x00000002,
|
||||
D3DCOMPILER_STRIP_TEST_BLOBS = 0x00000004,
|
||||
D3DCOMPILER_STRIP_PRIVATE_DATA = 0x00000008,
|
||||
D3DCOMPILER_STRIP_ROOT_SIGNATURE = 0x00000010,
|
||||
D3DCOMPILER_STRIP_FORCE_DWORD = 0x7fffffff,
|
||||
} D3DCOMPILER_STRIP_FLAGS;
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DStripShader(_In_reads_bytes_(BytecodeLength) LPCVOID pShaderBytecode,
|
||||
_In_ SIZE_T BytecodeLength,
|
||||
_In_ UINT uStripFlags,
|
||||
_Out_ ID3DBlob** ppStrippedBlob);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DGetBlobPart:
|
||||
// -----------------------
|
||||
// Extracts information from a compilation result.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
typedef enum D3D_BLOB_PART
|
||||
{
|
||||
D3D_BLOB_INPUT_SIGNATURE_BLOB,
|
||||
D3D_BLOB_OUTPUT_SIGNATURE_BLOB,
|
||||
D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB,
|
||||
D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB,
|
||||
D3D_BLOB_ALL_SIGNATURE_BLOB,
|
||||
D3D_BLOB_DEBUG_INFO,
|
||||
D3D_BLOB_LEGACY_SHADER,
|
||||
D3D_BLOB_XNA_PREPASS_SHADER,
|
||||
D3D_BLOB_XNA_SHADER,
|
||||
D3D_BLOB_PDB,
|
||||
D3D_BLOB_PRIVATE_DATA,
|
||||
D3D_BLOB_ROOT_SIGNATURE,
|
||||
D3D_BLOB_DEBUG_NAME,
|
||||
|
||||
// Test parts are only produced by special compiler versions and so
|
||||
// are usually not present in shaders.
|
||||
D3D_BLOB_TEST_ALTERNATE_SHADER = 0x8000,
|
||||
D3D_BLOB_TEST_COMPILE_DETAILS,
|
||||
D3D_BLOB_TEST_COMPILE_PERF,
|
||||
D3D_BLOB_TEST_COMPILE_REPORT,
|
||||
} D3D_BLOB_PART;
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DGetBlobPart(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_ D3D_BLOB_PART Part,
|
||||
_In_ UINT Flags,
|
||||
_Out_ ID3DBlob** ppPart);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DSetBlobPart:
|
||||
// -----------------------
|
||||
// Update information in a compilation result.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DSetBlobPart(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_ D3D_BLOB_PART Part,
|
||||
_In_ UINT Flags,
|
||||
_In_reads_bytes_(PartSize) LPCVOID pPart,
|
||||
_In_ SIZE_T PartSize,
|
||||
_Out_ ID3DBlob** ppNewShader);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DCreateBlob:
|
||||
// -----------------------
|
||||
// Create an ID3DBlob instance.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DCreateBlob(_In_ SIZE_T Size,
|
||||
_Out_ ID3DBlob** ppBlob);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DCompressShaders:
|
||||
// -----------------------
|
||||
// Compresses a set of shaders into a more compact form.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
typedef struct _D3D_SHADER_DATA
|
||||
{
|
||||
LPCVOID pBytecode;
|
||||
SIZE_T BytecodeLength;
|
||||
} D3D_SHADER_DATA;
|
||||
|
||||
#define D3D_COMPRESS_SHADER_KEEP_ALL_PARTS 0x00000001
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DCompressShaders(_In_ UINT uNumShaders,
|
||||
_In_reads_(uNumShaders) D3D_SHADER_DATA* pShaderData,
|
||||
_In_ UINT uFlags,
|
||||
_Out_ ID3DBlob** ppCompressedData);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DDecompressShaders:
|
||||
// -----------------------
|
||||
// Decompresses one or more shaders from a compressed set.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DDecompressShaders(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
|
||||
_In_ SIZE_T SrcDataSize,
|
||||
_In_ UINT uNumShaders,
|
||||
_In_ UINT uStartIndex,
|
||||
_In_reads_opt_(uNumShaders) UINT* pIndices,
|
||||
_In_ UINT uFlags,
|
||||
_Out_writes_(uNumShaders) ID3DBlob** ppShaders,
|
||||
_Out_opt_ UINT* pTotalShaders);
|
||||
|
||||
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES) */
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#pragma region Desktop Family
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// D3DDisassemble10Effect:
|
||||
// -----------------------
|
||||
// Takes a D3D10 effect interface and returns a
|
||||
// buffer containing text assembly.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI
|
||||
D3DDisassemble10Effect(_In_ interface ID3D10Effect *pEffect,
|
||||
_In_ UINT Flags,
|
||||
_Out_ ID3DBlob** ppDisassembly);
|
||||
|
||||
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif // #ifndef __D3DCOMPILER_H__
|
2958
include/dxsdk/dxgi.h
2958
include/dxsdk/dxgi.h
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
41
src/pc/gfx/gfx_cc.c
Normal file
41
src/pc/gfx/gfx_cc.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "gfx_cc.h"
|
||||
|
||||
void gfx_cc_get_features(uint32_t shader_id, struct CCFeatures *cc_features) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
cc_features->c[0][i] = (shader_id >> (i * 3)) & 7;
|
||||
cc_features->c[1][i] = (shader_id >> (12 + i * 3)) & 7;
|
||||
}
|
||||
|
||||
cc_features->opt_alpha = (shader_id & SHADER_OPT_ALPHA) != 0;
|
||||
cc_features->opt_fog = (shader_id & SHADER_OPT_FOG) != 0;
|
||||
cc_features->opt_texture_edge = (shader_id & SHADER_OPT_TEXTURE_EDGE) != 0;
|
||||
cc_features->opt_noise = (shader_id & SHADER_OPT_NOISE) != 0;
|
||||
|
||||
cc_features->used_textures[0] = false;
|
||||
cc_features->used_textures[1] = false;
|
||||
cc_features->num_inputs = 0;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (cc_features->c[i][j] >= SHADER_INPUT_1 && cc_features->c[i][j] <= SHADER_INPUT_4) {
|
||||
if (cc_features->c[i][j] > cc_features->num_inputs) {
|
||||
cc_features->num_inputs = cc_features->c[i][j];
|
||||
}
|
||||
}
|
||||
if (cc_features->c[i][j] == SHADER_TEXEL0 || cc_features->c[i][j] == SHADER_TEXEL0A) {
|
||||
cc_features->used_textures[0] = true;
|
||||
}
|
||||
if (cc_features->c[i][j] == SHADER_TEXEL1) {
|
||||
cc_features->used_textures[1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cc_features->do_single[0] = cc_features->c[0][2] == 0;
|
||||
cc_features->do_single[1] = cc_features->c[1][2] == 0;
|
||||
cc_features->do_multiply[0] = cc_features->c[0][1] == 0 && cc_features->c[0][3] == 0;
|
||||
cc_features->do_multiply[1] = cc_features->c[1][1] == 0 && cc_features->c[1][3] == 0;
|
||||
cc_features->do_mix[0] = cc_features->c[0][1] == cc_features->c[0][3];
|
||||
cc_features->do_mix[1] = cc_features->c[1][1] == cc_features->c[1][3];
|
||||
cc_features->color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff);
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
#ifndef GFX_CC_H
|
||||
#define GFX_CC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
enum {
|
||||
CC_0,
|
||||
CC_TEXEL0,
|
||||
|
@ -24,3 +30,29 @@ enum {
|
|||
#define SHADER_OPT_FOG (1 << 25)
|
||||
#define SHADER_OPT_TEXTURE_EDGE (1 << 26)
|
||||
#define SHADER_OPT_NOISE (1 << 27)
|
||||
|
||||
struct CCFeatures {
|
||||
uint8_t c[2][4];
|
||||
bool opt_alpha;
|
||||
bool opt_fog;
|
||||
bool opt_texture_edge;
|
||||
bool opt_noise;
|
||||
bool used_textures[2];
|
||||
int num_inputs;
|
||||
bool do_single[2];
|
||||
bool do_multiply[2];
|
||||
bool do_mix[2];
|
||||
bool color_alpha_same;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void gfx_cc_get_features(uint32_t shader_id, struct CCFeatures *cc_features);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,12 @@
|
|||
#ifdef RAPI_D3D11
|
||||
|
||||
#ifndef GFX_DIRECT3D11_H
|
||||
#define GFX_DIRECT3D11_H
|
||||
|
||||
#include "gfx_window_manager_api.h"
|
||||
#include "gfx_rendering_api.h"
|
||||
|
||||
extern struct GfxWindowManagerAPI gfx_dxgi;
|
||||
extern struct GfxRenderingAPI gfx_d3d11_api;
|
||||
extern struct GfxRenderingAPI gfx_direct3d11_api;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,12 @@
|
|||
#ifdef RAPI_D3D12
|
||||
|
||||
#ifndef GFX_DIRECT3D12_H
|
||||
#define GFX_DIRECT3D12_H
|
||||
|
||||
#include "gfx_window_manager_api.h"
|
||||
#include "gfx_rendering_api.h"
|
||||
|
||||
extern struct GfxWindowManagerAPI gfx_dxgi;
|
||||
extern struct GfxRenderingAPI gfx_d3d12_api;
|
||||
extern struct GfxRenderingAPI gfx_direct3d12_api;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
62
src/pc/gfx/gfx_direct3d12_guids.h
Normal file
62
src/pc/gfx/gfx_direct3d12_guids.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
#ifndef GFX_DIRECT3D12_GUIDS_H
|
||||
#define GFX_DIRECT3D12_GUIDS_H
|
||||
|
||||
#ifdef __MINGW32__
|
||||
|
||||
// This file is only needed due to missing MinGW-specific headers for d3d12.h.
|
||||
// It will define IID_* symbols having the "selectany" attribute (assuming
|
||||
// d3d12.h was earlier included), as well as make __uuidof(...) work.
|
||||
|
||||
#define DEF_GUID(type,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
|
||||
__CRT_UUID_DECL(type,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
|
||||
const GUID IID_##type = __uuidof(type)
|
||||
|
||||
DEF_GUID(ID3D12Object,0xc4fec28f,0x7966,0x4e95,0x9f,0x94,0xf4,0x31,0xcb,0x56,0xc3,0xb8);
|
||||
DEF_GUID(ID3D12DeviceChild,0x905db94b,0xa00c,0x4140,0x9d,0xf5,0x2b,0x64,0xca,0x9e,0xa3,0x57);
|
||||
DEF_GUID(ID3D12RootSignature,0xc54a6b66,0x72df,0x4ee8,0x8b,0xe5,0xa9,0x46,0xa1,0x42,0x92,0x14);
|
||||
DEF_GUID(ID3D12RootSignatureDeserializer,0x34AB647B,0x3CC8,0x46AC,0x84,0x1B,0xC0,0x96,0x56,0x45,0xC0,0x46);
|
||||
DEF_GUID(ID3D12VersionedRootSignatureDeserializer,0x7F91CE67,0x090C,0x4BB7,0xB7,0x8E,0xED,0x8F,0xF2,0xE3,0x1D,0xA0);
|
||||
DEF_GUID(ID3D12Pageable,0x63ee58fb,0x1268,0x4835,0x86,0xda,0xf0,0x08,0xce,0x62,0xf0,0xd6);
|
||||
DEF_GUID(ID3D12Heap,0x6b3b2502,0x6e51,0x45b3,0x90,0xee,0x98,0x84,0x26,0x5e,0x8d,0xf3);
|
||||
DEF_GUID(ID3D12Resource,0x696442be,0xa72e,0x4059,0xbc,0x79,0x5b,0x5c,0x98,0x04,0x0f,0xad);
|
||||
DEF_GUID(ID3D12CommandAllocator,0x6102dee4,0xaf59,0x4b09,0xb9,0x99,0xb4,0x4d,0x73,0xf0,0x9b,0x24);
|
||||
DEF_GUID(ID3D12Fence,0x0a753dcf,0xc4d8,0x4b91,0xad,0xf6,0xbe,0x5a,0x60,0xd9,0x5a,0x76);
|
||||
DEF_GUID(ID3D12Fence1,0x433685fe,0xe22b,0x4ca0,0xa8,0xdb,0xb5,0xb4,0xf4,0xdd,0x0e,0x4a);
|
||||
DEF_GUID(ID3D12PipelineState,0x765a30f3,0xf624,0x4c6f,0xa8,0x28,0xac,0xe9,0x48,0x62,0x24,0x45);
|
||||
DEF_GUID(ID3D12DescriptorHeap,0x8efb471d,0x616c,0x4f49,0x90,0xf7,0x12,0x7b,0xb7,0x63,0xfa,0x51);
|
||||
DEF_GUID(ID3D12QueryHeap,0x0d9658ae,0xed45,0x469e,0xa6,0x1d,0x97,0x0e,0xc5,0x83,0xca,0xb4);
|
||||
DEF_GUID(ID3D12CommandSignature,0xc36a797c,0xec80,0x4f0a,0x89,0x85,0xa7,0xb2,0x47,0x50,0x82,0xd1);
|
||||
DEF_GUID(ID3D12CommandList,0x7116d91c,0xe7e4,0x47ce,0xb8,0xc6,0xec,0x81,0x68,0xf4,0x37,0xe5);
|
||||
DEF_GUID(ID3D12GraphicsCommandList,0x5b160d0f,0xac1b,0x4185,0x8b,0xa8,0xb3,0xae,0x42,0xa5,0xa4,0x55);
|
||||
DEF_GUID(ID3D12GraphicsCommandList1,0x553103fb,0x1fe7,0x4557,0xbb,0x38,0x94,0x6d,0x7d,0x0e,0x7c,0xa7);
|
||||
DEF_GUID(ID3D12GraphicsCommandList2,0x38C3E585,0xFF17,0x412C,0x91,0x50,0x4F,0xC6,0xF9,0xD7,0x2A,0x28);
|
||||
DEF_GUID(ID3D12CommandQueue,0x0ec870a6,0x5d7e,0x4c22,0x8c,0xfc,0x5b,0xaa,0xe0,0x76,0x16,0xed);
|
||||
DEF_GUID(ID3D12Device,0x189819f1,0x1db6,0x4b57,0xbe,0x54,0x18,0x21,0x33,0x9b,0x85,0xf7);
|
||||
DEF_GUID(ID3D12PipelineLibrary,0xc64226a8,0x9201,0x46af,0xb4,0xcc,0x53,0xfb,0x9f,0xf7,0x41,0x4f);
|
||||
DEF_GUID(ID3D12PipelineLibrary1,0x80eabf42,0x2568,0x4e5e,0xbd,0x82,0xc3,0x7f,0x86,0x96,0x1d,0xc3);
|
||||
DEF_GUID(ID3D12Device1,0x77acce80,0x638e,0x4e65,0x88,0x95,0xc1,0xf2,0x33,0x86,0x86,0x3e);
|
||||
DEF_GUID(ID3D12Device2,0x30baa41e,0xb15b,0x475c,0xa0,0xbb,0x1a,0xf5,0xc5,0xb6,0x43,0x28);
|
||||
DEF_GUID(ID3D12Device3,0x81dadc15,0x2bad,0x4392,0x93,0xc5,0x10,0x13,0x45,0xc4,0xaa,0x98);
|
||||
DEF_GUID(ID3D12ProtectedSession,0xA1533D18,0x0AC1,0x4084,0x85,0xB9,0x89,0xA9,0x61,0x16,0x80,0x6B);
|
||||
DEF_GUID(ID3D12ProtectedResourceSession,0x6CD696F4,0xF289,0x40CC,0x80,0x91,0x5A,0x6C,0x0A,0x09,0x9C,0x3D);
|
||||
DEF_GUID(ID3D12Device4,0xe865df17,0xa9ee,0x46f9,0xa4,0x63,0x30,0x98,0x31,0x5a,0xa2,0xe5);
|
||||
DEF_GUID(ID3D12LifetimeOwner,0xe667af9f,0xcd56,0x4f46,0x83,0xce,0x03,0x2e,0x59,0x5d,0x70,0xa8);
|
||||
DEF_GUID(ID3D12SwapChainAssistant,0xf1df64b6,0x57fd,0x49cd,0x88,0x07,0xc0,0xeb,0x88,0xb4,0x5c,0x8f);
|
||||
DEF_GUID(ID3D12LifetimeTracker,0x3fd03d36,0x4eb1,0x424a,0xa5,0x82,0x49,0x4e,0xcb,0x8b,0xa8,0x13);
|
||||
DEF_GUID(ID3D12StateObject,0x47016943,0xfca8,0x4594,0x93,0xea,0xaf,0x25,0x8b,0x55,0x34,0x6d);
|
||||
DEF_GUID(ID3D12StateObjectProperties,0xde5fa827,0x9bf9,0x4f26,0x89,0xff,0xd7,0xf5,0x6f,0xde,0x38,0x60);
|
||||
DEF_GUID(ID3D12Device5,0x8b4f173b,0x2fea,0x4b80,0x8f,0x58,0x43,0x07,0x19,0x1a,0xb9,0x5d);
|
||||
DEF_GUID(ID3D12DeviceRemovedExtendedDataSettings,0x82BC481C,0x6B9B,0x4030,0xAE,0xDB,0x7E,0xE3,0xD1,0xDF,0x1E,0x63);
|
||||
DEF_GUID(ID3D12DeviceRemovedExtendedData,0x98931D33,0x5AE8,0x4791,0xAA,0x3C,0x1A,0x73,0xA2,0x93,0x4E,0x71);
|
||||
DEF_GUID(ID3D12Device6,0xc70b221b,0x40e4,0x4a17,0x89,0xaf,0x02,0x5a,0x07,0x27,0xa6,0xdc);
|
||||
DEF_GUID(ID3D12Resource1,0x9D5E227A,0x4430,0x4161,0x88,0xB3,0x3E,0xCA,0x6B,0xB1,0x6E,0x19);
|
||||
DEF_GUID(ID3D12Heap1,0x572F7389,0x2168,0x49E3,0x96,0x93,0xD6,0xDF,0x58,0x71,0xBF,0x6D);
|
||||
DEF_GUID(ID3D12GraphicsCommandList3,0x6FDA83A7,0xB84C,0x4E38,0x9A,0xC8,0xC7,0xBD,0x22,0x01,0x6B,0x3D);
|
||||
DEF_GUID(ID3D12MetaCommand,0xDBB84C27,0x36CE,0x4FC9,0xB8,0x01,0xF0,0x48,0xC4,0x6A,0xC5,0x70);
|
||||
DEF_GUID(ID3D12GraphicsCommandList4,0x8754318e,0xd3a9,0x4541,0x98,0xcf,0x64,0x5b,0x50,0xdc,0x48,0x74);
|
||||
DEF_GUID(ID3D12Tools,0x7071e1f0,0xe84b,0x4b33,0x97,0x4f,0x12,0xfa,0x49,0xde,0x65,0xc5);
|
||||
DEF_GUID(ID3D12GraphicsCommandList5,0x55050859,0x4024,0x474c,0x87,0xf5,0x64,0x72,0xea,0xee,0x44,0xea);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,24 +1,10 @@
|
|||
#if (defined(RAPI_D3D11) || defined(RAPI_D3D12)) && (defined(_WIN32) || defined(_WIN64))
|
||||
#if defined(RAPI_D3D11) || defined(RAPI_D3D12)
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
extern "C" {
|
||||
#include "../platform.h"
|
||||
}
|
||||
|
||||
#include "gfx_direct3d_common.h"
|
||||
#include "gfx_cc.h"
|
||||
|
||||
void ThrowIfFailed(HRESULT res) {
|
||||
if (FAILED(res))
|
||||
sys_fatal("error while initializing D3D:\nerror code 0x%08X", res);
|
||||
}
|
||||
|
||||
void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message) {
|
||||
if (FAILED(res))
|
||||
sys_fatal("%s\nerror code 0x%08X", message, res);
|
||||
}
|
||||
|
||||
void get_cc_features(uint32_t shader_id, CCFeatures *cc_features) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
cc_features->c[0][i] = (shader_id >> (i * 3)) & 7;
|
||||
|
@ -59,17 +45,17 @@ void get_cc_features(uint32_t shader_id, CCFeatures *cc_features) {
|
|||
cc_features->color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff);
|
||||
}
|
||||
|
||||
void append_str(char *buf, size_t *len, const char *str) {
|
||||
static void append_str(char *buf, size_t *len, const char *str) {
|
||||
while (*str != '\0') buf[(*len)++] = *str++;
|
||||
}
|
||||
|
||||
void append_line(char *buf, size_t *len, const char *str) {
|
||||
static void append_line(char *buf, size_t *len, const char *str) {
|
||||
while (*str != '\0') buf[(*len)++] = *str++;
|
||||
buf[(*len)++] = '\r';
|
||||
buf[(*len)++] = '\n';
|
||||
}
|
||||
|
||||
const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element) {
|
||||
static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element) {
|
||||
if (!only_alpha) {
|
||||
switch (item) {
|
||||
default:
|
||||
|
@ -113,7 +99,7 @@ const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha,
|
|||
}
|
||||
}
|
||||
|
||||
void append_formula(char *buf, size_t *len, uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha) {
|
||||
static void append_formula(char *buf, size_t *len, const uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha) {
|
||||
if (do_single) {
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false));
|
||||
} else if (do_multiply) {
|
||||
|
@ -140,4 +126,188 @@ void append_formula(char *buf, size_t *len, uint8_t c[2][4], bool do_single, boo
|
|||
}
|
||||
}
|
||||
|
||||
void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_floats, const CCFeatures& cc_features, bool include_root_signature, bool three_point_filtering) {
|
||||
len = 0;
|
||||
num_floats = 4;
|
||||
|
||||
// Pixel shader input struct
|
||||
|
||||
if (include_root_signature) {
|
||||
append_str(buf, &len, "#define RS \"RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | DENY_VERTEX_SHADER_ROOT_ACCESS)");
|
||||
if (cc_features.opt_alpha && cc_features.opt_noise) {
|
||||
append_str(buf, &len, ",CBV(b0, visibility = SHADER_VISIBILITY_PIXEL)");
|
||||
}
|
||||
if (cc_features.used_textures[0]) {
|
||||
append_str(buf, &len, ",DescriptorTable(SRV(t0), visibility = SHADER_VISIBILITY_PIXEL)");
|
||||
append_str(buf, &len, ",DescriptorTable(Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL)");
|
||||
}
|
||||
if (cc_features.used_textures[1]) {
|
||||
append_str(buf, &len, ",DescriptorTable(SRV(t1), visibility = SHADER_VISIBILITY_PIXEL)");
|
||||
append_str(buf, &len, ",DescriptorTable(Sampler(s1), visibility = SHADER_VISIBILITY_PIXEL)");
|
||||
}
|
||||
append_line(buf, &len, "\"");
|
||||
}
|
||||
|
||||
append_line(buf, &len, "struct PSInput {");
|
||||
append_line(buf, &len, " float4 position : SV_POSITION;");
|
||||
if (cc_features.used_textures[0] || cc_features.used_textures[1]) {
|
||||
append_line(buf, &len, " float2 uv : TEXCOORD;");
|
||||
num_floats += 2;
|
||||
}
|
||||
if (cc_features.opt_alpha && cc_features.opt_noise) {
|
||||
append_line(buf, &len, " float4 screenPos : TEXCOORD1;");
|
||||
}
|
||||
if (cc_features.opt_fog) {
|
||||
append_line(buf, &len, " float4 fog : FOG;");
|
||||
num_floats += 4;
|
||||
}
|
||||
for (int i = 0; i < cc_features.num_inputs; i++) {
|
||||
len += sprintf(buf + len, " float%d input%d : INPUT%d;\r\n", cc_features.opt_alpha ? 4 : 3, i + 1, i);
|
||||
num_floats += cc_features.opt_alpha ? 4 : 3;
|
||||
}
|
||||
append_line(buf, &len, "};");
|
||||
|
||||
// Textures and samplers
|
||||
|
||||
if (cc_features.used_textures[0]) {
|
||||
append_line(buf, &len, "Texture2D g_texture0 : register(t0);");
|
||||
append_line(buf, &len, "SamplerState g_sampler0 : register(s0);");
|
||||
}
|
||||
if (cc_features.used_textures[1]) {
|
||||
append_line(buf, &len, "Texture2D g_texture1 : register(t1);");
|
||||
append_line(buf, &len, "SamplerState g_sampler1 : register(s1);");
|
||||
}
|
||||
|
||||
// Constant buffer and random function
|
||||
|
||||
if (cc_features.opt_alpha && cc_features.opt_noise) {
|
||||
append_line(buf, &len, "cbuffer PerFrameCB : register(b0) {");
|
||||
append_line(buf, &len, " uint noise_frame;");
|
||||
append_line(buf, &len, " float2 noise_scale;");
|
||||
append_line(buf, &len, "}");
|
||||
|
||||
append_line(buf, &len, "float random(in float3 value) {");
|
||||
append_line(buf, &len, " float random = dot(value, float3(12.9898, 78.233, 37.719));");
|
||||
append_line(buf, &len, " return frac(sin(random) * 143758.5453);");
|
||||
append_line(buf, &len, "}");
|
||||
}
|
||||
|
||||
// 3 point texture filtering
|
||||
// Original author: ArthurCarvalho
|
||||
// Based on GLSL implementation by twinaphex, mupen64plus-libretro project.
|
||||
|
||||
if (three_point_filtering && (cc_features.used_textures[0] || cc_features.used_textures[1])) {
|
||||
append_line(buf, &len, "cbuffer PerDrawCB : register(b1) {");
|
||||
append_line(buf, &len, " struct {");
|
||||
append_line(buf, &len, " uint width;");
|
||||
append_line(buf, &len, " uint height;");
|
||||
append_line(buf, &len, " bool linear_filtering;");
|
||||
append_line(buf, &len, " } textures[2];");
|
||||
append_line(buf, &len, "}");
|
||||
append_line(buf, &len, "#define TEX_OFFSET(tex, tSampler, texCoord, off, texSize) tex.Sample(tSampler, texCoord - off / texSize)");
|
||||
append_line(buf, &len, "float4 tex2D3PointFilter(in Texture2D tex, in SamplerState tSampler, in float2 texCoord, in float2 texSize) {");
|
||||
append_line(buf, &len, " float2 offset = frac(texCoord * texSize - float2(0.5, 0.5));");
|
||||
append_line(buf, &len, " offset -= step(1.0, offset.x + offset.y);");
|
||||
append_line(buf, &len, " float4 c0 = TEX_OFFSET(tex, tSampler, texCoord, offset, texSize);");
|
||||
append_line(buf, &len, " float4 c1 = TEX_OFFSET(tex, tSampler, texCoord, float2(offset.x - sign(offset.x), offset.y), texSize);");
|
||||
append_line(buf, &len, " float4 c2 = TEX_OFFSET(tex, tSampler, texCoord, float2(offset.x, offset.y - sign(offset.y)), texSize);");
|
||||
append_line(buf, &len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);");
|
||||
append_line(buf, &len, "}");
|
||||
}
|
||||
|
||||
// Vertex shader
|
||||
|
||||
append_str(buf, &len, "PSInput VSMain(float4 position : POSITION");
|
||||
if (cc_features.used_textures[0] || cc_features.used_textures[1]) {
|
||||
append_str(buf, &len, ", float2 uv : TEXCOORD");
|
||||
}
|
||||
if (cc_features.opt_fog) {
|
||||
append_str(buf, &len, ", float4 fog : FOG");
|
||||
}
|
||||
for (int i = 0; i < cc_features.num_inputs; i++) {
|
||||
len += sprintf(buf + len, ", float%d input%d : INPUT%d", cc_features.opt_alpha ? 4 : 3, i + 1, i);
|
||||
}
|
||||
append_line(buf, &len, ") {");
|
||||
append_line(buf, &len, " PSInput result;");
|
||||
append_line(buf, &len, " result.position = position;");
|
||||
if (cc_features.opt_alpha && cc_features.opt_noise) {
|
||||
append_line(buf, &len, " result.screenPos = position;");
|
||||
}
|
||||
if (cc_features.used_textures[0] || cc_features.used_textures[1]) {
|
||||
append_line(buf, &len, " result.uv = uv;");
|
||||
}
|
||||
if (cc_features.opt_fog) {
|
||||
append_line(buf, &len, " result.fog = fog;");
|
||||
}
|
||||
for (int i = 0; i < cc_features.num_inputs; i++) {
|
||||
len += sprintf(buf + len, " result.input%d = input%d;\r\n", i + 1, i + 1);
|
||||
}
|
||||
append_line(buf, &len, " return result;");
|
||||
append_line(buf, &len, "}");
|
||||
|
||||
// Pixel shader
|
||||
if (include_root_signature) {
|
||||
append_line(buf, &len, "[RootSignature(RS)]");
|
||||
}
|
||||
append_line(buf, &len, "float4 PSMain(PSInput input) : SV_TARGET {");
|
||||
if (cc_features.used_textures[0]) {
|
||||
if (three_point_filtering) {
|
||||
append_line(buf, &len, " float4 texVal0;");
|
||||
append_line(buf, &len, " if (textures[0].linear_filtering)");
|
||||
append_line(buf, &len, " texVal0 = tex2D3PointFilter(g_texture0, g_sampler0, input.uv, float2(textures[0].width, textures[0].height));");
|
||||
append_line(buf, &len, " else");
|
||||
append_line(buf, &len, " texVal0 = g_texture0.Sample(g_sampler0, input.uv);");
|
||||
} else {
|
||||
append_line(buf, &len, " float4 texVal0 = g_texture0.Sample(g_sampler0, input.uv);");
|
||||
}
|
||||
}
|
||||
if (cc_features.used_textures[1]) {
|
||||
if (three_point_filtering) {
|
||||
append_line(buf, &len, " float4 texVal1;");
|
||||
append_line(buf, &len, " if (textures[1].linear_filtering)");
|
||||
append_line(buf, &len, " texVal1 = tex2D3PointFilter(g_texture1, g_sampler1, input.uv, float2(textures[1].width, textures[1].height));");
|
||||
append_line(buf, &len, " else");
|
||||
append_line(buf, &len, " texVal1 = g_texture1.Sample(g_sampler1, input.uv);");
|
||||
} else {
|
||||
append_line(buf, &len, " float4 texVal1 = g_texture1.Sample(g_sampler1, input.uv);");
|
||||
}
|
||||
}
|
||||
|
||||
append_str(buf, &len, cc_features.opt_alpha ? " float4 texel = " : " float3 texel = ");
|
||||
if (!cc_features.color_alpha_same && cc_features.opt_alpha) {
|
||||
append_str(buf, &len, "float4(");
|
||||
append_formula(buf, &len, cc_features.c, cc_features.do_single[0], cc_features.do_multiply[0], cc_features.do_mix[0], false, false, true);
|
||||
append_str(buf, &len, ", ");
|
||||
append_formula(buf, &len, cc_features.c, cc_features.do_single[1], cc_features.do_multiply[1], cc_features.do_mix[1], true, true, true);
|
||||
append_str(buf, &len, ")");
|
||||
} else {
|
||||
append_formula(buf, &len, cc_features.c, cc_features.do_single[0], cc_features.do_multiply[0], cc_features.do_mix[0], cc_features.opt_alpha, false, cc_features.opt_alpha);
|
||||
}
|
||||
append_line(buf, &len, ";");
|
||||
|
||||
if (cc_features.opt_texture_edge && cc_features.opt_alpha) {
|
||||
append_line(buf, &len, " if (texel.a > 0.3) texel.a = 1.0; else discard;");
|
||||
}
|
||||
// TODO discard if alpha is 0?
|
||||
if (cc_features.opt_fog) {
|
||||
if (cc_features.opt_alpha) {
|
||||
append_line(buf, &len, " texel = float4(lerp(texel.rgb, input.fog.rgb, input.fog.a), texel.a);");
|
||||
} else {
|
||||
append_line(buf, &len, " texel = lerp(texel, input.fog.rgb, input.fog.a);");
|
||||
}
|
||||
}
|
||||
|
||||
if (cc_features.opt_alpha && cc_features.opt_noise) {
|
||||
append_line(buf, &len, " float2 coords = (input.screenPos.xy / input.screenPos.w) * noise_scale;");
|
||||
append_line(buf, &len, " texel.a *= round(random(float3(floor(coords), noise_frame)));");
|
||||
}
|
||||
|
||||
if (cc_features.opt_alpha) {
|
||||
append_line(buf, &len, " return texel;");
|
||||
} else {
|
||||
append_line(buf, &len, " return float4(texel, 1.0);");
|
||||
}
|
||||
append_line(buf, &len, "}");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,29 +4,10 @@
|
|||
#define GFX_DIRECT3D_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
struct CCFeatures {
|
||||
uint8_t c[2][4];
|
||||
bool opt_alpha;
|
||||
bool opt_fog;
|
||||
bool opt_texture_edge;
|
||||
bool opt_noise;
|
||||
bool used_textures[2];
|
||||
uint32_t num_inputs;
|
||||
bool do_single[2];
|
||||
bool do_multiply[2];
|
||||
bool do_mix[2];
|
||||
bool color_alpha_same;
|
||||
};
|
||||
#include "gfx_cc.h"
|
||||
|
||||
void ThrowIfFailed(HRESULT res);
|
||||
void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message);
|
||||
void get_cc_features(uint32_t shader_id, CCFeatures *shader_features);
|
||||
void append_str(char *buf, size_t *len, const char *str);
|
||||
void append_line(char *buf, size_t *len, const char *str);
|
||||
const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element);
|
||||
void append_formula(char *buf, size_t *len, uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha);
|
||||
void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_floats, const CCFeatures& cc_features, bool include_root_signature, bool three_point_filtering);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
641
src/pc/gfx/gfx_dxgi.cpp
Normal file
641
src/pc/gfx/gfx_dxgi.cpp
Normal file
|
@ -0,0 +1,641 @@
|
|||
#ifdef WAPI_DXGI
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include <windows.h>
|
||||
#include <wrl/client.h>
|
||||
#include <dxgi1_3.h>
|
||||
#include <versionhelpers.h>
|
||||
|
||||
#include <shellscalingapi.h>
|
||||
|
||||
|
||||
#ifndef _LANGUAGE_C
|
||||
#define _LANGUAGE_C
|
||||
#endif
|
||||
#include <PR/gbi.h>
|
||||
|
||||
#include "../configfile.h"
|
||||
#include "../pc_main.h"
|
||||
|
||||
#include "gfx_window_manager_api.h"
|
||||
#include "gfx_rendering_api.h"
|
||||
#include "gfx_direct3d_common.h"
|
||||
#include "gfx_screen_config.h"
|
||||
#include "gfx_pc.h"
|
||||
|
||||
#define WINCLASS_NAME L"N64GAME"
|
||||
|
||||
#define DECLARE_GFX_DXGI_FUNCTIONS
|
||||
#include "gfx_dxgi.h"
|
||||
|
||||
#ifdef VERSION_EU
|
||||
#define FRAME_INTERVAL_US_NUMERATOR 40000
|
||||
#define FRAME_INTERVAL_US_DENOMINATOR 1
|
||||
#else
|
||||
#define FRAME_INTERVAL_US_NUMERATOR 100000
|
||||
#define FRAME_INTERVAL_US_DENOMINATOR 3
|
||||
#endif
|
||||
|
||||
using namespace Microsoft::WRL; // For ComPtr
|
||||
|
||||
static struct {
|
||||
HWND h_wnd;
|
||||
bool showing_error;
|
||||
uint32_t current_width, current_height;
|
||||
std::string window_title;
|
||||
|
||||
HMODULE dxgi_module;
|
||||
HRESULT (__stdcall *CreateDXGIFactory1)(REFIID riid, void **factory);
|
||||
HRESULT (__stdcall *CreateDXGIFactory2)(UINT flags, REFIID iid, void **factory);
|
||||
|
||||
bool process_dpi_awareness_done;
|
||||
|
||||
RECT last_window_rect;
|
||||
bool is_full_screen, last_maximized_state;
|
||||
|
||||
ComPtr<IDXGIFactory2> factory;
|
||||
ComPtr<IDXGISwapChain1> swap_chain;
|
||||
HANDLE waitable_object;
|
||||
uint64_t qpc_init, qpc_freq;
|
||||
uint64_t frame_timestamp; // in units of 1/FRAME_INTERVAL_US_DENOMINATOR microseconds
|
||||
std::map<UINT, DXGI_FRAME_STATISTICS> frame_stats;
|
||||
std::set<std::pair<UINT, UINT>> pending_frame_stats;
|
||||
bool dropped_frame;
|
||||
bool sync_interval_means_frames_to_wait;
|
||||
UINT length_in_vsync_frames;
|
||||
|
||||
void (*run_one_game_iter)(void);
|
||||
bool (*on_key_down)(int scancode);
|
||||
bool (*on_key_up)(int scancode);
|
||||
void (*on_all_keys_up)(void);
|
||||
} dxgi;
|
||||
|
||||
static void load_dxgi_library(void) {
|
||||
dxgi.dxgi_module = LoadLibraryW(L"dxgi.dll");
|
||||
*(FARPROC *)&dxgi.CreateDXGIFactory1 = GetProcAddress(dxgi.dxgi_module, "CreateDXGIFactory1");
|
||||
*(FARPROC *)&dxgi.CreateDXGIFactory2 = GetProcAddress(dxgi.dxgi_module, "CreateDXGIFactory2");
|
||||
}
|
||||
|
||||
template <typename Fun>
|
||||
static void run_as_dpi_aware(Fun f) {
|
||||
// Make sure Windows 8.1 or newer doesn't upscale/downscale the rendered images.
|
||||
// This is an issue on Windows 8.1 and newer where moving around the window
|
||||
// between different monitors having different scaling settings will
|
||||
// by default result in the DirectX image will also be scaled accordingly.
|
||||
// The resulting scale factor is the curent monitor's scale factor divided by
|
||||
// the initial monitor's scale factor. Setting per-monitor aware disables scaling.
|
||||
|
||||
// On Windows 10 1607 and later, that is solved by setting the awarenenss per window,
|
||||
// which is done by using SetThreadDpiAwarenessContext before and after creating
|
||||
// any window. When the message handler runs, the corresponding context also applies.
|
||||
|
||||
// From windef.h, missing in MinGW.
|
||||
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
||||
#define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1)
|
||||
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2)
|
||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3)
|
||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4)
|
||||
#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5)
|
||||
|
||||
DPI_AWARENESS_CONTEXT (WINAPI *SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext);
|
||||
*(FARPROC *)&SetThreadDpiAwarenessContext = GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetThreadDpiAwarenessContext");
|
||||
DPI_AWARENESS_CONTEXT old_awareness_context;
|
||||
if (SetThreadDpiAwarenessContext != nullptr) {
|
||||
old_awareness_context = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
} else {
|
||||
// Solution for Windows 8.1 and newer, but before Windows 10 1607.
|
||||
// SetProcessDpiAwareness must be called before any drawing related API is called.
|
||||
if (!dxgi.process_dpi_awareness_done) {
|
||||
HMODULE shcore_module = LoadLibraryW(L"SHCore.dll");
|
||||
if (shcore_module != nullptr) {
|
||||
HRESULT (WINAPI *SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS value);
|
||||
*(FARPROC *)&SetProcessDpiAwareness = GetProcAddress(shcore_module, "SetProcessDpiAwareness");
|
||||
if (SetProcessDpiAwareness != nullptr) {
|
||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
// Ignore result, will fail if already called or manifest already specifies dpi awareness.
|
||||
}
|
||||
FreeLibrary(shcore_module);
|
||||
}
|
||||
dxgi.process_dpi_awareness_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
f();
|
||||
|
||||
// Restore the old context
|
||||
if (SetThreadDpiAwarenessContext != nullptr && old_awareness_context != nullptr) {
|
||||
SetThreadDpiAwarenessContext(old_awareness_context);
|
||||
}
|
||||
}
|
||||
|
||||
static void toggle_borderless_window_full_screen(bool enable) {
|
||||
// Windows 7 + flip mode + waitable object can't go to exclusive fullscreen,
|
||||
// so do borderless instead. If DWM is enabled, this means we get one monitor
|
||||
// sync interval of latency extra. On Win 10 however (maybe Win 8 too), due to
|
||||
// "fullscreen optimizations" the latency is eliminated.
|
||||
|
||||
if (enable == dxgi.is_full_screen) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
RECT r = dxgi.last_window_rect;
|
||||
|
||||
// Set in window mode with the last saved position and size
|
||||
SetWindowLongPtr(dxgi.h_wnd, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW);
|
||||
|
||||
if (dxgi.last_maximized_state) {
|
||||
SetWindowPos(dxgi.h_wnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
|
||||
ShowWindow(dxgi.h_wnd, SW_MAXIMIZE);
|
||||
} else {
|
||||
SetWindowPos(dxgi.h_wnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_FRAMECHANGED);
|
||||
ShowWindow(dxgi.h_wnd, SW_RESTORE);
|
||||
}
|
||||
|
||||
ShowCursor(TRUE);
|
||||
|
||||
dxgi.is_full_screen = false;
|
||||
} else {
|
||||
// Save if window is maximized or not
|
||||
WINDOWPLACEMENT window_placement;
|
||||
window_placement.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(dxgi.h_wnd, &window_placement);
|
||||
dxgi.last_maximized_state = window_placement.showCmd == SW_SHOWMAXIMIZED;
|
||||
|
||||
// Save window position and size if the window is not maximized
|
||||
GetWindowRect(dxgi.h_wnd, &dxgi.last_window_rect);
|
||||
configWindow.x = dxgi.last_window_rect.left;
|
||||
configWindow.y = dxgi.last_window_rect.top;
|
||||
configWindow.w = dxgi.last_window_rect.right - dxgi.last_window_rect.left;
|
||||
configWindow.h = dxgi.last_window_rect.bottom - dxgi.last_window_rect.top;
|
||||
|
||||
// Get in which monitor the window is
|
||||
HMONITOR h_monitor = MonitorFromWindow(dxgi.h_wnd, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
// Get info from that monitor
|
||||
MONITORINFOEX monitor_info;
|
||||
monitor_info.cbSize = sizeof(MONITORINFOEX);
|
||||
GetMonitorInfo(h_monitor, &monitor_info);
|
||||
RECT r = monitor_info.rcMonitor;
|
||||
|
||||
// Set borderless full screen to that monitor
|
||||
SetWindowLongPtr(dxgi.h_wnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
|
||||
SetWindowPos(dxgi.h_wnd, HWND_TOP, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_FRAMECHANGED);
|
||||
|
||||
ShowCursor(FALSE);
|
||||
|
||||
dxgi.is_full_screen = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_screen_settings(void) {
|
||||
if (configWindow.fullscreen != dxgi.is_full_screen)
|
||||
toggle_borderless_window_full_screen(configWindow.fullscreen);
|
||||
if (!dxgi.is_full_screen) {
|
||||
const int screen_width = GetSystemMetrics(SM_CXSCREEN);
|
||||
const int screen_height = GetSystemMetrics(SM_CYSCREEN);
|
||||
const int xpos = (configWindow.x == WAPI_WIN_CENTERPOS) ? (screen_width - configWindow.w) * 0.5 : configWindow.x;
|
||||
const int ypos = (configWindow.y == WAPI_WIN_CENTERPOS) ? (screen_height - configWindow.h) * 0.5 : configWindow.y;
|
||||
RECT wr = { xpos, ypos, xpos + (int)configWindow.w, ypos + (int)configWindow.h };
|
||||
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
SetWindowPos(dxgi.h_wnd, NULL, wr.left, wr.top, wr.right - wr.left, wr.bottom - wr.top, SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_dxgi_on_resize(void) {
|
||||
if (dxgi.swap_chain.Get() != nullptr) {
|
||||
gfx_get_current_rendering_api()->on_resize();
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 desc1;
|
||||
ThrowIfFailed(dxgi.swap_chain->GetDesc1(&desc1));
|
||||
dxgi.current_width = desc1.Width;
|
||||
dxgi.current_height = desc1.Height;
|
||||
if (!dxgi.is_full_screen) {
|
||||
configWindow.w = dxgi.current_width;
|
||||
configWindow.h = dxgi.current_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void onkeydown(WPARAM w_param, LPARAM l_param) {
|
||||
int key = ((l_param >> 16) & 0x1ff);
|
||||
if (dxgi.on_key_down != nullptr) {
|
||||
dxgi.on_key_down(key);
|
||||
}
|
||||
}
|
||||
static void onkeyup(WPARAM w_param, LPARAM l_param) {
|
||||
int key = ((l_param >> 16) & 0x1ff);
|
||||
if (dxgi.on_key_up != nullptr) {
|
||||
dxgi.on_key_up(key);
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_param, LPARAM l_param) {
|
||||
switch (message) {
|
||||
case WM_SIZE:
|
||||
gfx_dxgi_on_resize();
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
game_exit();
|
||||
break;
|
||||
case WM_PAINT:
|
||||
if (dxgi.showing_error) {
|
||||
return DefWindowProcW(h_wnd, message, w_param, l_param);
|
||||
} else {
|
||||
if (dxgi.run_one_game_iter != nullptr) {
|
||||
dxgi.run_one_game_iter();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_ACTIVATEAPP:
|
||||
if (dxgi.on_all_keys_up != nullptr) {
|
||||
dxgi.on_all_keys_up();
|
||||
}
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
onkeydown(w_param, l_param);
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
onkeyup(w_param, l_param);
|
||||
break;
|
||||
case WM_SYSKEYDOWN:
|
||||
if ((w_param == VK_RETURN) && ((l_param & 1 << 30) == 0)) {
|
||||
toggle_borderless_window_full_screen(!dxgi.is_full_screen);
|
||||
break;
|
||||
} else {
|
||||
return DefWindowProcW(h_wnd, message, w_param, l_param);
|
||||
}
|
||||
default:
|
||||
return DefWindowProcW(h_wnd, message, w_param, l_param);
|
||||
}
|
||||
|
||||
if (configWindow.reset) {
|
||||
dxgi.last_maximized_state = false;
|
||||
configWindow.reset = false;
|
||||
configWindow.x = WAPI_WIN_CENTERPOS;
|
||||
configWindow.y = WAPI_WIN_CENTERPOS;
|
||||
configWindow.w = DESIRED_SCREEN_WIDTH;
|
||||
configWindow.h = DESIRED_SCREEN_HEIGHT;
|
||||
configWindow.fullscreen = false;
|
||||
configWindow.settings_changed = true;
|
||||
}
|
||||
|
||||
if (configWindow.settings_changed) {
|
||||
configWindow.settings_changed = false;
|
||||
update_screen_settings();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_dxgi_init(const char *window_title) {
|
||||
LARGE_INTEGER qpc_init, qpc_freq;
|
||||
QueryPerformanceCounter(&qpc_init);
|
||||
QueryPerformanceFrequency(&qpc_freq);
|
||||
dxgi.qpc_init = qpc_init.QuadPart;
|
||||
dxgi.qpc_freq = qpc_freq.QuadPart;
|
||||
|
||||
// Prepare window title
|
||||
|
||||
wchar_t w_title[512];
|
||||
int len = strlen(window_title);
|
||||
mbstowcs(w_title, window_title, len + 1);
|
||||
dxgi.window_title = window_title;
|
||||
|
||||
// Create window
|
||||
WNDCLASSEXW wcex;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = gfx_dxgi_wnd_proc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = nullptr;
|
||||
wcex.hIcon = nullptr;
|
||||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.lpszClassName = WINCLASS_NAME;
|
||||
wcex.hIconSm = nullptr;
|
||||
|
||||
ATOM winclass = RegisterClassExW(&wcex);
|
||||
|
||||
|
||||
run_as_dpi_aware([&] () {
|
||||
// We need to be dpi aware when calculating the size
|
||||
RECT wr = {0, 0, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT};
|
||||
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
|
||||
dxgi.h_wnd = CreateWindowW(WINCLASS_NAME, w_title, WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, 0, wr.right - wr.left, wr.bottom - wr.top, nullptr, nullptr, nullptr, nullptr);
|
||||
});
|
||||
|
||||
load_dxgi_library();
|
||||
|
||||
ShowWindow(dxgi.h_wnd, SW_SHOW);
|
||||
UpdateWindow(dxgi.h_wnd);
|
||||
|
||||
update_screen_settings();
|
||||
}
|
||||
|
||||
static void gfx_dxgi_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode), void (*on_all_keys_up)(void)) {
|
||||
dxgi.on_key_down = on_key_down;
|
||||
dxgi.on_key_up = on_key_up;
|
||||
dxgi.on_all_keys_up = on_all_keys_up;
|
||||
}
|
||||
|
||||
static void gfx_dxgi_main_loop(void (*run_one_game_iter)(void)) {
|
||||
dxgi.run_one_game_iter = run_one_game_iter;
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, nullptr, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_dxgi_get_dimensions(uint32_t *width, uint32_t *height) {
|
||||
*width = dxgi.current_width;
|
||||
*height = dxgi.current_height;
|
||||
}
|
||||
|
||||
static void gfx_dxgi_handle_events(void) {
|
||||
/*MSG msg;
|
||||
while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}*/
|
||||
}
|
||||
|
||||
static uint64_t qpc_to_us(uint64_t qpc) {
|
||||
return qpc / dxgi.qpc_freq * 1000000 + qpc % dxgi.qpc_freq * 1000000 / dxgi.qpc_freq;
|
||||
}
|
||||
|
||||
static bool gfx_dxgi_start_frame(void) {
|
||||
DXGI_FRAME_STATISTICS stats;
|
||||
if (dxgi.swap_chain->GetFrameStatistics(&stats) == S_OK && (stats.SyncRefreshCount != 0 || stats.SyncQPCTime.QuadPart != 0ULL)) {
|
||||
{
|
||||
LARGE_INTEGER t0;
|
||||
QueryPerformanceCounter(&t0);
|
||||
//printf("Get frame stats: %llu\n", (unsigned long long)(t0.QuadPart - dxgi.qpc_init));
|
||||
}
|
||||
//printf("stats: %u %u %u %u %u %.6f\n", dxgi.pending_frame_stats.rbegin()->first, dxgi.pending_frame_stats.rbegin()->second, stats.PresentCount, stats.PresentRefreshCount, stats.SyncRefreshCount, (double)(stats.SyncQPCTime.QuadPart - dxgi.qpc_init) / dxgi.qpc_freq);
|
||||
if (dxgi.frame_stats.empty() || dxgi.frame_stats.rbegin()->second.PresentCount != stats.PresentCount) {
|
||||
dxgi.frame_stats.insert(std::make_pair(stats.PresentCount, stats));
|
||||
}
|
||||
if (dxgi.frame_stats.size() > 3) {
|
||||
dxgi.frame_stats.erase(dxgi.frame_stats.begin());
|
||||
}
|
||||
}
|
||||
if (!dxgi.frame_stats.empty()) {
|
||||
while (!dxgi.pending_frame_stats.empty() && dxgi.pending_frame_stats.begin()->first < dxgi.frame_stats.rbegin()->first) {
|
||||
dxgi.pending_frame_stats.erase(dxgi.pending_frame_stats.begin());
|
||||
}
|
||||
}
|
||||
while (dxgi.pending_frame_stats.size() > 15) {
|
||||
// Just make sure the list doesn't grow too large if GetFrameStatistics fails.
|
||||
dxgi.pending_frame_stats.erase(dxgi.pending_frame_stats.begin());
|
||||
}
|
||||
|
||||
dxgi.frame_timestamp += FRAME_INTERVAL_US_NUMERATOR;
|
||||
|
||||
if (dxgi.frame_stats.size() >= 2) {
|
||||
DXGI_FRAME_STATISTICS *first = &dxgi.frame_stats.begin()->second;
|
||||
DXGI_FRAME_STATISTICS *last = &dxgi.frame_stats.rbegin()->second;
|
||||
uint64_t sync_qpc_diff = last->SyncQPCTime.QuadPart - first->SyncQPCTime.QuadPart;
|
||||
UINT sync_vsync_diff = last->SyncRefreshCount - first->SyncRefreshCount;
|
||||
UINT present_vsync_diff = last->PresentRefreshCount - first->PresentRefreshCount;
|
||||
UINT present_diff = last->PresentCount - first->PresentCount;
|
||||
|
||||
if (sync_vsync_diff == 0) {
|
||||
sync_vsync_diff = 1;
|
||||
}
|
||||
|
||||
double estimated_vsync_interval = (double)sync_qpc_diff / (double)sync_vsync_diff;
|
||||
uint64_t estimated_vsync_interval_us = qpc_to_us(estimated_vsync_interval);
|
||||
//printf("Estimated vsync_interval: %d\n", (int)estimated_vsync_interval_us);
|
||||
if (estimated_vsync_interval_us < 2 || estimated_vsync_interval_us > 1000000) {
|
||||
// Unreasonable, maybe a monitor change
|
||||
estimated_vsync_interval_us = 16666;
|
||||
estimated_vsync_interval = estimated_vsync_interval_us * dxgi.qpc_freq / 1000000;
|
||||
}
|
||||
|
||||
UINT queued_vsyncs = 0;
|
||||
bool is_first = true;
|
||||
for (const std::pair<UINT, UINT>& p : dxgi.pending_frame_stats) {
|
||||
if (is_first && dxgi.sync_interval_means_frames_to_wait) {
|
||||
is_first = false;
|
||||
continue;
|
||||
}
|
||||
queued_vsyncs += p.second;
|
||||
}
|
||||
|
||||
uint64_t last_frame_present_end_qpc = (last->SyncQPCTime.QuadPart - dxgi.qpc_init) + estimated_vsync_interval * queued_vsyncs;
|
||||
uint64_t last_end_us = qpc_to_us(last_frame_present_end_qpc);
|
||||
|
||||
double vsyncs_to_wait = (double)(int64_t)(dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR - last_end_us) / estimated_vsync_interval_us;
|
||||
//printf("ts: %llu, last_end_us: %llu, Init v: %f\n", dxgi.frame_timestamp / 3, last_end_us, vsyncs_to_wait);
|
||||
|
||||
if (vsyncs_to_wait <= 0) {
|
||||
// Too late
|
||||
|
||||
if ((int64_t)(dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR - last_end_us) < -66666) {
|
||||
// The application must have been paused or similar
|
||||
vsyncs_to_wait = round(((double)FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR) / estimated_vsync_interval_us);
|
||||
if (vsyncs_to_wait < 1) {
|
||||
vsyncs_to_wait = 1;
|
||||
}
|
||||
dxgi.frame_timestamp = FRAME_INTERVAL_US_DENOMINATOR * (last_end_us + vsyncs_to_wait * estimated_vsync_interval_us);
|
||||
} else {
|
||||
// Drop frame
|
||||
//printf("Dropping frame\n");
|
||||
dxgi.dropped_frame = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (floor(vsyncs_to_wait) != vsyncs_to_wait) {
|
||||
uint64_t left = last_end_us + floor(vsyncs_to_wait) * estimated_vsync_interval_us;
|
||||
uint64_t right = last_end_us + ceil(vsyncs_to_wait) * estimated_vsync_interval_us;
|
||||
uint64_t adjusted_desired_time = dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR + (last_end_us + (FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR) > dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR ? 2000 : -2000);
|
||||
int64_t diff_left = adjusted_desired_time - left;
|
||||
int64_t diff_right = right - adjusted_desired_time;
|
||||
if (diff_left < 0) {
|
||||
diff_left = -diff_left;
|
||||
}
|
||||
if (diff_right < 0) {
|
||||
diff_right = -diff_right;
|
||||
}
|
||||
if (diff_left < diff_right) {
|
||||
vsyncs_to_wait = floor(vsyncs_to_wait);
|
||||
} else {
|
||||
vsyncs_to_wait = ceil(vsyncs_to_wait);
|
||||
}
|
||||
if (vsyncs_to_wait == 0) {
|
||||
//printf("vsyncs_to_wait became 0 so dropping frame\n");
|
||||
dxgi.dropped_frame = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//printf("v: %d\n", (int)vsyncs_to_wait);
|
||||
if (vsyncs_to_wait > 4) {
|
||||
// Invalid, so change to 4
|
||||
vsyncs_to_wait = 4;
|
||||
}
|
||||
dxgi.length_in_vsync_frames = vsyncs_to_wait;
|
||||
} else {
|
||||
dxgi.length_in_vsync_frames = 2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gfx_dxgi_swap_buffers_begin(void) {
|
||||
//dxgi.length_in_vsync_frames = 1;
|
||||
ThrowIfFailed(dxgi.swap_chain->Present(dxgi.length_in_vsync_frames, 0));
|
||||
UINT this_present_id;
|
||||
if (dxgi.swap_chain->GetLastPresentCount(&this_present_id) == S_OK) {
|
||||
dxgi.pending_frame_stats.insert(std::make_pair(this_present_id, dxgi.length_in_vsync_frames));
|
||||
}
|
||||
dxgi.dropped_frame = false;
|
||||
}
|
||||
|
||||
static void gfx_dxgi_swap_buffers_end(void) {
|
||||
LARGE_INTEGER t0, t1, t2;
|
||||
QueryPerformanceCounter(&t0);
|
||||
QueryPerformanceCounter(&t1);
|
||||
|
||||
if (!dxgi.dropped_frame) {
|
||||
if (dxgi.waitable_object != nullptr) {
|
||||
WaitForSingleObject(dxgi.waitable_object, INFINITE);
|
||||
}
|
||||
// else TODO: maybe sleep until some estimated time the frame will be shown to reduce lag
|
||||
}
|
||||
|
||||
DXGI_FRAME_STATISTICS stats;
|
||||
dxgi.swap_chain->GetFrameStatistics(&stats);
|
||||
|
||||
QueryPerformanceCounter(&t2);
|
||||
|
||||
dxgi.sync_interval_means_frames_to_wait = dxgi.pending_frame_stats.rbegin()->first == stats.PresentCount;
|
||||
|
||||
//printf("done %llu gpu:%d wait:%d freed:%llu frame:%u %u monitor:%u t:%llu\n", (unsigned long long)(t0.QuadPart - dxgi.qpc_init), (int)(t1.QuadPart - t0.QuadPart), (int)(t2.QuadPart - t0.QuadPart), (unsigned long long)(t2.QuadPart - dxgi.qpc_init), dxgi.pending_frame_stats.rbegin()->first, stats.PresentCount, stats.SyncRefreshCount, (unsigned long long)(stats.SyncQPCTime.QuadPart - dxgi.qpc_init));
|
||||
}
|
||||
|
||||
static double gfx_dxgi_get_time(void) {
|
||||
LARGE_INTEGER t;
|
||||
QueryPerformanceCounter(&t);
|
||||
return (double)(t.QuadPart - dxgi.qpc_init) / dxgi.qpc_freq;
|
||||
}
|
||||
|
||||
void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only)) {
|
||||
if (dxgi.CreateDXGIFactory2 != nullptr) {
|
||||
ThrowIfFailed(dxgi.CreateDXGIFactory2(debug ? DXGI_CREATE_FACTORY_DEBUG : 0, __uuidof(IDXGIFactory2), &dxgi.factory));
|
||||
} else {
|
||||
ThrowIfFailed(dxgi.CreateDXGIFactory1(__uuidof(IDXGIFactory2), &dxgi.factory));
|
||||
}
|
||||
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
for (UINT i = 0; dxgi.factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; i++) {
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
adapter->GetDesc1(&desc);
|
||||
if (desc.Flags & 2/*DXGI_ADAPTER_FLAG_SOFTWARE*/) { // declaration missing in mingw headers
|
||||
continue;
|
||||
}
|
||||
if (create_device_fn(adapter.Get(), true)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
create_device_fn(adapter.Get(), false);
|
||||
|
||||
wchar_t w_title[512];
|
||||
int len = dxgi.window_title.length();
|
||||
mbstowcs(w_title, dxgi.window_title.c_str(), len + 1);
|
||||
SetWindowTextW(dxgi.h_wnd, w_title);
|
||||
}
|
||||
|
||||
ComPtr<IDXGISwapChain1> gfx_dxgi_create_swap_chain(IUnknown *device) {
|
||||
bool win8 = IsWindows8OrGreater(); // DXGI_SCALING_NONE is only supported on Win8 and beyond
|
||||
bool dxgi_13 = dxgi.CreateDXGIFactory2 != nullptr; // DXGI 1.3 introduced waitable object
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
|
||||
swap_chain_desc.BufferCount = 2;
|
||||
swap_chain_desc.Width = 0;
|
||||
swap_chain_desc.Height = 0;
|
||||
swap_chain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swap_chain_desc.Scaling = win8 ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH;
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // Apparently this was backported to Win 7 Platform Update
|
||||
swap_chain_desc.Flags = dxgi_13 ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
|
||||
run_as_dpi_aware([&] () {
|
||||
// When setting size for the buffers, the values that DXGI puts into the desc (that can later be retrieved by GetDesc1)
|
||||
// have been divided by the current scaling factor. By making this call dpi aware, no division will be performed.
|
||||
// The same goes for IDXGISwapChain::ResizeBuffers(), however that function is currently only called from the message handler.
|
||||
ThrowIfFailed(dxgi.factory->CreateSwapChainForHwnd(device, dxgi.h_wnd, &swap_chain_desc, nullptr, nullptr, &dxgi.swap_chain));
|
||||
});
|
||||
ThrowIfFailed(dxgi.factory->MakeWindowAssociation(dxgi.h_wnd, DXGI_MWA_NO_ALT_ENTER));
|
||||
|
||||
ComPtr<IDXGISwapChain2> swap_chain2;
|
||||
if (dxgi.swap_chain->QueryInterface(__uuidof(IDXGISwapChain2), &swap_chain2) == S_OK) {
|
||||
ThrowIfFailed(swap_chain2->SetMaximumFrameLatency(1));
|
||||
dxgi.waitable_object = swap_chain2->GetFrameLatencyWaitableObject();
|
||||
WaitForSingleObject(dxgi.waitable_object, INFINITE);
|
||||
} else {
|
||||
ComPtr<IDXGIDevice1> device1;
|
||||
ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&device1)));
|
||||
ThrowIfFailed(device1->SetMaximumFrameLatency(1));
|
||||
}
|
||||
|
||||
ThrowIfFailed(dxgi.swap_chain->GetDesc1(&swap_chain_desc));
|
||||
dxgi.current_width = swap_chain_desc.Width;
|
||||
dxgi.current_height = swap_chain_desc.Height;
|
||||
|
||||
return dxgi.swap_chain;
|
||||
}
|
||||
|
||||
HWND gfx_dxgi_get_h_wnd(void) {
|
||||
return dxgi.h_wnd;
|
||||
}
|
||||
|
||||
void gfx_dxgi_shutdown(void) {
|
||||
}
|
||||
|
||||
void ThrowIfFailed(HRESULT res) {
|
||||
if (FAILED(res)) {
|
||||
fprintf(stderr, "Error: 0x%08X\n", res);
|
||||
throw res;
|
||||
}
|
||||
}
|
||||
|
||||
void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message) {
|
||||
if (FAILED(res)) {
|
||||
char full_message[256];
|
||||
sprintf(full_message, "%s\n\nHRESULT: 0x%08X", message, res);
|
||||
dxgi.showing_error = true;
|
||||
MessageBox(h_wnd, full_message, "Error", MB_OK | MB_ICONERROR);
|
||||
throw res;
|
||||
}
|
||||
}
|
||||
|
||||
struct GfxWindowManagerAPI gfx_dxgi = {
|
||||
gfx_dxgi_init,
|
||||
gfx_dxgi_set_keyboard_callbacks,
|
||||
gfx_dxgi_main_loop,
|
||||
gfx_dxgi_get_dimensions,
|
||||
gfx_dxgi_handle_events,
|
||||
gfx_dxgi_start_frame,
|
||||
gfx_dxgi_swap_buffers_begin,
|
||||
gfx_dxgi_swap_buffers_end,
|
||||
gfx_dxgi_get_time,
|
||||
gfx_dxgi_shutdown,
|
||||
};
|
||||
|
||||
#endif
|
16
src/pc/gfx/gfx_dxgi.h
Normal file
16
src/pc/gfx/gfx_dxgi.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef GFX_DXGI_H
|
||||
#define GFX_DXGI_H
|
||||
|
||||
#include "gfx_rendering_api.h"
|
||||
|
||||
#ifdef DECLARE_GFX_DXGI_FUNCTIONS
|
||||
void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only));
|
||||
Microsoft::WRL::ComPtr<IDXGISwapChain1> gfx_dxgi_create_swap_chain(IUnknown *device);
|
||||
HWND gfx_dxgi_get_h_wnd(void);
|
||||
void ThrowIfFailed(HRESULT res);
|
||||
void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message);
|
||||
#endif
|
||||
|
||||
extern struct GfxWindowManagerAPI gfx_dxgi;
|
||||
|
||||
#endif
|
|
@ -634,6 +634,9 @@ static void gfx_opengl_init(void) {
|
|||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
static void gfx_opengl_on_resize(void) {
|
||||
}
|
||||
|
||||
static void gfx_opengl_start_frame(void) {
|
||||
frame_count++;
|
||||
|
||||
|
@ -644,6 +647,12 @@ static void gfx_opengl_start_frame(void) {
|
|||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
static void gfx_opengl_end_frame(void) {
|
||||
}
|
||||
|
||||
static void gfx_opengl_finish_render(void) {
|
||||
}
|
||||
|
||||
static void gfx_opengl_shutdown(void) {
|
||||
}
|
||||
|
||||
|
@ -666,7 +675,10 @@ struct GfxRenderingAPI gfx_opengl_api = {
|
|||
gfx_opengl_set_use_alpha,
|
||||
gfx_opengl_draw_triangles,
|
||||
gfx_opengl_init,
|
||||
gfx_opengl_on_resize,
|
||||
gfx_opengl_start_frame,
|
||||
gfx_opengl_end_frame,
|
||||
gfx_opengl_finish_render,
|
||||
gfx_opengl_shutdown
|
||||
};
|
||||
|
||||
|
|
|
@ -569,6 +569,9 @@ static void gfx_opengl_init(void) {
|
|||
TEXENV_COMBINE_OP(1, GL_SRC_COLOR, GL_SRC_ALPHA);
|
||||
}
|
||||
|
||||
static void gfx_opengl_on_resize(void) {
|
||||
}
|
||||
|
||||
static void gfx_opengl_start_frame(void) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDepthMask(GL_TRUE); // Must be set to clear Z-buffer
|
||||
|
@ -577,6 +580,15 @@ static void gfx_opengl_start_frame(void) {
|
|||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
static void gfx_opengl_end_frame(void) {
|
||||
}
|
||||
|
||||
static void gfx_opengl_finish_render(void) {
|
||||
}
|
||||
|
||||
static void gfx_opengl_shutdown(void) {
|
||||
}
|
||||
|
||||
static void gfx_opengl_shutdown(void) {
|
||||
}
|
||||
|
||||
|
@ -599,7 +611,10 @@ struct GfxRenderingAPI gfx_opengl_api = {
|
|||
gfx_opengl_set_use_alpha,
|
||||
gfx_opengl_draw_triangles,
|
||||
gfx_opengl_init,
|
||||
gfx_opengl_on_resize,
|
||||
gfx_opengl_start_frame,
|
||||
gfx_opengl_end_frame,
|
||||
gfx_opengl_finish_render,
|
||||
gfx_opengl_shutdown
|
||||
};
|
||||
|
||||
|
|
|
@ -778,16 +778,10 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
calculate_normal_dir(&lookat_y, rsp.current_lookat_coeffs[1]);
|
||||
rsp.lights_changed = false;
|
||||
}
|
||||
|
||||
// Inspired by:
|
||||
// https://github.com/gonetz/GLideN64/commit/c8cbafff71a81bee5112aaafe6e21d6648ff8125#diff-69d8715ec7f9fd627ec4f5516edd003dL484
|
||||
const bool useFirstColor = (dest_index & 1) == 0;
|
||||
const unsigned char* col = useFirstColor
|
||||
? rsp.current_lights[rsp.current_num_lights - 1].col
|
||||
: rsp.current_lights[rsp.current_num_lights - 1].colc;
|
||||
int r = col[0];
|
||||
int g = col[1];
|
||||
int b = col[2];
|
||||
|
||||
int r = rsp.current_lights[rsp.current_num_lights - 1].col[0];
|
||||
int g = rsp.current_lights[rsp.current_num_lights - 1].col[1];
|
||||
int b = rsp.current_lights[rsp.current_num_lights - 1].col[2];
|
||||
|
||||
for (int i = 0; i < rsp.current_num_lights - 1; i++) {
|
||||
float intensity = 0;
|
||||
|
@ -796,14 +790,9 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
intensity += vn->n[2] * rsp.current_lights_coeffs[i][2];
|
||||
intensity /= 127.0f;
|
||||
if (intensity > 0.0f) {
|
||||
// Inspired by:
|
||||
// https://github.com/gonetz/GLideN64/commit/c8cbafff71a81bee5112aaafe6e21d6648ff8125#diff-69d8715ec7f9fd627ec4f5516edd003dL492
|
||||
col = useFirstColor
|
||||
? rsp.current_lights[i].col
|
||||
: rsp.current_lights[i].colc;
|
||||
r += intensity * col[0];
|
||||
g += intensity * col[1];
|
||||
b += intensity * col[2];
|
||||
r += intensity * rsp.current_lights[i].col[0];
|
||||
g += intensity * rsp.current_lights[i].col[1];
|
||||
b += intensity * rsp.current_lights[i].col[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1777,6 +1766,10 @@ void gfx_precache_textures(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
struct GfxRenderingAPI *gfx_get_current_rendering_api(void) {
|
||||
return gfx_rapi;
|
||||
}
|
||||
|
||||
void gfx_start_frame(void) {
|
||||
gfx_wapi->handle_events();
|
||||
gfx_wapi->get_dimensions(&gfx_current_dimensions.width, &gfx_current_dimensions.height);
|
||||
|
@ -1804,11 +1797,13 @@ void gfx_run(Gfx *commands) {
|
|||
gfx_flush();
|
||||
double t1 = gfx_wapi->get_time();
|
||||
//printf("Process %f %f\n", t1, t1 - t0);
|
||||
gfx_rapi->end_frame();
|
||||
gfx_wapi->swap_buffers_begin();
|
||||
}
|
||||
|
||||
void gfx_end_frame(void) {
|
||||
if (!dropped_frame) {
|
||||
gfx_rapi->finish_render();
|
||||
gfx_wapi->swap_buffers_end();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,20 @@ struct GfxDimensions {
|
|||
|
||||
extern struct GfxDimensions gfx_current_dimensions;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, const char *window_title);
|
||||
struct GfxRenderingAPI *gfx_get_current_rendering_api(void);
|
||||
void gfx_start_frame(void);
|
||||
void gfx_run(Gfx *commands);
|
||||
void gfx_end_frame(void);
|
||||
void gfx_precache_textures(void);
|
||||
void gfx_shutdown(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,7 @@ struct GfxRenderingAPI {
|
|||
void (*shader_get_info)(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]);
|
||||
uint32_t (*new_texture)(void);
|
||||
void (*select_texture)(int tile, uint32_t texture_id);
|
||||
void (*upload_texture)(uint8_t *rgba32_buf, int width, int height);
|
||||
void (*upload_texture)(const uint8_t *rgba32_buf, int width, int height);
|
||||
void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt);
|
||||
void (*set_depth_test)(bool depth_test);
|
||||
void (*set_depth_mask)(bool z_upd);
|
||||
|
@ -26,7 +26,10 @@ struct GfxRenderingAPI {
|
|||
void (*set_use_alpha)(bool use_alpha);
|
||||
void (*draw_triangles)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris);
|
||||
void (*init)(void);
|
||||
void (*on_resize)(void);
|
||||
void (*start_frame)(void);
|
||||
void (*end_frame)(void);
|
||||
void (*finish_render)(void);
|
||||
void (*shutdown)(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -12,9 +12,12 @@
|
|||
#include "audio/external.h"
|
||||
|
||||
#include "gfx/gfx_pc.h"
|
||||
|
||||
#include "gfx/gfx_opengl.h"
|
||||
#include "gfx/gfx_direct3d11.h"
|
||||
#include "gfx/gfx_direct3d12.h"
|
||||
|
||||
#include "gfx/gfx_dxgi.h"
|
||||
#include "gfx/gfx_sdl.h"
|
||||
|
||||
#include "audio/audio_api.h"
|
||||
|
@ -193,10 +196,10 @@ void main_func(void) {
|
|||
#endif
|
||||
|
||||
#if defined(RAPI_D3D11)
|
||||
rendering_api = &gfx_d3d11_api;
|
||||
rendering_api = &gfx_direct3d11_api;
|
||||
# define RAPI_NAME "DirectX 11"
|
||||
#elif defined(RAPI_D3D12)
|
||||
rendering_api = &gfx_d3d12_api;
|
||||
rendering_api = &gfx_direct3d12_api;
|
||||
# define RAPI_NAME "DirectX 12"
|
||||
#elif defined(RAPI_GL) || defined(RAPI_GL_LEGACY)
|
||||
rendering_api = &gfx_opengl_api;
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
#ifndef _PC_MAIN_H
|
||||
#define _PC_MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void game_deinit(void);
|
||||
void game_exit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _PC_MAIN_H
|
||||
|
|
Loading…
Reference in a new issue