summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/emit_context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_context.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp65
1 files changed, 52 insertions, 13 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index 222baa177..8646fe989 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -14,6 +14,7 @@
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/div_ceil.h" 15#include "common/div_ceil.h"
16#include "shader_recompiler/backend/spirv/emit_context.h" 16#include "shader_recompiler/backend/spirv/emit_context.h"
17#include "shader_recompiler/backend/spirv/emit_spirv.h"
17 18
18namespace Shader::Backend::SPIRV { 19namespace Shader::Backend::SPIRV {
19namespace { 20namespace {
@@ -476,8 +477,9 @@ void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_vie
476 477
477EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_info_, 478EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_info_,
478 IR::Program& program, Bindings& bindings) 479 IR::Program& program, Bindings& bindings)
479 : Sirit::Module(profile_.supported_spirv), profile{profile_}, 480 : Sirit::Module(profile_.supported_spirv), profile{profile_}, runtime_info{runtime_info_},
480 runtime_info{runtime_info_}, stage{program.stage} { 481 stage{program.stage}, texture_rescaling_index{bindings.texture_scaling_index},
482 image_rescaling_index{bindings.image_scaling_index} {
481 const bool is_unified{profile.unified_descriptor_binding}; 483 const bool is_unified{profile.unified_descriptor_binding};
482 u32& uniform_binding{is_unified ? bindings.unified : bindings.uniform_buffer}; 484 u32& uniform_binding{is_unified ? bindings.unified : bindings.uniform_buffer};
483 u32& storage_binding{is_unified ? bindings.unified : bindings.storage_buffer}; 485 u32& storage_binding{is_unified ? bindings.unified : bindings.storage_buffer};
@@ -494,8 +496,8 @@ EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_inf
494 DefineStorageBuffers(program.info, storage_binding); 496 DefineStorageBuffers(program.info, storage_binding);
495 DefineTextureBuffers(program.info, texture_binding); 497 DefineTextureBuffers(program.info, texture_binding);
496 DefineImageBuffers(program.info, image_binding); 498 DefineImageBuffers(program.info, image_binding);
497 DefineTextures(program.info, texture_binding); 499 DefineTextures(program.info, texture_binding, bindings.texture_scaling_index);
498 DefineImages(program.info, image_binding); 500 DefineImages(program.info, image_binding, bindings.image_scaling_index);
499 DefineAttributeMemAccess(program.info); 501 DefineAttributeMemAccess(program.info);
500 DefineGlobalMemoryFunctions(program.info); 502 DefineGlobalMemoryFunctions(program.info);
501 DefineRescalingInput(program.info); 503 DefineRescalingInput(program.info);
@@ -1003,25 +1005,49 @@ void EmitContext::DefineRescalingInput(const Info& info) {
1003 if (!info.uses_rescaling_uniform) { 1005 if (!info.uses_rescaling_uniform) {
1004 return; 1006 return;
1005 } 1007 }
1006 boost::container::static_vector<Id, 2> members{F32[1]}; 1008 if (profile.unified_descriptor_binding) {
1009 DefineRescalingInputPushConstant(info);
1010 } else {
1011 DefineRescalingInputUniformConstant();
1012 }
1013}
1014
1015void EmitContext::DefineRescalingInputPushConstant(const Info& info) {
1016 boost::container::static_vector<Id, 3> members{F32[1]};
1007 u32 member_index{0}; 1017 u32 member_index{0};
1008 const u32 num_texture_words{Common::DivCeil(runtime_info.num_textures, 32u)}; 1018 if (!info.texture_descriptors.empty()) {
1009 if (runtime_info.num_textures > 0) { 1019 rescaling_textures_type = TypeArray(U32[1], Const(4u));
1010 rescaling_textures_type = TypeArray(U32[1], Const(num_texture_words));
1011 Decorate(rescaling_textures_type, spv::Decoration::ArrayStride, 4u); 1020 Decorate(rescaling_textures_type, spv::Decoration::ArrayStride, 4u);
1012 members.push_back(rescaling_textures_type); 1021 members.push_back(rescaling_textures_type);
1013 rescaling_textures_member_index = ++member_index; 1022 rescaling_textures_member_index = ++member_index;
1014 } 1023 }
1024 if (!info.image_descriptors.empty()) {
1025 rescaling_images_type = TypeArray(U32[1], Const(NUM_IMAGE_SCALING_WORDS));
1026 if (rescaling_textures_type.value != rescaling_images_type.value) {
1027 Decorate(rescaling_images_type, spv::Decoration::ArrayStride, 4u);
1028 }
1029 members.push_back(rescaling_images_type);
1030 rescaling_images_member_index = ++member_index;
1031 }
1015 const Id push_constant_struct{TypeStruct(std::span(members.data(), members.size()))}; 1032 const Id push_constant_struct{TypeStruct(std::span(members.data(), members.size()))};
1016 Decorate(push_constant_struct, spv::Decoration::Block); 1033 Decorate(push_constant_struct, spv::Decoration::Block);
1017 Name(push_constant_struct, "ResolutionInfo"); 1034 Name(push_constant_struct, "ResolutionInfo");
1035
1018 MemberDecorate(push_constant_struct, 0u, spv::Decoration::Offset, 0u); 1036 MemberDecorate(push_constant_struct, 0u, spv::Decoration::Offset, 0u);
1019 MemberName(push_constant_struct, 0u, "down_factor"); 1037 MemberName(push_constant_struct, 0u, "down_factor");
1020 if (runtime_info.num_textures > 0) { 1038
1021 MemberDecorate(push_constant_struct, rescaling_textures_member_index, 1039 const u32 offset_bias = stage == Stage::Compute ? sizeof(u32) : 0;
1022 spv::Decoration::Offset, 4u); 1040 if (!info.texture_descriptors.empty()) {
1041 MemberDecorate(
1042 push_constant_struct, rescaling_textures_member_index, spv::Decoration::Offset,
1043 static_cast<u32>(offsetof(RescalingLayout, rescaling_textures) - offset_bias));
1023 MemberName(push_constant_struct, rescaling_textures_member_index, "rescaling_textures"); 1044 MemberName(push_constant_struct, rescaling_textures_member_index, "rescaling_textures");
1024 } 1045 }
1046 if (!info.image_descriptors.empty()) {
1047 MemberDecorate(push_constant_struct, rescaling_images_member_index, spv::Decoration::Offset,
1048 static_cast<u32>(offsetof(RescalingLayout, rescaling_images) - offset_bias));
1049 MemberName(push_constant_struct, rescaling_images_member_index, "rescaling_images");
1050 }
1025 const Id pointer_type{TypePointer(spv::StorageClass::PushConstant, push_constant_struct)}; 1051 const Id pointer_type{TypePointer(spv::StorageClass::PushConstant, push_constant_struct)};
1026 rescaling_push_constants = AddGlobalVariable(pointer_type, spv::StorageClass::PushConstant); 1052 rescaling_push_constants = AddGlobalVariable(pointer_type, spv::StorageClass::PushConstant);
1027 Name(rescaling_push_constants, "rescaling_push_constants"); 1053 Name(rescaling_push_constants, "rescaling_push_constants");
@@ -1031,6 +1057,17 @@ void EmitContext::DefineRescalingInput(const Info& info) {
1031 } 1057 }
1032} 1058}
1033 1059
1060void EmitContext::DefineRescalingInputUniformConstant() {
1061 const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, F32[4])};
1062 rescaling_uniform_constant =
1063 AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant);
1064 Decorate(rescaling_uniform_constant, spv::Decoration::Location, 0u);
1065
1066 if (profile.supported_spirv >= 0x00010400) {
1067 interfaces.push_back(rescaling_uniform_constant);
1068 }
1069}
1070
1034void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) { 1071void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) {
1035 if (info.constant_buffer_descriptors.empty()) { 1072 if (info.constant_buffer_descriptors.empty()) {
1036 return; 1073 return;
@@ -1219,7 +1256,7 @@ void EmitContext::DefineImageBuffers(const Info& info, u32& binding) {
1219 } 1256 }
1220} 1257}
1221 1258
1222void EmitContext::DefineTextures(const Info& info, u32& binding) { 1259void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_index) {
1223 textures.reserve(info.texture_descriptors.size()); 1260 textures.reserve(info.texture_descriptors.size());
1224 for (const TextureDescriptor& desc : info.texture_descriptors) { 1261 for (const TextureDescriptor& desc : info.texture_descriptors) {
1225 const Id image_type{ImageType(*this, desc)}; 1262 const Id image_type{ImageType(*this, desc)};
@@ -1241,13 +1278,14 @@ void EmitContext::DefineTextures(const Info& info, u32& binding) {
1241 interfaces.push_back(id); 1278 interfaces.push_back(id);
1242 } 1279 }
1243 ++binding; 1280 ++binding;
1281 ++scaling_index;
1244 } 1282 }
1245 if (info.uses_atomic_image_u32) { 1283 if (info.uses_atomic_image_u32) {
1246 image_u32 = TypePointer(spv::StorageClass::Image, U32[1]); 1284 image_u32 = TypePointer(spv::StorageClass::Image, U32[1]);
1247 } 1285 }
1248} 1286}
1249 1287
1250void EmitContext::DefineImages(const Info& info, u32& binding) { 1288void EmitContext::DefineImages(const Info& info, u32& binding, u32& scaling_index) {
1251 images.reserve(info.image_descriptors.size()); 1289 images.reserve(info.image_descriptors.size());
1252 for (const ImageDescriptor& desc : info.image_descriptors) { 1290 for (const ImageDescriptor& desc : info.image_descriptors) {
1253 if (desc.count != 1) { 1291 if (desc.count != 1) {
@@ -1268,6 +1306,7 @@ void EmitContext::DefineImages(const Info& info, u32& binding) {
1268 interfaces.push_back(id); 1306 interfaces.push_back(id);
1269 } 1307 }
1270 ++binding; 1308 ++binding;
1309 ++scaling_index;
1271 } 1310 }
1272} 1311}
1273 1312