early-access version 2263

This commit is contained in:
pineappleEA
2021-12-03 04:35:20 +01:00
parent ecc126a6a8
commit a28afca771
18 changed files with 101 additions and 62 deletions

View File

@@ -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 {}",

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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