#include "fixtures/RHITestFixture.h" #include "XCEngine/RHI/RHICommandList.h" #include "XCEngine/RHI/RHITexture.h" #include "XCEngine/RHI/RHIBuffer.h" #include "XCEngine/RHI/RHIShader.h" #include "XCEngine/RHI/RHIPipelineState.h" #include "XCEngine/RHI/RHIRenderPass.h" #include "XCEngine/RHI/RHIFramebuffer.h" using namespace XCEngine::RHI; TEST_P(RHITestFixture, CommandList_Reset_Close) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_SetPrimitiveTopology) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->SetPrimitiveTopology(PrimitiveTopology::TriangleList); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_SetViewport) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); Viewport vp = { 0.0f, 0.0f, 800.0f, 600.0f, 0.0f, 1.0f }; cmdList->Reset(); cmdList->SetViewport(vp); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_SetViewports) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); Viewport viewports[2] = { { 0.0f, 0.0f, 400.0f, 300.0f, 0.0f, 1.0f }, { 400.0f, 300.0f, 400.0f, 300.0f, 0.0f, 1.0f } }; cmdList->Reset(); cmdList->SetViewports(2, viewports); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_SetScissorRect) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); Rect rect = { 0, 0, 800, 600 }; cmdList->Reset(); cmdList->SetScissorRect(rect); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_SetScissorRects_Multiple) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); Rect rects[2] = { { 0, 0, 400, 300 }, { 400, 300, 800, 600 } }; cmdList->Reset(); cmdList->SetScissorRects(2, rects); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_Draw) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->SetPrimitiveTopology(PrimitiveTopology::TriangleList); cmdList->Draw(3); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_DrawIndexed) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->SetPrimitiveTopology(PrimitiveTopology::TriangleList); cmdList->DrawIndexed(6); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_SetVertexBuffers_WithRealView) { BufferDesc bufferDesc = {}; bufferDesc.size = 256; bufferDesc.stride = 32; bufferDesc.bufferType = static_cast(BufferType::Vertex); RHIBuffer* buffer = GetDevice()->CreateBuffer(bufferDesc); ASSERT_NE(buffer, nullptr); ResourceViewDesc viewDesc = {}; viewDesc.dimension = ResourceViewDimension::Buffer; viewDesc.structureByteStride = 32; RHIResourceView* vbv = GetDevice()->CreateVertexBufferView(buffer, viewDesc); ASSERT_NE(vbv, nullptr); CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); uint64_t offsets[] = { 0 }; uint32_t strides[] = { 32 }; cmdList->Reset(); cmdList->SetVertexBuffers(0, 1, &vbv, offsets, strides); cmdList->Close(); cmdList->Shutdown(); delete cmdList; vbv->Shutdown(); delete vbv; buffer->Shutdown(); delete buffer; } TEST_P(RHITestFixture, CommandList_SetIndexBuffer_WithRealView) { BufferDesc bufferDesc = {}; bufferDesc.size = 256; bufferDesc.stride = sizeof(uint32_t); bufferDesc.bufferType = static_cast(BufferType::Index); RHIBuffer* buffer = GetDevice()->CreateBuffer(bufferDesc); ASSERT_NE(buffer, nullptr); ResourceViewDesc viewDesc = {}; viewDesc.dimension = ResourceViewDimension::Buffer; viewDesc.format = static_cast(Format::R32_UInt); RHIResourceView* ibv = GetDevice()->CreateIndexBufferView(buffer, viewDesc); ASSERT_NE(ibv, nullptr); CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->SetIndexBuffer(ibv, 0); cmdList->Close(); cmdList->Shutdown(); delete cmdList; ibv->Shutdown(); delete ibv; buffer->Shutdown(); delete buffer; } TEST_P(RHITestFixture, CommandList_SetStencilRef) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->SetStencilRef(0); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_SetBlendFactor) { CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); float blendFactor[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; cmdList->Reset(); cmdList->SetBlendFactor(blendFactor); cmdList->Close(); cmdList->Shutdown(); delete cmdList; } TEST_P(RHITestFixture, CommandList_ClearRenderTarget_WithRealView) { TextureDesc texDesc = {}; texDesc.width = 256; texDesc.height = 256; texDesc.format = static_cast(Format::R8G8B8A8_UNorm); texDesc.textureType = static_cast(TextureType::Texture2D); RHITexture* texture = GetDevice()->CreateTexture(texDesc); ASSERT_NE(texture, nullptr); ResourceViewDesc viewDesc = {}; viewDesc.format = texDesc.format; RHIResourceView* rtv = GetDevice()->CreateRenderTargetView(texture, viewDesc); ASSERT_NE(rtv, nullptr); float color[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->ClearRenderTarget(rtv, color); cmdList->Close(); cmdList->Shutdown(); delete cmdList; delete rtv; texture->Shutdown(); delete texture; } TEST_P(RHITestFixture, CommandList_ClearDepthStencil_WithRealView) { TextureDesc texDesc = {}; texDesc.width = 256; texDesc.height = 256; texDesc.format = static_cast(Format::D24_UNorm_S8_UInt); texDesc.textureType = static_cast(TextureType::Texture2D); RHITexture* texture = GetDevice()->CreateTexture(texDesc); ASSERT_NE(texture, nullptr); RHIResourceView* dsv = GetDevice()->CreateDepthStencilView(texture, {}); ASSERT_NE(dsv, nullptr); CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->ClearDepthStencil(dsv, 1.0f, 0); cmdList->Close(); cmdList->Shutdown(); delete cmdList; delete dsv; texture->Shutdown(); delete texture; } TEST_P(RHITestFixture, CommandList_TransitionBarrier_WithRealResource) { TextureDesc texDesc = {}; texDesc.width = 256; texDesc.height = 256; texDesc.format = static_cast(Format::R8G8B8A8_UNorm); texDesc.textureType = static_cast(TextureType::Texture2D); RHITexture* texture = GetDevice()->CreateTexture(texDesc); ASSERT_NE(texture, nullptr); RHIResourceView* srv = GetDevice()->CreateShaderResourceView(texture, {}); ASSERT_NE(srv, nullptr); CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->TransitionBarrier(srv, ResourceStates::Common, ResourceStates::PixelShaderResource); cmdList->Close(); cmdList->Shutdown(); delete cmdList; delete srv; texture->Shutdown(); delete texture; } TEST_P(RHITestFixture, CommandList_SetRenderTargets_WithRealViews) { TextureDesc texDesc = {}; texDesc.width = 256; texDesc.height = 256; texDesc.format = static_cast(Format::R8G8B8A8_UNorm); texDesc.textureType = static_cast(TextureType::Texture2D); RHITexture* texture = GetDevice()->CreateTexture(texDesc); ASSERT_NE(texture, nullptr); RHIResourceView* rtv = GetDevice()->CreateRenderTargetView(texture, {}); ASSERT_NE(rtv, nullptr); CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->SetRenderTargets(1, &rtv, nullptr); cmdList->Close(); cmdList->Shutdown(); delete cmdList; delete rtv; texture->Shutdown(); delete texture; } TEST_P(RHITestFixture, CommandList_CopyResource_WithRealResources) { TextureDesc texDesc = {}; texDesc.width = 256; texDesc.height = 256; texDesc.format = static_cast(Format::R8G8B8A8_UNorm); texDesc.textureType = static_cast(TextureType::Texture2D); RHITexture* srcTexture = GetDevice()->CreateTexture(texDesc); ASSERT_NE(srcTexture, nullptr); RHITexture* dstTexture = GetDevice()->CreateTexture(texDesc); ASSERT_NE(dstTexture, nullptr); RHIResourceView* srcView = GetDevice()->CreateShaderResourceView(srcTexture, {}); RHIResourceView* dstView = GetDevice()->CreateShaderResourceView(dstTexture, {}); CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->CopyResource(dstView, srcView); cmdList->Close(); cmdList->Shutdown(); delete cmdList; delete srcView; delete dstView; srcTexture->Shutdown(); delete srcTexture; dstTexture->Shutdown(); delete dstTexture; } TEST_P(RHITestFixture, CommandList_BeginEndRenderPass_Basic) { AttachmentDesc colorDesc = {}; colorDesc.format = Format::R8G8B8A8_UNorm; colorDesc.loadOp = LoadAction::Clear; colorDesc.storeOp = StoreAction::Store; RHIRenderPass* renderPass = GetDevice()->CreateRenderPass(1, &colorDesc, nullptr); ASSERT_NE(renderPass, nullptr); TextureDesc texDesc = {}; texDesc.width = 256; texDesc.height = 256; texDesc.format = static_cast(Format::R8G8B8A8_UNorm); texDesc.textureType = static_cast(TextureType::Texture2D); RHITexture* texture = GetDevice()->CreateTexture(texDesc); ASSERT_NE(texture, nullptr); RHIResourceView* rtv = GetDevice()->CreateRenderTargetView(texture, {}); ASSERT_NE(rtv, nullptr); RHIFramebuffer* fb = GetDevice()->CreateFramebuffer(renderPass, 256, 256, 1, &rtv, nullptr); ASSERT_NE(fb, nullptr); CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); Rect renderArea = { 0, 0, 256, 256 }; ClearValue clearValue = { { 0.0f, 0.0f, 0.0f, 1.0f }, 1.0f, 0 }; cmdList->Reset(); cmdList->BeginRenderPass(renderPass, fb, renderArea, 1, &clearValue); cmdList->EndRenderPass(); cmdList->Close(); cmdList->Shutdown(); delete cmdList; fb->Shutdown(); delete fb; delete rtv; texture->Shutdown(); delete texture; renderPass->Shutdown(); delete renderPass; } TEST_P(RHITestFixture, CommandList_BeginEndRenderPass_WithClear) { AttachmentDesc colorDesc = {}; colorDesc.format = Format::R8G8B8A8_UNorm; colorDesc.loadOp = LoadAction::Clear; colorDesc.storeOp = StoreAction::Store; RHIRenderPass* renderPass = GetDevice()->CreateRenderPass(1, &colorDesc, nullptr); ASSERT_NE(renderPass, nullptr); TextureDesc texDesc = {}; texDesc.width = 256; texDesc.height = 256; texDesc.format = static_cast(Format::R8G8B8A8_UNorm); texDesc.textureType = static_cast(TextureType::Texture2D); RHITexture* texture = GetDevice()->CreateTexture(texDesc); ASSERT_NE(texture, nullptr); RHIResourceView* rtv = GetDevice()->CreateRenderTargetView(texture, {}); ASSERT_NE(rtv, nullptr); RHIFramebuffer* fb = GetDevice()->CreateFramebuffer(renderPass, 256, 256, 1, &rtv, nullptr); ASSERT_NE(fb, nullptr); CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); Rect renderArea = { 0, 0, 256, 256 }; ClearValue clearValue = { { 1.0f, 0.0f, 0.0f, 1.0f }, 1.0f, 0 }; cmdList->Reset(); cmdList->BeginRenderPass(renderPass, fb, renderArea, 1, &clearValue); cmdList->EndRenderPass(); cmdList->Close(); cmdList->Shutdown(); delete cmdList; fb->Shutdown(); delete fb; delete rtv; texture->Shutdown(); delete texture; renderPass->Shutdown(); delete renderPass; } TEST_P(RHITestFixture, CommandList_SetShader) { ShaderCompileDesc shaderDesc = {}; if (GetBackendType() == RHIType::D3D12) { shaderDesc.fileName = L"tests/RHI/D3D12/integration/quad/Res/Shader/quad.hlsl"; shaderDesc.entryPoint = L"MainVS"; shaderDesc.profile = L"vs_5_0"; } else { shaderDesc.sourceLanguage = ShaderLanguage::GLSL; static const char* vs = "#version 430\nin vec4 aPosition;\nvoid main() { gl_Position = aPosition; }"; shaderDesc.source.assign(vs, vs + strlen(vs)); } RHIShader* shader = GetDevice()->CreateShader(shaderDesc); if (shader == nullptr) { return; } CommandListDesc cmdDesc = {}; cmdDesc.commandListType = static_cast(CommandQueueType::Direct); RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc); ASSERT_NE(cmdList, nullptr); cmdList->Reset(); cmdList->SetShader(shader); cmdList->Close(); cmdList->Shutdown(); delete cmdList; shader->Shutdown(); delete shader; }