VirtualBox

source: vbox/trunk/src/libs/dxvk-native-1.9.2a/tests/d3d11/test_d3d11_streamout.cpp@ 103444

最後變更 在這個檔案從103444是 96497,由 vboxsync 提交於 3 年 前

libs/dxvk-native-1.9.2a: export to OSE

  • 屬性 svn:eol-style 設為 native
檔案大小: 8.7 KB
 
1#include <array>
2#include <cstring>
3
4#include <d3dcompiler.h>
5#include <d3d11.h>
6
7#include <windows.h>
8#include <windowsx.h>
9
10#include "../test_utils.h"
11
12using namespace dxvk;
13
14const std::string g_vsCode =
15 "struct VS_IFACE {\n"
16 " float4 pos : VS_POSITION;\n"
17 "};\n"
18 "VS_IFACE main(VS_IFACE ia_in) {\n"
19 " return ia_in;\n"
20 "}\n";
21
22const std::string g_gsCode =
23 "struct GS_IN {\n"
24 " float4 pos : VS_POSITION;\n"
25 "};\n"
26 "struct GS_OUT_NORMAL {\n"
27 " float3 nor : GS_NORMAL;\n"
28 " float len : GS_LENGTH;\n"
29 "};\n"
30 "[maxvertexcount(1)]\n"
31 "void main(triangle GS_IN vs_in[3], inout PointStream<GS_OUT_NORMAL> o_normals) {\n"
32 " float3 ds1 = vs_in[1].pos.xyz - vs_in[0].pos.xyz;\n"
33 " float3 ds2 = vs_in[2].pos.xyz - vs_in[0].pos.xyz;\n"
34 " float3 cv = cross(ds1, ds2);\n"
35 " float cl = length(cv);\n"
36 " GS_OUT_NORMAL normal;\n"
37 " normal.nor = cv / cl;\n"
38 " normal.len = cl;"
39 " o_normals.Append(normal);\n"
40 "}\n";
41
42Com<ID3D11Device> g_d3d11Device;
43Com<ID3D11DeviceContext> g_d3d11Context;
44
45Com<ID3D11VertexShader> g_vertShader;
46Com<ID3D11GeometryShader> g_geomShader;
47
48Com<ID3D11InputLayout> g_inputLayout;
49
50Com<ID3D11Buffer> g_vertexBuffer;
51Com<ID3D11Buffer> g_normalBuffer;
52Com<ID3D11Buffer> g_readBuffer;
53
54Com<ID3D11Query> g_soStream;
55Com<ID3D11Query> g_soOverflow;
56
57struct Vertex {
58 float x, y, z, w;
59};
60
61struct Normal {
62 float x, y, z, len;
63};
64
65int WINAPI WinMain(HINSTANCE hInstance,
66 HINSTANCE hPrevInstance,
67 LPSTR lpCmdLine,
68 int nCmdShow) {
69 if (FAILED(D3D11CreateDevice(
70 nullptr, D3D_DRIVER_TYPE_HARDWARE,
71 nullptr, 0, nullptr, 0, D3D11_SDK_VERSION,
72 &g_d3d11Device, nullptr, &g_d3d11Context))) {
73 std::cerr << "Failed to create D3D11 device" << std::endl;
74 return 1;
75 }
76
77 Com<ID3DBlob> vsBlob;
78 Com<ID3DBlob> gsBlob;
79
80 if (FAILED(D3DCompile(g_vsCode.data(), g_vsCode.size(),
81 "Vertex shader", nullptr, nullptr, "main", "vs_4_0",
82 0, 0, &vsBlob, nullptr))) {
83 std::cerr << "Failed to compile vertex shader" << std::endl;
84 return 1;
85 }
86
87 if (FAILED(D3DCompile(g_gsCode.data(), g_gsCode.size(),
88 "Geometry shader", nullptr, nullptr, "main", "gs_4_0",
89 0, 0, &gsBlob, nullptr))) {
90 std::cerr << "Failed to compile geometry shader" << std::endl;
91 return 1;
92 }
93
94 if (FAILED(g_d3d11Device->CreateVertexShader(
95 vsBlob->GetBufferPointer(),
96 vsBlob->GetBufferSize(),
97 nullptr, &g_vertShader))) {
98 std::cerr << "Failed to create vertex shader" << std::endl;
99 return 1;
100 }
101
102 std::array<D3D11_SO_DECLARATION_ENTRY, 2> soDeclarations = {{
103 { 0, "GS_NORMAL", 0, 0, 3, 0 },
104 { 0, "GS_LENGTH", 0, 0, 1, 0 },
105 }};
106
107 std::array<UINT, 1> soBufferStrides = {{
108 sizeof(Normal),
109 }};
110
111 if (FAILED(g_d3d11Device->CreateGeometryShaderWithStreamOutput(
112 gsBlob->GetBufferPointer(),
113 gsBlob->GetBufferSize(),
114 soDeclarations.data(),
115 soDeclarations.size(),
116 soBufferStrides.data(),
117 soBufferStrides.size(),
118 D3D11_SO_NO_RASTERIZED_STREAM,
119 nullptr, &g_geomShader))) {
120 std::cerr << "Failed to create geometry shader" << std::endl;
121 return 1;
122 }
123
124 std::array<D3D11_INPUT_ELEMENT_DESC, 1> iaElements = {{
125 { "VS_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
126 }};
127
128 if (FAILED(g_d3d11Device->CreateInputLayout(
129 iaElements.data(),
130 iaElements.size(),
131 vsBlob->GetBufferPointer(),
132 vsBlob->GetBufferSize(),
133 &g_inputLayout))) {
134 std::cerr << "Failed to create input layout" << std::endl;
135 return 1;
136 }
137
138 std::array<Vertex, 9> vertexData = {{
139 { 0.0f, 0.0f, 0.0f, 1.0f },
140 { 1.0f, 0.0f, 0.0f, 1.0f },
141 { 0.0f, 1.0f, 0.0f, 1.0f },
142
143 { 0.5f,-1.0f,-0.2f, 1.0f },
144 { 3.2f, 2.0f, 0.0f, 1.0f },
145 {-1.0f,-1.0f, 0.4f, 1.0f },
146
147 { 0.7f,-0.5f,-0.8f, 1.0f },
148 { 1.2f, 1.0f,-1.0f, 1.0f },
149 {-0.1f, 1.0f,-2.7f, 1.0f },
150 }};
151
152 D3D11_BUFFER_DESC vertexDesc;
153 vertexDesc.ByteWidth = vertexData.size() * sizeof(Vertex);
154 vertexDesc.Usage = D3D11_USAGE_IMMUTABLE;
155 vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
156 vertexDesc.CPUAccessFlags = 0;
157 vertexDesc.MiscFlags = 0;
158 vertexDesc.StructureByteStride = 0;
159
160 D3D11_SUBRESOURCE_DATA vertexInfo;
161 vertexInfo.pSysMem = vertexData.data();
162 vertexInfo.SysMemPitch = vertexDesc.ByteWidth;
163 vertexInfo.SysMemSlicePitch = vertexDesc.ByteWidth;
164
165 if (FAILED(g_d3d11Device->CreateBuffer(&vertexDesc, &vertexInfo, &g_vertexBuffer))) {
166 std::cerr << "Failed to create vertex buffer" << std::endl;
167 return 1;
168 }
169
170 std::array<Normal, 2> normalData = { };
171
172 D3D11_BUFFER_DESC normalDesc;
173 normalDesc.ByteWidth = normalData.size() * sizeof(Normal);
174 normalDesc.Usage = D3D11_USAGE_DEFAULT;
175 normalDesc.BindFlags = D3D11_BIND_STREAM_OUTPUT;
176 normalDesc.CPUAccessFlags = 0;
177 normalDesc.MiscFlags = 0;
178 normalDesc.StructureByteStride = 0;
179
180 D3D11_SUBRESOURCE_DATA normalInfo;
181 normalInfo.pSysMem = normalData.data();
182 normalInfo.SysMemPitch = normalDesc.ByteWidth;
183 normalInfo.SysMemSlicePitch = normalDesc.ByteWidth;
184
185 if (FAILED(g_d3d11Device->CreateBuffer(&normalDesc, &normalInfo, &g_normalBuffer))) {
186 std::cerr << "Failed to create normal buffer" << std::endl;
187 return 1;
188 }
189
190 D3D11_BUFFER_DESC readDesc;
191 readDesc.ByteWidth = normalDesc.ByteWidth;
192 readDesc.Usage = D3D11_USAGE_STAGING;
193 readDesc.BindFlags = 0;
194 readDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
195 readDesc.MiscFlags = 0;
196 readDesc.StructureByteStride = 0;
197
198 if (FAILED(g_d3d11Device->CreateBuffer(&readDesc, nullptr, &g_readBuffer))) {
199 std::cerr << "Failed to create readback buffer" << std::endl;
200 return 1;
201 }
202
203 D3D11_QUERY_DESC soQueryDesc;
204 soQueryDesc.Query = D3D11_QUERY_SO_STATISTICS_STREAM0;
205 soQueryDesc.MiscFlags = 0;
206
207 if (FAILED(g_d3d11Device->CreateQuery(&soQueryDesc, &g_soStream))) {
208 std::cerr << "Failed to create streamout query" << std::endl;
209 return 1;
210 }
211
212 soQueryDesc.Query = D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0;
213 if (FAILED(g_d3d11Device->CreateQuery(&soQueryDesc, &g_soOverflow))) {
214 std::cerr << "Failed to create streamout overflow query" << std::endl;
215 return 1;
216 }
217
218 UINT soOffset = 0;
219 UINT vbOffset = 0;
220 UINT vbStride = sizeof(Vertex);
221
222 FLOAT omBlendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
223
224 D3D11_VIEWPORT omViewport;
225 omViewport.TopLeftX = 0.0f;
226 omViewport.TopLeftY = 0.0f;
227 omViewport.Width = 256.0f;
228 omViewport.Height = 256.0f;
229 omViewport.MinDepth = 0.0f;
230 omViewport.MaxDepth = 1.0f;
231
232 g_d3d11Context->IASetInputLayout(g_inputLayout.ptr());
233 g_d3d11Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
234 g_d3d11Context->IASetVertexBuffers(0, 1, &g_vertexBuffer, &vbStride, &vbOffset);
235
236 g_d3d11Context->RSSetState(nullptr);
237 g_d3d11Context->RSSetViewports(1, &omViewport);
238
239 g_d3d11Context->OMSetRenderTargets(0, nullptr, nullptr);
240 g_d3d11Context->OMSetBlendState(nullptr, omBlendFactor, 0xFFFFFFFF);
241 g_d3d11Context->OMSetDepthStencilState(nullptr, 0);
242
243 g_d3d11Context->SOSetTargets(1, &g_normalBuffer, &soOffset);
244
245 g_d3d11Context->VSSetShader(g_vertShader.ptr(), nullptr, 0);
246 g_d3d11Context->GSSetShader(g_geomShader.ptr(), nullptr, 0);
247
248 g_d3d11Context->Begin(g_soStream.ptr());
249 g_d3d11Context->Begin(g_soOverflow.ptr());
250
251 g_d3d11Context->Draw(vertexData.size(), 0);
252
253 g_d3d11Context->End(g_soOverflow.ptr());
254 g_d3d11Context->End(g_soStream.ptr());
255
256 g_d3d11Context->CopyResource(
257 g_readBuffer.ptr(),
258 g_normalBuffer.ptr());
259
260 D3D11_QUERY_DATA_SO_STATISTICS soQueryData = { };
261 BOOL soOverflowData = false;
262
263 while (g_d3d11Context->GetData(g_soStream.ptr(), &soQueryData, sizeof(soQueryData), 0) != S_OK
264 || g_d3d11Context->GetData(g_soOverflow.ptr(), &soOverflowData, sizeof(soOverflowData), 0) != S_OK)
265 continue;
266
267 std::cout << "Written: " << soQueryData.NumPrimitivesWritten << std::endl;
268 std::cout << "Needed: " << soQueryData.PrimitivesStorageNeeded << std::endl;
269 std::cout << "Overflow: " << (soOverflowData ? "Yes" : "No") << std::endl;
270
271 D3D11_MAPPED_SUBRESOURCE mapInfo;
272
273 if (FAILED(g_d3d11Context->Map(g_readBuffer.ptr(), 0, D3D11_MAP_READ, 0, &mapInfo))) {
274 std::cerr << "Failed to map readback buffer" << std::endl;
275 return 1;
276 }
277
278 std::memcpy(normalData.data(), mapInfo.pData, normalDesc.ByteWidth);
279 g_d3d11Context->Unmap(g_readBuffer.ptr(), 0);
280
281 for (uint32_t i = 0; i < normalData.size(); i++) {
282 std::cout << i << ": " << normalData[i].x << ","
283 << normalData[i].y << "," << normalData[i].z << ","
284 << normalData[i].len << std::endl;
285 }
286
287 return 0;
288}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette