1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-23 11:13:19 +01:00

rsx: Improve vertex textures support

- Adds proper support for vertex textures, including dimensions other than 2D textures
- Minor analyser fixup, removes spurious 'analyser failed' errors
- Minor optimizations for program state tracking
This commit is contained in:
kd-11 2018-07-09 21:31:31 +03:00 committed by kd-11
parent c5b2469fe7
commit fa55a8072c
20 changed files with 166 additions and 105 deletions

View File

@ -604,8 +604,13 @@ namespace glsl
return "dFdx($0)";
case FUNCTION::FUNCTION_DFDY:
return "dFdy($0)";
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH1D:
return "textureLod($t, $0.x, 0)";
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
return "textureLod($t, $0.xy, 0)";
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH3D:
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCHCUBE:
return "textureLod($t, $0.xyz, 0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
return "TEX2D_DEPTH_RGBA8($_i, $t, $0.xy)";
}

View File

@ -31,7 +31,7 @@ size_t vertex_program_utils::get_vertex_program_ucode_hash(const RSXVertexProgra
vertex_program_utils::vertex_program_metadata vertex_program_utils::analyse_vertex_program(const u32* data, u32 entry, RSXVertexProgram& dst_prog)
{
vertex_program_utils::vertex_program_metadata result;
vertex_program_utils::vertex_program_metadata result{};
u32 last_instruction_address = 0;
u32 first_instruction_address = entry;
@ -79,6 +79,17 @@ vertex_program_utils::vertex_program_metadata vertex_program_utils::analyse_vert
instruction_range.first = std::min(current_instrution, instruction_range.first);
instruction_range.second = std::max(current_instrution, instruction_range.second);
// Basic vec op analysis, must be done before flow analysis
switch (d1.vec_opcode)
{
case RSX_VEC_OPCODE_TXL:
{
d2.HEX = instruction->word[2];
result.referenced_textures_mask |= (1 << d2.tex_num);
break;
}
}
bool static_jump = false;
bool function_call = true;
@ -223,7 +234,7 @@ vertex_program_utils::vertex_program_metadata vertex_program_utils::analyse_vert
// Verification
for (const u32 target : dst_prog.jump_table)
{
if (!result.instruction_mask[target])
if (!dst_prog.instruction_mask[target])
{
LOG_ERROR(RSX, "vp_analyser: Failed, branch target 0x%x was not resolved", target);
}
@ -237,6 +248,7 @@ size_t vertex_program_storage_hash::operator()(const RSXVertexProgram &program)
{
size_t hash = vertex_program_utils::get_vertex_program_ucode_hash(program);
hash ^= program.output_mask;
hash ^= program.texture_dimensions;
return hash;
}
@ -244,6 +256,8 @@ bool vertex_program_compare::operator()(const RSXVertexProgram &binary1, const R
{
if (binary1.output_mask != binary2.output_mask)
return false;
if (binary1.texture_dimensions != binary2.texture_dimensions)
return false;
if (binary1.data.size() != binary2.data.size())
return false;
if (binary1.jump_table != binary2.jump_table)

View File

@ -31,6 +31,7 @@ namespace program_hash_util
{
std::bitset<512> instruction_mask;
u32 ucode_length;
u32 referenced_textures_mask;
};
static size_t get_vertex_program_ucode_hash(const RSXVertexProgram &program);

View File

@ -176,7 +176,24 @@ void VertexProgramDecompiler::SetDST(bool is_sca, std::string value)
std::string VertexProgramDecompiler::GetTex()
{
return m_parr.AddParam(PF_PARAM_UNIFORM, "sampler2D", std::string("vtex") + std::to_string(d2.tex_num));
std::string sampler;
switch (m_prog.get_texture_dimension(d2.tex_num))
{
case rsx::texture_dimension_extended::texture_dimension_1d:
sampler = "sampler1D";
break;
case rsx::texture_dimension_extended::texture_dimension_2d:
sampler = "sampler2D";
break;
case rsx::texture_dimension_extended::texture_dimension_3d:
sampler = "sampler3D";
break;
case rsx::texture_dimension_extended::texture_dimension_cubemap:
sampler = "samplerCube";
break;
}
return m_parr.AddParam(PF_PARAM_UNIFORM, sampler, std::string("vtex") + std::to_string(d2.tex_num));
}
std::string VertexProgramDecompiler::Format(const std::string& code)
@ -612,8 +629,26 @@ std::string VertexProgramDecompiler::Decompile()
case RSX_VEC_OPCODE_SNE: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SNE, "$0", "$1") + ")"); break;
case RSX_VEC_OPCODE_STR: SetDSTVec(getFunction(FUNCTION::FUNCTION_STR)); break;
case RSX_VEC_OPCODE_SSG: SetDSTVec("sign($0)"); break;
case RSX_VEC_OPCODE_TXL: SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D)); break;
case RSX_VEC_OPCODE_TXL:
{
switch (m_prog.get_texture_dimension(d2.tex_num))
{
case rsx::texture_dimension_extended::texture_dimension_1d:
SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH1D));
break;
case rsx::texture_dimension_extended::texture_dimension_2d:
SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D));
break;
case rsx::texture_dimension_extended::texture_dimension_3d:
SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH3D));
break;
case rsx::texture_dimension_extended::texture_dimension_cubemap:
SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCHCUBE));
break;
}
break;
}
default:
AddCode(fmt::format("//Unknown vp opcode 0x%x", u32{ d1.vec_opcode }));
LOG_ERROR(RSX, "Unknown vp opcode 0x%x", u32{ d1.vec_opcode });

View File

@ -25,7 +25,7 @@ std::string getFunctionImp(FUNCTION f)
switch (f)
{
default:
abort();
fmt::throw_exception("Unsupported program function %d", (u32)f);
case FUNCTION::FUNCTION_DP2:
return "dot($0.xy, $1.xy).xxxx";
case FUNCTION::FUNCTION_DP2A:

View File

@ -6,6 +6,7 @@
#include "D3D12Formats.h"
#include "../rsx_methods.h"
#include "../rsx_utils.h"
#include "../Common/TextureUtils.h"
#define TO_STRING(x) #x
@ -53,7 +54,7 @@ void D3D12GSRender::load_program()
return std::make_tuple(true, native_pitch);
};
get_current_vertex_program(false);
get_current_vertex_program({}, true);
get_current_fragment_program_legacy(rtt_lookup_func);
if (!current_fragment_program.valid)

View File

@ -24,7 +24,7 @@ namespace
GLGSRender::GLGSRender() : GSRender()
{
m_shaders_cache.reset(new gl::shader_cache(m_prog_buffer, "opengl", "v1.5"));
m_shaders_cache.reset(new gl::shader_cache(m_prog_buffer, "opengl", "v1.6"));
if (g_cfg.video.disable_vertex_cache)
m_vertex_cache.reset(new gl::null_vertex_cache());
@ -330,7 +330,7 @@ void GLGSRender::end()
*sampler_state = m_gl_texture_cache.upload_texture(unused, rsx::method_registers.fragment_textures[i], m_rtts);
if (m_textures_dirty[i])
m_gl_sampler_states[i].apply(rsx::method_registers.fragment_textures[i], fs_sampler_state[i].get());
m_fs_sampler_states[i].apply(rsx::method_registers.fragment_textures[i], fs_sampler_state[i].get());
}
else
{
@ -354,6 +354,9 @@ void GLGSRender::end()
if (rsx::method_registers.vertex_textures[i].enabled())
{
*sampler_state = m_gl_texture_cache.upload_texture(unused, rsx::method_registers.vertex_textures[i], m_rtts);
if (m_vertex_textures_dirty[i])
m_vs_sampler_states[i].apply(rsx::method_registers.vertex_textures[i], vs_sampler_state[i].get());
}
else
*sampler_state = {};
@ -783,8 +786,14 @@ void GLGSRender::on_init_thread()
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
{
m_gl_sampler_states[i].create();
m_gl_sampler_states[i].bind(i);
m_fs_sampler_states[i].create();
m_fs_sampler_states[i].bind(i);
}
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
{
m_vs_sampler_states[i].create();
m_vs_sampler_states[i].bind(rsx::limits::fragment_textures_count + i);
}
//Occlusion query
@ -917,7 +926,12 @@ void GLGSRender::on_exit()
m_gl_persistent_stream_buffer.reset();
m_gl_volatile_stream_buffer.reset();
for (auto &sampler : m_gl_sampler_states)
for (auto &sampler : m_fs_sampler_states)
{
sampler.remove();
}
for (auto &sampler : m_vs_sampler_states)
{
sampler.remove();
}
@ -1101,7 +1115,7 @@ void GLGSRender::load_program(const gl::vertex_upload_info& upload_info)
get_current_fragment_program(fs_sampler_state);
verify(HERE), current_fragment_program.valid;
get_current_vertex_program();
get_current_vertex_program(vs_sampler_state);
current_vertex_program.skip_vertex_input_check = true; //not needed for us since decoding is done server side
current_fragment_program.unnormalized_coords = 0; //unused

View File

@ -279,7 +279,8 @@ private:
GLFragmentProgram m_fragment_prog;
GLVertexProgram m_vertex_prog;
gl::sampler_state m_gl_sampler_states[rsx::limits::fragment_textures_count];
gl::sampler_state m_fs_sampler_states[rsx::limits::fragment_textures_count];
gl::sampler_state m_vs_sampler_states[rsx::limits::vertex_textures_count];
gl::glsl::program *m_program;

View File

@ -48,14 +48,14 @@ struct GLTraits
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
{
int location;
if (result.uniforms.has_location("tex" + std::to_string(i), &location))
if (result.uniforms.has_location(rsx::constants::fragment_texture_names[i], &location))
result.uniforms[location] = i;
}
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
{
int location;
if (result.uniforms.has_location("vtex" + std::to_string(i), &location))
if (result.uniforms.has_location(rsx::constants::vertex_texture_names[i], &location))
result.uniforms[location] = (i + rsx::limits::fragment_textures_count);
}

View File

@ -204,7 +204,7 @@ namespace gl
}
//Apply sampler state settings
void sampler_state::apply(rsx::fragment_texture& tex, const rsx::sampled_image_descriptor_base* sampled_image)
void sampler_state::apply(const rsx::fragment_texture& tex, const rsx::sampled_image_descriptor_base* sampled_image)
{
const color4f border_color = rsx::decode_border_color(tex.border_color());
@ -274,6 +274,22 @@ namespace gl
glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
void sampler_state::apply(const rsx::vertex_texture& tex, const rsx::sampled_image_descriptor_base* /*sampled_image*/)
{
const color4f border_color = rsx::decode_border_color(tex.border_color());
glSamplerParameterfv(samplerHandle, GL_TEXTURE_BORDER_COLOR, border_color.rgba);
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, wrap_mode(tex.wrap_s()));
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, wrap_mode(tex.wrap_t()));
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, wrap_mode(tex.wrap_r()));
glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameterf(samplerHandle, GL_TEXTURE_LOD_BIAS, tex.bias());
glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
bool is_compressed_format(u32 texture_format)
{
switch (texture_format)

View File

@ -57,6 +57,7 @@ namespace gl
glBindSampler(index, samplerHandle);
}
void apply(rsx::fragment_texture& tex, const rsx::sampled_image_descriptor_base* sampled_image);
void apply(const rsx::fragment_texture& tex, const rsx::sampled_image_descriptor_base* sampled_image);
void apply(const rsx::vertex_texture& tex, const rsx::sampled_image_descriptor_base* sampled_image);
};
}

