summaryrefslogtreecommitdiffstats
path: root/src/libs/dxvk-native-1.9.2a/tests/d3d11
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libs/dxvk-native-1.9.2a/tests/d3d11/meson.build10
-rw-r--r--src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_compute.cpp172
-rw-r--r--src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_formats.cpp273
-rw-r--r--src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_map_read.cpp203
-rw-r--r--src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_streamout.cpp288
-rw-r--r--src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_triangle.cpp606
-rw-r--r--src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_video.cpp459
-rw-r--r--src/libs/dxvk-native-1.9.2a/tests/d3d11/video_image.rawbin0 -> 49152 bytes
8 files changed, 2011 insertions, 0 deletions
diff --git a/src/libs/dxvk-native-1.9.2a/tests/d3d11/meson.build b/src/libs/dxvk-native-1.9.2a/tests/d3d11/meson.build
new file mode 100644
index 00000000..96fa90a3
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/tests/d3d11/meson.build
@@ -0,0 +1,10 @@
+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, override_options: ['cpp_std='+dxvk_cpp_std])
+executable('d3d11-formats'+exe_ext, files('test_d3d11_formats.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std])
+executable('d3d11-map-read'+exe_ext, files('test_d3d11_map_read.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std])
+executable('d3d11-streamout'+exe_ext, files('test_d3d11_streamout.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std])
+executable('d3d11-triangle'+exe_ext, files('test_d3d11_triangle.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std])
+executable('d3d11-video'+exe_ext, files('test_d3d11_video.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std])
+
+install_data('video_image.raw', install_dir : get_option('bindir')) \ No newline at end of file
diff --git a/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_compute.cpp b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_compute.cpp
new file mode 100644
index 00000000..87826581
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_compute.cpp
@@ -0,0 +1,172 @@
+#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;
+}
diff --git a/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_formats.cpp b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_formats.cpp
new file mode 100644
index 00000000..daac8365
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_formats.cpp
@@ -0,0 +1,273 @@
+#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);
+ }
+}
+
+
+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;
+ }
+ }
+
+ } else {
+ std::cout << " Not supported" << std::endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_map_read.cpp b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_map_read.cpp
new file mode 100644
index 00000000..8e73dc45
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_map_read.cpp
@@ -0,0 +1,203 @@
+#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;
+}
diff --git a/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_streamout.cpp b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_streamout.cpp
new file mode 100644
index 00000000..3ff5f9ec
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_streamout.cpp
@@ -0,0 +1,288 @@
+#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;
+}
diff --git a/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_triangle.cpp b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_triangle.cpp
new file mode 100644
index 00000000..5c2ea78f
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_triangle.cpp
@@ -0,0 +1,606 @@
+#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);
+}
diff --git a/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_video.cpp b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_video.cpp
new file mode 100644
index 00000000..a974962a
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_video.cpp
@@ -0,0 +1,459 @@
+#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);
+}
diff --git a/src/libs/dxvk-native-1.9.2a/tests/d3d11/video_image.raw b/src/libs/dxvk-native-1.9.2a/tests/d3d11/video_image.raw
new file mode 100644
index 00000000..7d1b5f38
--- /dev/null
+++ b/src/libs/dxvk-native-1.9.2a/tests/d3d11/video_image.raw
Binary files differ