shader_recompiler: Add more instructions and fix a few thinhs

This commit is contained in:
raphaelthegreat 2024-06-05 22:22:34 +03:00
parent 728249f58d
commit ae7e6dafd5
18 changed files with 245 additions and 78 deletions

View file

@ -252,6 +252,16 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
}
break;
}
case PM4ItOpcode::DrawIndexOffset2: {
const auto* draw_index_off = reinterpret_cast<const PM4CmdDrawIndexOffset2*>(header);
regs.max_index_size = draw_index_off->max_size;
regs.num_indices = draw_index_off->index_count;
regs.draw_initiator = draw_index_off->draw_initiator;
if (rasterizer) {
rasterizer->Draw(true, draw_index_off->index_offset);
}
break;
}
case PM4ItOpcode::DrawIndexAuto: {
const auto* draw_index = reinterpret_cast<const PM4CmdDrawIndexAuto*>(header);
regs.num_indices = draw_index->index_count;
@ -272,6 +282,17 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
}
break;
}
case PM4ItOpcode::NumInstances: {
const auto* num_instances = reinterpret_cast<const PM4CmdDrawNumInstances*>(header);
regs.num_instances.num_instances = num_instances->num_instances;
break;
}
case PM4ItOpcode::IndexBase: {
const auto* index_base = reinterpret_cast<const PM4CmdDrawIndexBase*>(header);
regs.index_base_address.base_addr_lo = index_base->addr_lo;
regs.index_base_address.base_addr_hi.Assign(index_base->addr_hi);
break;
}
case PM4ItOpcode::EventWrite: {
// const auto* event = reinterpret_cast<const PM4CmdEventWrite*>(header);
break;

View file

@ -548,4 +548,15 @@ struct PM4CmdDispatchDirect {
u32 dispatch_initiator; ///< Dispatch Initiator Register
};
struct PM4CmdDrawNumInstances {
PM4Type3Header header;
u32 num_instances;
};
struct PM4CmdDrawIndexBase {
PM4Type3Header header;
u32 addr_lo;
u32 addr_hi;
};
} // namespace AmdGpu

View file

@ -14,6 +14,8 @@ vk::StencilOp StencilOp(Liverpool::StencilFunc op) {
return vk::StencilOp::eKeep;
case Liverpool::StencilFunc::Zero:
return vk::StencilOp::eZero;
case Liverpool::StencilFunc::ReplaceTest:
return vk::StencilOp::eReplace;
case Liverpool::StencilFunc::AddClamp:
return vk::StencilOp::eIncrementAndClamp;
case Liverpool::StencilFunc::SubClamp:
@ -307,6 +309,13 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu
if (data_format == AmdGpu::DataFormat::FormatBc3 && num_format == AmdGpu::NumberFormat::Srgb) {
return vk::Format::eBc3SrgbBlock;
}
if (data_format == AmdGpu::DataFormat::Format16_16_16_16 &&
num_format == AmdGpu::NumberFormat::Sint) {
return vk::Format::eR16G16B16A16Sint;
}
if (data_format == AmdGpu::DataFormat::FormatBc7 && num_format == AmdGpu::NumberFormat::Srgb) {
return vk::Format::eBc7SrgbBlock;
}
UNREACHABLE();
}

View file