View File

@ -191,17 +191,6 @@ void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)
OS << " vec4 " << PI.name << "= read_location(" << std::to_string(PI.location) << ");\n";
}
}
for (const ParamType &PT : m_parr.params[PF_PARAM_UNIFORM])
{
if (PT.type == "sampler2D")
{
for (const ParamItem &PI : PT.items)
{
OS << " vec2 " << PI.name << "_coord_scale = vec2(1.);\n";
}
}
}
}
void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)

View File

@ -396,11 +396,6 @@ namespace rsx
return (max_mipmap_count > 0) ? max_mipmap_count : 1;
}
u8 vertex_texture::unsigned_remap() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 12) & 0xf);
}
std::pair<std::array<u8, 4>, std::array<u8, 4>> vertex_texture::decoded_remap() const
{
return
@ -416,26 +411,6 @@ namespace rsx
return 0xAAE4;
}
u8 vertex_texture::zfunc() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf);
}
u8 vertex_texture::gamma() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 20) & 0xf);
}
u8 vertex_texture::aniso_bias() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 4) & 0xf);
}
u8 vertex_texture::signed_remap() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 24) & 0xf);
}
bool vertex_texture::enabled() const
{
return location() <= 1 && ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1);
@ -451,16 +426,6 @@ namespace rsx
return ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff);
}
rsx::texture_max_anisotropy vertex_texture::max_aniso() const
{
return rsx::to_texture_max_anisotropy((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7);
}
bool vertex_texture::alpha_kill_enabled() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 2) & 0x1);
}
u16 vertex_texture::bias() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff);
@ -468,37 +433,27 @@ namespace rsx
rsx::texture_minify_filter vertex_texture::min_filter() const
{
return rsx::to_texture_minify_filter((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7);
return rsx::texture_minify_filter::nearest;
}
rsx::texture_magnify_filter vertex_texture::mag_filter() const
{
return rsx::to_texture_magnify_filter((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7);
return rsx::texture_magnify_filter::nearest;
}
u8 vertex_texture::convolution_filter() const
rsx::texture_wrap_mode vertex_texture::wrap_s() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 13) & 0xf);
return rsx::to_texture_wrap_mode((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)]) & 0xf);
}
bool vertex_texture::a_signed() const
rsx::texture_wrap_mode vertex_texture::wrap_t() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0x1);
return rsx::to_texture_wrap_mode((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 8) & 0xf);
}
bool vertex_texture::r_signed() const
rsx::texture_wrap_mode vertex_texture::wrap_r() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 29) & 0x1);
}
bool vertex_texture::g_signed() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 30) & 0x1);
}
bool vertex_texture::b_signed() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 31) & 0x1);
return rsx::texture_wrap_mode::wrap;
}
u16 vertex_texture::width() const

