summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.cpp47
1 files changed, 41 insertions, 6 deletions
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index 26d066004..f9ca55c36 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -30,7 +30,7 @@ bool ComputePipelineKey::operator==(const ComputePipelineKey& rhs) const noexcep
ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cache_,
BufferCache& buffer_cache_, ProgramManager& program_manager_,
const Shader::Info& info_, std::string code,
- std::vector<u32> code_v)
+ std::vector<u32> code_v, bool force_context_flush)
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
program_manager{program_manager_}, info{info_} {
switch (device.GetShaderBackend()) {
@@ -63,6 +63,16 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
writes_global_memory = !use_storage_buffers &&
std::ranges::any_of(info.storage_buffers_descriptors,
[](const auto& desc) { return desc.is_written; });
+ uses_local_memory = info.uses_local_memory;
+ if (force_context_flush) {
+ std::scoped_lock lock{built_mutex};
+ built_fence.Create();
+ // Flush this context to ensure compilation commands and fence are in the GPU pipe.
+ glFlush();
+ built_condvar.notify_one();
+ } else {
+ is_built = true;
+ }
}
void ComputePipeline::Configure() {
@@ -78,7 +88,8 @@ void ComputePipeline::Configure() {
texture_cache.SynchronizeComputeDescriptors();
boost::container::static_vector<VideoCommon::ImageViewInOut, MAX_TEXTURES + MAX_IMAGES> views;
- std::array<GLuint, MAX_TEXTURES> samplers;
+ boost::container::static_vector<VideoCommon::SamplerId, MAX_TEXTURES> samplers;
+ std::array<GLuint, MAX_TEXTURES> gl_samplers;
std::array<GLuint, MAX_TEXTURES> textures;
std::array<GLuint, MAX_IMAGES> images;
GLsizei sampler_binding{};
@@ -122,7 +133,6 @@ void ComputePipeline::Configure() {
for (u32 index = 0; index < desc.count; ++index) {
const auto handle{read_handle(desc, index)};
views.push_back({handle.first});
- samplers[sampler_binding++] = 0;
}
}
for (const auto& desc : info.image_buffer_descriptors) {
@@ -133,8 +143,8 @@ void ComputePipeline::Configure() {
const auto handle{read_handle(desc, index)};
views.push_back({handle.first});
- Sampler* const sampler = texture_cache.GetComputeSampler(handle.second);
- samplers[sampler_binding++] = sampler->Handle();
+ VideoCommon::SamplerId sampler = texture_cache.GetComputeSamplerId(handle.second);
+ samplers.push_back(sampler);
}
}
for (const auto& desc : info.image_descriptors) {
@@ -142,6 +152,9 @@ void ComputePipeline::Configure() {
}
texture_cache.FillComputeImageViews(std::span(views.data(), views.size()));
+ if (!is_built) {
+ WaitForBuild();
+ }
if (assembly_program.handle != 0) {
program_manager.BindComputeAssemblyProgram(assembly_program.handle);
} else {
@@ -174,10 +187,17 @@ void ComputePipeline::Configure() {
const VideoCommon::ImageViewInOut* views_it{views.data() + num_texture_buffers +
num_image_buffers};
+ const VideoCommon::SamplerId* samplers_it{samplers.data()};
texture_binding += num_texture_buffers;
image_binding += num_image_buffers;
u32 texture_scaling_mask{};
+
+ for (const auto& desc : info.texture_buffer_descriptors) {
+ for (u32 index = 0; index < desc.count; ++index) {
+ gl_samplers[sampler_binding++] = 0;
+ }
+ }
for (const auto& desc : info.texture_descriptors) {
for (u32 index = 0; index < desc.count; ++index) {
ImageView& image_view{texture_cache.GetImageView((views_it++)->id)};
@@ -186,6 +206,12 @@ void ComputePipeline::Configure() {
texture_scaling_mask |= 1u << texture_binding;
}
++texture_binding;
+
+ const Sampler& sampler{texture_cache.GetSampler(*(samplers_it++))};
+ const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
+ !image_view.SupportsAnisotropy()};
+ gl_samplers[sampler_binding++] =
+ use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() : sampler.Handle();
}
}
u32 image_scaling_mask{};
@@ -216,11 +242,20 @@ void ComputePipeline::Configure() {
if (texture_binding != 0) {
ASSERT(texture_binding == sampler_binding);
glBindTextures(0, texture_binding, textures.data());
- glBindSamplers(0, sampler_binding, samplers.data());
+ glBindSamplers(0, sampler_binding, gl_samplers.data());
}
if (image_binding != 0) {
glBindImageTextures(0, image_binding, images.data());
}
}
+void ComputePipeline::WaitForBuild() {
+ if (built_fence.handle == 0) {
+ std::unique_lock lock{built_mutex};
+ built_condvar.wait(lock, [this] { return built_fence.handle != 0; });
+ }
+ ASSERT(glClientWaitSync(built_fence.handle, 0, GL_TIMEOUT_IGNORED) != GL_WAIT_FAILED);
+ is_built = true;
+}
+
} // namespace OpenGL