Fix RHI texture binding and add pure quad test
This commit is contained in:
@@ -142,6 +142,7 @@ inline DXGI_FORMAT ToD3D12(Format format) {
|
||||
case Format::R32G32B32A32_Float: return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
case Format::R16_Float: return DXGI_FORMAT_R16_FLOAT;
|
||||
case Format::R32_Float: return DXGI_FORMAT_R32_FLOAT;
|
||||
case Format::R32G32_Float: return DXGI_FORMAT_R32G32_FLOAT;
|
||||
case Format::D16_UNorm: return DXGI_FORMAT_D16_UNORM;
|
||||
case Format::D24_UNorm_S8_UInt: return DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
case Format::D32_Float: return DXGI_FORMAT_D32_FLOAT;
|
||||
@@ -168,6 +169,7 @@ inline Format FromD3D12(DXGI_FORMAT format) {
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT: return Format::R32G32B32A32_Float;
|
||||
case DXGI_FORMAT_R16_FLOAT: return Format::R16_Float;
|
||||
case DXGI_FORMAT_R32_FLOAT: return Format::R32_Float;
|
||||
case DXGI_FORMAT_R32G32_FLOAT: return Format::R32G32_Float;
|
||||
case DXGI_FORMAT_D16_UNORM: return Format::D16_UNorm;
|
||||
case DXGI_FORMAT_D24_UNORM_S8_UINT: return Format::D24_UNorm_S8_UInt;
|
||||
case DXGI_FORMAT_D32_FLOAT: return Format::D32_Float;
|
||||
@@ -319,4 +321,4 @@ inline D3D12_COMMAND_LIST_TYPE ToD3D12(CommandQueueType type) {
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
} // namespace XCEngine
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "../RHIPipelineLayout.h"
|
||||
#include "D3D12RootSignature.h"
|
||||
@@ -36,7 +37,8 @@ private:
|
||||
D3D12Device* m_device;
|
||||
std::unordered_map<uint32_t, uint32_t> m_registerToRootIndex;
|
||||
std::vector<D3D12_ROOT_PARAMETER> m_rootParameters;
|
||||
std::vector<D3D12_DESCRIPTOR_RANGE> m_descriptorRanges;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
} // namespace XCEngine
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
bool Initialize(ID3D12Device* device, const D3D12_SAMPLER_DESC& desc);
|
||||
void Shutdown() override;
|
||||
|
||||
D3D12_SAMPLER_DESC GetDesc() const { return m_desc; }
|
||||
const D3D12_SAMPLER_DESC& GetDesc() const { return m_desc; }
|
||||
|
||||
void* GetNativeHandle() override { return &m_desc; }
|
||||
unsigned int GetID() override { return m_id; }
|
||||
|
||||
@@ -20,7 +20,8 @@ public:
|
||||
bool Initialize(ID3D12Device* device, const D3D12_RESOURCE_DESC& desc, D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON);
|
||||
bool InitializeFromExisting(ID3D12Resource* resource, bool ownsResource = false);
|
||||
bool InitializeFromData(ID3D12Device* device, ID3D12GraphicsCommandList* commandList,
|
||||
const void* pixelData, uint32_t width, uint32_t height, DXGI_FORMAT format, uint32_t rowPitch = 0);
|
||||
const void* pixelData, uint32_t width, uint32_t height, DXGI_FORMAT format, uint32_t rowPitch = 0,
|
||||
ComPtr<ID3D12Resource>* uploadBuffer = nullptr);
|
||||
bool InitializeDepthStencil(ID3D12Device* device, uint32_t width, uint32_t height, DXGI_FORMAT format = DXGI_FORMAT_D24_UNORM_S8_UINT);
|
||||
void Shutdown() override;
|
||||
|
||||
|
||||
@@ -126,6 +126,9 @@ inline void ToOpenGLFormat(OpenGLFormat fmt, GLint& internalFormat, GLenum& glFo
|
||||
case OpenGLFormat::RG8:
|
||||
internalFormat = GL_RG8; glFormat = GL_RG; glType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case OpenGLFormat::RG32F:
|
||||
internalFormat = GL_RG32F; glFormat = GL_RG; glType = GL_FLOAT;
|
||||
break;
|
||||
case OpenGLFormat::RGBA8:
|
||||
internalFormat = GL_RGBA8; glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
@@ -20,6 +20,7 @@ enum class OpenGLTextureType {
|
||||
enum class OpenGLFormat {
|
||||
R8,
|
||||
RG8,
|
||||
RG32F,
|
||||
RGBA8,
|
||||
RGBA16F,
|
||||
RGBA32F,
|
||||
@@ -32,6 +33,7 @@ enum class OpenGLFormat {
|
||||
enum class OpenGLInternalFormat {
|
||||
R8 = 1,
|
||||
RG8 = 2,
|
||||
RG32F = 13,
|
||||
RGBA8 = 4,
|
||||
RGBA16F = 11,
|
||||
RGBA32F = 16,
|
||||
|
||||
@@ -314,7 +314,8 @@ enum class Format : uint32_t {
|
||||
BC6H_UF16,
|
||||
BC7_UNorm,
|
||||
R32G32B32A32_UInt,
|
||||
R32_UInt
|
||||
R32_UInt,
|
||||
R32G32_Float
|
||||
};
|
||||
|
||||
enum class ResourceStates : uint32_t {
|
||||
|
||||
@@ -37,6 +37,7 @@ bool D3D12DescriptorHeap::Initialize(ID3D12Device* device, DescriptorHeapType ty
|
||||
return false;
|
||||
}
|
||||
|
||||
m_device = device;
|
||||
m_type = type;
|
||||
m_numDescriptors = numDescriptors;
|
||||
m_shaderVisible = shaderVisible;
|
||||
@@ -47,6 +48,7 @@ bool D3D12DescriptorHeap::Initialize(ID3D12Device* device, DescriptorHeapType ty
|
||||
}
|
||||
|
||||
void D3D12DescriptorHeap::Shutdown() {
|
||||
m_device.Reset();
|
||||
m_descriptorHeap.Reset();
|
||||
m_allocatedSets.clear();
|
||||
m_numDescriptors = 0;
|
||||
|
||||
@@ -74,6 +74,8 @@ uint32_t GetFormatBytesPerPixel(Format format) {
|
||||
return 8;
|
||||
case Format::R32_Float:
|
||||
return 4;
|
||||
case Format::R32G32_Float:
|
||||
return 8;
|
||||
case Format::R32G32B32A32_Float:
|
||||
return 16;
|
||||
default:
|
||||
@@ -390,6 +392,7 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc, const void* init
|
||||
uploadCommandList.Reset();
|
||||
|
||||
auto* texture = new D3D12Texture();
|
||||
ComPtr<ID3D12Resource> uploadBuffer;
|
||||
if (!texture->InitializeFromData(
|
||||
m_device.Get(),
|
||||
uploadCommandList.GetCommandList(),
|
||||
@@ -397,7 +400,8 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc, const void* init
|
||||
desc.width,
|
||||
desc.height,
|
||||
ToD3D12(format),
|
||||
resolvedRowPitch)) {
|
||||
resolvedRowPitch,
|
||||
&uploadBuffer)) {
|
||||
delete texture;
|
||||
uploadCommandList.Shutdown();
|
||||
uploadAllocator.Shutdown();
|
||||
@@ -411,6 +415,7 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc, const void* init
|
||||
ID3D12CommandList* commandLists[] = { uploadCommandList.GetCommandList() };
|
||||
uploadQueue.ExecuteCommandListsInternal(1, commandLists);
|
||||
uploadQueue.WaitForIdle();
|
||||
uploadBuffer.Reset();
|
||||
|
||||
uploadCommandList.Shutdown();
|
||||
uploadAllocator.Shutdown();
|
||||
@@ -442,13 +447,13 @@ RHIShader* D3D12Device::CreateShader(const ShaderCompileDesc& desc) {
|
||||
RHISampler* D3D12Device::CreateSampler(const SamplerDesc& desc) {
|
||||
auto* sampler = new D3D12Sampler();
|
||||
D3D12_SAMPLER_DESC d3d12Desc = {};
|
||||
d3d12Desc.Filter = static_cast<D3D12_FILTER>(desc.filter);
|
||||
d3d12Desc.AddressU = static_cast<D3D12_TEXTURE_ADDRESS_MODE>(desc.addressU);
|
||||
d3d12Desc.AddressV = static_cast<D3D12_TEXTURE_ADDRESS_MODE>(desc.addressV);
|
||||
d3d12Desc.AddressW = static_cast<D3D12_TEXTURE_ADDRESS_MODE>(desc.addressW);
|
||||
d3d12Desc.Filter = ToD3D12(static_cast<FilterMode>(desc.filter));
|
||||
d3d12Desc.AddressU = ToD3D12(static_cast<TextureAddressMode>(desc.addressU));
|
||||
d3d12Desc.AddressV = ToD3D12(static_cast<TextureAddressMode>(desc.addressV));
|
||||
d3d12Desc.AddressW = ToD3D12(static_cast<TextureAddressMode>(desc.addressW));
|
||||
d3d12Desc.MipLODBias = desc.mipLodBias;
|
||||
d3d12Desc.MaxAnisotropy = desc.maxAnisotropy;
|
||||
d3d12Desc.ComparisonFunc = static_cast<D3D12_COMPARISON_FUNC>(desc.comparisonFunc);
|
||||
d3d12Desc.ComparisonFunc = ToD3D12(static_cast<ComparisonFunc>(desc.comparisonFunc));
|
||||
d3d12Desc.BorderColor[0] = desc.borderColorR;
|
||||
d3d12Desc.BorderColor[1] = desc.borderColorG;
|
||||
d3d12Desc.BorderColor[2] = desc.borderColorB;
|
||||
@@ -735,7 +740,7 @@ RHIResourceView* D3D12Device::CreateShaderResourceView(RHITexture* texture, cons
|
||||
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
|
||||
auto heap = std::make_unique<D3D12DescriptorHeap>();
|
||||
if (!heap->Initialize(m_device.Get(), DescriptorHeapType::CBV_SRV_UAV, 1, true)) {
|
||||
if (!heap->Initialize(m_device.Get(), DescriptorHeapType::CBV_SRV_UAV, 1, false)) {
|
||||
delete view;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -756,7 +761,7 @@ RHIResourceView* D3D12Device::CreateUnorderedAccessView(RHITexture* texture, con
|
||||
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
|
||||
|
||||
auto heap = std::make_unique<D3D12DescriptorHeap>();
|
||||
if (!heap->Initialize(m_device.Get(), DescriptorHeapType::CBV_SRV_UAV, 1, true)) {
|
||||
if (!heap->Initialize(m_device.Get(), DescriptorHeapType::CBV_SRV_UAV, 1, false)) {
|
||||
delete view;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,20 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
||||
m_device = device;
|
||||
|
||||
m_rootParameters.clear();
|
||||
m_descriptorRanges.clear();
|
||||
m_registerToRootIndex.clear();
|
||||
|
||||
const uint32_t rootParameterCount =
|
||||
(desc.constantBufferCount > 0 ? 1u : 0u) +
|
||||
(desc.textureCount > 0 ? 1u : 0u) +
|
||||
(desc.samplerCount > 0 ? 1u : 0u);
|
||||
const uint32_t descriptorRangeCount =
|
||||
(desc.textureCount > 0 ? 1u : 0u) +
|
||||
(desc.samplerCount > 0 ? 1u : 0u);
|
||||
|
||||
m_rootParameters.reserve(rootParameterCount);
|
||||
m_descriptorRanges.reserve(descriptorRangeCount);
|
||||
|
||||
uint32_t rootIndex = 0;
|
||||
|
||||
if (desc.constantBufferCount > 0) {
|
||||
@@ -39,9 +51,10 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
||||
}
|
||||
|
||||
if (desc.textureCount > 0) {
|
||||
D3D12_DESCRIPTOR_RANGE range = D3D12RootSignature::CreateDescriptorRange(
|
||||
D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, desc.textureCount, 0);
|
||||
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(1, &range, ShaderVisibility::All);
|
||||
m_descriptorRanges.push_back(D3D12RootSignature::CreateDescriptorRange(
|
||||
D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, desc.textureCount, 0));
|
||||
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(
|
||||
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
||||
m_rootParameters.push_back(param);
|
||||
for (uint32_t i = 0; i < desc.textureCount; ++i) {
|
||||
m_registerToRootIndex[100 + i] = rootIndex;
|
||||
@@ -50,9 +63,10 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
||||
}
|
||||
|
||||
if (desc.samplerCount > 0) {
|
||||
D3D12_DESCRIPTOR_RANGE range = D3D12RootSignature::CreateDescriptorRange(
|
||||
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 0, desc.samplerCount, 0);
|
||||
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(1, &range, ShaderVisibility::All);
|
||||
m_descriptorRanges.push_back(D3D12RootSignature::CreateDescriptorRange(
|
||||
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 0, desc.samplerCount, 0));
|
||||
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(
|
||||
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
||||
m_rootParameters.push_back(param);
|
||||
for (uint32_t i = 0; i < desc.samplerCount; ++i) {
|
||||
m_registerToRootIndex[200 + i] = rootIndex;
|
||||
@@ -99,6 +113,7 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
||||
void D3D12PipelineLayout::Shutdown() {
|
||||
m_rootSignature.Reset();
|
||||
m_rootParameters.clear();
|
||||
m_descriptorRanges.clear();
|
||||
m_registerToRootIndex.clear();
|
||||
m_device = nullptr;
|
||||
}
|
||||
@@ -116,4 +131,4 @@ bool D3D12PipelineLayout::HasRootParameter(uint32_t shaderRegister) const {
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
} // namespace XCEngine
|
||||
|
||||
@@ -44,7 +44,8 @@ bool D3D12Texture::InitializeFromExisting(ID3D12Resource* resource, bool ownsRes
|
||||
}
|
||||
|
||||
bool D3D12Texture::InitializeFromData(ID3D12Device* device, ID3D12GraphicsCommandList* commandList,
|
||||
const void* pixelData, uint32_t width, uint32_t height, DXGI_FORMAT format, uint32_t rowPitch) {
|
||||
const void* pixelData, uint32_t width, uint32_t height, DXGI_FORMAT format, uint32_t rowPitch,
|
||||
ComPtr<ID3D12Resource>* uploadBuffer) {
|
||||
|
||||
D3D12_RESOURCE_DESC textureDesc = {};
|
||||
textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
@@ -84,7 +85,7 @@ bool D3D12Texture::InitializeFromData(ID3D12Device* device, ID3D12GraphicsComman
|
||||
device->GetCopyableFootprints(&textureDesc, 0, 1, 0,
|
||||
&subresourceFootprint, &rowUsed, &rowSizeInBytes, &memorySizeUsed);
|
||||
|
||||
ID3D12Resource* tempBufferObject = nullptr;
|
||||
ComPtr<ID3D12Resource> tempBufferObject;
|
||||
D3D12_HEAP_PROPERTIES d3dTempHeapProperties = {};
|
||||
d3dTempHeapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
|
||||
@@ -107,7 +108,7 @@ bool D3D12Texture::InitializeFromData(ID3D12Device* device, ID3D12GraphicsComman
|
||||
&d3d12TempResourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&tempBufferObject)
|
||||
IID_PPV_ARGS(tempBufferObject.GetAddressOf())
|
||||
);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
@@ -130,7 +131,7 @@ bool D3D12Texture::InitializeFromData(ID3D12Device* device, ID3D12GraphicsComman
|
||||
dst.SubresourceIndex = 0;
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION src = {};
|
||||
src.pResource = tempBufferObject;
|
||||
src.pResource = tempBufferObject.Get();
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
src.PlacedFootprint = subresourceFootprint;
|
||||
commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
|
||||
@@ -145,7 +146,9 @@ bool D3D12Texture::InitializeFromData(ID3D12Device* device, ID3D12GraphicsComman
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
m_state = ResourceStates::PixelShaderResource;
|
||||
|
||||
tempBufferObject->Release();
|
||||
if (uploadBuffer != nullptr) {
|
||||
*uploadBuffer = tempBufferObject;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ bool GetOpenGLVertexAttribFormat(Format format, OpenGLVertexAttribFormat& attrib
|
||||
case Format::R32_Float:
|
||||
attributeFormat = { 1, GL_FLOAT, GL_FALSE, false };
|
||||
return true;
|
||||
case Format::R32G32_Float:
|
||||
attributeFormat = { 2, GL_FLOAT, GL_FALSE, false };
|
||||
return true;
|
||||
case Format::R32G32B32A32_Float:
|
||||
attributeFormat = { 4, GL_FLOAT, GL_FALSE, false };
|
||||
return true;
|
||||
|
||||
@@ -61,6 +61,29 @@ std::string SourceToString(const ShaderCompileDesc& desc) {
|
||||
return std::string(reinterpret_cast<const char*>(desc.source.data()), desc.source.size());
|
||||
}
|
||||
|
||||
OpenGLFormat ToOpenGLTextureFormat(Format format) {
|
||||
switch (format) {
|
||||
case Format::R8_UNorm:
|
||||
return OpenGLFormat::R8;
|
||||
case Format::R8G8_UNorm:
|
||||
return OpenGLFormat::RG8;
|
||||
case Format::R32G32_Float:
|
||||
return OpenGLFormat::RG32F;
|
||||
case Format::R8G8B8A8_UNorm:
|
||||
return OpenGLFormat::RGBA8;
|
||||
case Format::R16G16B16A16_Float:
|
||||
return OpenGLFormat::RGBA16F;
|
||||
case Format::R32G32B32A32_Float:
|
||||
return OpenGLFormat::RGBA32F;
|
||||
case Format::D24_UNorm_S8_UInt:
|
||||
return OpenGLFormat::Depth24Stencil8;
|
||||
case Format::D32_Float:
|
||||
return OpenGLFormat::Depth32F;
|
||||
default:
|
||||
return OpenGLFormat::RGBA8;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OpenGLDevice::OpenGLDevice()
|
||||
@@ -338,19 +361,7 @@ RHITexture* OpenGLDevice::CreateTexture(const TextureDesc& desc) {
|
||||
break;
|
||||
}
|
||||
|
||||
OpenGLFormat format = OpenGLFormat::RGBA8;
|
||||
switch (desc.format) {
|
||||
case 1: format = OpenGLFormat::R8; break;
|
||||
case 2: format = OpenGLFormat::RG8; break;
|
||||
case 3: format = OpenGLFormat::RGBA8; break;
|
||||
case 4: format = OpenGLFormat::RGBA16F; break;
|
||||
case 5: format = OpenGLFormat::RGBA32F; break;
|
||||
case 6: format = OpenGLFormat::RGBA16F; break;
|
||||
case 7: format = OpenGLFormat::RGBA32F; break;
|
||||
case 8: format = OpenGLFormat::Depth24Stencil8; break;
|
||||
case 9: format = OpenGLFormat::Depth32F; break;
|
||||
default: format = OpenGLFormat::RGBA8; break;
|
||||
}
|
||||
OpenGLFormat format = ToOpenGLTextureFormat(static_cast<Format>(desc.format));
|
||||
texture->Initialize(type, desc.width, desc.height, desc.depth, desc.mipLevels, format, nullptr);
|
||||
texture->SetFormat(static_cast<Format>(desc.format));
|
||||
return texture;
|
||||
@@ -385,19 +396,7 @@ RHITexture* OpenGLDevice::CreateTexture(const TextureDesc& desc, const void* ini
|
||||
break;
|
||||
}
|
||||
|
||||
OpenGLFormat format = OpenGLFormat::RGBA8;
|
||||
switch (desc.format) {
|
||||
case 1: format = OpenGLFormat::R8; break;
|
||||
case 2: format = OpenGLFormat::RG8; break;
|
||||
case 3: format = OpenGLFormat::RGBA8; break;
|
||||
case 4: format = OpenGLFormat::RGBA16F; break;
|
||||
case 5: format = OpenGLFormat::RGBA32F; break;
|
||||
case 6: format = OpenGLFormat::RGBA16F; break;
|
||||
case 7: format = OpenGLFormat::RGBA32F; break;
|
||||
case 8: format = OpenGLFormat::Depth24Stencil8; break;
|
||||
case 9: format = OpenGLFormat::Depth32F; break;
|
||||
default: format = OpenGLFormat::RGBA8; break;
|
||||
}
|
||||
OpenGLFormat format = ToOpenGLTextureFormat(static_cast<Format>(desc.format));
|
||||
|
||||
if (!texture->Initialize(type, desc.width, desc.height, desc.depth, desc.mipLevels, format, initialData)) {
|
||||
delete texture;
|
||||
|
||||
Reference in New Issue
Block a user