[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;
|
register_count_ = 64;
|
||||||
total_attrib_count_ = 0;
|
total_attrib_count_ = 0;
|
||||||
vertex_bindings_.clear();
|
vertex_bindings_.clear();
|
||||||
|
unique_vertex_bindings_ = 0;
|
||||||
texture_bindings_.clear();
|
texture_bindings_.clear();
|
||||||
|
unique_texture_bindings_ = 0;
|
||||||
std::memset(&constant_register_map_, 0, sizeof(constant_register_map_));
|
std::memset(&constant_register_map_, 0, sizeof(constant_register_map_));
|
||||||
for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) {
|
for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) {
|
||||||
writes_color_targets_[i] = false;
|
writes_color_targets_[i] = false;
|
||||||
|
@ -300,7 +302,7 @@ void ShaderTranslator::GatherVertexBindingInformation(
|
||||||
if (!attrib) {
|
if (!attrib) {
|
||||||
assert_not_zero(fetch_instr.attributes.stride);
|
assert_not_zero(fetch_instr.attributes.stride);
|
||||||
VertexBinding vertex_binding;
|
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.fetch_constant = op.fetch_constant_index();
|
||||||
vertex_binding.stride_words = fetch_instr.attributes.stride;
|
vertex_binding.stride_words = fetch_instr.attributes.stride;
|
||||||
vertex_binding.attributes.push_back({});
|
vertex_binding.attributes.push_back({});
|
||||||
|
@ -328,9 +330,23 @@ void ShaderTranslator::GatherTextureBindingInformation(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Shader::TextureBinding binding;
|
Shader::TextureBinding binding;
|
||||||
binding.binding_index = texture_bindings_.size();
|
binding.binding_index = -1;
|
||||||
ParseTextureFetchInstruction(op, &binding.fetch_instr);
|
ParseTextureFetchInstruction(op, &binding.fetch_instr);
|
||||||
binding.fetch_constant = binding.fetch_instr.operands[1].storage_index;
|
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));
|
texture_bindings_.emplace_back(std::move(binding));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,9 @@ class ShaderTranslator {
|
||||||
int total_attrib_count_ = 0;
|
int total_attrib_count_ = 0;
|
||||||
std::vector<Shader::VertexBinding> vertex_bindings_;
|
std::vector<Shader::VertexBinding> vertex_bindings_;
|
||||||
std::vector<Shader::TextureBinding> texture_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};
|
Shader::ConstantRegisterMap constant_register_map_ = {0};
|
||||||
bool writes_color_targets_[4] = {false, false, false, false};
|
bool writes_color_targets_[4] = {false, false, false, false};
|
||||||
|
|
||||||
|
|
|
@ -189,32 +189,42 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
push_consts_ = b.createVariable(spv::StorageClass::StorageClassPushConstant,
|
push_consts_ = b.createVariable(spv::StorageClass::StorageClassPushConstant,
|
||||||
push_constants_type, "push_consts");
|
push_constants_type, "push_consts");
|
||||||
|
|
||||||
image_2d_type_ =
|
if (!texture_bindings().empty()) {
|
||||||
b.makeImageType(float_type_, spv::Dim::Dim2D, false, false, false, 1,
|
image_2d_type_ =
|
||||||
spv::ImageFormat::ImageFormatUnknown);
|
b.makeImageType(float_type_, spv::Dim::Dim2D, false, false, false, 1,
|
||||||
image_3d_type_ =
|
spv::ImageFormat::ImageFormatUnknown);
|
||||||
b.makeImageType(float_type_, spv::Dim::Dim3D, false, false, false, 1,
|
image_3d_type_ =
|
||||||
spv::ImageFormat::ImageFormatUnknown);
|
b.makeImageType(float_type_, spv::Dim::Dim3D, false, false, false, 1,
|
||||||
image_cube_type_ =
|
spv::ImageFormat::ImageFormatUnknown);
|
||||||
b.makeImageType(float_type_, spv::Dim::DimCube, false, false, false, 1,
|
image_cube_type_ =
|
||||||
spv::ImageFormat::ImageFormatUnknown);
|
b.makeImageType(float_type_, spv::Dim::DimCube, false, false, false, 1,
|
||||||
|
spv::ImageFormat::ImageFormatUnknown);
|
||||||
|
|
||||||
// Texture bindings
|
// Texture bindings
|
||||||
Id tex_t[] = {b.makeSampledImageType(image_2d_type_),
|
Id tex_t[] = {b.makeSampledImageType(image_2d_type_),
|
||||||
b.makeSampledImageType(image_3d_type_),
|
b.makeSampledImageType(image_3d_type_),
|
||||||
b.makeSampledImageType(image_cube_type_)};
|
b.makeSampledImageType(image_cube_type_)};
|
||||||
|
|
||||||
Id tex_a_t[] = {b.makeArrayType(tex_t[0], b.makeUintConstant(32), 0),
|
uint32_t num_tex_bindings = uint32_t(texture_bindings().size());
|
||||||
b.makeArrayType(tex_t[1], b.makeUintConstant(32), 0),
|
Id tex_a_t[] = {
|
||||||
b.makeArrayType(tex_t[2], b.makeUintConstant(32), 0)};
|
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
|
// Create 3 texture types, all aliased on the same binding
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
tex_[i] = b.createVariable(spv::StorageClass::StorageClassUniformConstant,
|
tex_[i] = b.createVariable(
|
||||||
tex_a_t[i],
|
spv::StorageClass::StorageClassUniformConstant, tex_a_t[i],
|
||||||
xe::format_string("textures%dD", i + 2).c_str());
|
xe::format_string("textures%dD", i + 2).c_str());
|
||||||
b.addDecoration(tex_[i], spv::Decoration::DecorationDescriptorSet, 1);
|
b.addDecoration(tex_[i], spv::Decoration::DecorationDescriptorSet, 1);
|
||||||
b.addDecoration(tex_[i], spv::Decoration::DecorationBinding, 0);
|
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.
|
// Interpolators.
|
||||||
|
@ -1760,7 +1770,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
|
|
||||||
switch (instr.opcode) {
|
switch (instr.opcode) {
|
||||||
case FetchOpcode::kTextureFetch: {
|
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 =
|
auto texture_ptr =
|
||||||
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
||||||
tex_[dim_idx], std::vector<Id>({texture_index}));
|
tex_[dim_idx], std::vector<Id>({texture_index}));
|
||||||
|
@ -1829,7 +1840,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
false, false, false, false, params);
|
false, false, false, false, params);
|
||||||
} break;
|
} break;
|
||||||
case FetchOpcode::kGetTextureGradients: {
|
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 =
|
auto texture_ptr =
|
||||||
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
||||||
tex_[dim_idx], std::vector<Id>({texture_index}));
|
tex_[dim_idx], std::vector<Id>({texture_index}));
|
||||||
|
@ -1849,7 +1861,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
} break;
|
} break;
|
||||||
case FetchOpcode::kGetTextureWeights: {
|
case FetchOpcode::kGetTextureWeights: {
|
||||||
// fract(src0 * textureSize);
|
// 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 =
|
auto texture_ptr =
|
||||||
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
b.createAccessChain(spv::StorageClass::StorageClassUniformConstant,
|
||||||
tex_[dim_idx], std::vector<Id>({texture_index}));
|
tex_[dim_idx], std::vector<Id>({texture_index}));
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "third_party/glslang-spirv/SpvBuilder.h"
|
#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 frag_outputs_ = 0, frag_depth_ = 0;
|
||||||
spv::Id samplers_ = 0;
|
spv::Id samplers_ = 0;
|
||||||
spv::Id tex_[3] = {0}; // Images {2D, 3D, Cube}
|
spv::Id tex_[3] = {0}; // Images {2D, 3D, Cube}
|
||||||
spv::Id vtx_ = 0; // Vertex buffer array (32 runtime arrays)
|
std::unordered_map<uint32_t, uint32_t> tex_binding_map_;
|
||||||
std::map<uint32_t, uint32_t> vtx_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.
|
// SPIR-V IDs that are part of the in/out interface.
|
||||||
std::vector<spv::Id> interface_ids_;
|
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_writes[update_set_info->image_write_count];
|
||||||
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->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
image_write->pNext = nullptr;
|
image_write->pNext = nullptr;
|
||||||
// image_write->dstSet is set later...
|
// image_write->dstSet is set later...
|
||||||
image_write->dstBinding = 0;
|
image_write->dstBinding = 0;
|
||||||
image_write->dstArrayElement = binding.fetch_constant;
|
image_write->dstArrayElement = uint32_t(binding.binding_index);
|
||||||
image_write->descriptorCount = 1;
|
image_write->descriptorCount = 1;
|
||||||
image_write->descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
image_write->descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
image_write->pImageInfo = image_info;
|
image_write->pImageInfo = image_info;
|
||||||
|
|
Loading…
Reference in New Issue