test: Add new RHI unit tests for capabilities, views, screenshot, descriptor set and pipeline layout
This commit is contained in:
107
tests/RHI/unit/test_capabilities.cpp
Normal file
107
tests/RHI/unit/test_capabilities.cpp
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#include "fixtures/RHITestFixture.h"
|
||||||
|
#include "XCEngine/RHI/RHICapabilities.h"
|
||||||
|
|
||||||
|
using namespace XCEngine::RHI;
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_Query_Basic) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
EXPECT_GE(caps.maxTexture2DSize, 1u);
|
||||||
|
EXPECT_GE(caps.maxTexture3DSize, 1u);
|
||||||
|
EXPECT_GE(caps.maxTextureCubeSize, 1u);
|
||||||
|
EXPECT_GE(caps.maxRenderTargets, 1u);
|
||||||
|
EXPECT_GE(caps.maxViewports, 1u);
|
||||||
|
EXPECT_GE(caps.maxVertexAttribs, 1u);
|
||||||
|
EXPECT_GE(caps.maxColorAttachments, 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_Query_Version) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
EXPECT_GE(caps.majorVersion, 0);
|
||||||
|
EXPECT_GE(caps.minorVersion, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_Query_ShaderModel) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
if (GetBackendType() == RHIType::D3D12) {
|
||||||
|
EXPECT_FALSE(caps.shaderModel.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_Query_Anisotropy) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
if (caps.maxAnisotropy > 1) {
|
||||||
|
EXPECT_GE(caps.maxAnisotropy, 2u);
|
||||||
|
EXPECT_LE(caps.maxAnisotropy, 16u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_Query_LineWidth) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
EXPECT_GE(caps.minSmoothedLineWidth, 1.0f);
|
||||||
|
EXPECT_GE(caps.maxSmoothedLineWidth, 1.0f);
|
||||||
|
EXPECT_GE(caps.maxLineWidth, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_Query_PointSize) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
EXPECT_GE(caps.minPointSize, 1.0f);
|
||||||
|
EXPECT_GE(caps.maxPointSize, 1.0f);
|
||||||
|
EXPECT_GE(caps.maxPointSizeAA, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_FeatureFlags) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
if (GetBackendType() == RHIType::D3D12) {
|
||||||
|
EXPECT_TRUE(caps.bSupportsComputeShaders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_Query_DeviceInfo) {
|
||||||
|
const RHIDeviceInfo& info = GetDevice()->GetDeviceInfo();
|
||||||
|
|
||||||
|
EXPECT_FALSE(info.vendor.empty());
|
||||||
|
EXPECT_FALSE(info.renderer.empty());
|
||||||
|
EXPECT_GT(info.vendorId, 0u);
|
||||||
|
EXPECT_GT(info.deviceId, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_DeviceInfo_Memory) {
|
||||||
|
const RHIDeviceInfo& info = GetDevice()->GetDeviceInfo();
|
||||||
|
|
||||||
|
if (!info.isSoftware) {
|
||||||
|
EXPECT_GT(info.dedicatedVideoMemory, 0ull);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_MaxTextureSizes) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
EXPECT_GE(caps.maxTexture2DSize, 2048u);
|
||||||
|
EXPECT_GE(caps.maxTextureCubeSize, 2048u);
|
||||||
|
|
||||||
|
if (GetBackendType() == RHIType::D3D12) {
|
||||||
|
EXPECT_GE(caps.maxTexture3DSize, 256u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_RenderTargets) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
EXPECT_GE(caps.maxRenderTargets, 1u);
|
||||||
|
EXPECT_GE(caps.maxColorAttachments, 1u);
|
||||||
|
EXPECT_LE(caps.maxRenderTargets, 8u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Capabilities_ConstantBuffer) {
|
||||||
|
const RHICapabilities& caps = GetDevice()->GetCapabilities();
|
||||||
|
|
||||||
|
EXPECT_GT(caps.maxConstantBufferSize, 0u);
|
||||||
|
EXPECT_LE(caps.maxConstantBufferSize, 128 * 1024 * 1024u);
|
||||||
|
}
|
||||||
362
tests/RHI/unit/test_descriptor_set.cpp
Normal file
362
tests/RHI/unit/test_descriptor_set.cpp
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
#include "fixtures/RHITestFixture.h"
|
||||||
|
#include "XCEngine/RHI/RHIDescriptorPool.h"
|
||||||
|
#include "XCEngine/RHI/RHIDescriptorSet.h"
|
||||||
|
#include "XCEngine/RHI/RHISampler.h"
|
||||||
|
#include "XCEngine/RHI/RHIResourceView.h"
|
||||||
|
#include "XCEngine/RHI/RHITexture.h"
|
||||||
|
|
||||||
|
using namespace XCEngine::RHI;
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_Allocate_Basic) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindings = nullptr;
|
||||||
|
layoutDesc.bindingCount = 0;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
EXPECT_GE(set->GetBindingCount(), 0u);
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_Update_ResourceView) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RHIResourceView* srv = GetDevice()->CreateShaderResourceView(texture, {});
|
||||||
|
if (srv == nullptr) {
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 1;
|
||||||
|
DescriptorSetLayoutBinding binding = {};
|
||||||
|
binding.binding = 0;
|
||||||
|
binding.type = static_cast<uint32_t>(DescriptorType::SRV);
|
||||||
|
binding.count = 1;
|
||||||
|
layoutDesc.bindings = &binding;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
set->Update(0, srv);
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
|
||||||
|
srv->Shutdown();
|
||||||
|
delete srv;
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_UpdateSampler) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::Sampler;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SamplerDesc samplerDesc = {};
|
||||||
|
samplerDesc.filter = static_cast<uint32_t>(FilterMode::Linear);
|
||||||
|
samplerDesc.addressU = static_cast<uint32_t>(TextureAddressMode::Wrap);
|
||||||
|
samplerDesc.addressV = static_cast<uint32_t>(TextureAddressMode::Wrap);
|
||||||
|
samplerDesc.addressW = static_cast<uint32_t>(TextureAddressMode::Wrap);
|
||||||
|
|
||||||
|
RHISampler* sampler = GetDevice()->CreateSampler(samplerDesc);
|
||||||
|
if (sampler == nullptr) {
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 1;
|
||||||
|
DescriptorSetLayoutBinding binding = {};
|
||||||
|
binding.binding = 0;
|
||||||
|
binding.type = static_cast<uint32_t>(DescriptorType::Sampler);
|
||||||
|
binding.count = 1;
|
||||||
|
layoutDesc.bindings = &binding;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
set->UpdateSampler(0, sampler);
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampler->Shutdown();
|
||||||
|
delete sampler;
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_WriteConstant) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = false;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 1;
|
||||||
|
DescriptorSetLayoutBinding binding = {};
|
||||||
|
binding.binding = 0;
|
||||||
|
binding.type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||||
|
binding.count = 1;
|
||||||
|
layoutDesc.bindings = &binding;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
float testData[16] = { 1.0f, 2.0f, 3.0f, 4.0f };
|
||||||
|
set->WriteConstant(0, testData, sizeof(testData));
|
||||||
|
|
||||||
|
void* constantData = set->GetConstantBufferData();
|
||||||
|
EXPECT_NE(constantData, nullptr);
|
||||||
|
|
||||||
|
size_t constantSize = set->GetConstantBufferSize();
|
||||||
|
EXPECT_GE(constantSize, sizeof(testData));
|
||||||
|
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_WriteConstant_PartialUpdate) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = false;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 1;
|
||||||
|
DescriptorSetLayoutBinding binding = {};
|
||||||
|
binding.binding = 0;
|
||||||
|
binding.type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||||
|
binding.count = 1;
|
||||||
|
layoutDesc.bindings = &binding;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
float offsetData[4] = { 100.0f, 200.0f };
|
||||||
|
set->WriteConstant(0, offsetData, sizeof(offsetData), 0);
|
||||||
|
|
||||||
|
EXPECT_TRUE(set->IsConstantDirty());
|
||||||
|
|
||||||
|
set->MarkConstantClean();
|
||||||
|
EXPECT_FALSE(set->IsConstantDirty());
|
||||||
|
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_Bind_Unbind) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 0;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
set->Bind();
|
||||||
|
set->Unbind();
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_GetBindings) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 2;
|
||||||
|
DescriptorSetLayoutBinding bindings[2] = {};
|
||||||
|
bindings[0].binding = 0;
|
||||||
|
bindings[0].type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||||
|
bindings[0].count = 1;
|
||||||
|
bindings[1].binding = 1;
|
||||||
|
bindings[1].type = static_cast<uint32_t>(DescriptorType::SRV);
|
||||||
|
bindings[1].count = 2;
|
||||||
|
layoutDesc.bindings = bindings;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
EXPECT_EQ(set->GetBindingCount(), 2u);
|
||||||
|
const DescriptorSetLayoutBinding* retrievedBindings = set->GetBindings();
|
||||||
|
ASSERT_NE(retrievedBindings, nullptr);
|
||||||
|
EXPECT_EQ(retrievedBindings[0].binding, 0u);
|
||||||
|
EXPECT_EQ(retrievedBindings[1].binding, 1u);
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_MultipleAllocations) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 100;
|
||||||
|
poolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RHIDescriptorSet* sets[10] = { nullptr };
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 0;
|
||||||
|
sets[i] = pool->AllocateSet(layoutDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
if (sets[i] != nullptr) {
|
||||||
|
sets[i]->Shutdown();
|
||||||
|
delete sets[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_FreeSet_ViaPool) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 0;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
pool->FreeSet(set);
|
||||||
|
set = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, DescriptorSet_ConstantBufferSize) {
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = false;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.bindingCount = 1;
|
||||||
|
DescriptorSetLayoutBinding binding = {};
|
||||||
|
binding.binding = 0;
|
||||||
|
binding.type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||||
|
binding.count = 1;
|
||||||
|
layoutDesc.bindings = &binding;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
float data[64] = {};
|
||||||
|
set->WriteConstant(0, data, sizeof(data));
|
||||||
|
|
||||||
|
EXPECT_GE(set->GetConstantBufferSize(), sizeof(data));
|
||||||
|
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
154
tests/RHI/unit/test_pipeline_layout.cpp
Normal file
154
tests/RHI/unit/test_pipeline_layout.cpp
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
#include "fixtures/RHITestFixture.h"
|
||||||
|
#include "XCEngine/RHI/RHIPipelineLayout.h"
|
||||||
|
#include "XCEngine/RHI/RHIDescriptorSet.h"
|
||||||
|
|
||||||
|
using namespace XCEngine::RHI;
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_Create_Basic) {
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.constantBufferCount = 1;
|
||||||
|
desc.textureCount = 0;
|
||||||
|
desc.samplerCount = 0;
|
||||||
|
desc.uavCount = 0;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
if (layout != nullptr) {
|
||||||
|
EXPECT_NE(layout->GetNativeHandle(), nullptr);
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_Create_WithTextures) {
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.constantBufferCount = 0;
|
||||||
|
desc.textureCount = 4;
|
||||||
|
desc.samplerCount = 0;
|
||||||
|
desc.uavCount = 0;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
if (layout != nullptr) {
|
||||||
|
EXPECT_NE(layout->GetNativeHandle(), nullptr);
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_Create_WithSamplers) {
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.constantBufferCount = 0;
|
||||||
|
desc.textureCount = 0;
|
||||||
|
desc.samplerCount = 2;
|
||||||
|
desc.uavCount = 0;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
if (layout != nullptr) {
|
||||||
|
EXPECT_NE(layout->GetNativeHandle(), nullptr);
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_Create_WithUAVs) {
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.constantBufferCount = 0;
|
||||||
|
desc.textureCount = 0;
|
||||||
|
desc.samplerCount = 0;
|
||||||
|
desc.uavCount = 3;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
if (layout != nullptr) {
|
||||||
|
EXPECT_NE(layout->GetNativeHandle(), nullptr);
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_Create_Complex) {
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.constantBufferCount = 2;
|
||||||
|
desc.textureCount = 4;
|
||||||
|
desc.samplerCount = 2;
|
||||||
|
desc.uavCount = 1;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
if (layout != nullptr) {
|
||||||
|
EXPECT_NE(layout->GetNativeHandle(), nullptr);
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_Create_ZeroCounts) {
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.constantBufferCount = 0;
|
||||||
|
desc.textureCount = 0;
|
||||||
|
desc.samplerCount = 0;
|
||||||
|
desc.uavCount = 0;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
if (layout != nullptr) {
|
||||||
|
EXPECT_NE(layout->GetNativeHandle(), nullptr);
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_Shutdown) {
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.constantBufferCount = 1;
|
||||||
|
desc.textureCount = 2;
|
||||||
|
desc.samplerCount = 1;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
if (layout != nullptr) {
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_DoubleShutdown) {
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.constantBufferCount = 1;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
if (layout != nullptr) {
|
||||||
|
layout->Shutdown();
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_DescriptorSetAllocation) {
|
||||||
|
RHIPipelineLayoutDesc layoutDesc = {};
|
||||||
|
layoutDesc.constantBufferCount = 1;
|
||||||
|
layoutDesc.textureCount = 2;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(layoutDesc);
|
||||||
|
if (layout == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorPoolDesc poolDesc = {};
|
||||||
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
poolDesc.descriptorCount = 10;
|
||||||
|
poolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
|
||||||
|
if (pool != nullptr) {
|
||||||
|
DescriptorSetLayoutDesc setDesc = {};
|
||||||
|
setDesc.bindingCount = 0;
|
||||||
|
|
||||||
|
RHIDescriptorSet* set = pool->AllocateSet(setDesc);
|
||||||
|
if (set != nullptr) {
|
||||||
|
EXPECT_GE(set->GetBindingCount(), 0u);
|
||||||
|
set->Shutdown();
|
||||||
|
delete set;
|
||||||
|
}
|
||||||
|
pool->Shutdown();
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
63
tests/RHI/unit/test_screenshot.cpp
Normal file
63
tests/RHI/unit/test_screenshot.cpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#include "fixtures/RHITestFixture.h"
|
||||||
|
#include "XCEngine/RHI/RHIScreenshot.h"
|
||||||
|
#include "XCEngine/RHI/RHISwapChain.h"
|
||||||
|
|
||||||
|
using namespace XCEngine::RHI;
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Screenshot_Create) {
|
||||||
|
RHIScreenshot* screenshot = RHIScreenshot::Create(GetBackendType());
|
||||||
|
if (screenshot != nullptr) {
|
||||||
|
screenshot->Shutdown();
|
||||||
|
delete screenshot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Screenshot_Capture_Basic) {
|
||||||
|
SwapChainDesc desc = {};
|
||||||
|
desc.windowHandle = GetWindowHandle();
|
||||||
|
desc.width = 800;
|
||||||
|
desc.height = 600;
|
||||||
|
desc.bufferCount = 2;
|
||||||
|
desc.format = Format::R8G8B8A8_UNorm;
|
||||||
|
|
||||||
|
RHISwapChain* swapChain = GetDevice()->CreateSwapChain(desc);
|
||||||
|
if (swapChain == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RHIScreenshot* screenshot = RHIScreenshot::Create(GetBackendType());
|
||||||
|
if (screenshot != nullptr) {
|
||||||
|
screenshot->Capture(GetDevice(), swapChain, "test_capture.ppm");
|
||||||
|
screenshot->Shutdown();
|
||||||
|
delete screenshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
swapChain->Shutdown();
|
||||||
|
delete swapChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Screenshot_Capture_WithPresent) {
|
||||||
|
SwapChainDesc desc = {};
|
||||||
|
desc.windowHandle = GetWindowHandle();
|
||||||
|
desc.width = 800;
|
||||||
|
desc.height = 600;
|
||||||
|
desc.bufferCount = 2;
|
||||||
|
desc.format = Format::R8G8B8A8_UNorm;
|
||||||
|
|
||||||
|
RHISwapChain* swapChain = GetDevice()->CreateSwapChain(desc);
|
||||||
|
if (swapChain == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
swapChain->Present(0, 0);
|
||||||
|
|
||||||
|
RHIScreenshot* screenshot = RHIScreenshot::Create(GetBackendType());
|
||||||
|
if (screenshot != nullptr) {
|
||||||
|
screenshot->Capture(GetDevice(), swapChain, "test_capture2.ppm");
|
||||||
|
screenshot->Shutdown();
|
||||||
|
delete screenshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
swapChain->Shutdown();
|
||||||
|
delete swapChain;
|
||||||
|
}
|
||||||
247
tests/RHI/unit/test_views.cpp
Normal file
247
tests/RHI/unit/test_views.cpp
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
#include "fixtures/RHITestFixture.h"
|
||||||
|
#include "XCEngine/RHI/RHIResourceView.h"
|
||||||
|
#include "XCEngine/RHI/RHITexture.h"
|
||||||
|
|
||||||
|
using namespace XCEngine::RHI;
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateRenderTargetView) {
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Texture2D;
|
||||||
|
|
||||||
|
RHIResourceView* rtv = GetDevice()->CreateRenderTargetView(texture, viewDesc);
|
||||||
|
if (rtv != nullptr) {
|
||||||
|
EXPECT_TRUE(rtv->IsValid());
|
||||||
|
EXPECT_EQ(rtv->GetViewType(), ResourceViewType::RenderTarget);
|
||||||
|
EXPECT_EQ(rtv->GetFormat(), Format::R8G8B8A8_UNorm);
|
||||||
|
rtv->Shutdown();
|
||||||
|
delete rtv;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateDepthStencilView) {
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Texture2D;
|
||||||
|
|
||||||
|
RHIResourceView* dsv = GetDevice()->CreateDepthStencilView(texture, viewDesc);
|
||||||
|
if (dsv != nullptr) {
|
||||||
|
EXPECT_TRUE(dsv->IsValid());
|
||||||
|
EXPECT_EQ(dsv->GetViewType(), ResourceViewType::DepthStencil);
|
||||||
|
dsv->Shutdown();
|
||||||
|
delete dsv;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateShaderResourceView) {
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Texture2D;
|
||||||
|
|
||||||
|
RHIResourceView* srv = GetDevice()->CreateShaderResourceView(texture, viewDesc);
|
||||||
|
if (srv != nullptr) {
|
||||||
|
EXPECT_TRUE(srv->IsValid());
|
||||||
|
EXPECT_EQ(srv->GetViewType(), ResourceViewType::ShaderResource);
|
||||||
|
srv->Shutdown();
|
||||||
|
delete srv;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateUnorderedAccessView) {
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Texture2D;
|
||||||
|
|
||||||
|
RHIResourceView* uav = GetDevice()->CreateUnorderedAccessView(texture, viewDesc);
|
||||||
|
if (uav != nullptr) {
|
||||||
|
EXPECT_TRUE(uav->IsValid());
|
||||||
|
EXPECT_EQ(uav->GetViewType(), ResourceViewType::UnorderedAccess);
|
||||||
|
uav->Shutdown();
|
||||||
|
delete uav;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateRenderTargetView_Multiple) {
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHIResourceView* rtvs[4] = { nullptr };
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Texture2D;
|
||||||
|
|
||||||
|
rtvs[i] = GetDevice()->CreateRenderTargetView(texture, viewDesc);
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
if (rtvs[i] != nullptr) {
|
||||||
|
EXPECT_TRUE(rtvs[i]->IsValid());
|
||||||
|
rtvs[i]->Shutdown();
|
||||||
|
delete rtvs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateShaderResourceView_ArrayTexture) {
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.arraySize = 4;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2DArray);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Texture2DArray;
|
||||||
|
viewDesc.arraySize = 4;
|
||||||
|
|
||||||
|
RHIResourceView* srv = GetDevice()->CreateShaderResourceView(texture, viewDesc);
|
||||||
|
if (srv != nullptr) {
|
||||||
|
EXPECT_TRUE(srv->IsValid());
|
||||||
|
srv->Shutdown();
|
||||||
|
delete srv;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateShaderResourceView_CubeTexture) {
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.arraySize = 6;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::TextureCube);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||||
|
viewDesc.dimension = ResourceViewDimension::TextureCube;
|
||||||
|
|
||||||
|
RHIResourceView* srv = GetDevice()->CreateShaderResourceView(texture, viewDesc);
|
||||||
|
if (srv != nullptr) {
|
||||||
|
EXPECT_TRUE(srv->IsValid());
|
||||||
|
srv->Shutdown();
|
||||||
|
delete srv;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateDepthStencilView_MipLevels) {
|
||||||
|
TextureDesc texDesc = {};
|
||||||
|
texDesc.width = 256;
|
||||||
|
texDesc.height = 256;
|
||||||
|
texDesc.mipLevels = 5;
|
||||||
|
texDesc.format = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||||
|
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||||
|
texDesc.sampleCount = 1;
|
||||||
|
|
||||||
|
RHITexture* texture = GetDevice()->CreateTexture(texDesc);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t mip = 0; mip < texDesc.mipLevels; ++mip) {
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Texture2D;
|
||||||
|
viewDesc.mipLevel = mip;
|
||||||
|
|
||||||
|
RHIResourceView* dsv = GetDevice()->CreateDepthStencilView(texture, viewDesc);
|
||||||
|
if (dsv != nullptr) {
|
||||||
|
EXPECT_TRUE(dsv->IsValid());
|
||||||
|
dsv->Shutdown();
|
||||||
|
delete dsv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->Shutdown();
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user