early-access version 2263
This commit is contained in:
@@ -23,6 +23,17 @@ namespace Tegra {
|
||||
namespace {
|
||||
constexpr AVPixelFormat PREFERRED_GPU_FMT = AV_PIX_FMT_NV12;
|
||||
constexpr AVPixelFormat PREFERRED_CPU_FMT = AV_PIX_FMT_YUV420P;
|
||||
constexpr std::array PREFERRED_GPU_DECODERS = {
|
||||
AV_HWDEVICE_TYPE_CUDA,
|
||||
#ifdef _WIN32
|
||||
AV_HWDEVICE_TYPE_D3D11VA,
|
||||
AV_HWDEVICE_TYPE_DXVA2,
|
||||
#elif defined(__linux__)
|
||||
AV_HWDEVICE_TYPE_VDPAU,
|
||||
#endif
|
||||
// last resort for Linux Flatpak (w/ NVIDIA)
|
||||
AV_HWDEVICE_TYPE_VULKAN,
|
||||
};
|
||||
|
||||
void AVPacketDeleter(AVPacket* ptr) {
|
||||
av_packet_free(&ptr);
|
||||
@@ -61,6 +72,20 @@ Codec::~Codec() {
|
||||
av_buffer_unref(&av_gpu_decoder);
|
||||
}
|
||||
|
||||
// List all the currently available hwcontext in ffmpeg
|
||||
static std::vector<AVHWDeviceType> ListSupportedContexts() {
|
||||
std::vector<AVHWDeviceType> contexts{};
|
||||
AVHWDeviceType current_device_type = AV_HWDEVICE_TYPE_NONE;
|
||||
do {
|
||||
current_device_type = av_hwdevice_iterate_types(current_device_type);
|
||||
// filter out VA-API since we will try that first if supported
|
||||
if (current_device_type != AV_HWDEVICE_TYPE_VAAPI) {
|
||||
contexts.push_back(current_device_type);
|
||||
}
|
||||
} while (current_device_type != AV_HWDEVICE_TYPE_NONE);
|
||||
return contexts;
|
||||
}
|
||||
|
||||
#ifdef LIBVA_FOUND
|
||||
// List all the currently loaded Linux modules
|
||||
static std::vector<std::string> ListLinuxKernelModules() {
|
||||
@@ -122,16 +147,12 @@ bool Codec::CreateGpuAvDevice() {
|
||||
av_dict_free(&hwdevice_options);
|
||||
#endif
|
||||
static constexpr auto HW_CONFIG_METHOD = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX;
|
||||
static constexpr std::array GPU_DECODER_TYPES{
|
||||
#ifdef linux
|
||||
AV_HWDEVICE_TYPE_VDPAU,
|
||||
#endif
|
||||
AV_HWDEVICE_TYPE_CUDA,
|
||||
#ifdef _WIN32
|
||||
AV_HWDEVICE_TYPE_D3D11VA,
|
||||
#endif
|
||||
};
|
||||
for (const auto& type : GPU_DECODER_TYPES) {
|
||||
static const auto supported_contexts = ListSupportedContexts();
|
||||
for (const auto& type : PREFERRED_GPU_DECODERS) {
|
||||
if (std::none_of(supported_contexts.begin(), supported_contexts.end(),
|
||||
[&type](const auto& context) { return context == type; })) {
|
||||
continue;
|
||||
}
|
||||
const int hwdevice_res = av_hwdevice_ctx_create(&av_gpu_decoder, type, nullptr, nullptr, 0);
|
||||
if (hwdevice_res < 0) {
|
||||
LOG_DEBUG(Service_NVDRV, "{} av_hwdevice_ctx_create failed {}",
|
||||
|
@@ -185,6 +185,16 @@ struct GPU::Impl {
|
||||
return *dma_pusher;
|
||||
}
|
||||
|
||||
/// Returns a reference to the GPU CDMA pusher.
|
||||
[[nodiscard]] Tegra::CDmaPusher& CDmaPusher() {
|
||||
return *cdma_pusher;
|
||||
}
|
||||
|
||||
/// Returns a const reference to the GPU CDMA pusher.
|
||||
[[nodiscard]] const Tegra::CDmaPusher& CDmaPusher() const {
|
||||
return *cdma_pusher;
|
||||
}
|
||||
|
||||
/// Returns a reference to the underlying renderer.
|
||||
[[nodiscard]] VideoCore::RendererBase& Renderer() {
|
||||
return *renderer;
|
||||
@@ -328,26 +338,25 @@ struct GPU::Impl {
|
||||
}
|
||||
|
||||
/// Push GPU command buffer entries to be processed
|
||||
void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) {
|
||||
void PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
|
||||
if (!use_nvdec) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cdma_pushers.find(id) == cdma_pushers.end()) {
|
||||
cdma_pushers[id] = std::make_unique<Tegra::CDmaPusher>(gpu);
|
||||
if (!cdma_pusher) {
|
||||
cdma_pusher = std::make_unique<Tegra::CDmaPusher>(gpu);
|
||||
}
|
||||
|
||||
// SubmitCommandBuffer would make the nvdec operations async, this is not currently working
|
||||
// TODO(ameerj): RE proper async nvdec operation
|
||||
// gpu_thread.SubmitCommandBuffer(std::move(entries));
|
||||
cdma_pushers[id]->ProcessEntries(std::move(entries));
|
||||
|
||||
cdma_pusher->ProcessEntries(std::move(entries));
|
||||
}
|
||||
|
||||
/// Frees the CDMAPusher instance to free up resources
|
||||
void ClearCdmaInstance(u32 id) {
|
||||
if (cdma_pushers.find(id) != cdma_pushers.end()) {
|
||||
cdma_pushers.erase(id);
|
||||
}
|
||||
void ClearCdmaInstance() {
|
||||
cdma_pusher.reset();
|
||||
}
|
||||
|
||||
/// Swap buffers (render frame)
|
||||
@@ -650,7 +659,7 @@ struct GPU::Impl {
|
||||
Core::System& system;
|
||||
std::unique_ptr<Tegra::MemoryManager> memory_manager;
|
||||
std::unique_ptr<Tegra::DmaPusher> dma_pusher;
|
||||
std::map<u32, std::unique_ptr<Tegra::CDmaPusher>> cdma_pushers;
|
||||
std::unique_ptr<Tegra::CDmaPusher> cdma_pusher;
|
||||
std::unique_ptr<VideoCore::RendererBase> renderer;
|
||||
VideoCore::RasterizerInterface* rasterizer = nullptr;
|
||||
const bool use_nvdec;
|
||||
@@ -802,6 +811,14 @@ const Tegra::DmaPusher& GPU::DmaPusher() const {
|
||||
return impl->DmaPusher();
|
||||
}
|
||||
|
||||
Tegra::CDmaPusher& GPU::CDmaPusher() {
|
||||
return impl->CDmaPusher();
|
||||
}
|
||||
|
||||
const Tegra::CDmaPusher& GPU::CDmaPusher() const {
|
||||
return impl->CDmaPusher();
|
||||
}
|
||||
|
||||
VideoCore::RendererBase& GPU::Renderer() {
|
||||
return impl->Renderer();
|
||||
}
|
||||
@@ -870,12 +887,12 @@ void GPU::PushGPUEntries(Tegra::CommandList&& entries) {
|
||||
impl->PushGPUEntries(std::move(entries));
|
||||
}
|
||||
|
||||
void GPU::PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) {
|
||||
impl->PushCommandBuffer(id, entries);
|
||||
void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
|
||||
impl->PushCommandBuffer(entries);
|
||||
}
|
||||
|
||||
void GPU::ClearCdmaInstance(u32 id) {
|
||||
impl->ClearCdmaInstance(id);
|
||||
void GPU::ClearCdmaInstance() {
|
||||
impl->ClearCdmaInstance();
|
||||
}
|
||||
|
||||
void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
|
||||
|
@@ -242,10 +242,10 @@ public:
|
||||
void PushGPUEntries(Tegra::CommandList&& entries);
|
||||
|
||||
/// Push GPU command buffer entries to be processed
|
||||
void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries);
|
||||
void PushCommandBuffer(Tegra::ChCommandHeaderList& entries);
|
||||
|
||||
/// Frees the CDMAPusher instance to free up resources
|
||||
void ClearCdmaInstance(u32 id);
|
||||
void ClearCdmaInstance();
|
||||
|
||||
/// Swap buffers (render frame)
|
||||
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer);
|
||||
|
@@ -18,7 +18,7 @@ int ShaderNotify::ShadersBuilding() noexcept {
|
||||
const int now_complete = num_complete.load(std::memory_order::relaxed);
|
||||
const int now_building = num_building.load(std::memory_order::relaxed);
|
||||
if (now_complete == now_building) {
|
||||
const auto now = std::chrono::high_resolution_clock::now();
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (completed && num_complete == num_when_completed) {
|
||||
if (now - complete_time > TIME_TO_STOP_REPORTING) {
|
||||
report_base = now_complete;
|
||||
|
@@ -28,6 +28,6 @@ private:
|
||||
|
||||
bool completed{};
|
||||
int num_when_completed{};
|
||||
std::chrono::high_resolution_clock::time_point complete_time;
|
||||
std::chrono::steady_clock::time_point complete_time;
|
||||
};
|
||||
} // namespace VideoCore
|
||||
|
Reference in New Issue
Block a user