shader: Initial OpenGL implementation

This commit is contained in:
ReinUsesLisp 2021-05-23 04:28:34 -03:00 committed by ameerj
parent 850b08a16c
commit d621e96d0d
38 changed files with 1427 additions and 705 deletions

View file

@ -19,23 +19,6 @@
namespace Vulkan {
struct TextureHandle {
explicit TextureHandle(u32 data, bool via_header_index) {
[[likely]] if (via_header_index) {
image = data;
sampler = data;
}
else {
const Tegra::Texture::TextureHandle handle{data};
image = handle.tic_id;
sampler = via_header_index ? image : handle.tsc_id.Value();
}
}
u32 image;
u32 sampler;
};
class DescriptorLayoutBuilder {
public:
DescriptorLayoutBuilder(const vk::Device& device_) : device{&device_} {}

View file

@ -140,8 +140,8 @@ struct BufferCacheParams {
static constexpr bool HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT = false;
static constexpr bool NEEDS_BIND_UNIFORM_INDEX = false;
static constexpr bool NEEDS_BIND_STORAGE_INDEX = false;
static constexpr bool NEEDS_BIND_TEXTURE_BUFFER_INDEX = false;
static constexpr bool USE_MEMORY_MAPS = true;
static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = false;
};
using BufferCache = VideoCommon::BufferCache<BufferCacheParams>;

View file

@ -18,6 +18,9 @@
namespace Vulkan {
using Shader::ImageBufferDescriptor;
using Tegra::Texture::TexturePair;
ComputePipeline::ComputePipeline(const Device& device_, DescriptorPool& descriptor_pool,
VKUpdateDescriptorQueue& update_descriptor_queue_,
Common::ThreadWorker* thread_worker, const Shader::Info& info_,
@ -106,25 +109,25 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
secondary_offset};
const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
return TextureHandle{lhs_raw | rhs_raw, via_header_index};
return TexturePair(lhs_raw | rhs_raw, via_header_index);
}
}
return TextureHandle{gpu_memory.Read<u32>(addr), via_header_index};
return TexturePair(gpu_memory.Read<u32>(addr), via_header_index);
}};
const auto add_image{[&](const auto& desc) {
for (u32 index = 0; index < desc.count; ++index) {
const TextureHandle handle{read_handle(desc, index)};
image_view_indices.push_back(handle.image);
const auto handle{read_handle(desc, index)};
image_view_indices.push_back(handle.first);
}
}};
std::ranges::for_each(info.texture_buffer_descriptors, add_image);
std::ranges::for_each(info.image_buffer_descriptors, add_image);
for (const auto& desc : info.texture_descriptors) {
for (u32 index = 0; index < desc.count; ++index) {
const TextureHandle handle{read_handle(desc, index)};
image_view_indices.push_back(handle.image);
const auto handle{read_handle(desc, index)};
image_view_indices.push_back(handle.first);
Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler);
Sampler* const sampler = texture_cache.GetComputeSampler(handle.second);
samplers.push_back(sampler->Handle());
}
}
@ -137,15 +140,16 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
ImageId* texture_buffer_ids{image_view_ids.data()};
size_t index{};
const auto add_buffer{[&](const auto& desc) {
constexpr bool is_image = std::is_same_v<decltype(desc), const ImageBufferDescriptor&>;
for (u32 i = 0; i < desc.count; ++i) {
bool is_written{false};
if constexpr (std::is_same_v<decltype(desc), const Shader::ImageBufferDescriptor&>) {
if constexpr (is_image) {
is_written = desc.is_written;
}
ImageView& image_view = texture_cache.GetImageView(*texture_buffer_ids);
buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(),
image_view.BufferSize(), image_view.format,
is_written);
is_written, is_image);
++texture_buffer_ids;
++index;
}

View file

@ -19,7 +19,7 @@
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
#include "video_core/vulkan_common/vulkan_device.h"
#ifdef _MSC_VER
#if defined(_MSC_VER) && defined(NDEBUG)
#define LAMBDA_FORCEINLINE [[msvc::forceinline]]
#else
#define LAMBDA_FORCEINLINE
@ -30,6 +30,7 @@ namespace {
using boost::container::small_vector;
using boost::container::static_vector;
using Shader::ImageBufferDescriptor;
using Tegra::Texture::TexturePair;
using VideoCore::Surface::PixelFormat;
using VideoCore::Surface::PixelFormatFromDepthFormat;
using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
@ -289,15 +290,15 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
const u32 raw{lhs_raw | rhs_raw};
return TextureHandle{raw, via_header_index};
return TexturePair(raw, via_header_index);
}
}
return TextureHandle{gpu_memory.Read<u32>(addr), via_header_index};
return TexturePair(gpu_memory.Read<u32>(addr), via_header_index);
}};
const auto add_image{[&](const auto& desc) {
for (u32 index = 0; index < desc.count; ++index) {
const TextureHandle handle{read_handle(desc, index)};
image_view_indices[image_index++] = handle.image;
const auto handle{read_handle(desc, index)};
image_view_indices[image_index++] = handle.first;
}
}};
if constexpr (Spec::has_texture_buffers) {
@ -312,10 +313,10 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
}
for (const auto& desc : info.texture_descriptors) {
for (u32 index = 0; index < desc.count; ++index) {
const TextureHandle handle{read_handle(desc, index)};
image_view_indices[image_index++] = handle.image;
const auto handle{read_handle(desc, index)};
image_view_indices[image_index++] = handle.first;
Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)};
Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)};
samplers[sampler_index++] = sampler->Handle();
}
}
@ -347,15 +348,16 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE {
size_t index{};
const auto add_buffer{[&](const auto& desc) {
constexpr bool is_image = std::is_same_v<decltype(desc), const ImageBufferDescriptor&>;
for (u32 i = 0; i < desc.count; ++i) {
bool is_written{false};
if constexpr (std::is_same_v<decltype(desc), const ImageBufferDescriptor&>) {
if constexpr (is_image) {
is_written = desc.is_written;
}
ImageView& image_view{texture_cache.GetImageView(*texture_buffer_index)};
buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(),
image_view.BufferSize(), image_view.format,
is_written);
is_written, is_image);
++index;
++texture_buffer_index;
}

View file

@ -342,28 +342,15 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
}
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
GraphicsEnvironments environments;
GetGraphicsEnvironments(environments, graphics_key.unique_hashes);
main_pools.ReleaseContents();
std::array<GraphicsEnvironment, Maxwell::MaxShaderProgram> graphics_envs;
boost::container::static_vector<Shader::Environment*, Maxwell::MaxShaderProgram> envs;
const GPUVAddr base_addr{maxwell3d.regs.code_address.CodeAddress()};
for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
if (graphics_key.unique_hashes[index] == 0) {
continue;
}
const auto program{static_cast<Maxwell::ShaderProgram>(index)};
auto& env{graphics_envs[index]};
const u32 start_address{maxwell3d.regs.shader_config[index].offset};
env = GraphicsEnvironment{maxwell3d, gpu_memory, program, base_addr, start_address};
env.SetCachedSize(shader_infos[index]->size_bytes);
envs.push_back(&env);
}
auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, MakeSpan(envs), true)};
auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)};
if (pipeline_cache_filename.empty()) {
return pipeline;
}
serialization_thread.QueueWork([this, key = graphics_key, envs = std::move(graphics_envs)] {
serialization_thread.QueueWork([this, key = graphics_key, envs = std::move(environments.envs)] {
boost::container::static_vector<const GenericEnvironment*, Maxwell::MaxShaderProgram>
env_ptrs;
for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {

View file

@ -96,17 +96,6 @@ VkRect2D GetScissorState(const Maxwell& regs, size_t index) {
return scissor;
}
struct TextureHandle {
constexpr TextureHandle(u32 data, bool via_header_index) {
const Tegra::Texture::TextureHandle handle{data};
image = handle.tic_id;
sampler = via_header_index ? image : handle.tsc_id.Value();
}
u32 image;
u32 sampler;
};
DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_instanced,
bool is_indexed) {
DrawParams params{