gl/vk: Enable vertex texture fetch (#2127)

* gl: Enable vertex textures

* rsx: use textureLod instead of generic texture sample

* rsx: handle uploading of W32_X32_Y32_Z32

* gl: Re-enable proper shader logging

remove old logging method that overwrites single file

* gl: Declare texture_coord_scale for vertex samplers

* gl: texture remap fixes; enable remap for vertex textures

* gl: offset texture indices to base layer 16

* rsx: Fix W32_Z32_Y32_X32_FLOAT subresource layout

* vk: Enable vertex textures

* rsx: define special calls for vertex texture fetch

* gl: improved vertex texture fetch setup

* vk: Fix texture formats and component mapping

* vk: Implement vertex texture fetch functions properly

* vk/gl: proper fix for primitive restart index

revert inadvertent decompiler update

* gl: Disable filtering for vertex textures
This commit is contained in:
kd-11 2016-09-20 17:23:56 +03:00 committed by raven02
parent 77f8ce503d
commit 867e9210d7
16 changed files with 216 additions and 80 deletions

View File

@ -33,6 +33,10 @@ enum class FUNCTION {
FUNCTION_TEXTURE_SAMPLE3D_PROJ,
FUNCTION_TEXTURE_SAMPLE3D_LOD,
FUNCTION_TEXTURE_SAMPLE3D_GRAD,
FUNCTION_VERTEX_TEXTURE_FETCH1D,
FUNCTION_VERTEX_TEXTURE_FETCH2D,
FUNCTION_VERTEX_TEXTURE_FETCH3D,
FUNCTION_VERTEX_TEXTURE_FETCHCUBE,
};
enum class COMPARE {

View File

@ -178,11 +178,12 @@ std::vector<rsx_subresource_layout> get_subresources_layout_impl(const RsxTextur
return get_subresources_layout_impl<1, u32>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
return get_subresources_layout_impl<1, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
return get_subresources_layout_impl<1, u128>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
return get_subresources_layout_impl<4, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
return get_subresources_layout_impl<4, u128>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
}
fmt::throw_exception("Wrong format 0x%x" HERE, format);
@ -264,6 +265,10 @@ void upload_texture_subresource(gsl::span<gsl::byte> dst_buffer, const rsx_subre
copy_unmodified_block::copy_mipmap_level(as_span_workaround<u64>(dst_buffer), gsl::as_span<const be_t<u64>>(src_layout.data), w, h, depth, get_row_pitch_in_block<u64>(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes);
break;
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
copy_unmodified_block::copy_mipmap_level(as_span_workaround<u128>(dst_buffer), gsl::as_span<const be_t<u128>>(src_layout.data), w, h, depth, get_row_pitch_in_block<u128>(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes);
break;
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
copy_unmodified_block::copy_mipmap_level(as_span_workaround<u64>(dst_buffer), gsl::as_span<const u64>(src_layout.data), w, h, depth, get_row_pitch_in_block<u64>(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes);
break;

View File

@ -674,7 +674,7 @@ 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("texture($t, $0.xy)"); break;
case RSX_VEC_OPCODE_TXL: SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D)); break;
default:
AddCode(fmt::format("//Unknown vp opcode 0x%x", u32{ d1.vec_opcode }));

View File

@ -78,6 +78,8 @@ std::string getFunctionImpl(FUNCTION f)
return "dFdx($0)";
case FUNCTION::FUNCTION_DFDY:
return "dFdy($0)";
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
return "textureLod($t, $0.xy, 0)";
}
}

View File

@ -347,6 +347,9 @@ void GLFragmentProgram::Compile()
const char* str = shader.c_str();
const int strlen = ::narrow<int>(shader.length());
fs::create_path(fs::get_config_dir() + "/shaderlog");
fs::file(fs::get_config_dir() + "shaderlog/FragmentProgram" + std::to_string(id) + ".glsl", fs::rewrite).write(str);
glShaderSource(id, 1, &str, &strlen);
glCompileShader(id);

View File

@ -301,11 +301,6 @@ void GLGSRender::begin()
//NV4097_SET_ANTI_ALIASING_CONTROL
//NV4097_SET_CLIP_ID_TEST_ENABLE
if (__glcheck enable(rsx::method_registers.restart_index_enabled(), GL_PRIMITIVE_RESTART))
{
__glcheck glPrimitiveRestartIndex(rsx::method_registers.restart_index());
}
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
m_begin_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(now - then).count();
m_draw_calls++;
@ -384,6 +379,28 @@ void GLGSRender::end()
}
}
//Vertex textures
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
{
int texture_index = i + rsx::limits::fragment_textures_count;
int location;
if (m_program->uniforms.has_location("vtex" + std::to_string(i), &location))
{
if (!rsx::method_registers.vertex_textures[i].enabled())
{
glActiveTexture(GL_TEXTURE0 + texture_index);
glBindTexture(GL_TEXTURE_2D, 0);
glProgramUniform1i(m_program->id(), location, texture_index);
continue;
}
m_gl_vertex_textures[i].set_target(get_gl_target_for_texture(rsx::method_registers.vertex_textures[i]));
__glcheck m_gl_texture_cache.upload_texture(texture_index, rsx::method_registers.vertex_textures[i], m_gl_vertex_textures[i], m_rtts);
glProgramUniform1i(m_program->id(), location, texture_index);
}
}
u32 vertex_draw_count;
std::optional<std::tuple<GLenum, u32> > indexed_draw_info;
std::tie(vertex_draw_count, indexed_draw_info) = set_vertex_buffer();
@ -398,6 +415,12 @@ void GLGSRender::end()
if (indexed_draw_info)
{
if (__glcheck enable(rsx::method_registers.restart_index_enabled(), GL_PRIMITIVE_RESTART))
{
GLenum index_type = std::get<0>(indexed_draw_info.value());
__glcheck glPrimitiveRestartIndex((index_type == GL_UNSIGNED_SHORT)? 0xffff: 0xffffffff);
}
__glcheck glDrawElements(gl::draw_mode(rsx::method_registers.current_draw_clause.primitive), vertex_draw_count, std::get<0>(indexed_draw_info.value()), (GLvoid *)(std::ptrdiff_t)std::get<1>(indexed_draw_info.value()));
}
else

