Merge pull request #1458 from vlj/rsx

rsx/common: Make RSXFragmentProgram key and not just pointer.
This commit is contained in:
Raul Tambre 2016-01-28 07:42:08 +02:00
commit b4b4ae7a78
8 changed files with 39 additions and 24 deletions

View File

@ -335,7 +335,7 @@ public:
u32 ctrl = (vmfprog.outputFromH0 ? 0 : 0x40) | (vmfprog.depthReplace ? 0xe : 0);
std::vector<texture_dimension> td;
RSXFragmentProgram prog;
prog.size = 0, prog.addr = ptr + vmprog.ucode, prog.offset = 0, prog.ctrl = ctrl;
prog.size = 0, prog.addr = vm::base(ptr + vmprog.ucode), prog.offset = 0, prog.ctrl = ctrl;
GLFragmentDecompilerThread(m_glsl_shader, param_array, prog, size).Task();
vm::close();
}

View File

@ -113,7 +113,7 @@ std::string FragmentProgramDecompiler::AddConst()
return name;
}
auto data = vm::ps3::ptr<u32>::make(m_prog.addr + m_size + 4 * SIZE_32(u32));
auto data = (be_t<u32>*) ((char*)m_prog.addr + m_size + 4 * SIZE_32(u32));
m_offset = 2 * 4 * sizeof(u32);
u32 x = GetData(data[0]);
@ -493,7 +493,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
std::string FragmentProgramDecompiler::Decompile()
{
auto data = vm::ps3::ptr<u32>::make(m_prog.addr);
auto data = (be_t<u32>*) m_prog.addr;
m_size = 0;
m_location = 0;
m_loop_count = 0;

View File

@ -26,7 +26,6 @@ class FragmentProgramDecompiler
std::string main;
u32& m_size;
const RSXFragmentProgram &m_prog;
u32 m_const_index;
u32 m_offset;
u32 m_location;
@ -75,6 +74,7 @@ class FragmentProgramDecompiler
*/
bool handle_tex_srb(u32 opcode);
protected:
const RSXFragmentProgram &m_prog;
u32 m_ctrl;
/** returns the type name of float vectors.
*/

View File

@ -74,11 +74,11 @@ size_t fragment_program_utils::get_fragment_program_ucode_size(void *ptr)
}
}
size_t fragment_program_hash::operator()(const void *program) const
size_t fragment_program_hash::operator()(const RSXFragmentProgram& program) const
{
// 64-bit Fowler/Noll/Vo FNV-1a hash code
size_t hash = 0xCBF29CE484222325ULL;
const qword *instbuffer = (const qword*)program;
const qword *instbuffer = (const qword*)program.addr;
size_t instIndex = 0;
while (true)
{
@ -101,10 +101,13 @@ size_t fragment_program_hash::operator()(const void *program) const
return 0;
}
bool fragment_program_compare::operator()(const void *binary1, const void *binary2) const
bool fragment_program_compare::operator()(const RSXFragmentProgram& binary1, const RSXFragmentProgram& binary2) const
{
const qword *instBuffer1 = (const qword*)binary1;
const qword *instBuffer2 = (const qword*)binary2;
if (binary1.texture_dimensions != binary2.texture_dimensions || binary1.unnormalized_coords != binary2.unnormalized_coords ||
binary1.height != binary2.height || binary1.origin_mode != binary2.origin_mode || binary1.pixel_center_mode != binary2.pixel_center_mode)
return false;
const qword *instBuffer1 = (const qword*)binary1.addr;
const qword *instBuffer2 = (const qword*)binary2.addr;
size_t instIndex = 0;
while (true)
{

View File

@ -43,12 +43,12 @@ namespace program_hash_util
struct fragment_program_hash
{
size_t operator()(const void *program) const;
size_t operator()(const RSXFragmentProgram &program) const;
};
struct fragment_program_compare
{
bool operator()(const void *binary1, const void *binary2) const;
bool operator()(const RSXFragmentProgram &binary1, const RSXFragmentProgram &binary2) const;
};
}
@ -76,7 +76,7 @@ class program_state_cache
using fragment_program_type = typename backend_traits::fragment_program_type;
using binary_to_vertex_program = std::unordered_map<RSXVertexProgram, vertex_program_type, program_hash_util::vertex_program_hash, program_hash_util::vertex_program_compare> ;
using binary_to_fragment_program = std::unordered_map<void *, fragment_program_type, program_hash_util::fragment_program_hash, program_hash_util::fragment_program_compare>;
using binary_to_fragment_program = std::unordered_map<RSXFragmentProgram, fragment_program_type, program_hash_util::fragment_program_hash, program_hash_util::fragment_program_compare>;
struct pipeline_key
@ -130,16 +130,18 @@ private:
/// bool here to inform that the program was preexisting.
std::tuple<const fragment_program_type&, bool> search_fragment_program(const RSXFragmentProgram& rsx_fp)
{
const auto& I = m_fragment_shader_cache.find(vm::base(rsx_fp.addr));
const auto& I = m_fragment_shader_cache.find(rsx_fp);
if (I != m_fragment_shader_cache.end())
{
return std::forward_as_tuple(I->second, true);
}
LOG_NOTICE(RSX, "FP not found in buffer!");
size_t fragment_program_size = program_hash_util::fragment_program_utils::get_fragment_program_ucode_size(vm::base(rsx_fp.addr));
size_t fragment_program_size = program_hash_util::fragment_program_utils::get_fragment_program_ucode_size(rsx_fp.addr);
gsl::not_null<void*> fragment_program_ucode_copy = malloc(fragment_program_size);
std::memcpy(fragment_program_ucode_copy, vm::base(rsx_fp.addr), fragment_program_size);
fragment_program_type &new_shader = m_fragment_shader_cache[fragment_program_ucode_copy];
std::memcpy(fragment_program_ucode_copy, rsx_fp.addr, fragment_program_size);
RSXFragmentProgram new_fp_key = rsx_fp;
new_fp_key.addr = fragment_program_ucode_copy;
fragment_program_type &new_shader = m_fragment_shader_cache[new_fp_key];
backend_traits::recompile_fragment_program(rsx_fp, new_shader, m_next_id++);
return std::forward_as_tuple(new_shader, false);
@ -147,7 +149,13 @@ private:
public:
program_state_cache() = default;
~program_state_cache() = default;
~program_state_cache()
{
for (auto& pair : m_fragment_shader_cache)
{
free(pair.first.addr);
}
};
const vertex_program_type& get_transform_program(const RSXVertexProgram& rsx_vp) const
{
@ -159,7 +167,7 @@ public:
const fragment_program_type& get_shader_program(const RSXFragmentProgram& rsx_fp) const
{
auto I = m_fragment_shader_cache.find(vm::base(rsx_fp.addr));
auto I = m_fragment_shader_cache.find(rsx_fp);
if (I != m_fragment_shader_cache.end())
return I->second;
throw new EXCEPTION("Trying to get unknow shader program");
@ -200,7 +208,7 @@ public:
size_t get_fragment_constants_buffer_size(const RSXFragmentProgram &fragmentShader) const
{
const auto I = m_fragment_shader_cache.find(vm::base(fragmentShader.addr));
const auto I = m_fragment_shader_cache.find(fragmentShader);
if (I != m_fragment_shader_cache.end())
return I->second.FragmentConstantOffsetCache.size() * 4 * sizeof(float);
LOG_ERROR(RSX, "Can't retrieve constant offset cache");
@ -209,7 +217,7 @@ public:
void fill_fragment_constans_buffer(gsl::span<f32, gsl::dynamic_range> dst_buffer, const RSXFragmentProgram &fragment_program) const
{
const auto I = m_fragment_shader_cache.find(vm::base(fragment_program.addr));
const auto I = m_fragment_shader_cache.find(fragment_program);
if (I == m_fragment_shader_cache.end())
return;
__m128i mask = _mm_set_epi8(0xE, 0xF, 0xC, 0xD,
@ -222,7 +230,7 @@ public:
size_t offset = 0;
for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache)
{
void *data = vm::base(fragment_program.addr + (u32)offset_in_fragment_program);
void *data = (char*)fragment_program.addr + (u32)offset_in_fragment_program;
const __m128i &vector = _mm_loadu_si128((__m128i*)data);
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
_mm_stream_si128((__m128i*)dst_buffer.subspan(offset, 4).data(), shuffled_vector);

View File

@ -42,7 +42,7 @@ void D3D12GSRender::load_program()
u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
m_fragment_program.offset = shader_program & ~0x3;
m_fragment_program.addr = rsx::get_address(m_fragment_program.offset, (shader_program & 0x3) - 1);
m_fragment_program.addr = vm::base(rsx::get_address(m_fragment_program.offset, (shader_program & 0x3) - 1));
m_fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
std::array<texture_dimension, 16> texture_dimensions;

View File

@ -741,7 +741,7 @@ bool GLGSRender::load_program()
RSXFragmentProgram fragment_program;
u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
fragment_program.offset = shader_program & ~0x3;
fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1);
fragment_program.addr = vm::base(rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1));
fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
std::array<texture_dimension, 16> texture_dimensions;

View File

@ -1,4 +1,5 @@
#pragma once
#include "GCM.h"
enum
{
@ -214,11 +215,14 @@ enum class texture_dimension : u8
struct RSXFragmentProgram
{
u32 size;
u32 addr;
void *addr;
u32 offset;
u32 ctrl;
u16 unnormalized_coords;
u32 texture_dimensions;
rsx::window_origin origin_mode;
rsx::window_pixel_center pixel_center_mode;
u16 height;
texture_dimension get_texture_dimension(u8 id) const
{