timestamp_query::timestamp_query(device const& dvc, dx12u::cmd_queue const& q, int gpu_ordinal, std::size_t max_num_query) : num_query(max_num_query) { if (!dvc.Get()) { throw error{ "null device" }; } std::uint32_t gpu_mask = gpu_ordinal < 0 ? 1 : (1u << static_cast<std::uint32_t>(gpu_ordinal)); // alloc query buffer size_t buf_aligned_sz = (num_query * sizeof(std::uint64_t) + 4095) & ~4095; // page aligned auto heap_read_back = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK, gpu_mask, gpu_mask); auto buffer_desc = CD3DX12_RESOURCE_DESC::Buffer(buf_aligned_sz); auto r = dvc->CreateCommittedResource(&heap_read_back, D3D12_HEAP_FLAG_NONE, &buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&buffer)); dx12u::throw_if_error(r, "timestamp resource creation failure"); // query heap D3D12_QUERY_HEAP_DESC heap_desc{}; heap_desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP; heap_desc.Count = static_cast<std::uint32_t>(num_query); heap_desc.NodeMask = gpu_mask; r = dvc->CreateQueryHeap(&heap_desc, IID_PPV_ARGS(&qh)); dx12u::throw_if_error(r, "timestamp query heap creation failure"); // clock frequency dvc->SetStablePowerState(true); q.get_com_ptr()->GetTimestampFrequency(&clock_freq); }
text_2d::text_2d(device const& dev, std::size_t max_str_size, std::size_t max_num_str, std::size_t max_buffered_frame, bool enable_filtering) : max_word_sz(max_str_size), max_num_word(max_num_str) { assert(max_str_size > 0 && max_num_str > 0 && max_buffered_frame > 0); if (dev.Get() == nullptr) { throw error{ "null device" }; } words.resize(max_buffered_frame); size_t const num_cb = max_num_str * max_buffered_frame; size_t const num_tex = 1; // 1 text texture srd_heap = dx12u::descriptor_heap{ dev.Get(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, num_cb + num_tex }; auto cb_sz = get_cb_size(max_str_size); auto cb_total_sz = get_cb_size(max_str_size) * num_cb; // alloc and upload texture { auto font_data = load_font_texture(); gu::mip_lvl_texture_view mip_view{}; mip_view.width = global::font_texture_width; mip_view.height = global::font_texture_height; mip_view.pitch = mip_view.width; mip_view.slice_sz = font_data.size(); mip_view.data = font_data.data(); gu::texture_view tex_view{}; tex_view.bpp = 1; tex_view.num_lvl = 1; tex_view.mip = &mip_view; dx12u::cmd_queue q{ dev }; dx12u::cmd_allocator allocator{ dev }; dx12u::gfx_cmd_list cl = allocator.alloc(); auto tex = dx12u::make_texture(dev, cl, tex_view, false, false, DXGI_FORMAT_R8_UNORM); cl->Close(); q.push(cl); q.sync(); font_texture = tex.texture_rsrc; dev->CreateShaderResourceView(font_texture.Get(), &tex.srv_desc, srd_heap.get_cpu_handle(0)); } // alloc cb_mem { auto upload_heap = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD); auto buffer_desc = CD3DX12_RESOURCE_DESC::Buffer(cb_total_sz); auto r = dev->CreateCommittedResource(&upload_heap, D3D12_HEAP_FLAG_NONE, &buffer_desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&cb_mem)); dx12u::throw_if_error(r); for (size_t i = 0; i < num_cb; ++i) { // sh_mask_cb views D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc = {}; cbv_desc.SizeInBytes = static_cast<uint32_t>(cb_sz); cbv_desc.BufferLocation = cb_mem->GetGPUVirtualAddress() + i * cb_sz; dev->CreateConstantBufferView(&cbv_desc, srd_heap.get_cpu_handle(num_tex + i)); } r = cb_mem->Map(0, nullptr, reinterpret_cast<void**>(&cb_ptr)); dx12u::throw_if_error(r); assert(!!cb_ptr); memset(cb_ptr, 0, cb_total_sz); } // pso { // root signature auto filter = enable_filtering ? D3D12_FILTER_MIN_MAG_MIP_LINEAR : D3D12_FILTER_MIN_MAG_MIP_POINT; dx12u::descriptor_sig_list descriptor_table0{}; dx12u::descriptor_sig_list descriptor_table1{}; descriptor_table0.append(dx12u::descriptor_sig{ dx12u::descriptor_type::srv, 0, 0, dx12u::shader_mask::ps }); descriptor_table1.append(dx12u::descriptor_sig{ dx12u::descriptor_type::cbv, 0, 0, dx12u::shader_mask::vs }); dx12u::descriptor_sig_list dsl{}; dsl.append(descriptor_table0); // TODO move to root once the number of sgpr is definite dsl.append(descriptor_table1); dx12u::static_sampler_list sl = { dx12u::make_default_static_sampler(0, filter), }; rs = dx12u::make_root_signature(dev.Get(), dsl, sl); // shader preprocessor definitions auto const texture_char_w = static_cast<double>(global::font_texture_char_w) / static_cast<double>(global::font_texture_width); using macro = std::pair<std::string, std::string>; macro max_str_macro = macro{ "MAX_STR_SZ", std::to_string(max_str_size) }; macro char_w_macro = macro{ "CHAR_WIDTH", std::to_string(texture_char_w) }; D3D_SHADER_MACRO def[] = { max_str_macro.first.c_str(), max_str_macro.second.c_str(), char_w_macro.first.c_str(), char_w_macro.second.c_str(), nullptr, nullptr }; // shader blobs auto vs = dx12u::compile_from_file("../../framework/d3d12/shader/ui/text2d.hlsl", def, "vs_main", "vs_5_0"); auto ps = dx12u::compile_from_file("../../framework/d3d12/shader/ui/text2d.hlsl", def, "ps_main", "ps_5_0"); // pso pso = dx12u::pipeline_state_object{ dev, rs, vs, ps }; D3D12_BLEND_DESC bd = CD3DX12_BLEND_DESC(D3D12_DEFAULT); bd.RenderTarget[0].BlendEnable = true; bd.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; bd.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; pso.set_blend_states(bd); pso.set_depth_test(false); pso.commit(); } }