View File

@ -123,11 +123,9 @@ namespace rsx
u16 mipmap() const;
// Address
u8 unsigned_remap() const;
u8 zfunc() const;
u8 gamma() const;
u8 aniso_bias() const;
u8 signed_remap() const;
rsx::texture_wrap_mode wrap_s() const;
rsx::texture_wrap_mode wrap_t() const;
rsx::texture_wrap_mode wrap_r() const;
std::pair<std::array<u8, 4>, std::array<u8, 4>> decoded_remap() const;
u32 remap() const;
@ -136,18 +134,11 @@ namespace rsx
bool enabled() const;
u16 min_lod() const;
u16 max_lod() const;
rsx::texture_max_anisotropy max_aniso() const;
bool alpha_kill_enabled() const;
// Filter
u16 bias() const;
rsx::texture_minify_filter min_filter() const;
rsx::texture_magnify_filter mag_filter() const;
u8 convolution_filter() const;
bool a_signed() const;
bool r_signed() const;
bool g_signed() const;
bool b_signed() const;
// Image Rect
u16 width() const;

View File

@ -829,15 +829,15 @@ namespace rsx
}
default:
{
//TODO: Reorder draw commands between synchronization events to maximize batched sizes
// TODO: Reorder draw commands between synchronization events to maximize batched sizes
static const std::pair<u32, u32> skippable_ranges[] =
{
//Texture configuration
// Texture configuration
{ NV4097_SET_TEXTURE_OFFSET, 8 * 16 },
{ NV4097_SET_TEXTURE_CONTROL2, 16 },
{ NV4097_SET_TEXTURE_CONTROL3, 16 },
{ NV4097_SET_VERTEX_TEXTURE_OFFSET, 8 * 4 },
//Surface configuration
// Surface configuration
{ NV4097_SET_SURFACE_CLIP_HORIZONTAL, 1 },
{ NV4097_SET_SURFACE_CLIP_VERTICAL, 1 },
{ NV4097_SET_SURFACE_COLOR_AOFFSET, 1 },
@ -855,7 +855,11 @@ namespace rsx
{ NV4097_SET_SURFACE_PITCH_B, 1 },
{ NV4097_SET_SURFACE_PITCH_C, 1 },
{ NV4097_SET_SURFACE_PITCH_D, 1 },
{ NV4097_SET_SURFACE_PITCH_Z, 1 }
{ NV4097_SET_SURFACE_PITCH_Z, 1 },
// Program configuration
{ NV4097_SET_TRANSFORM_PROGRAM_START, 1 },
{ NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, 1 },
{ NV4097_SET_TRANSFORM_PROGRAM, 512 }
};
if (has_deferred_call)
@ -1393,7 +1397,7 @@ namespace rsx
return rsx::get_address(offset_zeta, m_context_dma_z);
}
void thread::get_current_vertex_program(bool skip_vertex_inputs)
void thread::get_current_vertex_program(const std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::vertex_textures_count>& sampler_descriptors, bool skip_textures, bool skip_vertex_inputs)
{
if (!(m_graphics_state & rsx::pipeline_state::vertex_program_dirty))
return;
@ -1406,6 +1410,7 @@ namespace rsx
current_vertex_program.rsx_vertex_inputs.resize(0);
current_vertex_program.data.reserve(512 * 4);
current_vertex_program.jump_table.clear();
current_vertex_program.texture_dimensions = 0;
current_vp_metadata = program_hash_util::vertex_program_utils::analyse_vertex_program
(
@ -1414,6 +1419,18 @@ namespace rsx
current_vertex_program // [out] Program object
);
if (!skip_textures && current_vp_metadata.referenced_textures_mask != 0)
{
for (u32 i = 0; i < rsx::limits::vertex_textures_count; ++i)
{
const auto &tex = rsx::method_registers.vertex_textures[i];
if (tex.enabled() && (current_vp_metadata.referenced_textures_mask & (1 << i)))
{
current_vertex_program.texture_dimensions |= ((u32)sampler_descriptors[i]->image_type << (i << 1));
}
}
}
if (!skip_vertex_inputs)
{
const u32 input_mask = rsx::method_registers.vertex_attrib_input_mask();

View File

@ -362,6 +362,9 @@ namespace rsx
u32 m_graphics_state = 0;
u64 ROP_sync_timestamp = 0;
program_hash_util::fragment_program_utils::fragment_program_metadata current_fp_metadata = {};
program_hash_util::vertex_program_utils::vertex_program_metadata current_vp_metadata = {};
protected:
std::array<u32, 4> get_color_surface_addresses() const;
u32 get_zeta_surface_address() const;
@ -374,10 +377,7 @@ namespace rsx
RSXVertexProgram current_vertex_program = {};
RSXFragmentProgram current_fragment_program = {};
program_hash_util::fragment_program_utils::fragment_program_metadata current_fp_metadata = {};
program_hash_util::vertex_program_utils::vertex_program_metadata current_vp_metadata = {};
void get_current_vertex_program(bool skip_vertex_inputs = true);
void get_current_vertex_program(const std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::vertex_textures_count>& sampler_descriptors, bool skip_textures = false, bool skip_vertex_inputs = true);
/**
* Gets current fragment program and associated fragment state

View File

@ -1,5 +1,7 @@
#pragma once
#include "RSXTexture.h"
#include <bitset>
#include <set>
@ -231,10 +233,16 @@ struct RSXVertexProgram
std::vector<u32> data;
std::vector<rsx_vertex_input> rsx_vertex_inputs;
u32 output_mask;
u32 texture_dimensions;
bool skip_vertex_input_check;
u32 base_address;
u32 entry;
std::bitset<512> instruction_mask;
std::set<u32> jump_table;
rsx::texture_dimension_extended get_texture_dimension(u8 id) const
{
return (rsx::texture_dimension_extended)((texture_dimensions >> (id * 2)) & 0x3);
}
};

View File

@ -626,7 +626,7 @@ VKGSRender::VKGSRender() : GSRender()
else
m_vertex_cache.reset(new vk::weak_vertex_cache());
m_shaders_cache.reset(new vk::shader_cache(*m_prog_buffer.get(), "vulkan", "v1.5"));
m_shaders_cache.reset(new vk::shader_cache(*m_prog_buffer.get(), "vulkan", "v1.6"));
open_command_buffer();
@ -2200,7 +2200,7 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
get_current_fragment_program(fs_sampler_state);
verify(HERE), current_fragment_program.valid;
get_current_vertex_program();
get_current_vertex_program(vs_sampler_state);
}
auto &vertex_program = current_vertex_program;

View File

@ -378,6 +378,7 @@ namespace rsx
u64 pipeline_storage_hash;
u32 vp_ctrl;
u32 vp_texture_dimensions;
u64 vp_instruction_mask[8];
u32 vp_base_address;
@ -698,6 +699,7 @@ namespace rsx
u64 state_hash = 0;
state_hash ^= rpcs3::hash_base<u32>(data.vp_ctrl);
state_hash ^= rpcs3::hash_base<u32>(data.fp_ctrl);
state_hash ^= rpcs3::hash_base<u32>(data.vp_texture_dimensions);
state_hash ^= rpcs3::hash_base<u32>(data.fp_texture_dimensions);
state_hash ^= rpcs3::hash_base<u16>(data.fp_unnormalized_coords);
state_hash ^= rpcs3::hash_base<u16>(data.fp_height);
@ -750,6 +752,7 @@ namespace rsx
pipeline_storage_type pipeline = data.pipeline_properties;
vp.output_mask = data.vp_ctrl;
vp.texture_dimensions = data.vp_texture_dimensions;
vp.base_address = data.vp_base_address;
vp.entry = data.vp_entry;
@ -796,6 +799,7 @@ namespace rsx
data_block.pipeline_storage_hash = m_storage.get_hash(pipeline);
data_block.vp_ctrl = vp.output_mask;
data_block.vp_texture_dimensions = vp.texture_dimensions;
data_block.vp_base_address = vp.base_address;
data_block.vp_entry = vp.entry;

View File

@ -563,7 +563,11 @@ namespace rsx
static void impl(thread* rsx, u32 _reg, u32 arg)
{
rsx->m_textures_dirty[index] = true;
rsx->m_graphics_state |= rsx::pipeline_state::fragment_program_dirty;
if (rsx->current_fp_metadata.referenced_textures_mask & (1 << index))
{
rsx->m_graphics_state |= rsx::pipeline_state::fragment_program_dirty;
}
}
};
@ -573,6 +577,11 @@ namespace rsx
static void impl(thread* rsx, u32 _reg, u32 arg)
{
rsx->m_vertex_textures_dirty[index] = true;
if (rsx->current_vp_metadata.referenced_textures_mask & (1 << index))
{
rsx->m_graphics_state |= rsx::pipeline_state::vertex_program_dirty;
}
}
};
}