[Vulkan] Use locally generated texture binding indices instead of GPU indices
This commit is contained in:
parent
da4cf1bc80
commit
77da785d70
|
@ -54,7 +54,9 @@ void ShaderTranslator::Reset() {
|
|||
register_count_ = 64;
|
||||
total_attrib_count_ = 0;
|
||||
vertex_bindings_.clear();
|
||||
unique_vertex_bindings_ = 0;
|
||||
texture_bindings_.clear();
|
||||
unique_texture_bindings_ = 0;
|
||||
std::memset(&constant_register_map_, 0, sizeof(constant_register_map_));
|
||||
for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) {
|
||||
writes_color_targets_[i] = false;
|
||||
|
@ -300,7 +302,7 @@ void ShaderTranslator::GatherVertexBindingInformation(
|
|||
if (!attrib) {
|
||||
assert_not_zero(fetch_instr.attributes.stride);
|
||||
VertexBinding vertex_binding;
|
||||
vertex_binding.binding_index = static_cast<int>(vertex_bindings_.size());
|
||||
vertex_binding.binding_index = int(vertex_bindings_.size());
|
||||
vertex_binding.fetch_constant = op.fetch_constant_index();
|
||||
vertex_binding.stride_words = fetch_instr.attributes.stride;
|
||||
vertex_binding.attributes.push_back({});
|
||||
|
@ -328,9 +330,23 @@ void ShaderTranslator::GatherTextureBindingInformation(
|
|||
break;
|
||||
}
|
||||
Shader::TextureBinding binding;
|
||||
binding.binding_index = texture_bindings_.size();
|
||||
binding.binding_index = -1;
|
||||
ParseTextureFetchInstruction(op, &binding.fetch_instr);
|
||||
binding.fetch_constant = binding.fetch_instr.operands[1].storage_index;
|
||||
|
||||
// Check and see if this fetch constant was previously used...
|
||||
for (auto& tex_binding : texture_bindings_) {
|
||||
if (tex_binding.fetch_constant == binding.fetch_constant) {
|
||||
binding.binding_index = tex_binding.binding_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (binding.binding_index == -1) {
|
||||
// Assign a unique binding index.
|
||||
binding.binding_index = unique_texture_bindings_++;
|
||||
}
|
||||
|
||||
texture_bindings_.emplace_back(std::move(binding));
|
||||
}
|
||||
|
||||
|
|
|
@ -212,6 +212,9 @@ class ShaderTranslator {
|
|||
int total_attrib_count_ = 0;
|
||||
std::vector<Shader::VertexBinding> vertex_bindings_;
|
||||
std::vector<Shader::TextureBinding> texture_bindings_;
|
||||
uint32_t unique_vertex_bindings_ = 0;
|
||||
uint32_t unique_texture_bindings_ = 0;
|
||||
|
||||
Shader::ConstantRegisterMap constant_register_map_ = {0};
|
||||
bool writes_color_targets_[4] = {false, false, false, false};
|
||||
|
||||
|
|
|
@ -189,32 +189,42 @@ void SpirvShaderTranslator::StartTranslation() {
|
|||
push_consts_ = b.createVariable(spv::StorageClass::StorageClassPushConstant,
|
||||
push_constants_type, "push_consts");
|
||||
|
||||
image_2d_type_ =
|
||||
b.makeImageType(float_type_, spv::Dim::Dim2D, false, false, false, 1,
|
||||
spv::ImageFormat::ImageFormatUnknown);
|
||||
image_3d_type_ =
|
||||
b.makeImageType(float_type_, spv::Dim::Dim3D, false, false, false, 1,
|
||||
spv::ImageFormat::ImageFormatUnknown);
|
||||
image_cube_type_ =
|
||||
b.makeImageType(float_type_, spv::Dim::DimCube, false, false, false, 1,
|
||||
spv::ImageFormat::ImageFormatUnknown);
|
||||
if (!texture_bindings().empty()) {
|
||||
image_2d_type_ =
|
||||
b.makeImageType(float_type_, spv::Dim::Dim2D, false, false, false, 1,
|
||||
spv::ImageFormat::ImageFormatUnknown);
|
||||
image_3d_type_ =
|
||||
b.makeImageType(float_type_, spv::Dim::Dim3D, false, false, false, 1,
|
||||
spv::ImageFormat::ImageFormatUnknown);
|
||||
image_cube_type_ =
|
||||
b.makeImageType(float_type_, spv::Dim::DimCube, false, false, false, 1,
|
||||
spv::ImageFormat::ImageFormatUnknown);
|
||||
|
||||
// Texture bindings
|
||||
Id tex_t[] = {b.makeSampledImageType(image_2d_type_),
|
||||
b.makeSampledImageType(image_3d_type_),
|
||||
b.makeSampledImageType(image_cube_type_)};
|
||||
// Texture bindings
|
||||
Id tex_t[] = {b.makeSampledImageType(image_2d_type_),
|
||||
b.makeSampledImageType(image_3d_type_),
|
||||
b.makeSampledImageType(image_cube_type_)};
|
||||
|
||||
Id tex_a_t[] = {b.makeArrayType(tex_t[0], b.makeUintConstant(32), 0),
|
||||
b.makeArrayType(tex_t[1], b.makeUintConstant(32), 0),
|
||||
b.makeArrayType(tex_t[2], b.makeUintConstant(32), 0)};
|
||||
uint32_t num_tex_bindings = uint32_t(texture_bindings().size());
|
||||
Id tex_a_t[] = {
|
||||
b.makeArrayType(tex_t[0], b.makeUintConstant(num_tex_bindings), 0),
|
||||
b.makeArrayType(tex_t[1], b.makeUintConstant(num_tex_bindings), 0),
|
||||
b.makeArrayType(tex_t[2], b.makeUintConstant(num_tex_bindings), 0)};
|
||||
|
||||
// Create 3 texture types, all aliased on the same binding
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tex_[i] = b.createVariable(spv::StorageClass::StorageClassUniformConstant,
|
||||
tex_a_t[i],
|
||||
xe::format_string("textures%dD", i + 2).c_str());
|
||||
b.addDecoration(tex_[i], spv::Decoration::DecorationDescriptorSet, 1);
|
||||
b.addDecoration(tex_[i], spv::Decoration::DecorationBinding, 0);
|
||||
// Create 3 texture types, all aliased on the same binding
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tex_[i] = b.createVariable(
|
||||
spv::StorageClass::StorageClassUniformConstant, tex_a_t[i],
|
||||
xe::format_string("textures%dD", i + 2).c_str());
|
||||
b.addDecoration(tex_[i], spv::Decoration::DecorationDescriptorSet, 1);
|
||||
b.addDecoration(tex_[i], spv::Decoration::DecorationBinding, 0);
|
||||
}
|
||||
|
||||
// Set up the map from binding -> ssbo index
|
||||
for (const auto& binding : texture_bindings()) {
|
||||
tex_binding_map_[binding.fetch_constant] =
|
||||
uint32_t(binding.binding_index);
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolators.
|
||||
|
@ -1760,7 +1770,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
|
|||
|
||||
switch (instr.opcode) {
|
||||
case FetchOpcode::kTextureFetch: {
|
||||
auto texture_index = b.makeUintConstant(instr.operands[1].storage_index);
|
||||
auto texture_index =
|
||||
b.makeUintConstant(tex_binding_map_[instr.operands[1].storage_index]);
|
||||
auto texture_ptr =
|
||||
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
||||
tex_[dim_idx], std::vector<Id>({texture_index}));
|
||||
|
@ -1829,7 +1840,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
|
|||
false, false, false, false, params);
|
||||
} break;
|
||||
case FetchOpcode::kGetTextureGradients: {
|
||||
auto texture_index = b.makeUintConstant(instr.operands[2].storage_index);
|
||||
auto texture_index =
|
||||
b.makeUintConstant(tex_binding_map_[instr.operands[2].storage_index]);
|
||||
auto texture_ptr =
|
||||
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
||||
tex_[dim_idx], std::vector<Id>({texture_index}));
|
||||
|
@ -1849,7 +1861,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
|
|||
} break;
|
||||
case FetchOpcode::kGetTextureWeights: {
|
||||
// fract(src0 * textureSize);
|
||||
auto texture_index = b.makeUintConstant(instr.operands[1].storage_index);
|
||||
auto texture_index =
|
||||
b.makeUintConstant(tex_binding_map_[instr.operands[1].storage_index]);
|
||||
auto texture_ptr =
|
||||
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
||||
tex_[dim_idx], std::vector<Id>({texture_index}));
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "third_party/glslang-spirv/SpvBuilder.h"
|
||||
|
@ -157,8 +158,9 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
|||
spv::Id frag_outputs_ = 0, frag_depth_ = 0;
|
||||
spv::Id samplers_ = 0;
|
||||
spv::Id tex_[3] = {0}; // Images {2D, 3D, Cube}
|
||||
spv::Id vtx_ = 0; // Vertex buffer array (32 runtime arrays)
|
||||
std::map<uint32_t, uint32_t> vtx_binding_map_;
|
||||
std::unordered_map<uint32_t, uint32_t> tex_binding_map_;
|
||||
spv::Id vtx_ = 0; // Vertex buffer array (32 runtime arrays)
|
||||
std::unordered_map<uint32_t, uint32_t> vtx_binding_map_;
|
||||
|
||||
// SPIR-V IDs that are part of the in/out interface.
|
||||
std::vector<spv::Id> interface_ids_;
|
||||
|
|
|
@ -1442,11 +1442,14 @@ bool TextureCache::SetupTextureBinding(VkCommandBuffer command_buffer,
|
|||
&update_set_info->image_writes[update_set_info->image_write_count];
|
||||
update_set_info->image_write_count++;
|
||||
|
||||
// Sanity check, we only have 32 binding slots.
|
||||
assert(binding.binding_index < 32);
|
||||
|
||||
image_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
image_write->pNext = nullptr;
|
||||
// image_write->dstSet is set later...
|
||||
image_write->dstBinding = 0;
|
||||
image_write->dstArrayElement = binding.fetch_constant;
|
||||
image_write->dstArrayElement = uint32_t(binding.binding_index);
|
||||
image_write->descriptorCount = 1;
|
||||
image_write->descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
image_write->pImageInfo = image_info;
|
||||
|
|
Loading…
Reference in New Issue