Add support for programmable samplers in shaders
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "GPUPipelineStateDX11.h"
|
||||
#include "GPUTextureDX11.h"
|
||||
#include "GPUBufferDX11.h"
|
||||
#include "GPUSamplerDX11.h"
|
||||
#include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h"
|
||||
#include "Engine/Core/Math/Viewport.h"
|
||||
#include "Engine/Core/Math/Rectangle.h"
|
||||
@@ -384,6 +385,15 @@ void GPUContextDX11::BindIB(GPUBuffer* indexBuffer)
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextDX11::BindSampler(int32 slot, GPUSampler* sampler)
|
||||
{
|
||||
const auto samplerDX11 = sampler ? static_cast<GPUSamplerDX11*>(sampler)->SamplerState : nullptr;
|
||||
_context->VSSetSamplers(slot, 1, &samplerDX11);
|
||||
_context->DSSetSamplers(slot, 1, &samplerDX11);
|
||||
_context->PSSetSamplers(slot, 1, &samplerDX11);
|
||||
_context->CSSetSamplers(slot, 1, &samplerDX11);
|
||||
}
|
||||
|
||||
void GPUContextDX11::UpdateCB(GPUConstantBuffer* cb, const void* data)
|
||||
{
|
||||
ASSERT(data && cb);
|
||||
|
||||
@@ -122,6 +122,7 @@ public:
|
||||
void BindUA(int32 slot, GPUResourceView* view) override;
|
||||
void BindVB(const Span<GPUBuffer*>& vertexBuffers, const uint32* vertexBuffersOffsets = nullptr) override;
|
||||
void BindIB(GPUBuffer* indexBuffer) override;
|
||||
void BindSampler(int32 slot, GPUSampler* sampler) override;
|
||||
void UpdateCB(GPUConstantBuffer* cb, const void* data) override;
|
||||
void Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCountX, uint32 threadGroupCountY, uint32 threadGroupCountZ) override;
|
||||
void DispatchIndirect(GPUShaderProgramCS* shader, GPUBuffer* bufferForArgs, uint32 offsetForArgs) override;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "GPUTextureDX11.h"
|
||||
#include "GPUTimerQueryDX11.h"
|
||||
#include "GPUBufferDX11.h"
|
||||
#include "GPUSamplerDX11.h"
|
||||
#include "GPUSwapChainDX11.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Utilities.h"
|
||||
@@ -324,6 +325,7 @@ bool GPUDeviceDX11::Init()
|
||||
limits.MaximumTexture2DArraySize = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
|
||||
limits.MaximumTexture3DSize = D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
|
||||
limits.MaximumTextureCubeSize = D3D11_REQ_TEXTURECUBE_DIMENSION;
|
||||
limits.MaximumSamplerAnisotropy = D3D11_DEFAULT_MAX_ANISOTROPY;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -346,6 +348,7 @@ bool GPUDeviceDX11::Init()
|
||||
limits.MaximumTexture2DArraySize = D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
|
||||
limits.MaximumTexture3DSize = D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
|
||||
limits.MaximumTextureCubeSize = D3D10_REQ_TEXTURECUBE_DIMENSION;
|
||||
limits.MaximumSamplerAnisotropy = D3D10_DEFAULT_MAX_ANISOTROPY;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < static_cast<int32>(PixelFormat::MAX); i++)
|
||||
@@ -685,6 +688,11 @@ GPUBuffer* GPUDeviceDX11::CreateBuffer(const StringView& name)
|
||||
return New<GPUBufferDX11>(this, name);
|
||||
}
|
||||
|
||||
GPUSampler* GPUDeviceDX11::CreateSampler()
|
||||
{
|
||||
return New<GPUSamplerDX11>(this);
|
||||
}
|
||||
|
||||
GPUSwapChain* GPUDeviceDX11::CreateSwapChain(Window* window)
|
||||
{
|
||||
return New<GPUSwapChainDX11>(this, window);
|
||||
|
||||
@@ -99,6 +99,7 @@ public:
|
||||
GPUPipelineState* CreatePipelineState() override;
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
};
|
||||
|
||||
|
||||
128
Source/Engine/GraphicsDevice/DirectX/DX11/GPUSamplerDX11.cpp
Normal file
128
Source/Engine/GraphicsDevice/DirectX/DX11/GPUSamplerDX11.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#if GRAPHICS_API_DIRECTX11
|
||||
|
||||
#include "GPUSamplerDX11.h"
|
||||
|
||||
D3D11_TEXTURE_ADDRESS_MODE ToDX11(GPUSamplerAddressMode value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case GPUSamplerAddressMode::Wrap:
|
||||
return D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
case GPUSamplerAddressMode::Clamp:
|
||||
return D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
case GPUSamplerAddressMode::Mirror:
|
||||
return D3D11_TEXTURE_ADDRESS_MIRROR;
|
||||
case GPUSamplerAddressMode::Border:
|
||||
return D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
default:
|
||||
return (D3D11_TEXTURE_ADDRESS_MODE)-1;
|
||||
}
|
||||
}
|
||||
|
||||
bool GPUSamplerDX11::OnInit()
|
||||
{
|
||||
D3D11_SAMPLER_DESC samplerDesc;
|
||||
if (_desc.ComparisonFunction == GPUSamplerCompareFunction::Never)
|
||||
{
|
||||
switch (_desc.Filter)
|
||||
{
|
||||
case GPUSamplerFilter::Point:
|
||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
break;
|
||||
case GPUSamplerFilter::Bilinear:
|
||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
||||
break;
|
||||
case GPUSamplerFilter::Trilinear:
|
||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
break;
|
||||
case GPUSamplerFilter::Anisotropic:
|
||||
samplerDesc.Filter = D3D11_FILTER_ANISOTROPIC;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (_desc.Filter)
|
||||
{
|
||||
case GPUSamplerFilter::Point:
|
||||
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
|
||||
break;
|
||||
case GPUSamplerFilter::Bilinear:
|
||||
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT;
|
||||
break;
|
||||
case GPUSamplerFilter::Trilinear:
|
||||
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
|
||||
break;
|
||||
case GPUSamplerFilter::Anisotropic:
|
||||
samplerDesc.Filter = D3D11_FILTER_COMPARISON_ANISOTROPIC;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
samplerDesc.AddressU = ToDX11(_desc.AddressU);
|
||||
samplerDesc.AddressV = ToDX11(_desc.AddressV);
|
||||
samplerDesc.AddressW = ToDX11(_desc.AddressW);
|
||||
samplerDesc.MipLODBias = _desc.MipBias;
|
||||
samplerDesc.MaxAnisotropy = _desc.MaxAnisotropy;
|
||||
switch (_desc.ComparisonFunction)
|
||||
{
|
||||
case GPUSamplerCompareFunction::Never:
|
||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||
break;
|
||||
case GPUSamplerCompareFunction::Less:
|
||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
switch (_desc.BorderColor)
|
||||
{
|
||||
case GPUSamplerBorderColor::TransparentBlack:
|
||||
samplerDesc.BorderColor[0] = 0;
|
||||
samplerDesc.BorderColor[1] = 0;
|
||||
samplerDesc.BorderColor[2] = 0;
|
||||
samplerDesc.BorderColor[3] = 0;
|
||||
break;
|
||||
case GPUSamplerBorderColor::OpaqueBlack:
|
||||
samplerDesc.BorderColor[0] = 0;
|
||||
samplerDesc.BorderColor[1] = 0;
|
||||
samplerDesc.BorderColor[2] = 0;
|
||||
samplerDesc.BorderColor[3] = 1.0f;
|
||||
break;
|
||||
case GPUSamplerBorderColor::OpaqueWhite:
|
||||
samplerDesc.BorderColor[0] = 1.0f;
|
||||
samplerDesc.BorderColor[1] = 1.0f;
|
||||
samplerDesc.BorderColor[2] = 1.0f;
|
||||
samplerDesc.BorderColor[3] = 1.0f;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
samplerDesc.MinLOD = _desc.MinMipLevel;
|
||||
samplerDesc.MaxLOD = _desc.MaxMipLevel;
|
||||
HRESULT result = _device->GetDevice()->CreateSamplerState(&samplerDesc, &SamplerState);
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result);
|
||||
ASSERT(SamplerState != nullptr);
|
||||
_memoryUsage = sizeof(D3D11_SAMPLER_DESC);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GPUSamplerDX11::OnReleaseGPU()
|
||||
{
|
||||
if (SamplerState)
|
||||
{
|
||||
SamplerState->Release();
|
||||
SamplerState = nullptr;
|
||||
}
|
||||
|
||||
// Base
|
||||
GPUSampler::OnReleaseGPU();
|
||||
}
|
||||
|
||||
#endif
|
||||
31
Source/Engine/GraphicsDevice/DirectX/DX11/GPUSamplerDX11.h
Normal file
31
Source/Engine/GraphicsDevice/DirectX/DX11/GPUSamplerDX11.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Graphics/Textures/GPUSampler.h"
|
||||
#include "GPUDeviceDX11.h"
|
||||
|
||||
#if GRAPHICS_API_DIRECTX11
|
||||
|
||||
/// <summary>
|
||||
/// Sampler object for DirectX 11 backend.
|
||||
/// </summary>
|
||||
class GPUSamplerDX11 : public GPUResourceBase<GPUDeviceDX11, GPUSampler>
|
||||
{
|
||||
public:
|
||||
|
||||
GPUSamplerDX11(GPUDeviceDX11* device)
|
||||
: GPUResourceBase<GPUDeviceDX11, GPUSampler>(device, StringView::Empty)
|
||||
{
|
||||
}
|
||||
|
||||
ID3D11SamplerState* SamplerState = nullptr;
|
||||
|
||||
protected:
|
||||
|
||||
// [GPUSampler]
|
||||
bool OnInit() override;
|
||||
void OnReleaseGPU() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user