// TestApp1.cpp : Defines the entry point for the application. // #ifdef _WIN32 #include "Win32/stdafx.h" #endif #include const char* ShaderDataTypeStr(DKShaderDataType t) { switch (t) { case DKShaderDataType::Unknown: return "Unknown"; case DKShaderDataType::None: return "None"; case DKShaderDataType::Struct: return "Struct"; case DKShaderDataType::Texture: return "Texture"; case DKShaderDataType::Sampler: return "Sampler"; case DKShaderDataType::Float: return "Float"; case DKShaderDataType::Float2: return "Float2"; case DKShaderDataType::Float3: return "Float3"; case DKShaderDataType::Float4: return "Float4"; case DKShaderDataType::Float2x2: return "Float2x2"; case DKShaderDataType::Float2x3: return "Float2x3"; case DKShaderDataType::Float2x4: return "Float2x4"; case DKShaderDataType::Float3x2: return "Float3x2"; case DKShaderDataType::Float3x3: return "Float3x3"; case DKShaderDataType::Float3x4: return "Float3x4"; case DKShaderDataType::Float4x2: return "Float4x2"; case DKShaderDataType::Float4x3: return "Float4x3"; case DKShaderDataType::Float4x4: return "Float4x4"; case DKShaderDataType::Half: return "Half"; case DKShaderDataType::Half2: return "Half2"; case DKShaderDataType::Half3: return "Half3"; case DKShaderDataType::Half4: return "Half4"; case DKShaderDataType::Half2x2: return "Half2x2"; case DKShaderDataType::Half2x3: return "Half2x3"; case DKShaderDataType::Half2x4: return "Half2x4"; case DKShaderDataType::Half3x2: return "Half3x2"; case DKShaderDataType::Half3x3: return "Half3x3"; case DKShaderDataType::Half3x4: return "Half3x4"; case DKShaderDataType::Half4x2: return "Half4x2"; case DKShaderDataType::Half4x3: return "Half4x3"; case DKShaderDataType::Half4x4: return "Half4x4"; case DKShaderDataType::Int: return "Int"; case DKShaderDataType::Int2: return "Int2"; case DKShaderDataType::Int3: return "Int3"; case DKShaderDataType::Int4: return "Int4"; case DKShaderDataType::UInt: return "UInt"; case DKShaderDataType::UInt2: return "UInt2"; case DKShaderDataType::UInt3: return "UInt3"; case DKShaderDataType::UInt4: return "UInt4"; case DKShaderDataType::Short: return "Short"; case DKShaderDataType::Short2: return "Short2"; case DKShaderDataType::Short3: return "Short3"; case DKShaderDataType::Short4: return "Short4"; case DKShaderDataType::UShort: return "UShort"; case DKShaderDataType::UShort2: return "UShort2"; case DKShaderDataType::UShort3: return "UShort3"; case DKShaderDataType::UShort4: return "UShort4"; case DKShaderDataType::Char: return "Char"; case DKShaderDataType::Char2: return "Char2"; case DKShaderDataType::Char3: return "Char3"; case DKShaderDataType::Char4: return "Char4"; case DKShaderDataType::UChar: return "UChar"; case DKShaderDataType::UChar2: return "UChar2"; case DKShaderDataType::UChar3: return "UChar3"; case DKShaderDataType::UChar4: return "UChar4"; case DKShaderDataType::Bool: return "Bool"; case DKShaderDataType::Bool2: return "Bool2"; case DKShaderDataType::Bool3: return "Bool3"; case DKShaderDataType::Bool4: return "Bool4"; } return "Error"; } void PrintShaderResource(const DKShaderResource& res) { struct MemberPrinter { const DKShaderResource& res; int indent; void operator()(const DKShaderResourceStruct& str) const { DKString indentStr = ""; for (int i = 0; i < indent; ++i) { indentStr += " "; } for (const DKShaderResourceStructMember& mem : str.members) { if (mem.count > 1) { DKLogI(" %ls+ %ls[%d] (%s, Offset: %d, Size: %d, Stride: %d)", (const wchar_t*)indentStr, (const wchar_t*)mem.name, mem.count, ShaderDataTypeStr(mem.dataType), mem.offset, mem.size, mem.stride); } else { DKLogI(" %ls+ %ls (%s, Offset: %d, Size: %d)", (const wchar_t*)indentStr, (const wchar_t*)mem.name, ShaderDataTypeStr(mem.dataType), mem.offset, mem.size); } auto* p = res.structTypeMemberMap.Find(mem.typeInfoKey); if (p) { DKLogI(" %ls+TypeKey: %ls (struct)", (const wchar_t*)indentStr, (const wchar_t*)res.typeInfoKey); MemberPrinter{ res, indent + 1 }.operator()(p->value); } } } }; if (res.count > 1) DKLogI("ShaderResource: %ls[%d] (set=%d, binding=%d)", (const wchar_t*)res.name, res.count, res.set, res.binding); else DKLogI("ShaderResource: %ls (set=%d, binding=%d)", (const wchar_t*)res.name, res.set, res.binding); const char* type = "Unknown (ERROR)"; switch (res.type) { case DKShaderResource::TypeBuffer: type = "Buffer"; break; case DKShaderResource::TypeTexture: type = "Texture"; break; case DKShaderResource::TypeSampler: type = "Sampler"; break; case DKShaderResource::TypeThreadgroupMemory: type = "Threadinggroup"; break; } const char* access = "Unknown (ERROR)"; switch (res.access) { case DKShaderResource::AccessReadOnly: access = "ReadOnly"; break; case DKShaderResource::AccessWriteOnly: access = "WriteOnly"; break; case DKShaderResource::AccessReadWrite: access = "ReadWrite"; break; } DKLogI(" +Type:%s, Access:%s, Enabled:%d Alignment:%d, Size:%d", type, access, int(res.enabled), res.typeInfo.buffer.alignment, res.typeInfo.buffer.size); if (res.typeInfoKey.Length() > 0) DKLogI(" +TypeKey: %ls (struct)", (const wchar_t*)res.typeInfoKey); if (res.type == DKShaderResource::TypeBuffer) { auto p = res.structTypeMemberMap.Find(res.typeInfoKey); if (p) MemberPrinter{ res, 1 }.operator()(p->value); } } class TestApp1 : public DKApplication { DKResourcePool resourcePool; DKString userConfigPath; public: void OnInitialize(void) override { DKLogD("%s", DKGL_FUNCTION_NAME); DKString resPath = DefaultPath(SystemPath::AppResource); resPath = resPath.FilePathStringByAppendingPath("Data"); DKLog("resPath: %ls", (const wchar_t*)resPath); resourcePool.AddLocatorForPath(resPath); userConfigPath = DefaultPath(SystemPath::AppExecutable).FilePathStringByAppendingPath("app.config.xml"); int numItemsImported = DKPropertySet::DefaultSet().Import(userConfigPath, true); if (numItemsImported >= 0) DKLogI("UserSettings: %ls (%d items imported)", (const wchar_t*)userConfigPath, numItemsImported); DKObject vertData = resourcePool.LoadResourceData("shaders/texture/texture.vert.spv"); DKObject fragData = resourcePool.LoadResourceData("shaders/texture/texture.frag.spv"); struct Vertex { DKVector3 position; DKVector2 uv; DKVector3 normal; }; DKVertexDescriptor vertexDescriptor; vertexDescriptor.attributes = { { DKVertexFormat::Float3, 0, 0, 0 }, { DKVertexFormat::Float2, sizeof(DKVector2), 0, 1 }, { DKVertexFormat::Float3, sizeof(DKVector3), 0, 2 }, }; vertexDescriptor.layouts = { { DKVertexStepRate::Vertex, sizeof(Vertex), 0 }, }; DKShader vertShader(vertData, DKShader::Vertex); DKShader fragShader(fragData, DKShader::Fragment); DKObject device = DKGraphicsDevice::SharedInstance(); DKObject vertShaderModule = device->CreateShaderModule(&vertShader); DKObject fragShaderModule = device->CreateShaderModule(&fragShader); DKObject vertShaderFunction = vertShaderModule->CreateFunction(vertShaderModule->FunctionNames().Value(0)); DKObject fragShaderFunction = fragShaderModule->CreateFunction(fragShaderModule->FunctionNames().Value(0)); DKObject queue = device->CreateCommandQueue(DKCommandQueue::Graphics); DKLog("VertexFunction.VertexAttributes: %d", vertShaderFunction->VertexAttributes().Count()); for (int i = 0; i < vertShaderFunction->VertexAttributes().Count(); ++i) { const DKVertexAttribute& attr = vertShaderFunction->VertexAttributes().Value(i); DKLog(" --> VertexAttribute[%d]: \"%ls\" (location:%u)", i, (const wchar_t*)attr.name, attr.location); } DKRenderPipelineDescriptor pipelineDescriptor; pipelineDescriptor.vertexFunction = vertShaderFunction; pipelineDescriptor.fragmentFunction = fragShaderFunction; pipelineDescriptor.colorAttachments.Resize(1); pipelineDescriptor.colorAttachments.Value(0).pixelFormat = DKPixelFormat::RGBA8Unorm; pipelineDescriptor.depthStencilAttachmentPixelFormat = DKPixelFormat::Invalid; // no depth buffer pipelineDescriptor.vertexDescriptor = vertexDescriptor; pipelineDescriptor.primitiveTopology = DKPrimitiveType::Triangle; pipelineDescriptor.frontFace = DKFrontFace::CCW; pipelineDescriptor.triangleFillMode = DKTriangleFillMode::Fill; pipelineDescriptor.depthClipMode = DKDepthClipMode::Clip; pipelineDescriptor.cullMode = DKCullMode::None; pipelineDescriptor.rasterizationEnabled = true; DKRenderPipelineReflection reflection; DKObject pipelineState = device->CreateRenderPipeline(pipelineDescriptor, &reflection); if (pipelineState) { DKLog("PipelineReflection.VertexResources: %d", reflection.vertexResources.Count()); for (auto& arg : reflection.vertexResources) PrintShaderResource(arg); DKLog("PipelineReflection.FragmentResources: %d", reflection.fragmentResources.Count()); for (auto& arg : reflection.fragmentResources) PrintShaderResource(arg); } Terminate(0); } void OnTerminate(void) override { DKLogD("%s", DKGL_FUNCTION_NAME); int numItemsExported = DKPropertySet::DefaultSet().Export(userConfigPath, true); DKLogI("Setting saved: %ls (%d items exported)", (const wchar_t*)userConfigPath, numItemsExported); DKLogI("Memory Pool Statistics"); size_t numBuckets = DKMemoryPoolNumberOfBuckets(); DKMemoryPoolBucketStatus* buckets = new DKMemoryPoolBucketStatus[numBuckets]; DKMemoryPoolQueryAllocationStatus(buckets, numBuckets); size_t usedBytes = 0; for (int i = 0; i < numBuckets; ++i) { if (buckets[i].totalChunks > 0) { DKLogI("--> %5lu: %5lu/%5lu, usage: %.1f%%, used: %.1fKB, total: %.1fKB", buckets[i].chunkSize, buckets[i].usedChunks, buckets[i].totalChunks, double(buckets[i].usedChunks) / double(buckets[i].totalChunks) * 100.0, double(buckets[i].chunkSize * buckets[i].usedChunks) / 1024.0, double(buckets[i].chunkSize * buckets[i].totalChunks) / 1024.0 ); usedBytes += buckets[i].chunkSize * buckets[i].usedChunks; } } DKLogI("MemoryPool Usage: %.1fMB / %.1fMB", double(usedBytes) / (1024 * 1024), double(DKMemoryPoolSize()) / (1024 * 1024)); delete[] buckets; } }; #ifdef _WIN32 int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) #else int main(int argc, const char * argv[]) #endif { TestApp1 app; DKPropertySet::SystemConfig().SetValue("AppDelegate", "AppDelegate"); DKPropertySet::SystemConfig().SetValue("GraphicsAPI", "Vulkan"); return app.Run(); }