View File

@ -15,9 +15,6 @@ struct GLTraits
{
fragmentProgramData.Decompile(RSXFP);
fragmentProgramData.Compile();
//checkForGlError("m_fragment_prog.Compile");
fs::file(fs::get_config_dir() + "shaderlog/FragmentProgram.glsl", fs::rewrite).write(fragmentProgramData.shader);
}
static
@ -25,9 +22,6 @@ struct GLTraits
{
vertexProgramData.Decompile(RSXVP);
vertexProgramData.Compile();
//checkForGlError("m_vertex_prog.Compile");
fs::file(fs::get_config_dir() + "shaderlog/VertexProgram.glsl", fs::rewrite).write(vertexProgramData.shader);
}
static

View File

@ -133,7 +133,6 @@ namespace
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT:
case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
@ -151,18 +150,19 @@ namespace
return { GL_GREEN, GL_RED, GL_GREEN, GL_RED};
case CELL_GCM_TEXTURE_X16:
return { GL_RED, GL_ONE, GL_RED, GL_ONE };
return { GL_RED, GL_RED, GL_RED, GL_RED };
case CELL_GCM_TEXTURE_Y16_X16:
return { GL_RED, GL_GREEN, GL_RED, GL_GREEN};
case CELL_GCM_TEXTURE_X32_FLOAT:
return { GL_RED, GL_ONE, GL_ONE, GL_ONE };
return { GL_RED, GL_RED, GL_RED, GL_RED };
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
return { GL_GREEN, GL_RED, GL_GREEN, GL_RED };
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
return { GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN };
case CELL_GCM_TEXTURE_D1R5G5B5:
@ -595,50 +595,18 @@ namespace rsx
glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, tex.get_exact_mipmap_count() - 1);
/*
if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT)
{
u8 remap_a = tex.remap() & 0x3;
u8 remap_r = (tex.remap() >> 2) & 0x3;
u8 remap_g = (tex.remap() >> 4) & 0x3;
u8 remap_b = (tex.remap() >> 6) & 0x3;
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_A, glRemap[0]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_R, glRemap[1]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, glRemap[2]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, glRemap[3]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]);
}
else
{
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_A, glRemap[0]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_R, glRemap[1]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, glRemap[2]);
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, glRemap[3]);
}
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_S, GL_REPEAT);
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_T, GL_REPEAT);
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_R, GL_REPEAT);
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s()));
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t()));
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r()));
*/
__glcheck glTexParameterf(m_target, GL_TEXTURE_LOD_BIAS, tex.bias());
__glcheck glTexParameteri(m_target, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
__glcheck glTexParameteri(m_target, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
int min_filter = gl_tex_min_filter(tex.min_filter());
if (min_filter != GL_LINEAR && min_filter != GL_NEAREST)
{
if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE)
{
LOG_WARNING(RSX, "Texture %d, target 0x%x, requesting mipmap filtering without any mipmaps set!", m_id, m_target);
min_filter = GL_LINEAR;
}
}
__glcheck glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, min_filter);
__glcheck glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter(tex.mag_filter()));
__glcheck glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
__glcheck glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
__glcheck glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
__glcheck glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
}
void texture::bind()