@ -81,8 +81,17 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler
ComputePipeline::~ComputePipeline() = default;
void ComputePipeline::BindResources(Core::MemoryManager* memory,
void ComputePipeline::BindResources(Core::MemoryManager* memory, StreamBuffer& staging,
VideoCore::TextureCache& texture_cache) const {
static constexpr u64 MinUniformAlignment = 64;
const auto map_staging = [&](auto src, size_t size) {
const auto [data, offset, _] = staging.Map(size, MinUniformAlignment);
std::memcpy(data, reinterpret_cast<const void*>(src), size);
staging.Commit(size);
return offset;
};
// Bind resource buffers and textures.
boost::container::static_vector<vk::DescriptorBufferInfo, 4> buffer_infos;
boost::container::static_vector<vk::DescriptorImageInfo, 8> image_infos;
@ -94,8 +103,9 @@ void ComputePipeline::BindResources(Core::MemoryManager* memory,
const u32 size = vsharp.GetSize();
const VAddr addr = vsharp.base_address.Value();
texture_cache.OnCpuWrite(addr);
const auto [vk_buffer, offset] = memory->GetVulkanBuffer(addr);
buffer_infos.emplace_back(vk_buffer, offset, size);
const u32 offset = map_staging(addr, size);
// const auto [vk_buffer, offset] = memory->GetVulkanBuffer(addr);
buffer_infos.emplace_back(staging.Handle(), offset, size);
set_writes.push_back({
.dstSet = VK_NULL_HANDLE,
.dstBinding = binding++,

View file

@ -31,7 +31,8 @@ public:
return *pipeline;
}
void BindResources(Core::MemoryManager* memory, VideoCore::TextureCache& texture_cache) const;
void BindResources(Core::MemoryManager* memory, StreamBuffer& staging,
VideoCore::TextureCache& texture_cache) const;
private:
const Instance& instance;

View file

@ -32,10 +32,10 @@ Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_,
Rasterizer::~Rasterizer() = default;
void Rasterizer::Draw(bool is_indexed) {
void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
const auto cmdbuf = scheduler.CommandBuffer();
const auto& regs = liverpool->regs;
const u32 num_indices = SetupIndexBuffer(is_indexed);
const u32 num_indices = SetupIndexBuffer(is_indexed, index_offset);
const GraphicsPipeline* pipeline = pipeline_cache.GetGraphicsPipeline();
pipeline->BindResources(memory, vertex_index_buffer, texture_cache);
@ -85,17 +85,16 @@ void Rasterizer::Draw(bool is_indexed) {
}
void Rasterizer::DispatchDirect() {
return;
const auto cmdbuf = scheduler.CommandBuffer();
const auto& cs_program = liverpool->regs.cs_program;
const ComputePipeline* pipeline = pipeline_cache.GetComputePipeline();
pipeline->BindResources(memory, texture_cache);
pipeline->BindResources(memory, vertex_index_buffer, texture_cache);
cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, pipeline->Handle());
cmdbuf.dispatch(cs_program.dim_x, cs_program.dim_y, cs_program.dim_z);
}
u32 Rasterizer::SetupIndexBuffer(bool& is_indexed) {
u32 Rasterizer::SetupIndexBuffer(bool& is_indexed, u32 index_offset) {
// Emulate QuadList primitive type with CPU made index buffer.
const auto& regs = liverpool->regs;
if (liverpool->regs.primitive_type == Liverpool::PrimitiveType::QuadList) {
@ -131,7 +130,8 @@ u32 Rasterizer::SetupIndexBuffer(bool& is_indexed) {
// Bind index buffer.
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.bindIndexBuffer(vertex_index_buffer.Handle(), offset, index_type);
cmdbuf.bindIndexBuffer(vertex_index_buffer.Handle(), offset + index_offset * index_size,
index_type);
return regs.num_indices;
}

View file

@ -29,12 +29,12 @@ public:
VideoCore::TextureCache& texture_cache, AmdGpu::Liverpool* liverpool);
~Rasterizer();
void Draw(bool is_indexed);
void Draw(bool is_indexed, u32 index_offset = 0);
void DispatchDirect();
private:
u32 SetupIndexBuffer(bool& is_indexed);
u32 SetupIndexBuffer(bool& is_indexed, u32 index_offset);
void MapMemory(VAddr addr, size_t size);
void UpdateDynamicState(const GraphicsPipeline& pipeline);

View file

@ -116,7 +116,7 @@ Image& TextureCache::FindImage(const ImageInfo& info, VAddr cpu_address) {
std::unique_lock lock{m_page_table};
boost::container::small_vector<ImageId, 2> image_ids;
ForEachImageInRegion(cpu_address, info.guest_size_bytes, [&](ImageId image_id, Image& image) {
if (image.cpu_addr == cpu_address) {
if (image.cpu_addr == cpu_address && image.info.size.width == info.size.width) {
image_ids.push_back(image_id);
}
});