[D3D12] DXBC samplers

This commit is contained in:
Triang3l 2018-09-11 12:37:47 +03:00
parent 06fabd16ad
commit d4334312f3
8 changed files with 188 additions and 65 deletions

View File

@ -129,11 +129,11 @@ ID3D12RootSignature* D3D12CommandProcessor::GetRootSignature(
uint32_t pixel_texture_count = 0, pixel_sampler_count = 0; uint32_t pixel_texture_count = 0, pixel_sampler_count = 0;
if (pixel_shader != nullptr) { if (pixel_shader != nullptr) {
pixel_shader->GetTextureSRVs(pixel_texture_count); pixel_shader->GetTextureSRVs(pixel_texture_count);
pixel_shader->GetSamplerFetchConstants(pixel_sampler_count); pixel_shader->GetSamplerBindings(pixel_sampler_count);
} }
uint32_t vertex_texture_count, vertex_sampler_count; uint32_t vertex_texture_count, vertex_sampler_count;
vertex_shader->GetTextureSRVs(vertex_texture_count); vertex_shader->GetTextureSRVs(vertex_texture_count);
vertex_shader->GetSamplerFetchConstants(vertex_sampler_count); vertex_shader->GetSamplerBindings(vertex_sampler_count);
// Max 96 textures (if all kinds of tfetch instructions are used for all fetch // Max 96 textures (if all kinds of tfetch instructions are used for all fetch
// registers) and 32 samplers (one sampler per used fetch), but different // registers) and 32 samplers (one sampler per used fetch), but different
// shader stages have different texture sets. // shader stages have different texture sets.
@ -319,11 +319,11 @@ uint32_t D3D12CommandProcessor::GetRootExtraParameterIndices(
uint32_t pixel_texture_count = 0, pixel_sampler_count = 0; uint32_t pixel_texture_count = 0, pixel_sampler_count = 0;
if (pixel_shader != nullptr) { if (pixel_shader != nullptr) {
pixel_shader->GetTextureSRVs(pixel_texture_count); pixel_shader->GetTextureSRVs(pixel_texture_count);
pixel_shader->GetSamplerFetchConstants(pixel_sampler_count); pixel_shader->GetSamplerBindings(pixel_sampler_count);
} }
uint32_t vertex_texture_count, vertex_sampler_count; uint32_t vertex_texture_count, vertex_sampler_count;
vertex_shader->GetTextureSRVs(vertex_texture_count); vertex_shader->GetTextureSRVs(vertex_texture_count);
vertex_shader->GetSamplerFetchConstants(vertex_sampler_count); vertex_shader->GetSamplerBindings(vertex_sampler_count);
uint32_t index = kRootParameter_Count_Base; uint32_t index = kRootParameter_Count_Base;
if (pixel_texture_count != 0) { if (pixel_texture_count != 0) {
@ -1525,11 +1525,10 @@ bool D3D12CommandProcessor::UpdateBindings(
// Get used textures and samplers. // Get used textures and samplers.
uint32_t pixel_texture_count, pixel_sampler_count; uint32_t pixel_texture_count, pixel_sampler_count;
const D3D12Shader::TextureSRV* pixel_textures; const D3D12Shader::TextureSRV* pixel_textures;
const uint32_t* pixel_samplers; const D3D12Shader::SamplerBinding* pixel_samplers;
if (pixel_shader != nullptr) { if (pixel_shader != nullptr) {
pixel_textures = pixel_shader->GetTextureSRVs(pixel_texture_count); pixel_textures = pixel_shader->GetTextureSRVs(pixel_texture_count);
pixel_samplers = pixel_samplers = pixel_shader->GetSamplerBindings(pixel_sampler_count);
pixel_shader->GetSamplerFetchConstants(pixel_sampler_count);
} else { } else {
pixel_textures = nullptr; pixel_textures = nullptr;
pixel_texture_count = 0; pixel_texture_count = 0;
@ -1539,8 +1538,8 @@ bool D3D12CommandProcessor::UpdateBindings(
uint32_t vertex_texture_count, vertex_sampler_count; uint32_t vertex_texture_count, vertex_sampler_count;
const D3D12Shader::TextureSRV* vertex_textures = const D3D12Shader::TextureSRV* vertex_textures =
vertex_shader->GetTextureSRVs(vertex_texture_count); vertex_shader->GetTextureSRVs(vertex_texture_count);
const uint32_t* vertex_samplers = const D3D12Shader::SamplerBinding* vertex_samplers =
vertex_shader->GetSamplerFetchConstants(vertex_sampler_count); vertex_shader->GetSamplerBindings(vertex_sampler_count);
uint32_t texture_count = pixel_texture_count + vertex_texture_count; uint32_t texture_count = pixel_texture_count + vertex_texture_count;
uint32_t sampler_count = pixel_sampler_count + vertex_sampler_count; uint32_t sampler_count = pixel_sampler_count + vertex_sampler_count;
@ -1785,7 +1784,10 @@ bool D3D12CommandProcessor::UpdateBindings(
RootExtraParameterIndices::kUnavailable); RootExtraParameterIndices::kUnavailable);
gpu_handle_pixel_samplers_ = sampler_gpu_handle; gpu_handle_pixel_samplers_ = sampler_gpu_handle;
for (uint32_t i = 0; i < pixel_sampler_count; ++i) { for (uint32_t i = 0; i < pixel_sampler_count; ++i) {
texture_cache_->WriteSampler(pixel_samplers[i], sampler_cpu_handle); const D3D12Shader::SamplerBinding& sampler = pixel_samplers[i];
texture_cache_->WriteSampler(sampler.fetch_constant, sampler.mag_filter,
sampler.min_filter, sampler.mip_filter,
sampler.aniso_filter, sampler_cpu_handle);
sampler_cpu_handle.ptr += descriptor_size_sampler; sampler_cpu_handle.ptr += descriptor_size_sampler;
sampler_gpu_handle.ptr += descriptor_size_sampler; sampler_gpu_handle.ptr += descriptor_size_sampler;
} }
@ -1797,7 +1799,10 @@ bool D3D12CommandProcessor::UpdateBindings(
RootExtraParameterIndices::kUnavailable); RootExtraParameterIndices::kUnavailable);
gpu_handle_vertex_samplers_ = sampler_gpu_handle; gpu_handle_vertex_samplers_ = sampler_gpu_handle;
for (uint32_t i = 0; i < vertex_sampler_count; ++i) { for (uint32_t i = 0; i < vertex_sampler_count; ++i) {
texture_cache_->WriteSampler(vertex_samplers[i], sampler_cpu_handle); const D3D12Shader::SamplerBinding& sampler = vertex_samplers[i];
texture_cache_->WriteSampler(sampler.fetch_constant, sampler.mag_filter,
sampler.min_filter, sampler.mip_filter,
sampler.aniso_filter, sampler_cpu_handle);
sampler_cpu_handle.ptr += descriptor_size_sampler; sampler_cpu_handle.ptr += descriptor_size_sampler;
sampler_gpu_handle.ptr += descriptor_size_sampler; sampler_gpu_handle.ptr += descriptor_size_sampler;
} }

View File

@ -29,27 +29,33 @@ D3D12Shader::~D3D12Shader() {
void D3D12Shader::SetTexturesAndSamplers( void D3D12Shader::SetTexturesAndSamplers(
const DxbcShaderTranslator::TextureSRV* texture_srvs, const DxbcShaderTranslator::TextureSRV* texture_srvs,
uint32_t texture_srv_count, const uint32_t* sampler_fetch_constants, uint32_t texture_srv_count,
uint32_t sampler_count) { const DxbcShaderTranslator::SamplerBinding* sampler_bindings,
uint32_t sampler_binding_count) {
texture_srvs_.clear();
texture_srvs_.reserve(texture_srv_count);
used_texture_mask_ = 0; used_texture_mask_ = 0;
for (uint32_t i = 0; i < texture_srv_count; ++i) { for (uint32_t i = 0; i < texture_srv_count; ++i) {
TextureSRV& srv = texture_srvs_[i]; TextureSRV srv;
const DxbcShaderTranslator::TextureSRV& translator_srv = texture_srvs[i]; const DxbcShaderTranslator::TextureSRV& translator_srv = texture_srvs[i];
srv.fetch_constant = translator_srv.fetch_constant; srv.fetch_constant = translator_srv.fetch_constant;
srv.dimension = translator_srv.dimension; srv.dimension = translator_srv.dimension;
texture_srvs_.push_back(srv);
used_texture_mask_ |= 1u << translator_srv.fetch_constant; used_texture_mask_ |= 1u << translator_srv.fetch_constant;
} }
texture_srv_count_ = texture_srv_count; sampler_bindings_.clear();
#if 0 sampler_bindings_.reserve(sampler_binding_count);
// If there's a texture, there's a sampler for it. for (uint32_t i = 0; i < texture_srv_count; ++i) {
used_texture_mask_ = 0; SamplerBinding sampler;
for (uint32_t i = 0; i < sampler_count; ++i) { const DxbcShaderTranslator::SamplerBinding& translator_sampler =
uint32_t sampler_fetch_constant = sampler_fetch_constants[i]; sampler_bindings[i];
sampler_fetch_constants_[i] = sampler_fetch_constant; sampler.fetch_constant = translator_sampler.fetch_constant;
used_texture_mask_ |= 1u << sampler_fetch_constant; sampler.mag_filter = translator_sampler.mag_filter;
sampler.min_filter = translator_sampler.min_filter;
sampler.mip_filter = translator_sampler.mip_filter;
sampler.aniso_filter = translator_sampler.aniso_filter;
sampler_bindings_.push_back(sampler);
} }
sampler_count_ = sampler_count;
#endif
} }
bool D3D12Shader::DisassembleDXBC() { bool D3D12Shader::DisassembleDXBC() {

View File

@ -10,6 +10,8 @@
#ifndef XENIA_GPU_D3D12_D3D12_SHADER_H_ #ifndef XENIA_GPU_D3D12_D3D12_SHADER_H_
#define XENIA_GPU_D3D12_D3D12_SHADER_H_ #define XENIA_GPU_D3D12_D3D12_SHADER_H_
#include <vector>
#include "xenia/gpu/dxbc_shader_translator.h" #include "xenia/gpu/dxbc_shader_translator.h"
#include "xenia/gpu/shader.h" #include "xenia/gpu/shader.h"
#include "xenia/ui/d3d12/d3d12_api.h" #include "xenia/ui/d3d12/d3d12_api.h"
@ -26,34 +28,48 @@ class D3D12Shader : public Shader {
void SetTexturesAndSamplers( void SetTexturesAndSamplers(
const DxbcShaderTranslator::TextureSRV* texture_srvs, const DxbcShaderTranslator::TextureSRV* texture_srvs,
uint32_t texture_srv_count, const uint32_t* sampler_fetch_constants, uint32_t texture_srv_count,
uint32_t sampler_count); const DxbcShaderTranslator::SamplerBinding* sampler_bindings,
uint32_t sampler_binding_count);
bool DisassembleDXBC(); bool DisassembleDXBC();
static constexpr uint32_t kMaxTextureSRVIndexBits =
DxbcShaderTranslator::kMaxTextureSRVIndexBits;
static constexpr uint32_t kMaxTextureSRVs =
DxbcShaderTranslator::kMaxTextureSRVs;
struct TextureSRV { struct TextureSRV {
uint32_t fetch_constant; uint32_t fetch_constant;
TextureDimension dimension; TextureDimension dimension;
}; };
const TextureSRV* GetTextureSRVs(uint32_t& count_out) const { const TextureSRV* GetTextureSRVs(uint32_t& count_out) const {
count_out = texture_srv_count_; count_out = uint32_t(texture_srvs_.size());
return texture_srvs_; return texture_srvs_.data();
}
const uint32_t* GetSamplerFetchConstants(uint32_t& count_out) const {
count_out = sampler_count_;
return sampler_fetch_constants_;
} }
const uint32_t GetUsedTextureMask() const { return used_texture_mask_; } const uint32_t GetUsedTextureMask() const { return used_texture_mask_; }
static constexpr uint32_t kMaxSamplerBindingIndexBits =
DxbcShaderTranslator::kMaxSamplerBindingIndexBits;
static constexpr uint32_t kMaxSamplerBindings =
DxbcShaderTranslator::kMaxSamplerBindings;
struct SamplerBinding {
uint32_t fetch_constant;
TextureFilter mag_filter;
TextureFilter min_filter;
TextureFilter mip_filter;
AnisoFilter aniso_filter;
};
const SamplerBinding* GetSamplerBindings(uint32_t& count_out) const {
count_out = uint32_t(sampler_bindings_.size());
return sampler_bindings_.data();
}
private: private:
ID3DBlob* blob_ = nullptr; ID3DBlob* blob_ = nullptr;
// Up to 32 2D array textures, 32 3D textures and 32 cube textures. std::vector<TextureSRV> texture_srvs_;
TextureSRV texture_srvs_[96];
uint32_t texture_srv_count_ = 0;
uint32_t sampler_fetch_constants_[32];
uint32_t sampler_count_ = 0;
uint32_t used_texture_mask_ = 0; uint32_t used_texture_mask_ = 0;
std::vector<SamplerBinding> sampler_bindings_;
}; };
} // namespace d3d12 } // namespace d3d12

View File

@ -196,17 +196,14 @@ bool PipelineCache::TranslateShader(D3D12Shader* shader,
return false; return false;
} }
// TODO(Triang3l): Re-enable this when the DXBC shader translators supports
// textures.
uint32_t texture_srv_count; uint32_t texture_srv_count;
const DxbcShaderTranslator::TextureSRV* texture_srvs = const DxbcShaderTranslator::TextureSRV* texture_srvs =
shader_translator_->GetTextureSRVs(texture_srv_count); shader_translator_->GetTextureSRVs(texture_srv_count);
#if 0 uint32_t sampler_binding_count;
uint32_t sampler_count; const DxbcShaderTranslator::SamplerBinding* sampler_bindings =
const uint32_t* sampler_fetch_constants = shader_translator_->GetSamplerBindings(sampler_binding_count);
shader_translator_->GetSamplerFetchConstants(sampler_count); shader->SetTexturesAndSamplers(texture_srvs, texture_srv_count,
#endif sampler_bindings, sampler_binding_count);
shader->SetTexturesAndSamplers(texture_srvs, texture_srv_count, nullptr, 0);
if (shader->is_valid()) { if (shader->is_valid()) {
XELOGGPU("Generated %s shader (%db) - hash %.16" PRIX64 ":\n%s\n", XELOGGPU("Generated %s shader (%db) - hash %.16" PRIX64 ":\n%s\n",

View File

@ -445,34 +445,46 @@ void TextureCache::WriteTextureSRV(uint32_t fetch_constant,
} }
void TextureCache::WriteSampler(uint32_t fetch_constant, void TextureCache::WriteSampler(uint32_t fetch_constant,
TextureFilter mag_filter,
TextureFilter min_filter,
TextureFilter mip_filter,
AnisoFilter aniso_filter,
D3D12_CPU_DESCRIPTOR_HANDLE handle) { D3D12_CPU_DESCRIPTOR_HANDLE handle) {
auto& regs = *register_file_; auto& regs = *register_file_;
uint32_t r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + fetch_constant * 6; uint32_t r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + fetch_constant * 6;
auto group = auto group =
reinterpret_cast<const xenos::xe_gpu_fetch_group_t*>(&regs.values[r]); reinterpret_cast<const xenos::xe_gpu_fetch_group_t*>(&regs.values[r]);
auto& fetch = group->texture_fetch; auto& fetch = group->texture_fetch;
// TODO(Triang3l): Fetch shader instruction overrides. if (mag_filter == TextureFilter::kUseFetchConst) {
mag_filter = TextureFilter(fetch.mag_filter);
}
if (min_filter == TextureFilter::kUseFetchConst) {
min_filter = TextureFilter(fetch.min_filter);
}
if (mip_filter == TextureFilter::kUseFetchConst) {
mip_filter = TextureFilter(fetch.mip_filter);
}
if (aniso_filter == AnisoFilter::kUseFetchConst) {
aniso_filter = AnisoFilter(fetch.aniso_filter);
}
D3D12_SAMPLER_DESC desc; D3D12_SAMPLER_DESC desc;
if (fetch.aniso_filter) { if (fetch.aniso_filter) {
desc.Filter = D3D12_FILTER_ANISOTROPIC; desc.Filter = D3D12_FILTER_ANISOTROPIC;
desc.MaxAnisotropy = std::min(1u << (fetch.aniso_filter - 1), 16u); desc.MaxAnisotropy = std::min(1u << (uint32_t(aniso_filter) - 1), 16u);
} else { } else {
D3D12_FILTER_TYPE filter_min = D3D12_FILTER_TYPE d3d_filter_min = min_filter == TextureFilter::kLinear
TextureFilter(fetch.min_filter) == TextureFilter::kLinear ? D3D12_FILTER_TYPE_LINEAR
? D3D12_FILTER_TYPE_LINEAR : D3D12_FILTER_TYPE_POINT;
: D3D12_FILTER_TYPE_POINT; D3D12_FILTER_TYPE d3d_filter_mag = mag_filter == TextureFilter::kLinear
D3D12_FILTER_TYPE filter_mag = ? D3D12_FILTER_TYPE_LINEAR
TextureFilter(fetch.mag_filter) == TextureFilter::kLinear : D3D12_FILTER_TYPE_POINT;
? D3D12_FILTER_TYPE_LINEAR D3D12_FILTER_TYPE d3d_filter_mip = mip_filter == TextureFilter::kLinear
: D3D12_FILTER_TYPE_POINT; ? D3D12_FILTER_TYPE_LINEAR
D3D12_FILTER_TYPE filter_mip = : D3D12_FILTER_TYPE_POINT;
TextureFilter(fetch.mip_filter) == TextureFilter::kLinear
? D3D12_FILTER_TYPE_LINEAR
: D3D12_FILTER_TYPE_POINT;
// TODO(Triang3l): Investigate mip_filter TextureFilter::kBaseMap. // TODO(Triang3l): Investigate mip_filter TextureFilter::kBaseMap.
desc.Filter = desc.Filter = D3D12_ENCODE_BASIC_FILTER(
D3D12_ENCODE_BASIC_FILTER(filter_min, filter_mag, filter_mip, d3d_filter_min, d3d_filter_mag, d3d_filter_mip,
D3D12_FILTER_REDUCTION_TYPE_STANDARD); D3D12_FILTER_REDUCTION_TYPE_STANDARD);
desc.MaxAnisotropy = 1; desc.MaxAnisotropy = 1;
} }
// FIXME(Triang3l): Halfway and mirror clamp to border aren't mapped properly. // FIXME(Triang3l): Halfway and mirror clamp to border aren't mapped properly.

View File

@ -76,7 +76,9 @@ class TextureCache {
void WriteTextureSRV(uint32_t fetch_constant, void WriteTextureSRV(uint32_t fetch_constant,
TextureDimension shader_dimension, TextureDimension shader_dimension,
D3D12_CPU_DESCRIPTOR_HANDLE handle); D3D12_CPU_DESCRIPTOR_HANDLE handle);
void WriteSampler(uint32_t fetch_constant, void WriteSampler(uint32_t fetch_constant, TextureFilter mag_filter,
TextureFilter min_filter, TextureFilter mip_filter,
AnisoFilter aniso_filter,
D3D12_CPU_DESCRIPTOR_HANDLE handle); D3D12_CPU_DESCRIPTOR_HANDLE handle);
static DXGI_FORMAT GetResolveDXGIFormat(TextureFormat format); static DXGI_FORMAT GetResolveDXGIFormat(TextureFormat format);

View File

@ -13,6 +13,8 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <memory>
#include <sstream>
#include "third_party/dxbc/DXBCChecksum.h" #include "third_party/dxbc/DXBCChecksum.h"
#include "third_party/dxbc/d3d12TokenizedProgramFormat.hpp" #include "third_party/dxbc/d3d12TokenizedProgramFormat.hpp"
@ -2870,6 +2872,10 @@ uint32_t DxbcShaderTranslator::FindOrAddTextureSRV(uint32_t fetch_constant,
return 1 + i; return 1 + i;
} }
} }
if (texture_srvs_.size() >= kMaxTextureSRVs) {
assert_always();
return 1 + (kMaxTextureSRVs - 1);
}
TextureSRV new_texture_srv; TextureSRV new_texture_srv;
new_texture_srv.fetch_constant = fetch_constant; new_texture_srv.fetch_constant = fetch_constant;
new_texture_srv.dimension = dimension; new_texture_srv.dimension = dimension;
@ -2887,10 +2893,63 @@ uint32_t DxbcShaderTranslator::FindOrAddTextureSRV(uint32_t fetch_constant,
new_texture_srv.name = new_texture_srv.name =
xe::format_string("xe_texture%u_%s", fetch_constant, dimension_name); xe::format_string("xe_texture%u_%s", fetch_constant, dimension_name);
uint32_t srv_register = 1 + uint32_t(texture_srvs_.size()); uint32_t srv_register = 1 + uint32_t(texture_srvs_.size());
texture_srvs_.push_back(new_texture_srv); texture_srvs_.emplace_back(std::move(new_texture_srv));
return srv_register; return srv_register;
} }
uint32_t DxbcShaderTranslator::FindOrAddSamplerBinding(
uint32_t fetch_constant, TextureFilter mag_filter, TextureFilter min_filter,
TextureFilter mip_filter, AnisoFilter aniso_filter) {
// In Direct3D 12, anisotropic filtering implies linear filtering.
if (aniso_filter != AnisoFilter::kDisabled &&
aniso_filter != AnisoFilter::kUseFetchConst) {
mag_filter = TextureFilter::kLinear;
min_filter = TextureFilter::kLinear;
mip_filter = TextureFilter::kLinear;
aniso_filter = std::min(aniso_filter, AnisoFilter::kMax_16_1);
}
for (uint32_t i = 0; i < uint32_t(sampler_bindings_.size()); ++i) {
const SamplerBinding& sampler_binding = sampler_bindings_[i];
if (sampler_binding.fetch_constant == fetch_constant &&
sampler_binding.mag_filter == mag_filter &&
sampler_binding.min_filter == min_filter &&
sampler_binding.mip_filter == mip_filter &&
sampler_binding.aniso_filter == aniso_filter) {
return i;
}
}
if (sampler_bindings_.size() >= kMaxSamplerBindings) {
assert_always();
return kMaxSamplerBindings - 1;
}
std::ostringstream name;
name << "xe_sampler" << fetch_constant;
if (aniso_filter != AnisoFilter::kUseFetchConst) {
name << "_a" << (1u << uint32_t(aniso_filter));
}
if (aniso_filter == AnisoFilter::kDisabled ||
aniso_filter == AnisoFilter::kUseFetchConst) {
static const char* kFilterSuffixes[] = {"p", "l", "b", "f"};
name << "_" << kFilterSuffixes[uint32_t(mag_filter)]
<< kFilterSuffixes[uint32_t(min_filter)]
<< kFilterSuffixes[uint32_t(mip_filter)];
}
SamplerBinding new_sampler_binding;
new_sampler_binding.fetch_constant = fetch_constant;
new_sampler_binding.mag_filter = mag_filter;
new_sampler_binding.min_filter = min_filter;
new_sampler_binding.mip_filter = mip_filter;
new_sampler_binding.aniso_filter = aniso_filter;
new_sampler_binding.name = name.str();
uint32_t sampler_register = 1 + uint32_t(sampler_bindings_.size());
sampler_bindings_.emplace_back(std::move(new_sampler_binding));
return sampler_register;
}
void DxbcShaderTranslator::ProcessTextureFetchInstruction( void DxbcShaderTranslator::ProcessTextureFetchInstruction(
const ParsedTextureFetchInstruction& instr) { const ParsedTextureFetchInstruction& instr) {
CheckPredicate(instr.is_predicated, instr.predicate_condition); CheckPredicate(instr.is_predicated, instr.predicate_condition);
@ -2927,7 +2986,11 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
srv_register_3d = UINT32_MAX; srv_register_3d = UINT32_MAX;
} }
// TODO(Triang3l): Sampler, actually sample instead of this stub. uint32_t sampler_register = FindOrAddSamplerBinding(
tfetch_index, instr.attributes.mag_filter, instr.attributes.min_filter,
instr.attributes.mip_filter, instr.attributes.aniso_filter);
// TODO(Triang3l): Actually sample instead of this stub.
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8));
shader_code_.push_back( shader_code_.push_back(

View File

@ -62,6 +62,11 @@ class DxbcShaderTranslator : public ShaderTranslator {
uint32_t color_output_map[4]; uint32_t color_output_map[4];
}; };
// 96 textures at most because there are 32 fetch constants, and textures can
// be 2D array, 3D or cube.
static constexpr uint32_t kMaxTextureSRVIndexBits = 7;
static constexpr uint32_t kMaxTextureSRVs =
(1 << kMaxTextureSRVIndexBits) - 1;
struct TextureSRV { struct TextureSRV {
uint32_t fetch_constant; uint32_t fetch_constant;
TextureDimension dimension; TextureDimension dimension;
@ -73,6 +78,17 @@ class DxbcShaderTranslator : public ShaderTranslator {
return texture_srvs_.data(); return texture_srvs_.data();
} }
// Arbitrary limit - there can't be more than 2048 in a shader-visible
// descriptor heap, though some older hardware (tier 1 resource binding -
// Nvidia Fermi) doesn't support more than 16 samplers bound at once (we can't
// really do anything if a game uses more than 16), but just to have some
// limit so sampler count can easily be packed into 32-bit map keys (for
// instance, for root signatures). But shaders can specify overrides for
// filtering modes, and the number of possible combinations is huge - let's
// limit it to something sane.
static constexpr uint32_t kMaxSamplerBindingIndexBits = 7;
static constexpr uint32_t kMaxSamplerBindings =
(1 << kMaxSamplerBindingIndexBits) - 1;
struct SamplerBinding { struct SamplerBinding {
uint32_t fetch_constant; uint32_t fetch_constant;
TextureFilter mag_filter; TextureFilter mag_filter;
@ -341,6 +357,12 @@ class DxbcShaderTranslator : public ShaderTranslator {
// Returns T#/t# index (they are the same in this translator). // Returns T#/t# index (they are the same in this translator).
uint32_t FindOrAddTextureSRV(uint32_t fetch_constant, uint32_t FindOrAddTextureSRV(uint32_t fetch_constant,
TextureDimension dimension); TextureDimension dimension);
// Returns S#/s# index (they are the same in this translator).
uint32_t FindOrAddSamplerBinding(uint32_t fetch_constant,
TextureFilter mag_filter,
TextureFilter min_filter,
TextureFilter mip_filter,
AnisoFilter aniso_filter);
void ProcessVectorAluInstruction(const ParsedAluInstruction& instr); void ProcessVectorAluInstruction(const ParsedAluInstruction& instr);
void ProcessScalarAluInstruction(const ParsedAluInstruction& instr); void ProcessScalarAluInstruction(const ParsedAluInstruction& instr);