View File

@ -90,7 +90,18 @@ void GLVertexDecompilerThread::insertConstants(std::stringstream & OS, const std
OS << "layout(std140, binding = 1) uniform VertexConstantsBuffer" << std::endl;
OS << "{" << std::endl;
OS << " vec4 vc[468];" << std::endl;
OS << "};" << std::endl;
OS << "};" << std::endl << std::endl;
for (const ParamType &PT: constants)
{
for (const ParamItem &PI : PT.items)
{
if (PI.name == "vc[468]")
continue;
OS << "uniform " << PT.type << " " << PI.name << ";" << std::endl;
}
}
}
struct reg_info
@ -201,6 +212,17 @@ void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)
for (const ParamItem &PI : PT.items)
add_input(OS, PI, rsx_vertex_program.rsx_vertex_inputs);
}
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.);" << std::endl;
}
}
}
}
void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
@ -247,6 +269,9 @@ void GLVertexProgram::Compile()
const char* str = shader.c_str();
const int strlen = ::narrow<int>(shader.length());
fs::create_path(fs::get_config_dir() + "/shaderlog");
fs::file(fs::get_config_dir() + "shaderlog/VertexProgram" + std::to_string(id) + ".glsl", fs::rewrite).write(str);
glShaderSource(id, 1, &str, &strlen);
glCompileShader(id);

View File

@ -73,6 +73,8 @@ namespace vk
return "dFdx($0)";
case FUNCTION::FUNCTION_DFDY:
return "dFdy($0)";
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
return "textureLod($t, $0.xy, 0)";
}
}

View File

@ -126,7 +126,6 @@ VkComponentMapping get_component_mapping(u32 format, u8 swizzle_mask)
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT:
case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
@ -144,7 +143,8 @@ VkComponentMapping get_component_mapping(u32 format, u8 swizzle_mask)
}
case CELL_GCM_TEXTURE_X16:
return { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R };
case CELL_GCM_TEXTURE_X32_FLOAT:
return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R };
case CELL_GCM_TEXTURE_Y16_X16:
return { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R };
@ -153,11 +153,9 @@ VkComponentMapping get_component_mapping(u32 format, u8 swizzle_mask)
return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G };
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
return { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R };
case CELL_GCM_TEXTURE_X32_FLOAT:
return { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R };
case CELL_GCM_TEXTURE_A4R4G4B4:
{
VkComponentSwizzle map_table[] = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };

View File

