mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[tests] Remove D3D11 and DXGI tests
This commit is contained in:
parent
2b6a903ad9
commit
632e26f687
@ -1,10 +0,0 @@
|
||||
test_d3d11_deps = [ util_dep, lib_dxgi, lib_d3d11, lib_d3dcompiler_47 ]
|
||||
|
||||
executable('d3d11-compute'+exe_ext, files('test_d3d11_compute.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true)
|
||||
executable('d3d11-formats'+exe_ext, files('test_d3d11_formats.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true)
|
||||
executable('d3d11-map-read'+exe_ext, files('test_d3d11_map_read.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true)
|
||||
executable('d3d11-streamout'+exe_ext, files('test_d3d11_streamout.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true)
|
||||
executable('d3d11-triangle'+exe_ext, files('test_d3d11_triangle.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true)
|
||||
executable('d3d11-video'+exe_ext, files('test_d3d11_video.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true)
|
||||
|
||||
install_data('video_image.raw', install_dir : get_option('bindir'))
|
@ -1,172 +0,0 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
const std::string g_computeShaderCode =
|
||||
"StructuredBuffer<uint> buf_in : register(t0);\n"
|
||||
"RWStructuredBuffer<uint> buf_out : register(u0);\n"
|
||||
"groupshared uint tmp[64];\n"
|
||||
"[numthreads(64,1,1)]\n"
|
||||
"void main(uint localId : SV_GroupIndex, uint3 globalId : SV_DispatchThreadID) {\n"
|
||||
" tmp[localId] = buf_in[2 * globalId.x + 0]\n"
|
||||
" + buf_in[2 * globalId.x + 1];\n"
|
||||
" GroupMemoryBarrierWithGroupSync();\n"
|
||||
" uint activeGroups = 32;\n"
|
||||
" while (activeGroups != 0) {\n"
|
||||
" if (localId < activeGroups)\n"
|
||||
" tmp[localId] += tmp[localId + activeGroups];\n"
|
||||
" GroupMemoryBarrierWithGroupSync();\n"
|
||||
" activeGroups >>= 1;\n"
|
||||
" }\n"
|
||||
" if (localId == 0)\n"
|
||||
" buf_out[0] = tmp[0];\n"
|
||||
"}\n";
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
Com<ID3D11Device> device;
|
||||
Com<ID3D11DeviceContext> context;
|
||||
Com<ID3D11ComputeShader> computeShader;
|
||||
|
||||
Com<ID3D11Buffer> srcBuffer;
|
||||
Com<ID3D11Buffer> dstBuffer;
|
||||
Com<ID3D11Buffer> readBuffer;
|
||||
|
||||
Com<ID3D11ShaderResourceView> srcView;
|
||||
Com<ID3D11UnorderedAccessView> dstView;
|
||||
|
||||
if (FAILED(D3D11CreateDevice(
|
||||
nullptr, D3D_DRIVER_TYPE_HARDWARE,
|
||||
nullptr, 0, nullptr, 0, D3D11_SDK_VERSION,
|
||||
&device, nullptr, &context))) {
|
||||
std::cerr << "Failed to create D3D11 device" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Com<ID3DBlob> computeShaderBlob;
|
||||
|
||||
if (FAILED(D3DCompile(
|
||||
g_computeShaderCode.data(),
|
||||
g_computeShaderCode.size(),
|
||||
"Compute shader",
|
||||
nullptr, nullptr,
|
||||
"main", "cs_5_0", 0, 0,
|
||||
&computeShaderBlob,
|
||||
nullptr))) {
|
||||
std::cerr << "Failed to compile compute shader" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (FAILED(device->CreateComputeShader(
|
||||
computeShaderBlob->GetBufferPointer(),
|
||||
computeShaderBlob->GetBufferSize(),
|
||||
nullptr, &computeShader))) {
|
||||
std::cerr << "Failed to create compute shader" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::array<uint32_t, 128> srcData;
|
||||
for (uint32_t i = 0; i < srcData.size(); i++)
|
||||
srcData[i] = i + 1;
|
||||
|
||||
D3D11_BUFFER_DESC srcBufferDesc;
|
||||
srcBufferDesc.ByteWidth = sizeof(uint32_t) * srcData.size();
|
||||
srcBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
srcBufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
srcBufferDesc.CPUAccessFlags = 0;
|
||||
srcBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
srcBufferDesc.StructureByteStride = sizeof(uint32_t);
|
||||
|
||||
D3D11_SUBRESOURCE_DATA srcDataInfo;
|
||||
srcDataInfo.pSysMem = srcData.data();
|
||||
srcDataInfo.SysMemPitch = 0;
|
||||
srcDataInfo.SysMemSlicePitch = 0;
|
||||
|
||||
if (FAILED(device->CreateBuffer(&srcBufferDesc, &srcDataInfo, &srcBuffer))) {
|
||||
std::cerr << "Failed to create source buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_BUFFER_DESC dstBufferDesc;
|
||||
dstBufferDesc.ByteWidth = sizeof(uint32_t);
|
||||
dstBufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
dstBufferDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
|
||||
dstBufferDesc.CPUAccessFlags = 0;
|
||||
dstBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
dstBufferDesc.StructureByteStride = sizeof(uint32_t);
|
||||
|
||||
if (FAILED(device->CreateBuffer(&dstBufferDesc, &srcDataInfo, &dstBuffer))) {
|
||||
std::cerr << "Failed to create destination buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_BUFFER_DESC readBufferDesc;
|
||||
readBufferDesc.ByteWidth = sizeof(uint32_t);
|
||||
readBufferDesc.Usage = D3D11_USAGE_STAGING;
|
||||
readBufferDesc.BindFlags = 0;
|
||||
readBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
readBufferDesc.MiscFlags = 0;
|
||||
readBufferDesc.StructureByteStride = 0;
|
||||
|
||||
if (FAILED(device->CreateBuffer(&readBufferDesc, nullptr, &readBuffer))) {
|
||||
std::cerr << "Failed to create readback buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srcViewDesc;
|
||||
srcViewDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
srcViewDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
|
||||
srcViewDesc.BufferEx.FirstElement = 0;
|
||||
srcViewDesc.BufferEx.NumElements = srcData.size();
|
||||
srcViewDesc.BufferEx.Flags = 0;
|
||||
|
||||
if (FAILED(device->CreateShaderResourceView(srcBuffer.ptr(), &srcViewDesc, &srcView))) {
|
||||
std::cerr << "Failed to create shader resource view" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC dstViewDesc;
|
||||
dstViewDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
dstViewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||
dstViewDesc.Buffer.FirstElement = 0;
|
||||
dstViewDesc.Buffer.NumElements = 1;
|
||||
dstViewDesc.Buffer.Flags = 0;
|
||||
|
||||
if (FAILED(device->CreateUnorderedAccessView(dstBuffer.ptr(), &dstViewDesc, &dstView))) {
|
||||
std::cerr << "Failed to create unordered access view" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Compute sum of the source buffer values
|
||||
context->CSSetShader(computeShader.ptr(), nullptr, 0);
|
||||
context->CSSetShaderResources(0, 1, &srcView);
|
||||
context->CSSetUnorderedAccessViews(0, 1, &dstView, nullptr);
|
||||
context->Dispatch(1, 1, 1);
|
||||
|
||||
// Write data to the readback buffer and query the result
|
||||
context->CopyResource(readBuffer.ptr(), dstBuffer.ptr());
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||
if (FAILED(context->Map(readBuffer.ptr(), 0, D3D11_MAP_READ, 0, &mappedResource))) {
|
||||
std::cerr << "Failed to map readback buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
std::memcpy(&result, mappedResource.pData, sizeof(result));
|
||||
context->Unmap(readBuffer.ptr(), 0);
|
||||
|
||||
std::cout << "Sum of the numbers 1 to " << srcData.size() << " = " << result << std::endl;
|
||||
context->ClearState();
|
||||
return 0;
|
||||
}
|
@ -1,304 +0,0 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
#include <d3d11_4.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
#undef ENUM_NAME
|
||||
#define ENUM_NAME(e) case e: return #e;
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
std::string GetFormatName(DXGI_FORMAT Format) {
|
||||
switch (Format) {
|
||||
ENUM_NAME(DXGI_FORMAT_UNKNOWN);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32B32A32_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32B32A32_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32B32A32_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32B32A32_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32B32_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32B32_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32B32_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32B32_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16B16A16_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16B16A16_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16B16A16_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16B16A16_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16B16A16_SNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16B16A16_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G32_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32G8X24_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R10G10B10A2_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R10G10B10A2_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R10G10B10A2_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R11G11B10_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8B8A8_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8B8A8_SNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8B8A8_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16_SNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R16G16_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_D32_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R32_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R24G8_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_D24_UNORM_S8_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R24_UNORM_X8_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_X24_TYPELESS_G8_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8_SNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R16_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R16_FLOAT);
|
||||
ENUM_NAME(DXGI_FORMAT_D16_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R16_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R16_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R16_SNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R16_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R8_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_R8_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R8_UINT);
|
||||
ENUM_NAME(DXGI_FORMAT_R8_SNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R8_SINT);
|
||||
ENUM_NAME(DXGI_FORMAT_A8_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R1_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R9G9B9E5_SHAREDEXP);
|
||||
ENUM_NAME(DXGI_FORMAT_R8G8_B8G8_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_G8R8_G8B8_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_BC1_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_BC1_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_BC1_UNORM_SRGB);
|
||||
ENUM_NAME(DXGI_FORMAT_BC2_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_BC2_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_BC2_UNORM_SRGB);
|
||||
ENUM_NAME(DXGI_FORMAT_BC3_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_BC3_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_BC3_UNORM_SRGB);
|
||||
ENUM_NAME(DXGI_FORMAT_BC4_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_BC4_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_BC4_SNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_BC5_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_BC5_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_BC5_SNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_B5G6R5_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_B5G5R5A1_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_B8G8R8A8_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_B8G8R8X8_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_B8G8R8A8_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB);
|
||||
ENUM_NAME(DXGI_FORMAT_B8G8R8X8_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB);
|
||||
ENUM_NAME(DXGI_FORMAT_BC6H_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_BC6H_UF16);
|
||||
ENUM_NAME(DXGI_FORMAT_BC6H_SF16);
|
||||
ENUM_NAME(DXGI_FORMAT_BC7_TYPELESS);
|
||||
ENUM_NAME(DXGI_FORMAT_BC7_UNORM);
|
||||
ENUM_NAME(DXGI_FORMAT_BC7_UNORM_SRGB);
|
||||
default: return std::to_string(Format);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string GetFormatFlagName(D3D11_FORMAT_SUPPORT Flag) {
|
||||
switch (Flag) {
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_BUFFER);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_SO_BUFFER);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_TEXTURE1D);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_TEXTURE2D);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_TEXTURE3D);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_TEXTURECUBE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_LOAD);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_MIP);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_MIP_AUTOGEN);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_RENDER_TARGET);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_BLENDABLE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_DEPTH_STENCIL);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_CPU_LOCKABLE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_DISPLAY);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_GATHER);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_BACK_BUFFER_CAST);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_DECODER_OUTPUT);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT_VIDEO_ENCODER);
|
||||
default: return std::to_string(Flag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string GetFormatFlagName2(UINT Flag) {
|
||||
switch (Flag) {
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_TILED);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_SHAREABLE);
|
||||
ENUM_NAME(D3D11_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY);
|
||||
default: return std::to_string(Flag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
Com<ID3D11Device> device;
|
||||
|
||||
if (FAILED(D3D11CreateDevice(
|
||||
nullptr, D3D_DRIVER_TYPE_HARDWARE,
|
||||
nullptr, 0, nullptr, 0, D3D11_SDK_VERSION,
|
||||
&device, nullptr, nullptr))) {
|
||||
std::cerr << "Failed to create D3D11 device" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_FEATURE_DATA_THREADING featureThreading = { };
|
||||
D3D11_FEATURE_DATA_DOUBLES featureDoubles = { };
|
||||
D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT featureMinPrecision = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS featureD3D11Options = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS1 featureD3D11Options1 = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS2 featureD3D11Options2 = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS3 featureD3D11Options3 = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS4 featureD3D11Options4 = { };
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_THREADING, &featureThreading, sizeof(featureThreading)))) {
|
||||
std::cout << "D3D11_FEATURE_THREADING:" << std::endl
|
||||
<< " DriverConcurrentCreates: " << featureThreading.DriverConcurrentCreates << std::endl
|
||||
<< " DriverCommandLists: " << featureThreading.DriverCommandLists << std::endl;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_DOUBLES, &featureDoubles, sizeof(featureDoubles)))) {
|
||||
std::cout << "D3D11_FEATURE_DOUBLES:" << std::endl
|
||||
<< " DoublePrecisionFloatShaderOps: " << featureDoubles.DoublePrecisionFloatShaderOps << std::endl;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT, &featureMinPrecision, sizeof(featureMinPrecision)))) {
|
||||
std::cout << "D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT:" << std::endl
|
||||
<< " PixelShaderMinPrecision: " << featureMinPrecision.PixelShaderMinPrecision << std::endl
|
||||
<< " AllOtherShaderStagesMinPrecision: " << featureMinPrecision.AllOtherShaderStagesMinPrecision << std::endl;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &featureD3D11Options, sizeof(featureD3D11Options)))) {
|
||||
std::cout << "D3D11_FEATURE_D3D11_OPTIONS:" << std::endl
|
||||
<< " OutputMergerLogicOp: " << featureD3D11Options.OutputMergerLogicOp << std::endl
|
||||
<< " UAVOnlyRenderingForcedSampleCount: " << featureD3D11Options.UAVOnlyRenderingForcedSampleCount << std::endl
|
||||
<< " DiscardAPIsSeenByDriver: " << featureD3D11Options.DiscardAPIsSeenByDriver << std::endl
|
||||
<< " FlagsForUpdateAndCopySeenByDriver: " << featureD3D11Options.FlagsForUpdateAndCopySeenByDriver << std::endl
|
||||
<< " ClearView: " << featureD3D11Options.ClearView << std::endl
|
||||
<< " CopyWithOverlap: " << featureD3D11Options.CopyWithOverlap << std::endl
|
||||
<< " ConstantBufferPartialUpdate: " << featureD3D11Options.ConstantBufferPartialUpdate << std::endl
|
||||
<< " ConstantBufferOffsetting: " << featureD3D11Options.ConstantBufferOffsetting << std::endl
|
||||
<< " MapNoOverwriteOnDynamicConstantBuffer: " << featureD3D11Options.MapNoOverwriteOnDynamicConstantBuffer << std::endl
|
||||
<< " MapNoOverwriteOnDynamicBufferSRV: " << featureD3D11Options.MapNoOverwriteOnDynamicBufferSRV << std::endl
|
||||
<< " MultisampleRTVWithForcedSampleCountOne: " << featureD3D11Options.MultisampleRTVWithForcedSampleCountOne << std::endl
|
||||
<< " SAD4ShaderInstructions: " << featureD3D11Options.SAD4ShaderInstructions << std::endl
|
||||
<< " ExtendedDoublesShaderInstructions: " << featureD3D11Options.ExtendedDoublesShaderInstructions << std::endl
|
||||
<< " ExtendedResourceSharing: " << featureD3D11Options.ExtendedResourceSharing << std::endl;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS1, &featureD3D11Options1, sizeof(featureD3D11Options1)))) {
|
||||
std::cout << "D3D11_FEATURE_D3D11_OPTIONS1:" << std::endl
|
||||
<< " TiledResourcesTier: " << featureD3D11Options1.TiledResourcesTier << std::endl
|
||||
<< " MinMaxFiltering: " << featureD3D11Options1.MinMaxFiltering << std::endl
|
||||
<< " ClearViewAlsoSupportsDepthOnlyFormats: " << featureD3D11Options1.ClearViewAlsoSupportsDepthOnlyFormats << std::endl
|
||||
<< " MapOnDefaultBuffers: " << featureD3D11Options1.MapOnDefaultBuffers << std::endl;
|
||||
|
||||
}
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &featureD3D11Options2, sizeof(featureD3D11Options2)))) {
|
||||
std::cout << "D3D11_FEATURE_D3D11_OPTIONS2:" << std::endl
|
||||
<< " PSSpecifiedStencilRefSupported: " << featureD3D11Options2.PSSpecifiedStencilRefSupported << std::endl
|
||||
<< " TypedUAVLoadAdditionalFormats: " << featureD3D11Options2.TypedUAVLoadAdditionalFormats << std::endl
|
||||
<< " ROVsSupported: " << featureD3D11Options2.ROVsSupported << std::endl
|
||||
<< " ConservativeRasterizationTier: " << featureD3D11Options2.ConservativeRasterizationTier << std::endl
|
||||
<< " MapOnDefaultTextures: " << featureD3D11Options2.MapOnDefaultTextures << std::endl
|
||||
<< " TiledResourcesTier: " << featureD3D11Options2.TiledResourcesTier << std::endl
|
||||
<< " StandardSwizzle: " << featureD3D11Options2.StandardSwizzle << std::endl
|
||||
<< " UnifiedMemoryArchitecture: " << featureD3D11Options2.UnifiedMemoryArchitecture << std::endl;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &featureD3D11Options3, sizeof(featureD3D11Options3)))) {
|
||||
std::cout << "D3D11_FEATURE_D3D11_OPTIONS3:" << std::endl
|
||||
<< " VPAndRTArrayIndexFromAnyShaderFeedingRasterizer: " << featureD3D11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer << std::endl;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS4, &featureD3D11Options4, sizeof(featureD3D11Options4)))) {
|
||||
std::cout << "D3D11_FEATURE_D3D11_OPTIONS4:" << std::endl
|
||||
<< " ExtendedNV12SharedTextureSupported: " << featureD3D11Options4.ExtendedNV12SharedTextureSupported << std::endl;
|
||||
}
|
||||
|
||||
for (UINT i = UINT(DXGI_FORMAT_UNKNOWN);
|
||||
i <= UINT(DXGI_FORMAT_BC7_UNORM_SRGB);
|
||||
i++) {
|
||||
DXGI_FORMAT format = DXGI_FORMAT(i);
|
||||
UINT flags = 0;
|
||||
|
||||
std::cout << GetFormatName(format) << ": " << std::endl;
|
||||
|
||||
if (SUCCEEDED(device->CheckFormatSupport(format, &flags))) {
|
||||
for (uint32_t i = 0; i < 32; i++) {
|
||||
if (flags & (1 << i)) {
|
||||
std::cout << " "
|
||||
<< GetFormatFlagName(D3D11_FORMAT_SUPPORT(1 << i))
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
D3D11_FEATURE_DATA_FORMAT_SUPPORT2 support2 = { };
|
||||
support2.InFormat = format;
|
||||
|
||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &support2, sizeof(support2)))) {
|
||||
for (uint32_t i = 0; i < 32; i++) {
|
||||
if (support2.OutFormatSupport2 & (1u << i)) {
|
||||
std::cout << " "
|
||||
<< GetFormatFlagName2(1u << i)
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::cout << " Not supported" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,203 +0,0 @@
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
const std::string g_vsCode =
|
||||
"float4 main(float4 v_pos : VS_POSITION) : SV_POSITION {\n"
|
||||
" return v_pos;\n"
|
||||
"}\n";
|
||||
|
||||
Com<ID3D11Device> g_d3d11Device;
|
||||
Com<ID3D11DeviceContext> g_d3d11Context;
|
||||
|
||||
Com<ID3D11VertexShader> g_vertShader;
|
||||
Com<ID3D11InputLayout> g_inputLayout;
|
||||
|
||||
Com<ID3D11Buffer> g_vertexBuffer;
|
||||
|
||||
Com<ID3D11Texture2D> g_depthRender;
|
||||
Com<ID3D11Texture2D> g_depthRead;
|
||||
Com<ID3D11DepthStencilView> g_depthView;
|
||||
Com<ID3D11DepthStencilState>g_depthState;
|
||||
|
||||
struct Vertex {
|
||||
float x, y, z, w;
|
||||
};
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
if (FAILED(D3D11CreateDevice(
|
||||
nullptr, D3D_DRIVER_TYPE_HARDWARE,
|
||||
nullptr, 0, nullptr, 0, D3D11_SDK_VERSION,
|
||||
&g_d3d11Device, nullptr, &g_d3d11Context))) {
|
||||
std::cerr << "Failed to create D3D11 device" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Com<ID3DBlob> vsBlob;
|
||||
Com<ID3DBlob> gsBlob;
|
||||
|
||||
if (FAILED(D3DCompile(g_vsCode.data(), g_vsCode.size(),
|
||||
"Vertex shader", nullptr, nullptr, "main", "vs_4_0",
|
||||
0, 0, &vsBlob, nullptr))) {
|
||||
std::cerr << "Failed to compile vertex shader" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateVertexShader(
|
||||
vsBlob->GetBufferPointer(),
|
||||
vsBlob->GetBufferSize(),
|
||||
nullptr, &g_vertShader))) {
|
||||
std::cerr << "Failed to create vertex shader" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::array<D3D11_INPUT_ELEMENT_DESC, 1> iaElements = {{
|
||||
{ "VS_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
}};
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateInputLayout(
|
||||
iaElements.data(),
|
||||
iaElements.size(),
|
||||
vsBlob->GetBufferPointer(),
|
||||
vsBlob->GetBufferSize(),
|
||||
&g_inputLayout))) {
|
||||
std::cerr << "Failed to create input layout" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::array<Vertex, 4> vertexData = {{
|
||||
{ -1.0f, -1.0f, 0.00f, 1.0f },
|
||||
{ -1.0f, 1.0f, 0.66f, 1.0f },
|
||||
{ 1.0f, -1.0f, 0.33f, 1.0f },
|
||||
{ 1.0f, 1.0f, 1.00f, 1.0f },
|
||||
}};
|
||||
|
||||
D3D11_BUFFER_DESC vertexDesc;
|
||||
vertexDesc.ByteWidth = vertexData.size() * sizeof(Vertex);
|
||||
vertexDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
vertexDesc.CPUAccessFlags = 0;
|
||||
vertexDesc.MiscFlags = 0;
|
||||
vertexDesc.StructureByteStride = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexInfo;
|
||||
vertexInfo.pSysMem = vertexData.data();
|
||||
vertexInfo.SysMemPitch = vertexDesc.ByteWidth;
|
||||
vertexInfo.SysMemSlicePitch = vertexDesc.ByteWidth;
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateBuffer(&vertexDesc, &vertexInfo, &g_vertexBuffer))) {
|
||||
std::cerr << "Failed to create vertex buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC depthDesc;
|
||||
depthDesc.Width = 16;
|
||||
depthDesc.Height = 16;
|
||||
depthDesc.MipLevels = 1;
|
||||
depthDesc.ArraySize = 1;
|
||||
depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
// depthDesc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
||||
depthDesc.SampleDesc = { 1, 0 };
|
||||
depthDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
|
||||
depthDesc.CPUAccessFlags = 0;
|
||||
depthDesc.MiscFlags = 0;
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateTexture2D(&depthDesc, nullptr, &g_depthRender))) {
|
||||
std::cerr << "Failed to create render buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
depthDesc.Usage = D3D11_USAGE_STAGING;
|
||||
depthDesc.BindFlags = 0;
|
||||
depthDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateTexture2D(&depthDesc, nullptr, &g_depthRead))) {
|
||||
std::cerr << "Failed to create readback buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateDepthStencilView(g_depthRender.ptr(), nullptr, &g_depthView))) {
|
||||
std::cerr << "Failed to create depth-stencil view" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_DEPTH_STENCIL_DESC dsDesc;
|
||||
dsDesc.DepthEnable = TRUE;
|
||||
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||
dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
||||
dsDesc.StencilEnable = FALSE;
|
||||
dsDesc.StencilReadMask = 0;
|
||||
dsDesc.StencilWriteMask = 0;
|
||||
dsDesc.FrontFace = { };
|
||||
dsDesc.BackFace = { };
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateDepthStencilState(&dsDesc, &g_depthState))) {
|
||||
std::cerr << "Failed to create depth-stencil state" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
FLOAT omBlendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
D3D11_VIEWPORT omViewport;
|
||||
omViewport.TopLeftX = 0.0f;
|
||||
omViewport.TopLeftY = 0.0f;
|
||||
omViewport.Width = 16.0f;
|
||||
omViewport.Height = 16.0f;
|
||||
omViewport.MinDepth = 0.0f;
|
||||
omViewport.MaxDepth = 1.0f;
|
||||
|
||||
UINT vbOffset = 0;
|
||||
UINT vbStride = sizeof(Vertex);
|
||||
|
||||
g_d3d11Context->RSSetState(nullptr);
|
||||
g_d3d11Context->RSSetViewports(1, &omViewport);
|
||||
|
||||
g_d3d11Context->OMSetRenderTargets(0, nullptr, g_depthView.ptr());
|
||||
g_d3d11Context->OMSetBlendState(nullptr, omBlendFactor, 0xFFFFFFFF);
|
||||
g_d3d11Context->OMSetDepthStencilState(g_depthState.ptr(), 0);
|
||||
|
||||
g_d3d11Context->ClearDepthStencilView(g_depthView.ptr(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.5f, 0x80);
|
||||
|
||||
g_d3d11Context->IASetInputLayout(g_inputLayout.ptr());
|
||||
g_d3d11Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
g_d3d11Context->IASetVertexBuffers(0, 1, &g_vertexBuffer, &vbStride, &vbOffset);
|
||||
|
||||
g_d3d11Context->VSSetShader(g_vertShader.ptr(), nullptr, 0);
|
||||
g_d3d11Context->Draw(4, 0);
|
||||
|
||||
g_d3d11Context->CopyResource(g_depthRead.ptr(), g_depthRender.ptr());
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
|
||||
if (FAILED(g_d3d11Context->Map(g_depthRead.ptr(), 0, D3D11_MAP_READ, 0, &mapped))) {
|
||||
std::cerr << "Failed to map image" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (uint32_t y = 0; y < 16; y++) {
|
||||
auto data = reinterpret_cast<const uint32_t*>(mapped.pData)
|
||||
+ (y * mapped.RowPitch / 4);
|
||||
|
||||
for (uint32_t x = 0; x < 16; x++)
|
||||
std::cout << std::hex << std::setfill('0') << std::setw(8) << data[x] << " ";
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
g_d3d11Context->Unmap(g_depthRead.ptr(), 0);
|
||||
g_d3d11Context->ClearState();
|
||||
return 0;
|
||||
}
|
@ -1,288 +0,0 @@
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
const std::string g_vsCode =
|
||||
"struct VS_IFACE {\n"
|
||||
" float4 pos : VS_POSITION;\n"
|
||||
"};\n"
|
||||
"VS_IFACE main(VS_IFACE ia_in) {\n"
|
||||
" return ia_in;\n"
|
||||
"}\n";
|
||||
|
||||
const std::string g_gsCode =
|
||||
"struct GS_IN {\n"
|
||||
" float4 pos : VS_POSITION;\n"
|
||||
"};\n"
|
||||
"struct GS_OUT_NORMAL {\n"
|
||||
" float3 nor : GS_NORMAL;\n"
|
||||
" float len : GS_LENGTH;\n"
|
||||
"};\n"
|
||||
"[maxvertexcount(1)]\n"
|
||||
"void main(triangle GS_IN vs_in[3], inout PointStream<GS_OUT_NORMAL> o_normals) {\n"
|
||||
" float3 ds1 = vs_in[1].pos.xyz - vs_in[0].pos.xyz;\n"
|
||||
" float3 ds2 = vs_in[2].pos.xyz - vs_in[0].pos.xyz;\n"
|
||||
" float3 cv = cross(ds1, ds2);\n"
|
||||
" float cl = length(cv);\n"
|
||||
" GS_OUT_NORMAL normal;\n"
|
||||
" normal.nor = cv / cl;\n"
|
||||
" normal.len = cl;"
|
||||
" o_normals.Append(normal);\n"
|
||||
"}\n";
|
||||
|
||||
Com<ID3D11Device> g_d3d11Device;
|
||||
Com<ID3D11DeviceContext> g_d3d11Context;
|
||||
|
||||
Com<ID3D11VertexShader> g_vertShader;
|
||||
Com<ID3D11GeometryShader> g_geomShader;
|
||||
|
||||
Com<ID3D11InputLayout> g_inputLayout;
|
||||
|
||||
Com<ID3D11Buffer> g_vertexBuffer;
|
||||
Com<ID3D11Buffer> g_normalBuffer;
|
||||
Com<ID3D11Buffer> g_readBuffer;
|
||||
|
||||
Com<ID3D11Query> g_soStream;
|
||||
Com<ID3D11Query> g_soOverflow;
|
||||
|
||||
struct Vertex {
|
||||
float x, y, z, w;
|
||||
};
|
||||
|
||||
struct Normal {
|
||||
float x, y, z, len;
|
||||
};
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
if (FAILED(D3D11CreateDevice(
|
||||
nullptr, D3D_DRIVER_TYPE_HARDWARE,
|
||||
nullptr, 0, nullptr, 0, D3D11_SDK_VERSION,
|
||||
&g_d3d11Device, nullptr, &g_d3d11Context))) {
|
||||
std::cerr << "Failed to create D3D11 device" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Com<ID3DBlob> vsBlob;
|
||||
Com<ID3DBlob> gsBlob;
|
||||
|
||||
if (FAILED(D3DCompile(g_vsCode.data(), g_vsCode.size(),
|
||||
"Vertex shader", nullptr, nullptr, "main", "vs_4_0",
|
||||
0, 0, &vsBlob, nullptr))) {
|
||||
std::cerr << "Failed to compile vertex shader" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (FAILED(D3DCompile(g_gsCode.data(), g_gsCode.size(),
|
||||
"Geometry shader", nullptr, nullptr, "main", "gs_4_0",
|
||||
0, 0, &gsBlob, nullptr))) {
|
||||
std::cerr << "Failed to compile geometry shader" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateVertexShader(
|
||||
vsBlob->GetBufferPointer(),
|
||||
vsBlob->GetBufferSize(),
|
||||
nullptr, &g_vertShader))) {
|
||||
std::cerr << "Failed to create vertex shader" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::array<D3D11_SO_DECLARATION_ENTRY, 2> soDeclarations = {{
|
||||
{ 0, "GS_NORMAL", 0, 0, 3, 0 },
|
||||
{ 0, "GS_LENGTH", 0, 0, 1, 0 },
|
||||
}};
|
||||
|
||||
std::array<UINT, 1> soBufferStrides = {{
|
||||
sizeof(Normal),
|
||||
}};
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateGeometryShaderWithStreamOutput(
|
||||
gsBlob->GetBufferPointer(),
|
||||
gsBlob->GetBufferSize(),
|
||||
soDeclarations.data(),
|
||||
soDeclarations.size(),
|
||||
soBufferStrides.data(),
|
||||
soBufferStrides.size(),
|
||||
D3D11_SO_NO_RASTERIZED_STREAM,
|
||||
nullptr, &g_geomShader))) {
|
||||
std::cerr << "Failed to create geometry shader" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::array<D3D11_INPUT_ELEMENT_DESC, 1> iaElements = {{
|
||||
{ "VS_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
}};
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateInputLayout(
|
||||
iaElements.data(),
|
||||
iaElements.size(),
|
||||
vsBlob->GetBufferPointer(),
|
||||
vsBlob->GetBufferSize(),
|
||||
&g_inputLayout))) {
|
||||
std::cerr << "Failed to create input layout" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::array<Vertex, 9> vertexData = {{
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ 1.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ 0.0f, 1.0f, 0.0f, 1.0f },
|
||||
|
||||
{ 0.5f,-1.0f,-0.2f, 1.0f },
|
||||
{ 3.2f, 2.0f, 0.0f, 1.0f },
|
||||
{-1.0f,-1.0f, 0.4f, 1.0f },
|
||||
|
||||
{ 0.7f,-0.5f,-0.8f, 1.0f },
|
||||
{ 1.2f, 1.0f,-1.0f, 1.0f },
|
||||
{-0.1f, 1.0f,-2.7f, 1.0f },
|
||||
}};
|
||||
|
||||
D3D11_BUFFER_DESC vertexDesc;
|
||||
vertexDesc.ByteWidth = vertexData.size() * sizeof(Vertex);
|
||||
vertexDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
vertexDesc.CPUAccessFlags = 0;
|
||||
vertexDesc.MiscFlags = 0;
|
||||
vertexDesc.StructureByteStride = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexInfo;
|
||||
vertexInfo.pSysMem = vertexData.data();
|
||||
vertexInfo.SysMemPitch = vertexDesc.ByteWidth;
|
||||
vertexInfo.SysMemSlicePitch = vertexDesc.ByteWidth;
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateBuffer(&vertexDesc, &vertexInfo, &g_vertexBuffer))) {
|
||||
std::cerr << "Failed to create vertex buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::array<Normal, 2> normalData = { };
|
||||
|
||||
D3D11_BUFFER_DESC normalDesc;
|
||||
normalDesc.ByteWidth = normalData.size() * sizeof(Normal);
|
||||
normalDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
normalDesc.BindFlags = D3D11_BIND_STREAM_OUTPUT;
|
||||
normalDesc.CPUAccessFlags = 0;
|
||||
normalDesc.MiscFlags = 0;
|
||||
normalDesc.StructureByteStride = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA normalInfo;
|
||||
normalInfo.pSysMem = normalData.data();
|
||||
normalInfo.SysMemPitch = normalDesc.ByteWidth;
|
||||
normalInfo.SysMemSlicePitch = normalDesc.ByteWidth;
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateBuffer(&normalDesc, &normalInfo, &g_normalBuffer))) {
|
||||
std::cerr << "Failed to create normal buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_BUFFER_DESC readDesc;
|
||||
readDesc.ByteWidth = normalDesc.ByteWidth;
|
||||
readDesc.Usage = D3D11_USAGE_STAGING;
|
||||
readDesc.BindFlags = 0;
|
||||
readDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
readDesc.MiscFlags = 0;
|
||||
readDesc.StructureByteStride = 0;
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateBuffer(&readDesc, nullptr, &g_readBuffer))) {
|
||||
std::cerr << "Failed to create readback buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
D3D11_QUERY_DESC soQueryDesc;
|
||||
soQueryDesc.Query = D3D11_QUERY_SO_STATISTICS_STREAM0;
|
||||
soQueryDesc.MiscFlags = 0;
|
||||
|
||||
if (FAILED(g_d3d11Device->CreateQuery(&soQueryDesc, &g_soStream))) {
|
||||
std::cerr << "Failed to create streamout query" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
soQueryDesc.Query = D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0;
|
||||
if (FAILED(g_d3d11Device->CreateQuery(&soQueryDesc, &g_soOverflow))) {
|
||||
std::cerr << "Failed to create streamout overflow query" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
UINT soOffset = 0;
|
||||
UINT vbOffset = 0;
|
||||
UINT vbStride = sizeof(Vertex);
|
||||
|
||||
FLOAT omBlendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
D3D11_VIEWPORT omViewport;
|
||||
omViewport.TopLeftX = 0.0f;
|
||||
omViewport.TopLeftY = 0.0f;
|
||||
omViewport.Width = 256.0f;
|
||||
omViewport.Height = 256.0f;
|
||||
omViewport.MinDepth = 0.0f;
|
||||
omViewport.MaxDepth = 1.0f;
|
||||
|
||||
g_d3d11Context->IASetInputLayout(g_inputLayout.ptr());
|
||||
g_d3d11Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
g_d3d11Context->IASetVertexBuffers(0, 1, &g_vertexBuffer, &vbStride, &vbOffset);
|
||||
|
||||
g_d3d11Context->RSSetState(nullptr);
|
||||
g_d3d11Context->RSSetViewports(1, &omViewport);
|
||||
|
||||
g_d3d11Context->OMSetRenderTargets(0, nullptr, nullptr);
|
||||
g_d3d11Context->OMSetBlendState(nullptr, omBlendFactor, 0xFFFFFFFF);
|
||||
g_d3d11Context->OMSetDepthStencilState(nullptr, 0);
|
||||
|
||||
g_d3d11Context->SOSetTargets(1, &g_normalBuffer, &soOffset);
|
||||
|
||||
g_d3d11Context->VSSetShader(g_vertShader.ptr(), nullptr, 0);
|
||||
g_d3d11Context->GSSetShader(g_geomShader.ptr(), nullptr, 0);
|
||||
|
||||
g_d3d11Context->Begin(g_soStream.ptr());
|
||||
g_d3d11Context->Begin(g_soOverflow.ptr());
|
||||
|
||||
g_d3d11Context->Draw(vertexData.size(), 0);
|
||||
|
||||
g_d3d11Context->End(g_soOverflow.ptr());
|
||||
g_d3d11Context->End(g_soStream.ptr());
|
||||
|
||||
g_d3d11Context->CopyResource(
|
||||
g_readBuffer.ptr(),
|
||||
g_normalBuffer.ptr());
|
||||
|
||||
D3D11_QUERY_DATA_SO_STATISTICS soQueryData = { };
|
||||
BOOL soOverflowData = false;
|
||||
|
||||
while (g_d3d11Context->GetData(g_soStream.ptr(), &soQueryData, sizeof(soQueryData), 0) != S_OK
|
||||
|| g_d3d11Context->GetData(g_soOverflow.ptr(), &soOverflowData, sizeof(soOverflowData), 0) != S_OK)
|
||||
continue;
|
||||
|
||||
std::cout << "Written: " << soQueryData.NumPrimitivesWritten << std::endl;
|
||||
std::cout << "Needed: " << soQueryData.PrimitivesStorageNeeded << std::endl;
|
||||
std::cout << "Overflow: " << (soOverflowData ? "Yes" : "No") << std::endl;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapInfo;
|
||||
|
||||
if (FAILED(g_d3d11Context->Map(g_readBuffer.ptr(), 0, D3D11_MAP_READ, 0, &mapInfo))) {
|
||||
std::cerr << "Failed to map readback buffer" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::memcpy(normalData.data(), mapInfo.pData, normalDesc.ByteWidth);
|
||||
g_d3d11Context->Unmap(g_readBuffer.ptr(), 0);
|
||||
|
||||
for (uint32_t i = 0; i < normalData.size(); i++) {
|
||||
std::cout << i << ": " << normalData[i].x << ","
|
||||
<< normalData[i].y << "," << normalData[i].z << ","
|
||||
<< normalData[i].len << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,606 +0,0 @@
|
||||
#include <d3dcompiler.h>
|
||||
#include <d3d11_1.h>
|
||||
#include <dxgi1_3.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
struct Vertex {
|
||||
float x, y;
|
||||
};
|
||||
|
||||
struct VsConstants {
|
||||
float x, y;
|
||||
float w, h;
|
||||
};
|
||||
|
||||
struct VsConstantsPad {
|
||||
VsConstants data;
|
||||
uint32_t pad[60];
|
||||
};
|
||||
|
||||
struct PsConstants {
|
||||
float r, g, b, a;
|
||||
};
|
||||
|
||||
struct DrawOptions {
|
||||
bool mapDiscardOnce;
|
||||
bool sortByTexture;
|
||||
bool drawIndexed;
|
||||
};
|
||||
|
||||
const std::string g_vertexShaderCode =
|
||||
"cbuffer vs_cb : register(b0) {\n"
|
||||
" float2 v_offset;\n"
|
||||
" float2 v_scale;\n"
|
||||
"};\n"
|
||||
"float4 main(float4 v_pos : IN_POSITION) : SV_POSITION {\n"
|
||||
" float2 coord = 2.0f * (v_pos * v_scale + v_offset) - 1.0f;\n"
|
||||
" return float4(coord, 0.0f, 1.0f);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string g_pixelShaderCode =
|
||||
"Texture2D<float4> tex0 : register(t0);"
|
||||
"cbuffer ps_cb : register(b0) {\n"
|
||||
" float4 color;\n"
|
||||
"};\n"
|
||||
"float4 main() : SV_TARGET {\n"
|
||||
" return color * tex0.Load(int3(0, 0, 0));\n"
|
||||
"}\n";
|
||||
|
||||
class TriangleApp {
|
||||
|
||||
public:
|
||||
|
||||
TriangleApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
Com<ID3D11Device> device;
|
||||
|
||||
D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_1;
|
||||
|
||||
HRESULT status = D3D11CreateDevice(
|
||||
nullptr, D3D_DRIVER_TYPE_HARDWARE,
|
||||
nullptr, 0, &fl, 1, D3D11_SDK_VERSION,
|
||||
&device, nullptr, nullptr);
|
||||
|
||||
if (FAILED(status)) {
|
||||
std::cerr << "Failed to create D3D11 device" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&m_device)))) {
|
||||
std::cerr << "Failed to query ID3D11DeviceContext1" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Com<IDXGIDevice> dxgiDevice;
|
||||
|
||||
if (FAILED(m_device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)))) {
|
||||
std::cerr << "Failed to query DXGI device" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(dxgiDevice->GetAdapter(&m_adapter))) {
|
||||
std::cerr << "Failed to query DXGI adapter" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(m_adapter->GetParent(IID_PPV_ARGS(&m_factory)))) {
|
||||
std::cerr << "Failed to query DXGI factory" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
m_device->GetImmediateContext1(&m_context);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapDesc;
|
||||
swapDesc.Width = m_windowSizeW;
|
||||
swapDesc.Height = m_windowSizeH;
|
||||
swapDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
swapDesc.Stereo = FALSE;
|
||||
swapDesc.SampleDesc = { 1, 0 };
|
||||
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapDesc.BufferCount = 3;
|
||||
swapDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT
|
||||
| DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsDesc;
|
||||
fsDesc.RefreshRate = { 0, 0 };
|
||||
fsDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
fsDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
fsDesc.Windowed = TRUE;
|
||||
|
||||
Com<IDXGISwapChain1> swapChain;
|
||||
if (FAILED(m_factory->CreateSwapChainForHwnd(m_device.ptr(), m_window, &swapDesc, &fsDesc, nullptr, &swapChain))) {
|
||||
std::cerr << "Failed to create DXGI swap chain" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(swapChain->QueryInterface(IID_PPV_ARGS(&m_swapChain)))) {
|
||||
std::cerr << "Failed to query DXGI swap chain interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
m_factory->MakeWindowAssociation(m_window, 0);
|
||||
|
||||
Com<ID3DBlob> vertexShaderBlob;
|
||||
Com<ID3DBlob> pixelShaderBlob;
|
||||
|
||||
if (FAILED(D3DCompile(g_vertexShaderCode.data(), g_vertexShaderCode.size(),
|
||||
"Vertex shader", nullptr, nullptr, "main", "vs_5_0", 0, 0, &vertexShaderBlob, nullptr))) {
|
||||
std::cerr << "Failed to compile vertex shader" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(D3DCompile(g_pixelShaderCode.data(), g_pixelShaderCode.size(),
|
||||
"Pixel shader", nullptr, nullptr, "main", "ps_5_0", 0, 0, &pixelShaderBlob, nullptr))) {
|
||||
std::cerr << "Failed to compile pixel shader" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(m_device->CreateVertexShader(
|
||||
vertexShaderBlob->GetBufferPointer(),
|
||||
vertexShaderBlob->GetBufferSize(),
|
||||
nullptr, &m_vs))) {
|
||||
std::cerr << "Failed to create vertex shader" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(m_device->CreatePixelShader(
|
||||
pixelShaderBlob->GetBufferPointer(),
|
||||
pixelShaderBlob->GetBufferSize(),
|
||||
nullptr, &m_ps))) {
|
||||
std::cerr << "Failed to create pixel shader" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<D3D11_INPUT_ELEMENT_DESC, 1> vertexFormatDesc = {{
|
||||
{ "IN_POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
}};
|
||||
|
||||
if (FAILED(m_device->CreateInputLayout(
|
||||
vertexFormatDesc.data(),
|
||||
vertexFormatDesc.size(),
|
||||
vertexShaderBlob->GetBufferPointer(),
|
||||
vertexShaderBlob->GetBufferSize(),
|
||||
&m_vertexFormat))) {
|
||||
std::cerr << "Failed to create input layout" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<Vertex, 6> vertexData = {{
|
||||
Vertex { -0.3f, 0.1f },
|
||||
Vertex { 0.5f, 0.9f },
|
||||
Vertex { 1.3f, 0.1f },
|
||||
Vertex { -0.3f, 0.9f },
|
||||
Vertex { 1.3f, 0.9f },
|
||||
Vertex { 0.5f, 0.1f },
|
||||
}};
|
||||
|
||||
D3D11_BUFFER_DESC vboDesc;
|
||||
vboDesc.ByteWidth = sizeof(vertexData);
|
||||
vboDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
vboDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
vboDesc.CPUAccessFlags = 0;
|
||||
vboDesc.MiscFlags = 0;
|
||||
vboDesc.StructureByteStride = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vboData;
|
||||
vboData.pSysMem = vertexData.data();
|
||||
vboData.SysMemPitch = vboDesc.ByteWidth;
|
||||
vboData.SysMemSlicePitch = vboDesc.ByteWidth;
|
||||
|
||||
if (FAILED(m_device->CreateBuffer(&vboDesc, &vboData, &m_vbo))) {
|
||||
std::cerr << "Failed to create index buffer" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<uint32_t, 6> indexData = {{ 0, 1, 2, 3, 4, 5 }};
|
||||
|
||||
D3D11_BUFFER_DESC iboDesc;
|
||||
iboDesc.ByteWidth = sizeof(indexData);
|
||||
iboDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
iboDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
iboDesc.CPUAccessFlags = 0;
|
||||
iboDesc.MiscFlags = 0;
|
||||
iboDesc.StructureByteStride = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA iboData;
|
||||
iboData.pSysMem = indexData.data();
|
||||
iboData.SysMemPitch = iboDesc.ByteWidth;
|
||||
iboData.SysMemSlicePitch = iboDesc.ByteWidth;
|
||||
|
||||
if (FAILED(m_device->CreateBuffer(&iboDesc, &iboData, &m_ibo))) {
|
||||
std::cerr << "Failed to create index buffer" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_BUFFER_DESC cbDesc;
|
||||
cbDesc.ByteWidth = sizeof(PsConstants);
|
||||
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
cbDesc.MiscFlags = 0;
|
||||
cbDesc.StructureByteStride = 0;
|
||||
|
||||
if (FAILED(m_device->CreateBuffer(&cbDesc, nullptr, &m_cbPs))) {
|
||||
std::cerr << "Failed to create constant buffer" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
cbDesc.ByteWidth = sizeof(VsConstantsPad) * 128 * 8;
|
||||
|
||||
if (FAILED(m_device->CreateBuffer(&cbDesc, nullptr, &m_cbVs))) {
|
||||
std::cerr << "Failed to create constant buffer" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<uint32_t, 2> colors = { 0xFFFFFFFF, 0xFFC0C0C0 };
|
||||
|
||||
D3D11_SUBRESOURCE_DATA texData;
|
||||
texData.pSysMem = &colors[0];
|
||||
texData.SysMemPitch = sizeof(colors[0]);
|
||||
texData.SysMemSlicePitch = sizeof(colors[0]);
|
||||
|
||||
D3D11_TEXTURE2D_DESC texDesc;
|
||||
texDesc.Width = 1;
|
||||
texDesc.Height = 1;
|
||||
texDesc.MipLevels = 1;
|
||||
texDesc.ArraySize = 1;
|
||||
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
texDesc.SampleDesc = { 1, 0 };
|
||||
texDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
texDesc.CPUAccessFlags = 0;
|
||||
texDesc.MiscFlags = 0;
|
||||
|
||||
if (FAILED(m_device->CreateTexture2D(&texDesc, &texData, &m_tex0))) {
|
||||
std::cerr << "Failed to create texture" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
texData.pSysMem = &colors[1];
|
||||
|
||||
if (FAILED(m_device->CreateTexture2D(&texDesc, &texData, &m_tex1))) {
|
||||
std::cerr << "Failed to create texture" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(m_device->CreateShaderResourceView(m_tex0.ptr(), nullptr, &m_srv0))
|
||||
|| FAILED(m_device->CreateShaderResourceView(m_tex1.ptr(), nullptr, &m_srv1))) {
|
||||
std::cerr << "Failed to create SRV" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
~TriangleApp() {
|
||||
m_context->ClearState();
|
||||
}
|
||||
|
||||
|
||||
bool run() {
|
||||
if (!m_initialized)
|
||||
return false;
|
||||
|
||||
if (m_occluded && (m_occluded = isOccluded()))
|
||||
return true;
|
||||
|
||||
if (!beginFrame())
|
||||
return true;
|
||||
|
||||
std::array<PsConstants, 2> colors = {{
|
||||
PsConstants { 0.25f, 0.25f, 0.25f, 1.0f },
|
||||
PsConstants { 0.40f, 0.40f, 0.40f, 1.0f },
|
||||
}};
|
||||
|
||||
for (uint32_t i = 0; i < 8; i++) {
|
||||
DrawOptions options;
|
||||
options.sortByTexture = i & 1;
|
||||
options.drawIndexed = i & 2;
|
||||
options.mapDiscardOnce = i & 4;
|
||||
drawLines(colors[i & 1], options, i);
|
||||
}
|
||||
|
||||
if (!endFrame())
|
||||
return false;
|
||||
|
||||
updateFps();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void drawLines(const PsConstants& psData, const DrawOptions& options, uint32_t baseY) {
|
||||
D3D11_MAPPED_SUBRESOURCE sr;
|
||||
|
||||
// Update color for the row
|
||||
m_context->PSSetConstantBuffers(0, 1, &m_cbPs);
|
||||
m_context->Map(m_cbPs.ptr(), 0, D3D11_MAP_WRITE_DISCARD, 0, &sr);
|
||||
std::memcpy(sr.pData, &psData, sizeof(psData));
|
||||
m_context->Unmap(m_cbPs.ptr(), 0);
|
||||
|
||||
baseY *= 8;
|
||||
|
||||
if (options.mapDiscardOnce) {
|
||||
uint32_t drawIndex = 0;
|
||||
|
||||
// Discard and map the entire vertex constant buffer
|
||||
// once, then bind sub-ranges while emitting draw calls
|
||||
m_context->Map(m_cbVs.ptr(), 0, D3D11_MAP_WRITE_DISCARD, 0, &sr);
|
||||
auto vsData = reinterpret_cast<VsConstantsPad*>(sr.pData);
|
||||
|
||||
for (uint32_t y = 0; y < 8; y++) {
|
||||
for (uint32_t x = 0; x < 128; x++)
|
||||
vsData[drawIndex++].data = getVsConstants(x, baseY + y);
|
||||
}
|
||||
|
||||
m_context->Unmap(m_cbVs.ptr(), 0);
|
||||
}
|
||||
|
||||
if (options.drawIndexed)
|
||||
m_context->IASetIndexBuffer(m_ibo.ptr(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
uint32_t vsStride = sizeof(Vertex);
|
||||
uint32_t vsOffset = 0;
|
||||
m_context->IASetVertexBuffers(0, 1, &m_vbo, &vsStride, &vsOffset);
|
||||
|
||||
uint32_t maxZ = options.sortByTexture ? 2 : 1;
|
||||
|
||||
for (uint32_t z = 0; z < maxZ; z++) {
|
||||
uint32_t drawIndex = z;
|
||||
|
||||
if (options.sortByTexture) {
|
||||
ID3D11ShaderResourceView* view = z ? m_srv1.ptr() : m_srv0.ptr();
|
||||
m_context->PSSetShaderResources(0, 1, &view);
|
||||
}
|
||||
|
||||
for (uint32_t y = 0; y < 8; y++) {
|
||||
for (uint32_t x = z; x < 128; x += maxZ) {
|
||||
uint32_t triIndex = (x ^ y) & 1;
|
||||
|
||||
if (!options.mapDiscardOnce) {
|
||||
D3D11_MAP mapMode = drawIndex ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD;
|
||||
m_context->Map(m_cbVs.ptr(), 0, mapMode, 0, &sr);
|
||||
auto vsData = reinterpret_cast<VsConstantsPad*>(sr.pData);
|
||||
vsData[drawIndex].data = getVsConstants(x, baseY + y);
|
||||
m_context->Unmap(m_cbVs.ptr(), 0);
|
||||
}
|
||||
|
||||
uint32_t constantOffset = 16 * drawIndex;
|
||||
uint32_t constantCount = 16;
|
||||
m_context->VSSetConstantBuffers1(0, 1, &m_cbVs, &constantOffset, &constantCount);
|
||||
|
||||
if (!options.sortByTexture) {
|
||||
ID3D11ShaderResourceView* view = triIndex ? m_srv1.ptr() : m_srv0.ptr();
|
||||
m_context->PSSetShaderResources(0, 1, &view);
|
||||
}
|
||||
|
||||
// Submit draw call
|
||||
uint32_t baseIndex = 3 * triIndex;
|
||||
|
||||
if (options.drawIndexed)
|
||||
m_context->DrawIndexed(3, baseIndex, 0);
|
||||
else
|
||||
m_context->Draw(3, baseIndex);
|
||||
|
||||
drawIndex += maxZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static VsConstants getVsConstants(uint32_t x, uint32_t y) {
|
||||
VsConstants result;
|
||||
result.x = float(x) / 128.0f;
|
||||
result.y = float(y) / 64.0f;
|
||||
result.w = 1.0f / 128.0f;
|
||||
result.h = 1.0f / 64.0f;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool beginFrame() {
|
||||
// Make sure we can actually render to the window
|
||||
RECT windowRect = { 0, 0, 1024, 600 };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
uint32_t newWindowSizeW = uint32_t(windowRect.right - windowRect.left);
|
||||
uint32_t newWindowSizeH = uint32_t(windowRect.bottom - windowRect.top);
|
||||
|
||||
if (m_windowSizeW != newWindowSizeW || m_windowSizeH != newWindowSizeH) {
|
||||
m_rtv = nullptr;
|
||||
m_context->ClearState();
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 desc;
|
||||
m_swapChain->GetDesc1(&desc);
|
||||
|
||||
if (FAILED(m_swapChain->ResizeBuffers(desc.BufferCount,
|
||||
newWindowSizeW, newWindowSizeH, desc.Format, desc.Flags))) {
|
||||
std::cerr << "Failed to resize back buffers" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Com<ID3D11Texture2D> backBuffer;
|
||||
if (FAILED(m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)))) {
|
||||
std::cerr << "Failed to get swap chain back buffer" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
|
||||
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||
rtvDesc.Texture2D = { 0u };
|
||||
|
||||
if (FAILED(m_device->CreateRenderTargetView(backBuffer.ptr(), &rtvDesc, &m_rtv))) {
|
||||
std::cerr << "Failed to create render target view" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_windowSizeW = newWindowSizeW;
|
||||
m_windowSizeH = newWindowSizeH;
|
||||
}
|
||||
|
||||
// Set up render state
|
||||
FLOAT color[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
m_context->OMSetRenderTargets(1, &m_rtv, nullptr);
|
||||
m_context->ClearRenderTargetView(m_rtv.ptr(), color);
|
||||
|
||||
m_context->VSSetShader(m_vs.ptr(), nullptr, 0);
|
||||
m_context->PSSetShader(m_ps.ptr(), nullptr, 0);
|
||||
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->IASetInputLayout(m_vertexFormat.ptr());
|
||||
|
||||
D3D11_VIEWPORT viewport;
|
||||
viewport.TopLeftX = 0.0f;
|
||||
viewport.TopLeftY = 0.0f;
|
||||
viewport.Width = float(m_windowSizeW);
|
||||
viewport.Height = float(m_windowSizeH);
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
m_context->RSSetViewports(1, &viewport);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool endFrame() {
|
||||
HRESULT hr = m_swapChain->Present(0, DXGI_PRESENT_TEST);
|
||||
|
||||
if (hr == S_OK)
|
||||
hr = m_swapChain->Present(0, 0);
|
||||
|
||||
m_occluded = hr == DXGI_STATUS_OCCLUDED;
|
||||
return true;
|
||||
}
|
||||
|
||||
void updateFps() {
|
||||
if (!m_qpcFrequency.QuadPart)
|
||||
QueryPerformanceFrequency(&m_qpcFrequency);
|
||||
|
||||
if (!m_qpcLastUpdate.QuadPart)
|
||||
QueryPerformanceCounter(&m_qpcLastUpdate);
|
||||
|
||||
LARGE_INTEGER now;
|
||||
QueryPerformanceCounter(&now);
|
||||
|
||||
m_frameCount++;
|
||||
|
||||
if (now.QuadPart - m_qpcLastUpdate.QuadPart < m_qpcFrequency.QuadPart)
|
||||
return;
|
||||
|
||||
double seconds = double(now.QuadPart - m_qpcLastUpdate.QuadPart) / double(m_qpcFrequency.QuadPart);
|
||||
double fps = double(m_frameCount) / seconds;
|
||||
|
||||
std::wstringstream str;
|
||||
str << L"D3D11 triangle (" << fps << L" FPS)";
|
||||
|
||||
SetWindowTextW(m_window, str.str().c_str());
|
||||
|
||||
m_qpcLastUpdate = now;
|
||||
m_frameCount = 0;
|
||||
}
|
||||
|
||||
bool isOccluded() {
|
||||
return m_swapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
uint32_t m_windowSizeW = 1024;
|
||||
uint32_t m_windowSizeH = 600;
|
||||
bool m_initialized = false;
|
||||
bool m_occluded = false;
|
||||
|
||||
Com<IDXGIFactory3> m_factory;
|
||||
Com<IDXGIAdapter> m_adapter;
|
||||
Com<ID3D11Device1> m_device;
|
||||
Com<ID3D11DeviceContext1> m_context;
|
||||
Com<IDXGISwapChain2> m_swapChain;
|
||||
|
||||
Com<ID3D11RenderTargetView> m_rtv;
|
||||
Com<ID3D11Buffer> m_ibo;
|
||||
Com<ID3D11Buffer> m_vbo;
|
||||
Com<ID3D11InputLayout> m_vertexFormat;
|
||||
|
||||
Com<ID3D11Texture2D> m_tex0;
|
||||
Com<ID3D11Texture2D> m_tex1;
|
||||
Com<ID3D11ShaderResourceView> m_srv0;
|
||||
Com<ID3D11ShaderResourceView> m_srv1;
|
||||
|
||||
Com<ID3D11Buffer> m_cbPs;
|
||||
Com<ID3D11Buffer> m_cbVs;
|
||||
|
||||
Com<ID3D11VertexShader> m_vs;
|
||||
Com<ID3D11PixelShader> m_ps;
|
||||
|
||||
LARGE_INTEGER m_qpcLastUpdate = { };
|
||||
LARGE_INTEGER m_qpcFrequency = { };
|
||||
|
||||
uint32_t m_frameCount = 0;
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||
WNDCLASSEXW wc = { };
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = HBRUSH(COLOR_WINDOW);
|
||||
wc.lpszClassName = L"WindowClass";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
HWND hWnd = CreateWindowExW(0, L"WindowClass", L"D3D11 triangle",
|
||||
WS_OVERLAPPEDWINDOW, 300, 300, 1024, 600,
|
||||
nullptr, nullptr, hInstance, nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
TriangleApp app(hInstance, hWnd);
|
||||
|
||||
MSG msg;
|
||||
|
||||
while (true) {
|
||||
if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
if (!app.run())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProcW(hWnd, message, wParam, lParam);
|
||||
}
|
@ -1,459 +0,0 @@
|
||||
#include <d3d11_1.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
class VideoApp {
|
||||
|
||||
public:
|
||||
|
||||
VideoApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
// Create base D3D11 device and swap chain
|
||||
DXGI_SWAP_CHAIN_DESC swapchainDesc = { };
|
||||
swapchainDesc.BufferDesc.Width = m_windowSizeX;
|
||||
swapchainDesc.BufferDesc.Height = m_windowSizeY;
|
||||
swapchainDesc.BufferDesc.RefreshRate = { 0, 0 };
|
||||
swapchainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
swapchainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
swapchainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
swapchainDesc.BufferCount = 2;
|
||||
swapchainDesc.SampleDesc = { 1, 0 };
|
||||
swapchainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapchainDesc.OutputWindow = m_window;
|
||||
swapchainDesc.Windowed = true;
|
||||
swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
swapchainDesc.Flags = 0;
|
||||
|
||||
HRESULT hr = D3D11CreateDeviceAndSwapChain(nullptr,
|
||||
D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0,
|
||||
D3D11_SDK_VERSION, &swapchainDesc, &m_swapchain,
|
||||
&m_device, nullptr, &m_context);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
std::cerr << "Failed to initialize D3D11 device and swap chain" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_device->QueryInterface(IID_PPV_ARGS(&m_vdevice)))) {
|
||||
std::cerr << "Failed to query D3D11 video device" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_context->QueryInterface(IID_PPV_ARGS(&m_vcontext)))) {
|
||||
std::cerr << "Failed to query D3D11 video context" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_swapchain->ResizeTarget(&swapchainDesc.BufferDesc))) {
|
||||
std::cerr << "Failed to resize target" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_swapchain->GetBuffer(0, IID_PPV_ARGS(&m_swapImage)))) {
|
||||
std::cerr << "Failed to query swap chain image" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_device->CreateRenderTargetView(m_swapImage.ptr(), nullptr, &m_swapImageView))) {
|
||||
std::cerr << "Failed to create render target view" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create video processor instance
|
||||
D3D11_VIDEO_PROCESSOR_CONTENT_DESC videoEnumDesc = { };
|
||||
videoEnumDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
|
||||
videoEnumDesc.InputFrameRate = { 60, 1 };
|
||||
videoEnumDesc.InputWidth = 128;
|
||||
videoEnumDesc.InputHeight = 128;
|
||||
videoEnumDesc.OutputFrameRate = { 60, 1 };
|
||||
videoEnumDesc.OutputWidth = 256;
|
||||
videoEnumDesc.OutputHeight = 256;
|
||||
videoEnumDesc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL;
|
||||
|
||||
if (FAILED(hr = m_vdevice->CreateVideoProcessorEnumerator(&videoEnumDesc, &m_venum))) {
|
||||
std::cerr << "Failed to create D3D11 video processor enumerator" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_vdevice->CreateVideoProcessor(m_venum.ptr(), 0, &m_vprocessor))) {
|
||||
std::cerr << "Failed to create D3D11 video processor" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Video output image and view
|
||||
D3D11_TEXTURE2D_DESC textureDesc = { };
|
||||
textureDesc.Width = 256;
|
||||
textureDesc.Height = 256;
|
||||
textureDesc.MipLevels = 1;
|
||||
textureDesc.ArraySize = 1;
|
||||
textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
textureDesc.SampleDesc = { 1, 0 };
|
||||
textureDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||
|
||||
if (FAILED(hr = m_device->CreateTexture2D(&textureDesc, nullptr, &m_videoOutput))) {
|
||||
std::cerr << "Failed to create D3D11 video output image" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputDesc = { };
|
||||
outputDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
|
||||
outputDesc.Texture2D.MipSlice = 0;
|
||||
|
||||
if (FAILED(hr = m_vdevice->CreateVideoProcessorOutputView(m_videoOutput.ptr(), m_venum.ptr(), &outputDesc, &m_videoOutputView))) {
|
||||
std::cerr << "Failed to create D3D11 video output view" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_device->CreateRenderTargetView(m_videoOutput.ptr(), nullptr, &m_videoOutputRtv))) {
|
||||
std::cerr << "Failed to create video render target view" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// RGBA input image and view
|
||||
textureDesc.Width = 128;
|
||||
textureDesc.Height = 128;
|
||||
textureDesc.BindFlags = 0;
|
||||
|
||||
size_t pixelCount = textureDesc.Width * textureDesc.Height;
|
||||
|
||||
size_t rowSizeRgba = textureDesc.Width * 4;
|
||||
size_t rowSizeNv12 = textureDesc.Width;
|
||||
size_t rowSizeYuy2 = textureDesc.Width * 2;
|
||||
size_t imageSizeRgba = textureDesc.Height * rowSizeRgba;
|
||||
size_t imageSizeNv12 = pixelCount + pixelCount / 2;
|
||||
size_t imageSizeYuy2 = textureDesc.Height * rowSizeYuy2;
|
||||
|
||||
std::vector<uint8_t> srcData(pixelCount * 3);
|
||||
std::vector<uint8_t> imgDataRgba(imageSizeRgba);
|
||||
std::vector<uint8_t> imgDataNv12(imageSizeNv12);
|
||||
std::vector<uint8_t> imgDataYuy2(imageSizeYuy2);
|
||||
std::ifstream ifile("video_image.raw", std::ios::binary);
|
||||
|
||||
if (!ifile || !ifile.read(reinterpret_cast<char*>(srcData.data()), srcData.size())) {
|
||||
std::cerr << "Failed to read image file" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < pixelCount; i++) {
|
||||
imgDataRgba[4 * i + 0] = srcData[3 * i + 0];
|
||||
imgDataRgba[4 * i + 1] = srcData[3 * i + 1];
|
||||
imgDataRgba[4 * i + 2] = srcData[3 * i + 2];
|
||||
imgDataRgba[4 * i + 3] = 0xFF;
|
||||
|
||||
imgDataNv12[i] = y_coeff(&srcData[3 * i], 0.299000f, 0.587000f, 0.114000f);
|
||||
|
||||
imgDataYuy2[2 * i + 0] = y_coeff(&srcData[3 * i], 0.299000f, 0.587000f, 0.114000f);
|
||||
imgDataYuy2[2 * i + 1] = i % 2
|
||||
? c_coeff(&srcData[3 * i], -0.168736f, -0.331264f, 0.500000f)
|
||||
: c_coeff(&srcData[3 * i], 0.500000f, -0.418688f, -0.081312f);
|
||||
}
|
||||
|
||||
for (size_t y = 0; y < textureDesc.Height / 2; y++) {
|
||||
for (size_t x = 0; x < textureDesc.Width / 2; x++) {
|
||||
size_t p = textureDesc.Width * (2 * y) + 2 * x;
|
||||
size_t i = pixelCount + textureDesc.Width * y + 2 * x;
|
||||
imgDataNv12[i + 0] = c_coeff(&srcData[3 * p], 0.500000f, -0.418688f, -0.081312f);
|
||||
imgDataNv12[i + 1] = c_coeff(&srcData[3 * p], -0.168736f, -0.331264f, 0.500000f);
|
||||
}
|
||||
}
|
||||
|
||||
D3D11_SUBRESOURCE_DATA subresourceData = { };
|
||||
subresourceData.pSysMem = imgDataRgba.data();
|
||||
subresourceData.SysMemPitch = rowSizeRgba;
|
||||
subresourceData.SysMemSlicePitch = rowSizeRgba * textureDesc.Height;
|
||||
|
||||
if (FAILED(hr = m_device->CreateTexture2D(&textureDesc, &subresourceData, &m_videoInput))) {
|
||||
std::cerr << "Failed to create D3D11 video input image" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputDesc = { };
|
||||
inputDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
|
||||
inputDesc.Texture2D.MipSlice = 0;
|
||||
|
||||
if (FAILED(hr = m_vdevice->CreateVideoProcessorInputView(m_videoInput.ptr(), m_venum.ptr(), &inputDesc, &m_videoInputView))) {
|
||||
std::cerr << "Failed to create D3D11 video input view" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// NV12 input image and view
|
||||
textureDesc.Format = DXGI_FORMAT_NV12;
|
||||
textureDesc.BindFlags = 0;
|
||||
|
||||
subresourceData.pSysMem = imgDataNv12.data();
|
||||
subresourceData.SysMemPitch = rowSizeNv12;
|
||||
subresourceData.SysMemSlicePitch = rowSizeNv12 * textureDesc.Height;
|
||||
|
||||
if (SUCCEEDED(hr = m_device->CreateTexture2D(&textureDesc, nullptr, &m_videoInputNv12))) {
|
||||
if (FAILED(hr = m_vdevice->CreateVideoProcessorInputView(m_videoInputNv12.ptr(), m_venum.ptr(), &inputDesc, &m_videoInputViewNv12))) {
|
||||
std::cerr << "Failed to create D3D11 video input view for NV12" << std::endl;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "NV12 not supported" << std::endl;
|
||||
}
|
||||
|
||||
textureDesc.Usage = D3D11_USAGE_STAGING;
|
||||
textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
|
||||
|
||||
if (SUCCEEDED(hr = m_device->CreateTexture2D(&textureDesc, nullptr, &m_videoInputNv12Host))) {
|
||||
D3D11_MAPPED_SUBRESOURCE mr = { };
|
||||
m_context->Map(m_videoInputNv12Host.ptr(), 0, D3D11_MAP_WRITE, D3D11_MAP_FLAG_DO_NOT_WAIT, &mr);
|
||||
memcpy(mr.pData, imgDataNv12.data(), imgDataNv12.size());
|
||||
m_context->Unmap(m_videoInputNv12Host.ptr(), 0);
|
||||
D3D11_BOX box = { 0, 0, 0, 128, 128, 1 };
|
||||
m_context->CopySubresourceRegion(m_videoInputNv12.ptr(), 0, 0, 0, 0, m_videoInputNv12Host.ptr(), 0, &box);
|
||||
}
|
||||
|
||||
// YUY2 input image and view
|
||||
textureDesc.Format = DXGI_FORMAT_YUY2;
|
||||
textureDesc.BindFlags = 0;
|
||||
textureDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
textureDesc.CPUAccessFlags = 0;
|
||||
|
||||
subresourceData.pSysMem = imgDataYuy2.data();
|
||||
subresourceData.SysMemPitch = rowSizeYuy2;
|
||||
subresourceData.SysMemSlicePitch = imageSizeYuy2;
|
||||
|
||||
if (SUCCEEDED(hr = m_device->CreateTexture2D(&textureDesc, &subresourceData, &m_videoInputYuy2))) {
|
||||
if (FAILED(hr = m_vdevice->CreateVideoProcessorInputView(m_videoInputYuy2.ptr(), m_venum.ptr(), &inputDesc, &m_videoInputViewYuy2))) {
|
||||
std::cerr << "Failed to create D3D11 video input view for YUY2" << std::endl;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "YUY2 not supported" << std::endl;
|
||||
}
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
~VideoApp() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void run() {
|
||||
this->adjustBackBuffer();
|
||||
|
||||
float color[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
m_context->ClearRenderTargetView(m_swapImageView.ptr(), color);
|
||||
|
||||
// Full range RGB output color space
|
||||
D3D11_VIDEO_PROCESSOR_COLOR_SPACE csOut = { };
|
||||
csOut.Usage = 0; // Present
|
||||
csOut.RGB_Range = 0; // Full range
|
||||
csOut.Nominal_Range = 1; // Full range
|
||||
|
||||
D3D11_VIDEO_PROCESSOR_COLOR_SPACE csIn = { };
|
||||
csIn.Usage = 0; // Present
|
||||
csIn.RGB_Range = 0; // Full range
|
||||
csIn.Nominal_Range = 1; // Full range
|
||||
csIn.YCbCr_Matrix = 0; // BT.601
|
||||
|
||||
m_vcontext->VideoProcessorSetStreamAutoProcessingMode(m_vprocessor.ptr(), 0, false);
|
||||
m_vcontext->VideoProcessorSetOutputColorSpace(m_vprocessor.ptr(), &csOut);
|
||||
m_vcontext->VideoProcessorSetStreamColorSpace(m_vprocessor.ptr(), 0, &csIn);
|
||||
blit(m_videoInputView.ptr(), 32, 32);
|
||||
blit(m_videoInputViewNv12.ptr(), 32, 320);
|
||||
blit(m_videoInputViewYuy2.ptr(), 32, 608);
|
||||
|
||||
csIn.RGB_Range = 1; // Limited range
|
||||
csIn.Nominal_Range = 0; // Limited range
|
||||
m_vcontext->VideoProcessorSetStreamColorSpace(m_vprocessor.ptr(), 0, &csIn);
|
||||
blit(m_videoInputView.ptr(), 320, 32);
|
||||
blit(m_videoInputViewNv12.ptr(), 320, 320);
|
||||
blit(m_videoInputViewYuy2.ptr(), 320, 608);
|
||||
|
||||
// Limited range RGB output color space
|
||||
csOut.RGB_Range = 1;
|
||||
csOut.Nominal_Range = 0;
|
||||
m_vcontext->VideoProcessorSetOutputColorSpace(m_vprocessor.ptr(), &csOut);
|
||||
|
||||
csIn.RGB_Range = 0; // Full range
|
||||
csIn.Nominal_Range = 1; // Full range
|
||||
m_vcontext->VideoProcessorSetStreamColorSpace(m_vprocessor.ptr(), 0, &csIn);
|
||||
blit(m_videoInputView.ptr(), 608, 32);
|
||||
blit(m_videoInputViewNv12.ptr(), 608, 320);
|
||||
blit(m_videoInputViewYuy2.ptr(), 608, 608);
|
||||
|
||||
csIn.RGB_Range = 1; // Limited range
|
||||
csIn.Nominal_Range = 0; // Limited range
|
||||
m_vcontext->VideoProcessorSetStreamColorSpace(m_vprocessor.ptr(), 0, &csIn);
|
||||
blit(m_videoInputView.ptr(), 896, 32);
|
||||
blit(m_videoInputViewNv12.ptr(), 896, 320);
|
||||
blit(m_videoInputViewYuy2.ptr(), 896, 608);
|
||||
|
||||
m_swapchain->Present(1, 0);
|
||||
}
|
||||
|
||||
|
||||
void blit(ID3D11VideoProcessorInputView* pView, uint32_t x, uint32_t y) {
|
||||
if (!pView)
|
||||
return;
|
||||
|
||||
D3D11_VIDEO_PROCESSOR_STREAM stream = { };
|
||||
stream.Enable = true;
|
||||
stream.pInputSurface = pView;
|
||||
|
||||
D3D11_BOX box;
|
||||
box.left = 0;
|
||||
box.top = 0;
|
||||
box.front = 0;
|
||||
box.right = 256;
|
||||
box.bottom = 256;
|
||||
box.back = 1;
|
||||
|
||||
FLOAT red[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||
m_context->ClearRenderTargetView(m_videoOutputRtv.ptr(), red);
|
||||
m_vcontext->VideoProcessorBlt(m_vprocessor.ptr(), m_videoOutputView.ptr(), 0, 1, &stream);
|
||||
m_context->CopySubresourceRegion(m_swapImage.ptr(), 0, x, y, 0, m_videoOutput.ptr(), 0, &box);
|
||||
}
|
||||
|
||||
|
||||
void adjustBackBuffer() {
|
||||
RECT windowRect = { };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
if (uint32_t(windowRect.right - windowRect.left) != m_windowSizeX
|
||||
|| uint32_t(windowRect.bottom - windowRect.top) != m_windowSizeY) {
|
||||
m_windowSizeX = windowRect.right - windowRect.left;
|
||||
m_windowSizeY = windowRect.bottom - windowRect.top;
|
||||
|
||||
m_swapImage = nullptr;
|
||||
m_swapImageView = nullptr;
|
||||
|
||||
HRESULT hr = m_swapchain->ResizeBuffers(0,
|
||||
m_windowSizeX, m_windowSizeY, DXGI_FORMAT_UNKNOWN, 0);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
std::cerr << "Failed to resize swap chain buffer" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_swapchain->GetBuffer(0, IID_PPV_ARGS(&m_swapImage)))) {
|
||||
std::cerr << "Failed to query swap chain image" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_device->CreateRenderTargetView(m_swapImage.ptr(), nullptr, &m_swapImageView))) {
|
||||
std::cerr << "Failed to create render target view" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator bool () const {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
uint32_t m_windowSizeX = 1280;
|
||||
uint32_t m_windowSizeY = 720;
|
||||
|
||||
Com<IDXGISwapChain> m_swapchain;
|
||||
Com<ID3D11Device> m_device;
|
||||
Com<ID3D11DeviceContext> m_context;
|
||||
Com<ID3D11VideoDevice> m_vdevice;
|
||||
Com<ID3D11VideoContext> m_vcontext;
|
||||
Com<ID3D11VideoProcessorEnumerator> m_venum;
|
||||
Com<ID3D11VideoProcessor> m_vprocessor;
|
||||
Com<ID3D11Texture2D> m_swapImage;
|
||||
Com<ID3D11RenderTargetView> m_swapImageView;
|
||||
Com<ID3D11Texture2D> m_videoOutput;
|
||||
Com<ID3D11VideoProcessorOutputView> m_videoOutputView;
|
||||
Com<ID3D11RenderTargetView> m_videoOutputRtv;
|
||||
Com<ID3D11Texture2D> m_videoInput;
|
||||
Com<ID3D11VideoProcessorInputView> m_videoInputView;
|
||||
Com<ID3D11Texture2D> m_videoInputNv12;
|
||||
Com<ID3D11Texture2D> m_videoInputNv12Host;
|
||||
Com<ID3D11Texture2D> m_videoInputYuy2;
|
||||
Com<ID3D11VideoProcessorInputView> m_videoInputViewNv12;
|
||||
Com<ID3D11VideoProcessorInputView> m_videoInputViewYuy2;
|
||||
|
||||
bool m_initialized = false;
|
||||
|
||||
static inline uint8_t y_coeff(const uint8_t* rgb, float r, float g, float b) {
|
||||
float x = (rgb[0] * r + rgb[1] * g + rgb[2] * b) / 255.0f;
|
||||
return 16 + uint8_t(std::roundf(219.0f * std::clamp(x, 0.0f, 1.0f)));
|
||||
}
|
||||
|
||||
static inline uint8_t c_coeff(const uint8_t* rgb, float r, float g, float b) {
|
||||
float x = ((rgb[0] * r + rgb[1] * g + rgb[2] * b) / 255.0f) + 0.5f;
|
||||
return uint8_t(std::roundf(255.0f * std::clamp(x, 0.0f, 1.0f)));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
HWND hWnd;
|
||||
WNDCLASSEXW wc;
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = L"WindowClass1";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(0,
|
||||
L"WindowClass1",
|
||||
L"Our First Windowed Program",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
300, 300,
|
||||
1280, 720,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
MSG msg;
|
||||
VideoApp app(hInstance, hWnd);
|
||||
|
||||
while (app) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
test_dxgi_deps = [ util_dep, lib_dxgi ]
|
||||
|
||||
executable('dxgi-factory'+exe_ext, files('test_dxgi_factory.cpp'), dependencies : test_dxgi_deps, install: true, gui_app : true)
|
@ -1,123 +0,0 @@
|
||||
#include <vector>
|
||||
|
||||
#include <dxgi.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
Com<IDXGIFactory> factory;
|
||||
|
||||
if (CreateDXGIFactory(__uuidof(IDXGIFactory),
|
||||
reinterpret_cast<void**>(&factory)) != S_OK) {
|
||||
std::cerr << "Failed to create DXGI factory" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Com<IDXGIAdapter> adapter;
|
||||
|
||||
for (UINT i = 0; factory->EnumAdapters(i, &adapter) == S_OK; i++) {
|
||||
DXGI_ADAPTER_DESC adapterDesc;
|
||||
|
||||
if (adapter->GetDesc(&adapterDesc) != S_OK) {
|
||||
std::cerr << "Failed to get DXGI adapter info" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
|
||||
if (adapter->GetDesc(&desc) != S_OK) {
|
||||
std::cerr << "Failed to get DXGI adapter info" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << str::format("Adapter ", i, ":") << std::endl;
|
||||
std::cout << str::format(" ", desc.Description) << std::endl;
|
||||
std::cout << str::format(" Vendor: ", desc.VendorId) << std::endl;
|
||||
std::cout << str::format(" Device: ", desc.DeviceId) << std::endl;
|
||||
std::cout << str::format(" Dedicated RAM: ", desc.DedicatedVideoMemory) << std::endl;
|
||||
std::cout << str::format(" Shared RAM: ", desc.SharedSystemMemory) << std::endl;
|
||||
|
||||
Com<IDXGIOutput> output;
|
||||
|
||||
for (UINT j = 0; adapter->EnumOutputs(j, &output) == S_OK; j++) {
|
||||
std::vector<DXGI_MODE_DESC> modes;
|
||||
|
||||
DXGI_OUTPUT_DESC desc;
|
||||
|
||||
if (output->GetDesc(&desc) != S_OK) {
|
||||
std::cerr << "Failed to get DXGI output info" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << str::format(" Output ", j, ":") << std::endl;
|
||||
std::cout << str::format(" ", desc.DeviceName) << std::endl;
|
||||
std::cout << str::format(" Coordinates: ",
|
||||
desc.DesktopCoordinates.left, ",",
|
||||
desc.DesktopCoordinates.top, ":",
|
||||
desc.DesktopCoordinates.right - desc.DesktopCoordinates.left, "x",
|
||||
desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top) << std::endl;
|
||||
|
||||
HRESULT status = S_OK;
|
||||
UINT displayModeCount = 0;
|
||||
|
||||
do {
|
||||
if (output->GetDisplayModeList(
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_ENUM_MODES_SCALING,
|
||||
&displayModeCount, nullptr) != S_OK) {
|
||||
std::cerr << "Failed to get DXGI output display mode count" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
modes.resize(displayModeCount);
|
||||
|
||||
status = output->GetDisplayModeList(
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_ENUM_MODES_SCALING,
|
||||
&displayModeCount, modes.data());
|
||||
} while (status == DXGI_ERROR_MORE_DATA);
|
||||
|
||||
if (status != S_OK) {
|
||||
std::cerr << "Failed to get DXGI output display mode list" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (auto mode : modes) {
|
||||
std::cout << str::format(" ",
|
||||
mode.Width, "x", mode.Height, " @ ",
|
||||
mode.RefreshRate.Numerator / mode.RefreshRate.Denominator,
|
||||
mode.Scaling == DXGI_MODE_SCALING_CENTERED ? " (native)" : "") << std::endl;
|
||||
|
||||
//test matching modes
|
||||
DXGI_MODE_DESC matched_mode{ 0 };
|
||||
status = output->FindClosestMatchingMode(&mode, &matched_mode, nullptr);
|
||||
|
||||
if (status != S_OK) {
|
||||
std::cerr << "Failed to get matching mode" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (matched_mode.Width != mode.Width ||
|
||||
matched_mode.Height != mode.Height ||
|
||||
matched_mode.RefreshRate.Numerator != mode.RefreshRate.Numerator ||
|
||||
matched_mode.RefreshRate.Denominator != mode.RefreshRate.Denominator ||
|
||||
matched_mode.Format != mode.Format)
|
||||
{
|
||||
std::cerr << "Matched mode is incorrect" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +1 @@
|
||||
subdir('d3d9')
|
||||
subdir('d3d11')
|
||||
subdir('dxgi')
|
||||
|
Loading…
x
Reference in New Issue
Block a user