From a627ef3d6637ee994a580b6954cc67f8d60ba4ed Mon Sep 17 00:00:00 2001 From: Triang3l Date: Wed, 1 Aug 2018 18:15:17 +0300 Subject: [PATCH] [D3D12] Immediate drawer pixel shader and root signature --- src/xenia/ui/d3d12/d3d12_immediate_drawer.cc | 84 +++++++++++++++++++- src/xenia/ui/d3d12/d3d12_immediate_drawer.h | 12 ++- src/xenia/ui/d3d12/shaders/immediate.ps.hlsl | 16 ++++ src/xenia/ui/d3d12/shaders/immediate.vs.hlsl | 4 +- 4 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 src/xenia/ui/d3d12/shaders/immediate.ps.hlsl diff --git a/src/xenia/ui/d3d12/d3d12_immediate_drawer.cc b/src/xenia/ui/d3d12/d3d12_immediate_drawer.cc index 185a6dc54..fb663eea6 100644 --- a/src/xenia/ui/d3d12/d3d12_immediate_drawer.cc +++ b/src/xenia/ui/d3d12/d3d12_immediate_drawer.cc @@ -15,6 +15,10 @@ namespace xe { namespace ui { namespace d3d12 { +// Generated with `xb buildhlsl`. +#include "xenia/ui/d3d12/shaders/bin/immediate_ps.h" +#include "xenia/ui/d3d12/shaders/bin/immediate_vs.h" + class D3D12ImmediateTexture : public ImmediateTexture { public: D3D12ImmediateTexture(uint32_t width, uint32_t height) @@ -30,10 +34,83 @@ bool D3D12ImmediateDrawer::Initialize() { auto provider = context_->GetD3D12Provider(); auto device = provider->GetDevice(); + // Create the root signature. + D3D12_ROOT_PARAMETER root_parameters[size_t(RootParameter::kCount)]; + D3D12_DESCRIPTOR_RANGE descriptor_range_texture, descriptor_range_sampler; + { + auto& root_parameter = root_parameters[size_t(RootParameter::kTexture)]; + root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameter.DescriptorTable.NumDescriptorRanges = 1; + root_parameter.DescriptorTable.pDescriptorRanges = + &descriptor_range_texture; + descriptor_range_texture.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + descriptor_range_texture.NumDescriptors = 1; + descriptor_range_texture.BaseShaderRegister = 0; + descriptor_range_texture.RegisterSpace = 0; + descriptor_range_texture.OffsetInDescriptorsFromTableStart = 0; + root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + { + auto& root_parameter = root_parameters[size_t(RootParameter::kSampler)]; + root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameter.DescriptorTable.NumDescriptorRanges = 1; + root_parameter.DescriptorTable.pDescriptorRanges = + &descriptor_range_sampler; + descriptor_range_sampler.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + descriptor_range_sampler.NumDescriptors = 1; + descriptor_range_sampler.BaseShaderRegister = 0; + descriptor_range_sampler.RegisterSpace = 0; + descriptor_range_sampler.OffsetInDescriptorsFromTableStart = 0; + root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + { + auto& root_parameter = + root_parameters[size_t(RootParameter::kRestrictTextureSamples)]; + root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + root_parameter.Constants.ShaderRegister = 0; + root_parameter.Constants.RegisterSpace = 0; + root_parameter.Constants.Num32BitValues = 1; + root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + } + { + auto& root_parameter = + root_parameters[size_t(RootParameter::kViewportInvSize)]; + root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + root_parameter.Constants.ShaderRegister = 0; + root_parameter.Constants.RegisterSpace = 0; + root_parameter.Constants.Num32BitValues = 2; + root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + } + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + root_signature_desc.NumParameters = UINT(RootParameter::kCount); + root_signature_desc.pParameters = root_parameters; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = nullptr; + root_signature_desc.Flags = + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + ID3DBlob* root_signature_blob; + if (FAILED(D3D12SerializeRootSignature(&root_signature_desc, + D3D_ROOT_SIGNATURE_VERSION_1, + &root_signature_blob, nullptr))) { + XELOGE("Failed to serialize immediate drawer root signature"); + Shutdown(); + return false; + } + if (FAILED(device->CreateRootSignature( + 0, root_signature_blob->GetBufferPointer(), + root_signature_blob->GetBufferSize(), + IID_PPV_ARGS(&root_signature_)))) { + XELOGE("Failed to create immediate drawer root signature"); + root_signature_blob->Release(); + Shutdown(); + return false; + } + root_signature_blob->Release(); + // Create the samplers. D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_desc; sampler_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - sampler_heap_desc.NumDescriptors = uint32_t(SamplerIndex::kSamplerCount); + sampler_heap_desc.NumDescriptors = UINT(SamplerIndex::kCount); sampler_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; sampler_heap_desc.NodeMask = 0; if (FAILED(device->CreateDescriptorHeap(&sampler_heap_desc, @@ -99,6 +176,11 @@ void D3D12ImmediateDrawer::Shutdown() { sampler_heap_->Release(); sampler_heap_ = nullptr; } + + if (root_signature_ != nullptr) { + root_signature_->Release(); + root_signature_ = nullptr; + } } std::unique_ptr D3D12ImmediateDrawer::CreateTexture( diff --git a/src/xenia/ui/d3d12/d3d12_immediate_drawer.h b/src/xenia/ui/d3d12/d3d12_immediate_drawer.h index 39b4b4e15..6fc81007c 100644 --- a/src/xenia/ui/d3d12/d3d12_immediate_drawer.h +++ b/src/xenia/ui/d3d12/d3d12_immediate_drawer.h @@ -46,13 +46,23 @@ class D3D12ImmediateDrawer : public ImmediateDrawer { private: D3D12Context* context_ = nullptr; + ID3D12RootSignature* root_signature_ = nullptr; + enum class RootParameter { + kTexture, + kSampler, + kRestrictTextureSamples, + kViewportInvSize, + + kCount + }; + enum class SamplerIndex { kNearestClamp, kLinearClamp, kNearestRepeat, kLinearRepeat, - kSamplerCount + kCount }; ID3D12DescriptorHeap* sampler_heap_ = nullptr; D3D12_CPU_DESCRIPTOR_HANDLE sampler_heap_cpu_start_; diff --git a/src/xenia/ui/d3d12/shaders/immediate.ps.hlsl b/src/xenia/ui/d3d12/shaders/immediate.ps.hlsl new file mode 100644 index 000000000..6a0cd8566 --- /dev/null +++ b/src/xenia/ui/d3d12/shaders/immediate.ps.hlsl @@ -0,0 +1,16 @@ +Texture2D immediate_texture : register(t0); +SamplerState immediate_sampler : register(s0); +bool restrict_texture_samples : register(b0); + +struct ps_input { + float2 uv : TEXCOORD0; + float4 color : TEXCOORD1; +}; + +float4 main(ps_input input) : SV_Target { + float4 output = input.color; + if (!restrict_texture_samples || input.uv.x <= 1.0) { + output *= immediate_texture.Sample(immediate_sampler, input.uv); + } + return output; +} diff --git a/src/xenia/ui/d3d12/shaders/immediate.vs.hlsl b/src/xenia/ui/d3d12/shaders/immediate.vs.hlsl index afc3f6d1b..75f823464 100644 --- a/src/xenia/ui/d3d12/shaders/immediate.vs.hlsl +++ b/src/xenia/ui/d3d12/shaders/immediate.vs.hlsl @@ -1,4 +1,4 @@ -float2 scale : register(b0); +float2 viewport_inv_size : register(b0); struct vs_input { float2 pos : POSITION; @@ -14,7 +14,7 @@ struct vs_output { vs_output main(vs_input input) { vs_output output; - output.pos = float4(scale * input.pos, 0.0, 1.0); + output.pos = float4(viewport_inv_size * input.pos, 0.0, 1.0); output.uv = input.uv; output.color = input.color; return output;