@ -117,7 +117,7 @@ void VKFragmentDecompilerThread::insertOutputs(std::stringstream & OS)
void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
{
int location = 2;
int location = 0;
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
{

View File

@ -364,7 +364,7 @@ namespace
std::tuple<VkPipelineLayout, VkDescriptorSetLayout> get_shared_pipeline_layout(VkDevice dev)
{
std::array<VkDescriptorSetLayoutBinding, 35> bindings = {};
std::array<VkDescriptorSetLayoutBinding, 39> bindings = {};
size_t idx = 0;
// Vertex buffer
@ -400,6 +400,15 @@ namespace
idx++;
}
for (int i = 0; i < 4; i++)
{
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[idx].descriptorCount = 1;
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
bindings[idx].binding = VERTEX_TEXTURES_FIRST_BIND_SLOT + i;
idx++;
}
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
bindings[idx].descriptorCount = 1;
bindings[idx].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
@ -677,6 +686,72 @@ void VKGSRender::end()
}
}
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
{
if (m_program->has_uniform("tex" + std::to_string(i)))
{
if (!rsx::method_registers.fragment_textures[i].enabled())
{
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets);
continue;
}
vk::image_view *texture0 = m_texture_cache.upload_texture(m_command_buffer, rsx::method_registers.fragment_textures[i], m_rtts, m_memory_type_mapping, m_texture_upload_buffer_ring_info, m_texture_upload_buffer_ring_info.heap.get());
if (!texture0)
{
LOG_ERROR(RSX, "Texture upload failed to texture index %d. Binding null sampler.", i);
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets);
continue;
}
VkFilter min_filter;
VkSamplerMipmapMode mip_mode;
std::tie(min_filter, mip_mode) = vk::get_min_filter_and_mip(rsx::method_registers.fragment_textures[i].min_filter());
m_sampler_to_clean.push_back(std::make_unique<vk::sampler>(
*m_device,
vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_s()), vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_t()), vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_r()),
!!(rsx::method_registers.fragment_textures[i].format() & CELL_GCM_TEXTURE_UN),
rsx::method_registers.fragment_textures[i].bias(), vk::max_aniso(rsx::method_registers.fragment_textures[i].max_aniso()), rsx::method_registers.fragment_textures[i].min_lod(), rsx::method_registers.fragment_textures[i].max_lod(),
min_filter, vk::get_mag_filter(rsx::method_registers.fragment_textures[i].mag_filter()), mip_mode, vk::get_border_color(rsx::method_registers.fragment_textures[i].border_color())
));
m_program->bind_uniform({ m_sampler_to_clean.back()->value, texture0->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets);
}
}
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
{
if (m_program->has_uniform("vtex" + std::to_string(i)))
{
if (!rsx::method_registers.vertex_textures[i].enabled())
{
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "vtex" + std::to_string(i), descriptor_sets);
continue;
}
vk::image_view *texture0 = m_texture_cache.upload_texture(m_command_buffer, rsx::method_registers.vertex_textures[i], m_rtts, m_memory_type_mapping, m_texture_upload_buffer_ring_info, m_texture_upload_buffer_ring_info.heap.get());
if (!texture0)
{
LOG_ERROR(RSX, "Texture upload failed to vtexture index %d. Binding null sampler.", i);
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "vtex" + std::to_string(i), descriptor_sets);
continue;
}
m_sampler_to_clean.push_back(std::make_unique<vk::sampler>(
*m_device,
VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT,
!!(rsx::method_registers.vertex_textures[i].format() & CELL_GCM_TEXTURE_UN),
0, 1.f, rsx::method_registers.vertex_textures[i].min_lod(), rsx::method_registers.vertex_textures[i].max_lod(),
VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, vk::get_border_color(rsx::method_registers.vertex_textures[i].border_color())
));
m_program->bind_uniform({ m_sampler_to_clean.back()->value, texture0->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "vtex" + std::to_string(i), descriptor_sets);
}
}
VkRenderPassBeginInfo rp_begin = {};
rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rp_begin.renderPass = current_render_pass;
@ -884,11 +959,6 @@ bool VKGSRender::load_program()
if (rsx::method_registers.restart_index_enabled())
{
if (rsx::method_registers.restart_index() != 0xFFFF &&
rsx::method_registers.restart_index() != 0xFFFFFFFF)
{
LOG_ERROR(RSX, "Custom primitive restart index 0x%x should rewrite index buffer with proper value!", rsx::method_registers.restart_index());
}
properties.ia.primitiveRestartEnable = VK_TRUE;
}
else

View File

