Пример #1
0
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);
}
Пример #2
0
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();
    }
}