rework the binding system

This commit is contained in:
Samuliak 2024-10-05 15:06:58 +02:00
parent 08dbc9bd8d
commit a66708e362
No known key found for this signature in database
5 changed files with 41 additions and 69 deletions

View file

@ -159,8 +159,8 @@ private:
StagingBufferPool& staging_pool; StagingBufferPool& staging_pool;
// Common buffers // Common buffers
MTL::Buffer* null_buffer = nil; MTL::Buffer* null_buffer = nullptr;
MTL::Buffer* quad_index_buffer = nil; MTL::Buffer* quad_index_buffer = nullptr;
}; };
struct BufferCacheParams { struct BufferCacheParams {

View file

@ -53,9 +53,6 @@ struct RenderState {
BoundIndexBuffer bound_index_buffer; BoundIndexBuffer bound_index_buffer;
}; };
// TODO: whenever a render pass gets interrupted by either a compute or blit command and application
// then tries to perform a render command, begin the same render pass, but with all load actions set
// to "load"
class CommandRecorder { class CommandRecorder {
using PrimitiveTopology = Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology; using PrimitiveTopology = Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology;
using IndexFormat = Tegra::Engines::Maxwell3D::Regs::IndexFormat; using IndexFormat = Tegra::Engines::Maxwell3D::Regs::IndexFormat;

View file

@ -60,16 +60,27 @@ GraphicsPipeline::GraphicsPipeline(const Device& device_, CommandRecorder& comma
void GraphicsPipeline::Configure(bool is_indexed) { void GraphicsPipeline::Configure(bool is_indexed) {
texture_cache.SynchronizeGraphicsDescriptors(); texture_cache.SynchronizeGraphicsDescriptors();
struct {
std::array<VideoCommon::ImageViewInOut, 32> views; std::array<VideoCommon::ImageViewInOut, 32> views;
std::array<VideoCommon::SamplerId, 32> samplers;
size_t view_index{}; size_t view_index{};
} all_views[5];
struct {
std::array<VideoCommon::SamplerId, 32> samplers;
size_t sampler_index{}; size_t sampler_index{};
} all_samplers[5];
// Find resources // Find resources
const auto& regs{maxwell3d->regs}; const auto& regs{maxwell3d->regs};
const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding}; const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
const auto configure_stage{[&](u32 stage) { const auto configure_stage{[&](u32 stage) {
const Shader::Info& info{stage_infos[stage]}; const Shader::Info& info{stage_infos[stage]};
std::array<VideoCommon::ImageViewInOut, 32>& views{all_views[stage].views};
std::array<VideoCommon::SamplerId, 32>& samplers{all_samplers[stage].samplers};
size_t& view_index{all_views[stage].view_index};
size_t& sampler_index{all_samplers[stage].sampler_index};
buffer_cache.UnbindGraphicsStorageBuffers(stage); buffer_cache.UnbindGraphicsStorageBuffers(stage);
size_t ssbo_index{}; size_t ssbo_index{};
for (const auto& desc : info.storage_buffers_descriptors) { for (const auto& desc : info.storage_buffers_descriptors) {
@ -141,53 +152,6 @@ void GraphicsPipeline::Configure(bool is_indexed) {
for (const auto& desc : info.image_descriptors) { for (const auto& desc : info.image_descriptors) {
add_image(desc, desc.is_written); add_image(desc, desc.is_written);
} }
/*
const auto& cbufs{maxwell3d->state.shader_stages[stage].const_buffers};
const auto read_handle{[&](const auto& desc, u32 index) {
ASSERT(cbufs[desc.cbuf_index].enabled);
const u32 index_offset{index << desc.size_shift};
const u32 offset{desc.cbuf_offset + index_offset};
const GPUVAddr addr{cbufs[desc.cbuf_index].address + offset};
if constexpr (std::is_same_v<decltype(desc), const Shader::TextureDescriptor&> ||
std::is_same_v<decltype(desc), const Shader::TextureBufferDescriptor&>) {
if (desc.has_secondary) {
ASSERT(cbufs[desc.secondary_cbuf_index].enabled);
const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
second_offset};
const u32 lhs_raw{gpu_memory->Read<u32>(addr) << desc.shift_left};
const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)
<< desc.secondary_shift_left};
const u32 raw{lhs_raw | rhs_raw};
return TexturePair(raw, false);
}
}
auto a = gpu_memory->Read<u32>(addr);
// HACK: this particular texture breaks SMO
if (a == 310378931)
a = 310378932;
return TexturePair(a, false);
}};
const Shader::Info& info{stage_infos[stage]};
std::array<VideoCommon::ImageViewInOut, 32> views;
std::array<VideoCommon::SamplerId, 32> samplers;
size_t view_index{};
size_t sampler_index{};
for (const auto& desc : info.texture_descriptors) {
for (u32 index = 0; index < desc.count; ++index) {
const auto handle{read_handle(desc, index)};
views[view_index++] = {handle.first};
VideoCommon::SamplerId sampler{texture_cache.GetGraphicsSamplerId(handle.second)};
samplers[sampler_index++] = sampler;
}
}
*/
}}; }};
configure_stage(0); configure_stage(0);
@ -196,19 +160,30 @@ void GraphicsPipeline::Configure(bool is_indexed) {
buffer_cache.UpdateGraphicsBuffers(is_indexed); buffer_cache.UpdateGraphicsBuffers(is_indexed);
buffer_cache.BindHostGeometryBuffers(is_indexed); buffer_cache.BindHostGeometryBuffers(is_indexed);
// Bind resources
const auto bind_stage_resources{[&](u32 stage) {
std::array<VideoCommon::ImageViewInOut, 32>& views{all_views[stage].views};
std::array<VideoCommon::SamplerId, 32>& samplers{all_samplers[stage].samplers};
const size_t& view_index{all_views[stage].view_index};
const size_t& sampler_index{all_samplers[stage].sampler_index};
texture_cache.FillGraphicsImageViews<true>(std::span(views.data(), view_index)); texture_cache.FillGraphicsImageViews<true>(std::span(views.data(), view_index));
// Bind resources for (u8 i = 0; i < view_index; i++) {
const VideoCommon::ImageViewInOut& view{views[i]};
ImageView& image_view{texture_cache.GetImageView(view.id)};
command_recorder.SetTexture(stage, image_view.GetHandle(), i);
}
// HACK: try to find a texture that we can bind for (u8 i = 0; i < sampler_index; i++) {
const VideoCommon::ImageViewInOut* views_it{views.data()}; const VideoCommon::SamplerId& sampler_id{samplers[i]};
const VideoCommon::SamplerId* samplers_it{samplers.data()}; Sampler& sampler{texture_cache.GetSampler(sampler_id)};
command_recorder.SetSamplerState(stage, sampler.GetHandle(), i);
}
}};
ImageView& image_view{texture_cache.GetImageView(views_it->id)}; bind_stage_resources(0);
Sampler& sampler{texture_cache.GetSampler(*samplers_it)}; bind_stage_resources(4);
command_recorder.SetTexture(4, image_view.GetHandle(), 0);
command_recorder.SetSamplerState(4, sampler.GetHandle(), 0);
// Begin render pass // Begin render pass
texture_cache.UpdateRenderTargets(false); texture_cache.UpdateRenderTargets(false);

View file

@ -289,6 +289,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
} }
// HACK: create hardcoded shaders // HACK: create hardcoded shaders
/*
MTL::CompileOptions* compile_options = MTL::CompileOptions::alloc()->init(); MTL::CompileOptions* compile_options = MTL::CompileOptions::alloc()->init();
NS::Error* error = nullptr; NS::Error* error = nullptr;
MTL::Library* library = device.GetDevice()->newLibrary(NS::String::string( MTL::Library* library = device.GetDevice()->newLibrary(NS::String::string(
@ -330,6 +331,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
functions[0] = library->newFunction(NS::String::string("vertexMain", NS::ASCIIStringEncoding)); functions[0] = library->newFunction(NS::String::string("vertexMain", NS::ASCIIStringEncoding));
functions[4] = functions[4] =
library->newFunction(NS::String::string("fragmentMain", NS::ASCIIStringEncoding)); library->newFunction(NS::String::string("fragmentMain", NS::ASCIIStringEncoding));
*/
return std::make_unique<GraphicsPipeline>(device, command_recorder, key, buffer_cache, return std::make_unique<GraphicsPipeline>(device, command_recorder, key, buffer_cache,
texture_cache, &shader_notify, functions, infos); texture_cache, &shader_notify, functions, infos);

View file

@ -175,15 +175,13 @@ void Framebuffer::CreateRenderPassDescriptor(TextureCacheRuntime& runtime,
} }
// TODO: don't use index as attachment index // TODO: don't use index as attachment index
auto color_attachment = render_pass->colorAttachments()->object(index); auto color_attachment = render_pass->colorAttachments()->object(index);
color_attachment->setClearColor(MTL::ClearColor::Make(0.5, 1.0, 0.0, 1.0)); color_attachment->setLoadAction(MTL::LoadActionLoad);
color_attachment->setLoadAction(MTL::LoadActionClear);
color_attachment->setStoreAction(MTL::StoreActionStore); color_attachment->setStoreAction(MTL::StoreActionStore);
color_attachment->setTexture(color_buffer->GetHandle()); color_attachment->setTexture(color_buffer->GetHandle());
} }
if (depth_buffer) { if (depth_buffer) {
auto depth_attachment = render_pass->depthAttachment(); auto depth_attachment = render_pass->depthAttachment();
depth_attachment->setClearDepth(1.0); depth_attachment->setLoadAction(MTL::LoadActionLoad);
depth_attachment->setLoadAction(MTL::LoadActionClear);
depth_attachment->setStoreAction(MTL::StoreActionStore); depth_attachment->setStoreAction(MTL::StoreActionStore);
depth_attachment->setTexture(depth_buffer->GetHandle()); depth_attachment->setTexture(depth_buffer->GetHandle());
} }