@ -15,6 +15,14 @@
#include "../Common/ring_buffer_helper.h"
#define DESCRIPTOR_MAX_DRAW_CALLS 1024
#define VERTEX_BUFFERS_FIRST_BIND_SLOT 3
#define FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT 2
#define VERTEX_CONSTANT_BUFFERS_BIND_SLOT 1
#define SCALE_OFFSET_BIND_SLOT 0
#define TEXTURES_FIRST_BIND_SLOT 19
#define VERTEX_TEXTURES_FIRST_BIND_SLOT 35 //19+16
extern cfg::bool_entry g_cfg_rsx_debug_output;
namespace rsx
@ -1327,11 +1335,6 @@ namespace vk
program& load_uniforms(program_domain domain, const std::vector<program_input>& inputs);
bool has_uniform(std::string uniform_name);
#define VERTEX_BUFFERS_FIRST_BIND_SLOT 3
#define FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT 2
#define VERTEX_CONSTANT_BUFFERS_BIND_SLOT 1
#define TEXTURES_FIRST_BIND_SLOT 19
#define SCALE_OFFSET_BIND_SLOT 0
void bind_uniform(VkDescriptorImageInfo image_descriptor, std::string uniform_name, VkDescriptorSet &descriptor_set);
void bind_uniform(VkDescriptorBufferInfo buffer_descriptor, uint32_t binding_point, VkDescriptorSet &descriptor_set);
void bind_uniform(const VkBufferView &buffer_view, const std::string &binding_name, VkDescriptorSet &descriptor_set);

View File

@ -151,6 +151,17 @@ namespace vk
m_cache.resize(0);
}
//Helpers
VkComponentMapping get_component_map(rsx::fragment_texture &tex, u32 gcm_format)
{
return vk::get_component_mapping(gcm_format, tex.remap());
}
VkComponentMapping get_component_map(rsx::vertex_texture &tex, u32 gcm_format)
{
return vk::get_component_mapping(gcm_format, (0 | 1 << 2 | 2 << 4 | 3 << 6));
}
public:
texture_cache() {}
@ -161,7 +172,8 @@ namespace vk
purge_cache();
}
vk::image_view* upload_texture(command_buffer cmd, rsx::fragment_texture &tex, rsx::vk_render_targets &m_rtts, const vk::memory_type_mapping &memory_type_mapping, vk_data_heap& upload_heap, vk::buffer* upload_buffer)
template <typename RsxTextureType>
vk::image_view* upload_texture(command_buffer cmd, RsxTextureType &tex, rsx::vk_render_targets &m_rtts, const vk::memory_type_mapping &memory_type_mapping, vk_data_heap& upload_heap, vk::buffer* upload_buffer)
{
const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
const u32 range = (u32)get_texture_size(tex);
@ -193,7 +205,7 @@ namespace vk
u32 raw_format = tex.format();
u32 format = raw_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
VkComponentMapping mapping = vk::get_component_mapping(format, tex.remap());
VkComponentMapping mapping = get_component_map(tex, format);
VkFormat vk_format = get_compatible_sampler_format(format);
VkImageType image_type;
@ -251,7 +263,7 @@ namespace vk
change_image_layout(cmd, cto.uploaded_texture->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range);
cto.uploaded_image_view = std::make_unique<vk::image_view>(*vk::get_current_renderer(), cto.uploaded_texture->value, image_view_type, vk_format,
vk::get_component_mapping(tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN), tex.remap()),
mapping,
subresource_range);
copy_mipmaped_image_using_buffer(cmd, cto.uploaded_texture->value, get_subresources_layout(tex), format, !(tex.format() & CELL_GCM_TEXTURE_LN), tex.get_exact_mipmap_count(),

View File

@ -106,7 +106,7 @@ void VKVertexDecompilerThread::insertConstants(std::stringstream & OS, const std
OS << "layout(std140, set=0, binding = 1) uniform VertexConstantsBuffer" << std::endl;
OS << "{" << std::endl;
OS << " vec4 vc[468];" << std::endl;
OS << "};" << std::endl;
OS << "};" << std::endl << std::endl;
vk::glsl::program_input in;
in.location = 1;
@ -115,6 +115,33 @@ void VKVertexDecompilerThread::insertConstants(std::stringstream & OS, const std
in.type = vk::glsl::input_type_uniform_buffer;
inputs.push_back(in);
//We offset this value by the index of the first fragment texture (19) below
//and allow 16 fragment textures to precede this slot
int location = 16;
for (const ParamType &PT : constants)
{
for (const ParamItem &PI : PT.items)
{
if (PI.name == "vc[468]")
continue;
if (PT.type == "sampler2D" ||
PT.type == "samplerCube" ||
PT.type == "sampler1D" ||
PT.type == "sampler3D")
{
in.location = location;
in.name = PI.name;
in.type = vk::glsl::input_type_texture;
inputs.push_back(in);
OS << "layout(set = 0, binding=" << 19 + location++ << ") uniform " << PT.type << " " << PI.name << ";" << std::endl;
}
}
}
}
struct reg_info