rsx: Implement stencil mirror views

- Implements a mirror view of D24S8 data that accesses the stencil components.
  Finishes the implementation of TEX2D_DEPTH_RGBA as the stencil component was previously missing from the reconstructed data
- Add a few missing destructors
  Image classes are inherited a lot and I forgot to make the dtors virtual
This commit is contained in:
kd-11 2018-11-24 15:54:46 +03:00 committed by kd-11
parent 696b91cb9b
commit 4b79ef1ad9
19 changed files with 401 additions and 156 deletions

View File

@ -278,10 +278,10 @@ std::string FragmentProgramDecompiler::Format(const std::string& code, bool igno
const std::pair<std::string, std::function<std::string()>> repl_list[] =
{
{ "$$", []() -> std::string { return "$"; } },
{ "$0", [this]() -> std::string {return GetSRC<SRC0>(src0);} },//std::bind(std::mem_fn(&GLFragmentDecompilerThread::GetSRC<SRC0>), *this, src0) },
{ "$1", [this]() -> std::string {return GetSRC<SRC1>(src1);} },//std::bind(std::mem_fn(&GLFragmentDecompilerThread::GetSRC<SRC1>), this, src1) },
{ "$2", [this]() -> std::string {return GetSRC<SRC2>(src2);} },//std::bind(std::mem_fn(&GLFragmentDecompilerThread::GetSRC<SRC2>), this, src2) },
{ "$t", std::bind(std::mem_fn(&FragmentProgramDecompiler::AddTex), this) },
{ "$0", [this]() -> std::string {return GetSRC<SRC0>(src0);} },
{ "$1", [this]() -> std::string {return GetSRC<SRC1>(src1);} },
{ "$2", [this]() -> std::string {return GetSRC<SRC2>(src2);} },
{ "$t", [this]() -> std::string { return "tex" + std::to_string(dst.tex_num);} },
{ "$_i", [this]() -> std::string {return std::to_string(dst.tex_num);} },
{ "$m", std::bind(std::mem_fn(&FragmentProgramDecompiler::GetMask), this) },
{ "$ifcond ", [this]() -> std::string
@ -624,6 +624,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
AddX2d();
AddCode(Format("x2d = $0.xyxy + $1.xxxx * $2.xzxz + $1.yyyy * $2.ywyw;", true));
case RSX_FP_OPCODE_TEX:
AddTex();
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case rsx::texture_dimension_extended::texture_dimension_1d:
@ -655,6 +656,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
AddX2d();
AddCode(Format("x2d = $0.xyxy + $1.xxxx * $2.xzxz + $1.yyyy * $2.ywyw;", true));
case RSX_FP_OPCODE_TXP:
AddTex();
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case rsx::texture_dimension_extended::texture_dimension_1d:
@ -679,6 +681,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
}
return false;
case RSX_FP_OPCODE_TXD:
AddTex();
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case rsx::texture_dimension_extended::texture_dimension_1d:
@ -697,6 +700,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
}
return false;
case RSX_FP_OPCODE_TXB:
AddTex();
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case rsx::texture_dimension_extended::texture_dimension_1d:
@ -715,6 +719,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
}
return false;
case RSX_FP_OPCODE_TXL:
AddTex();
switch (m_prog.get_texture_dimension(dst.tex_num))
{
case rsx::texture_dimension_extended::texture_dimension_1d:

View File

@ -481,9 +481,10 @@ namespace glsl
" }\n"
"}\n\n"
"vec4 texture2DReconstruct(sampler2D tex, vec2 coord, float remap)\n"
"vec4 texture2DReconstruct(sampler2D tex, usampler2D stencil_tex, vec2 coord, float remap)\n"
"{\n"
" vec4 result = decodeLinearDepth(texture(tex, coord.xy).r);\n"
" result.z = float(texture(stencil_tex, coord.xy).x) / 255.f;\n"
" uint remap_vector = floatBitsToUint(remap) & 0xFF;\n"
" if (remap_vector == 0xE4) return result;\n\n"
" vec4 tmp;\n"
@ -555,27 +556,30 @@ namespace glsl
" return rgba;\n"
"}\n\n"
"#define TEX1D(index, tex, coord1) process_texel(texture(tex, coord1 * texture_parameters[index].x), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D_BIAS(index, tex, coord1, bias) process_texel(texture(tex, coord1 * texture_parameters[index].x, bias), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D_LOD(index, tex, coord1, lod) process_texel(textureLod(tex, coord1 * texture_parameters[index].x, lod), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D_GRAD(index, tex, coord1, dpdx, dpdy) process_texel(textureGrad(tex, coord1 * texture_parameters[index].x, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D_PROJ(index, tex, coord2) process_texel(textureProj(tex, coord2 * vec2(texture_parameters[index].x, 1.)), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX_NAME(index) tex##index\n"
"#define TEX_NAME_STENCIL(index) tex##index##_stencil\n\n"
"#define TEX2D(index, tex, coord2) process_texel(texture(tex, coord2 * texture_parameters[index].xy), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_BIAS(index, tex, coord2, bias) process_texel(texture(tex, coord2 * texture_parameters[index].xy, bias), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_LOD(index, tex, coord2, lod) process_texel(textureLod(tex, coord2 * texture_parameters[index].xy, lod), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_GRAD(index, tex, coord2, dpdx, dpdy) process_texel(textureGrad(tex, coord2 * texture_parameters[index].xy, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_PROJ(index, tex, coord4) process_texel(textureProj(tex, coord4 * vec4(texture_parameters[index].xy, 1., 1.)), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D(index, coord1) process_texel(texture(TEX_NAME(index), coord1 * texture_parameters[index].x), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D_BIAS(index, coord1, bias) process_texel(texture(TEX_NAME(index), coord1 * texture_parameters[index].x, bias), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D_LOD(index, coord1, lod) process_texel(textureLod(TEX_NAME(index), coord1 * texture_parameters[index].x, lod), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D_GRAD(index, coord1, dpdx, dpdy) process_texel(textureGrad(TEX_NAME(index), coord1 * texture_parameters[index].x, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX1D_PROJ(index, coord2) process_texel(textureProj(TEX_NAME(index), coord2 * vec2(texture_parameters[index].x, 1.)), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_DEPTH_RGBA8(index, tex, coord2) process_texel(texture2DReconstruct(tex, coord2 * texture_parameters[index].xy, texture_parameters[index].z), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_SHADOW(index, tex, coord3) texture(tex, coord3 * vec3(texture_parameters[index].xy, 1.))\n"
"#define TEX2D_SHADOWPROJ(index, tex, coord4) textureProj(tex, coord4 * vec4(texture_parameters[index].xy, 1., 1.))\n"
"#define TEX2D(index, coord2) process_texel(texture(TEX_NAME(index), coord2 * texture_parameters[index].xy), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_BIAS(index, coord2, bias) process_texel(texture(TEX_NAME(index), coord2 * texture_parameters[index].xy, bias), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_LOD(index, coord2, lod) process_texel(textureLod(TEX_NAME(index), coord2 * texture_parameters[index].xy, lod), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_GRAD(index, coord2, dpdx, dpdy) process_texel(textureGrad(TEX_NAME(index), coord2 * texture_parameters[index].xy, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_PROJ(index, coord4) process_texel(textureProj(TEX_NAME(index), coord4 * vec4(texture_parameters[index].xy, 1., 1.)), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D(index, tex, coord3) process_texel(texture(tex, coord3), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D_BIAS(index, tex, coord3, bias) process_texel(texture(tex, coord3, bias), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D_LOD(index, tex, coord3, lod) process_texel(textureLod(tex, coord3, lod), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D_GRAD(index, tex, coord3, dpdx, dpdy) process_texel(textureGrad(tex, coord3, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D_PROJ(index, tex, coord4) process_texel(textureProj(tex, coord4), floatBitsToUint(texture_parameters[index].w))\n\n";
"#define TEX2D_DEPTH_RGBA8(index, coord2) process_texel(texture2DReconstruct(TEX_NAME(index), TEX_NAME_STENCIL(index), coord2 * texture_parameters[index].xy, texture_parameters[index].z), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX2D_SHADOW(index, coord3) texture(TEX_NAME(index), coord3 * vec3(texture_parameters[index].xy, 1.))\n"
"#define TEX2D_SHADOWPROJ(index, coord4) textureProj(TEX_NAME(index), coord4 * vec4(texture_parameters[index].xy, 1., 1.))\n"
"#define TEX3D(index, coord3) process_texel(texture(TEX_NAME(index), coord3), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D_BIAS(index, coord3, bias) process_texel(texture(TEX_NAME(index), coord3, bias), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D_LOD(index, coord3, lod) process_texel(textureLod(TEX_NAME(index), coord3, lod), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D_GRAD(index, coord3, dpdx, dpdy) process_texel(textureGrad(TEX_NAME(index), coord3, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"
"#define TEX3D_PROJ(index, coord4) process_texel(textureProj(TEX_NAME(index), coord4), floatBitsToUint(texture_parameters[index].w))\n\n";
}
if (require_wpos)
@ -619,49 +623,49 @@ namespace glsl
case FUNCTION::FUNCTION_REFL:
return "vec4($0 - 2.0 * (dot($0, $1)) * $1)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D:
return "TEX1D($_i, $t, $0.x)";
return "TEX1D($_i, $0.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_BIAS:
return "TEX1D_BIAS($_i, $t, $0.x, $1.x)";
return "TEX1D_BIAS($_i, $0.x, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ:
return "TEX1D_PROJ($_i, $t, $0.xy)";
return "TEX1D_PROJ($_i, $0.xy)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD:
return "TEX1D_LOD($_i, $t, $0.x, $1.x)";
return "TEX1D_LOD($_i, $0.x, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD:
return "TEX1D_GRAD($_i, $t, $0.x, $1.x, $2.x)";
return "TEX1D_GRAD($_i, $0.x, $1.x, $2.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
return "TEX2D($_i, $t, $0.xy)";
return "TEX2D($_i, $0.xy)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_BIAS:
return "TEX2D_BIAS($_i, $t, $0.xy, $1.x)";
return "TEX2D_BIAS($_i, $0.xy, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
return "TEX2D_PROJ($_i, $t, $0)";
return "TEX2D_PROJ($_i, $0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
return "TEX2D_LOD($_i, $t, $0.xy, $1.x)";
return "TEX2D_LOD($_i, $0.xy, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD:
return "TEX2D_GRAD($_i, $t, $0.xy, $1.xy, $2.xy)";
return "TEX2D_GRAD($_i, $0.xy, $1.xy, $2.xy)";
case FUNCTION::FUNCTION_TEXTURE_SHADOW2D:
return "TEX2D_SHADOW($_i, $t, $0.xyz)";
return "TEX2D_SHADOW($_i, $0.xyz)";
case FUNCTION::FUNCTION_TEXTURE_SHADOW2D_PROJ:
return "TEX2D_SHADOWPROJ($_i, $t, $0)";
return "TEX2D_SHADOWPROJ($_i, $0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE:
return "TEX3D($_i, $t, $0.xyz)";
return "TEX3D($_i, $0.xyz)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_BIAS:
return "TEX3D_BIAS($_i, $t, $0.xyz, $1.x)";
return "TEX3D_BIAS($_i, $0.xyz, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ:
return "TEX3D($_i, $t, ($0.xyz / $0.w))";
return "TEX3D($_i, ($0.xyz / $0.w))";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD:
return "TEX3D_LOD($_i, $t, $0.xyz, $1.x)";
return "TEX3D_LOD($_i, $0.xyz, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD:
return "TEX3D_GRAD($_i, $t, $0.xyz, $1.xyz, $2.xyz)";
return "TEX3D_GRAD($_i, $0.xyz, $1.xyz, $2.xyz)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D:
return "TEX3D($_i, $t, $0.xyz)";
return "TEX3D($_i, $0.xyz)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_BIAS:
return "TEX3D_BIAS($_i, $t, $0.xyz, $1.x)";
return "TEX3D_BIAS($_i, $0.xyz, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ:
return "TEX3D_PROJ($_i, $t, $0)";
return "TEX3D_PROJ($_i, $0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD:
return "TEX3D_LOD($_i, $t, $0.xyz, $1.x)";
return "TEX3D_LOD($_i, $0.xyz, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD:
return "TEX3D_GRAD($_i, $t, $0.xyz, $1.xyz, $2.xyz)";
return "TEX3D_GRAD($_i, $0.xyz, $1.xyz, $2.xyz)";
case FUNCTION::FUNCTION_DFDX:
return "dFdx($0)";
case FUNCTION::FUNCTION_DFDY:
@ -674,7 +678,7 @@ namespace glsl
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)";
return "TEX2D_DEPTH_RGBA8($_i, $0.xy)";
}
}
}

View File

@ -225,7 +225,7 @@ std::string VertexProgramDecompiler::Format(const std::string& code)
{ "$2", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 2) },
{ "$s", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 2) },
{ "$a", std::bind(std::mem_fn(&VertexProgramDecompiler::AddAddrReg), this) },
{ "$t", std::bind(std::mem_fn(&VertexProgramDecompiler::GetTex), this) },
{ "$t", [this]() -> std::string { return "vtex" + std::to_string(d2.tex_num); } },
{ "$ifcond ", [this]() -> std::string
{
const std::string& cond = GetCond();
@ -582,6 +582,7 @@ std::string VertexProgramDecompiler::Decompile()
case RSX_VEC_OPCODE_SSG: SetDSTVec("sign($0)"); break;
case RSX_VEC_OPCODE_TXL:
{
GetTex();
switch (m_prog.get_texture_dimension(d2.tex_num))
{
case rsx::texture_dimension_extended::texture_dimension_1d:

View File

@ -116,7 +116,12 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
const auto mask = (1 << index);
if (m_prog.shadow_textures & mask)
if (m_prog.redirected_textures & mask)
{
// Provide a stencil view of the main resource for the S channel
OS << "uniform u" << samplerType << " " << PI.name << "_stencil;\n";
}
else if (m_prog.shadow_textures & mask)
{
if (m_shadow_sampled_textures & mask)
{

View File

@ -401,40 +401,48 @@ void GLGSRender::end()
//Bind textures and resolve external copy operations
std::chrono::time_point<steady_clock> textures_start = steady_clock::now();
void *unused = nullptr;
gl::texture_view* tmp_view;
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
{
if (current_fp_metadata.referenced_textures_mask & (1 << i))
{
auto sampler_state = static_cast<gl::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
auto &tex = rsx::method_registers.fragment_textures[i];
_SelectTexture(GL_FRAGMENT_TEXTURES_START + i);
glActiveTexture(GL_TEXTURE0 + i);
if (tex.enabled())
gl::texture_view* view = nullptr;
if (rsx::method_registers.fragment_textures[i].enabled())
{
if (sampler_state->image_handle)
auto sampler_state = static_cast<gl::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
view = sampler_state->image_handle;
if (!view && sampler_state->external_subresource_desc.external_handle)
{
sampler_state->image_handle->bind();
view = m_gl_texture_cache.create_temporary_subresource(unused, sampler_state->external_subresource_desc);
}
else if (sampler_state->external_subresource_desc.external_handle &&
(tmp_view = m_gl_texture_cache.create_temporary_subresource(unused, sampler_state->external_subresource_desc)))
}
if (LIKELY(view))
{
view->bind();
if (current_fragment_program.redirected_textures & (1 << i))
{
tmp_view->bind();
}
else
{
auto target = gl::get_target(sampler_state->image_type);
glBindTexture(target, m_null_textures[target]->id());
_SelectTexture(GL_STENCIL_MIRRORS_START + i);
auto root_texture = static_cast<gl::viewable_image*>(view->image());
auto stencil_view = root_texture->get_view(0xAAE4, rsx::default_remap_vector, gl::image_aspect::stencil);
stencil_view->bind();
}
}
else
{
glBindTexture(GL_TEXTURE_1D, m_null_textures[GL_TEXTURE_1D]->id());
glBindTexture(GL_TEXTURE_2D, m_null_textures[GL_TEXTURE_2D]->id());
glBindTexture(GL_TEXTURE_3D, m_null_textures[GL_TEXTURE_3D]->id());
glBindTexture(GL_TEXTURE_CUBE_MAP, m_null_textures[GL_TEXTURE_CUBE_MAP]->id());
auto target = gl::get_target(current_fragment_program.get_texture_dimension(i));
glBindTexture(target, m_null_textures[target]->id());
if (current_fragment_program.redirected_textures & (1 << i))
{
_SelectTexture(GL_STENCIL_MIRRORS_START + i);
glBindTexture(target, m_null_textures[target]->id());
}
}
}
}
@ -444,7 +452,7 @@ void GLGSRender::end()
if (current_vp_metadata.referenced_textures_mask & (1 << i))
{
auto sampler_state = static_cast<gl::texture_cache::sampled_image_descriptor*>(vs_sampler_state[i].get());
glActiveTexture(GL_TEXTURE0 + rsx::limits::fragment_textures_count + i);
_SelectTexture(GL_VERTEX_TEXTURES_START + i);
if (sampler_state->image_handle)
{
@ -773,25 +781,23 @@ void GLGSRender::on_init_thread()
m_max_texbuffer_size = (16 * 0x100000);
}
const u32 texture_index_offset = rsx::limits::fragment_textures_count + rsx::limits::vertex_textures_count;
//Array stream buffer
{
m_gl_persistent_stream_buffer = std::make_unique<gl::texture>(GL_TEXTURE_BUFFER, 0, 0, 0, 0, GL_R8UI);
glActiveTexture(GL_TEXTURE0 + texture_index_offset);
_SelectTexture(GL_STREAM_BUFFER_START + 0);
glBindTexture(GL_TEXTURE_BUFFER, m_gl_persistent_stream_buffer->id());
}
//Register stream buffer
{
m_gl_volatile_stream_buffer = std::make_unique<gl::texture>(GL_TEXTURE_BUFFER, 0, 0, 0, 0, GL_R8UI);
glActiveTexture(GL_TEXTURE0 + texture_index_offset + 1);
_SelectTexture(GL_STREAM_BUFFER_START + 1);
glBindTexture(GL_TEXTURE_BUFFER, m_gl_volatile_stream_buffer->id());
}
//Fallback null texture instead of relying on texture0
{
std::vector<u32> pixeldata = {0, 0, 0, 0};
std::vector<u32> pixeldata = { 0, 0, 0, 0 };
//1D
auto tex1D = std::make_unique<gl::texture>(GL_TEXTURE_1D, 1, 1, 1, 1, GL_RGBA8);
@ -888,16 +894,24 @@ void GLGSRender::on_init_thread()
}
}
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
int image_unit = 0;
for (auto &sampler : m_fs_sampler_states)
{
m_fs_sampler_states[i].create();
m_fs_sampler_states[i].bind(i);
sampler.create();
sampler.bind(image_unit++);
}
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
for (auto &sampler : m_fs_sampler_mirror_states)
{
m_vs_sampler_states[i].create();
m_vs_sampler_states[i].bind(rsx::limits::fragment_textures_count + i);
sampler.create();
sampler.apply_defaults();
sampler.bind(image_unit++);
}
for (auto &sampler : m_vs_sampler_states)
{
sampler.create();
sampler.bind(image_unit++);
}
//Occlusion query
@ -1037,6 +1051,11 @@ void GLGSRender::on_exit()
sampler.remove();
}
for (auto &sampler : m_fs_sampler_mirror_states)
{
sampler.remove();
}
for (auto &sampler : m_vs_sampler_states)
{
sampler.remove();

View File

@ -277,8 +277,9 @@ private:
GLFragmentProgram m_fragment_prog;
GLVertexProgram m_vertex_prog;
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::sampler_state m_fs_sampler_states[rsx::limits::fragment_textures_count]; // Fragment textures
gl::sampler_state m_fs_sampler_mirror_states[rsx::limits::fragment_textures_count]; // Alternate views of fragment textures with different format (e.g Depth vs Stencil for D24S8)
gl::sampler_state m_vs_sampler_states[rsx::limits::vertex_textures_count]; // Vertex textures
gl::glsl::program *m_program;

View File

@ -13,6 +13,13 @@
#include "Utilities/geometry.h"
#define GL_FRAGMENT_TEXTURES_START 0
#define GL_VERTEX_TEXTURES_START GL_FRAGMENT_TEXTURES_START + 16
#define GL_STENCIL_MIRRORS_START GL_VERTEX_TEXTURES_START + 4
#define GL_STREAM_BUFFER_START GL_STENCIL_MIRRORS_START + 16
inline static void _SelectTexture(int unit) { glActiveTexture(GL_TEXTURE0 + unit); }
namespace gl
{
#ifdef _DEBUG
@ -1609,7 +1616,7 @@ namespace gl
m_component_layout = { GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE };
}
~texture()
virtual ~texture()
{
glDeleteTextures(1, &m_id);
}
@ -1793,20 +1800,29 @@ namespace gl
}
};
enum image_aspect : u32
{
color = 1,
depth = 2,
stencil = 4
};
class texture_view
{
GLuint m_id = 0;
GLenum m_target = 0;
GLenum m_format = 0;
GLenum m_aspect_flags = 0;
texture *m_image_data = nullptr;
GLenum component_swizzle[4];
void create(texture* data, GLenum target, GLenum sized_format, const GLenum* argb_swizzle = nullptr)
void create(texture* data, GLenum target, GLenum sized_format, GLenum aspect_flags, const GLenum* argb_swizzle = nullptr)
{
m_target = target;
m_format = sized_format;
m_image_data = data;
m_aspect_flags = aspect_flags;
const auto num_levels = data->levels();
const auto num_layers = (target != GL_TEXTURE_CUBE_MAP) ? 1 : 6;
@ -1831,22 +1847,34 @@ namespace gl
component_swizzle[2] = GL_BLUE;
component_swizzle[3] = GL_ALPHA;
}
if (aspect_flags & image_aspect::stencil)
{
constexpr u32 depth_stencil_mask = (image_aspect::depth | image_aspect::stencil);
verify("Invalid aspect mask combination" HERE), (aspect_flags & depth_stencil_mask) != depth_stencil_mask;
glBindTexture(m_target, m_id);
glTexParameteri(m_target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
}
}
public:
texture_view(const texture_view&) = delete;
texture_view(texture_view&&) = delete;
texture_view(texture* data, GLenum target, GLenum sized_format, const GLenum* argb_swizzle = nullptr)
texture_view(texture* data, GLenum target, GLenum sized_format,
const GLenum* argb_swizzle = nullptr,
GLenum aspect_flags = image_aspect::color | image_aspect::depth)
{
create(data, target, sized_format, argb_swizzle);
create(data, target, sized_format, aspect_flags, argb_swizzle);
}
texture_view(texture* data, const GLenum* argb_swizzle = nullptr)
texture_view(texture* data, const GLenum* argb_swizzle = nullptr,
GLenum aspect_flags = image_aspect::color | image_aspect::depth)
{
GLenum target = (GLenum)data->get_target();
GLenum sized_format = (GLenum)data->get_internal_format();
create(data, target, sized_format, argb_swizzle);
create(data, target, sized_format, aspect_flags, argb_swizzle);
}
~texture_view()
@ -1869,6 +1897,11 @@ namespace gl
return m_format;
}
GLenum aspect() const
{
return m_aspect_flags;
}
bool compare_swizzle(GLenum* argb_swizzle) const
{
return (argb_swizzle[0] == component_swizzle[3] &&
@ -1901,23 +1934,26 @@ namespace gl
class viewable_image : public texture
{
std::unordered_map<u32, std::unique_ptr<texture_view>> views;
std::unordered_multimap<u32, std::unique_ptr<texture_view>> views;
public:
using texture::texture;
texture_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
texture_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap, GLenum aspect_flags = image_aspect::color | image_aspect::depth)
{
auto found = views.find(remap_encoding);
if (found != views.end())
auto found = views.equal_range(remap_encoding);
for (auto It = found.first; It != found.second; ++It)
{
return found->second.get();
if (It->second->aspect() & aspect_flags)
{
return It->second.get();
}
}
auto mapping = apply_swizzle_remap(get_native_component_layout(), remap);
auto view = std::make_unique<texture_view>(this, mapping.data());
auto view = std::make_unique<texture_view>(this, mapping.data(), aspect_flags);
auto result = view.get();
views[remap_encoding] = std::move(view);
views.emplace(remap_encoding, std::move(view));
return result;
}

View File

@ -1,6 +1,7 @@
#pragma once
#pragma once
#include "GLVertexProgram.h"
#include "GLFragmentProgram.h"
#include "GLHelpers.h"
#include "../Common/ProgramStateCache.h"
struct GLTraits
@ -42,27 +43,36 @@ struct GLTraits
.bind_fragment_data_location("ocol3", 3)
.make();
//Progam locations are guaranteed to not change after linking
//Texture locations are simply bound to the TIUs so this can be done once
// Progam locations are guaranteed to not change after linking
// Texture locations are simply bound to the TIUs so this can be done once
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
{
int location;
if (result->uniforms.has_location(rsx::constants::fragment_texture_names[i], &location))
result->uniforms[location] = i;
{
// Assign location to TIU
result->uniforms[location] = GL_FRAGMENT_TEXTURES_START + i;
// Check for stencil mirror
const std::string mirror_name = std::string(rsx::constants::fragment_texture_names[i]) + "_stencil";
if (result->uniforms.has_location(mirror_name, &location))
{
// Assign mirror to TIU
result->uniforms[location] = GL_STENCIL_MIRRORS_START + i;
}
}
}
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
{
int location;
if (result->uniforms.has_location(rsx::constants::vertex_texture_names[i], &location))
result->uniforms[location] = (i + rsx::limits::fragment_textures_count);
result->uniforms[location] = GL_VERTEX_TEXTURES_START + i;
}
const int stream_buffer_start = rsx::limits::fragment_textures_count + rsx::limits::vertex_textures_count;
//Bind locations 0 and 1 to the stream buffers
result->uniforms[0] = stream_buffer_start;
result->uniforms[1] = stream_buffer_start + 1;
// Bind locations 0 and 1 to the stream buffers
result->uniforms[0] = GL_STREAM_BUFFER_START + 0;
result->uniforms[1] = GL_STREAM_BUFFER_START + 1;
LOG_NOTICE(RSX, "*** prog id = %d", result->id());
LOG_NOTICE(RSX, "*** vp id = %d", vertexProgramData.id);

View File

@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "GLTexture.h"
#include "../GCM.h"
#include "../RSXThread.h"
@ -290,6 +290,19 @@ namespace gl
glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
void sampler_state::apply_defaults()
{
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, GL_REPEAT);
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, GL_REPEAT);
glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameterf(samplerHandle, GL_TEXTURE_LOD_BIAS, 0.f);
glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_LOD, 0);
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAX_LOD, 0);
glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
bool is_compressed_format(u32 texture_format)
{
switch (texture_format)

View File

@ -1,4 +1,4 @@
#include "OpenGL.h"
#include "OpenGL.h"
#include "../GCM.h"
#include "../Common/TextureUtils.h"
#include "GLHelpers.h"
@ -56,5 +56,7 @@ namespace gl
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);
void apply_defaults();
};
}

View File

@ -758,7 +758,7 @@ namespace gl
}
}
auto dst = std::make_unique<gl::texture>(dst_type, width, height, 1, 1, sized_internal_fmt);
std::unique_ptr<gl::texture> dst = std::make_unique<gl::viewable_image>(dst_type, width, height, 1, 1, sized_internal_fmt);
if (copy)
{
@ -855,7 +855,7 @@ namespace gl
gl::texture_view* generate_cubemap_from_images(void*&, u32 gcm_format, u16 size, const std::vector<copy_region_descriptor>& sources, const texture_channel_remap_t& /*remap_vector*/) override
{
const GLenum ifmt = gl::get_sized_internal_format(gcm_format);
auto dst_image = std::make_unique<gl::texture>(GL_TEXTURE_CUBE_MAP, size, size, 1, 1, ifmt);
std::unique_ptr<gl::texture> dst_image = std::make_unique<gl::viewable_image>(GL_TEXTURE_CUBE_MAP, size, size, 1, 1, ifmt);
auto view = std::make_unique<gl::texture_view>(dst_image.get(), GL_TEXTURE_CUBE_MAP, ifmt);
//Empty GL_ERROR
@ -884,7 +884,7 @@ namespace gl
gl::texture_view* generate_3d_from_2d_images(void*&, u32 gcm_format, u16 width, u16 height, u16 depth, const std::vector<copy_region_descriptor>& sources, const texture_channel_remap_t& /*remap_vector*/) override
{
const GLenum ifmt = gl::get_sized_internal_format(gcm_format);
auto dst_image = std::make_unique<gl::texture>(GL_TEXTURE_3D, width, height, depth, 1, ifmt);
std::unique_ptr<gl::texture> dst_image = std::make_unique<gl::viewable_image>(GL_TEXTURE_3D, width, height, depth, 1, ifmt);
auto view = std::make_unique<gl::texture_view>(dst_image.get(), GL_TEXTURE_3D, ifmt);
//Empty GL_ERROR

View File

@ -141,9 +141,24 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
inputs.push_back(in);
OS << "layout(set=0, binding=" << location++ << ") uniform " << samplerType << " " << PI.name << ";\n";
if (m_prog.redirected_textures & mask)
{
// Insert stencil mirror declaration
in.name += "_stencil";
in.location = location;
inputs.push_back(in);
OS << "layout(set=0, binding=" << location++ << ") uniform u" << PT.type << " " << in.name << ";\n";
}
}
}
// Some drivers (macOS) do not support more than 16 texture descriptors per stage
// TODO: If any application requires more than this, the layout can be restructured a bit
verify("Too many sampler descriptors!" HERE), location <= VERTEX_TEXTURES_FIRST_BIND_SLOT;
std::string constants_block;
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
{

View File

@ -805,6 +805,8 @@ VKGSRender::~VKGSRender()
for (auto& handle : vs_sampler_handles)
handle.reset();
m_stencil_mirror_sampler.reset();
//Overlay text handler
m_text_writer.reset();
@ -1585,29 +1587,66 @@ void VKGSRender::end()
{
if (current_fp_metadata.referenced_textures_mask & (1 << i))
{
if (!rsx::method_registers.fragment_textures[i].enabled())
vk::image_view* view = nullptr;
if (rsx::method_registers.fragment_textures[i].enabled())
{
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, rsx::constants::fragment_texture_names[i], m_current_frame->descriptor_set);
continue;
auto sampler_state = static_cast<vk::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
view = sampler_state->image_handle;
if (!view && sampler_state->external_subresource_desc.external_handle)
{
//Requires update, copy subresource
view = m_texture_cache.create_temporary_subresource(*m_current_command_buffer, sampler_state->external_subresource_desc);
}
}
auto sampler_state = static_cast<vk::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
auto image_ptr = sampler_state->image_handle;
if (!image_ptr && sampler_state->external_subresource_desc.external_handle)
if (LIKELY(view))
{
//Requires update, copy subresource
image_ptr = m_texture_cache.create_temporary_subresource(*m_current_command_buffer, sampler_state->external_subresource_desc);
}
m_program->bind_uniform({ fs_sampler_handles[i]->value, view->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_fragment_program,
m_current_frame->descriptor_set);
if (!image_ptr)
if (current_fragment_program.redirected_textures & (1 << i))
{
// Stencil mirror required
auto root_image = static_cast<vk::viewable_image*>(view->image());
auto stencil_view = root_image->get_view(0xAAE4, rsx::default_remap_vector, VK_IMAGE_ASPECT_STENCIL_BIT);
if (!m_stencil_mirror_sampler)
{
m_stencil_mirror_sampler = std::make_unique<vk::sampler>(*m_device,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
VK_FALSE, 0.f, 1.f, 0.f, 0.f,
VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
VK_BORDER_COLOR_INT_OPAQUE_BLACK);
}
m_program->bind_uniform({ m_stencil_mirror_sampler->value, stencil_view->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_fragment_program,
m_current_frame->descriptor_set,
true);
}
}
else
{
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(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, rsx::constants::fragment_texture_names[i], m_current_frame->descriptor_set);
continue;
}
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_fragment_program,
m_current_frame->descriptor_set);
m_program->bind_uniform({ fs_sampler_handles[i]->value, image_ptr->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, rsx::constants::fragment_texture_names[i], m_current_frame->descriptor_set);
if (current_fragment_program.redirected_textures & (1 << i))
{
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_fragment_program,
m_current_frame->descriptor_set,
true);
}
}
}
}
@ -1617,7 +1656,11 @@ void VKGSRender::end()
{
if (!rsx::method_registers.vertex_textures[i].enabled())
{
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, rsx::constants::vertex_texture_names[i], m_current_frame->descriptor_set);
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_vertex_program,
m_current_frame->descriptor_set);
continue;
}
@ -1637,7 +1680,10 @@ void VKGSRender::end()
continue;
}
m_program->bind_uniform({ vs_sampler_handles[i]->value, image_ptr->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, rsx::constants::vertex_texture_names[i], m_current_frame->descriptor_set);
m_program->bind_uniform({ vs_sampler_handles[i]->value, image_ptr->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
i,
::glsl::program_domain::glsl_vertex_program,
m_current_frame->descriptor_set);
}
}

View File

@ -291,6 +291,7 @@ private:
shared_mutex m_sampler_mutex;
u64 surface_store_tag = 0;
std::atomic_bool m_samplers_dirty = { true };
std::unique_ptr<vk::sampler> m_stencil_mirror_sampler;
std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::fragment_textures_count> fs_sampler_state = {};
std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::vertex_textures_count> vs_sampler_state = {};
std::array<std::unique_ptr<vk::sampler>, rsx::limits::fragment_textures_count> fs_sampler_handles;

View File

@ -692,7 +692,7 @@ namespace vk
// TODO: Ctor that uses a provided memory heap
~image()
virtual ~image()
{
vkDestroyImage(m_device, value, nullptr);
}
@ -746,7 +746,7 @@ namespace vk
image_view(VkDevice dev, vk::image* resource,
const VkComponentMapping mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1})
: m_device(dev)
: m_device(dev), m_resource(resource)
{
info.format = resource->info.format;
info.image = resource->value;
@ -792,11 +792,17 @@ namespace vk
#endif
}
vk::image* image() const
{
return m_resource;
}
image_view(const image_view&) = delete;
image_view(image_view&&) = delete;
private:
VkDevice m_device;
vk::image* m_resource = nullptr;
void create_impl()
{
@ -2844,6 +2850,11 @@ public:
std::array<std::vector<program_input>, input_type_max_enum> uniforms;
VkDevice m_device;
std::array<u32, 16> fs_texture_bindings;
std::array<u32, 16> fs_texture_mirror_bindings;
std::array<u32, 4> vs_texture_bindings;
bool linked;
public:
VkPipeline pipeline;
u64 attribute_location_mask;
@ -2855,9 +2866,11 @@ public:
~program();
program& load_uniforms(::glsl::program_domain domain, const std::vector<program_input>& inputs);
program& link();
bool has_uniform(program_input_type type, const std::string &uniform_name);
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, const std::string &uniform_name, VkDescriptorSet &descriptor_set);
void bind_uniform(const VkDescriptorImageInfo &image_descriptor, int texture_unit, ::glsl::program_domain domain, VkDescriptorSet &descriptor_set, bool is_stencil_mirror = false);
void bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, uint32_t binding_point, VkDescriptorSet &descriptor_set);
void bind_uniform(const VkBufferView &buffer_view, program_input_type type, const std::string &binding_name, VkDescriptorSet &descriptor_set);

View File

@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "VKVertexProgram.h"
#include "VKFragmentProgram.h"
#include "../Common/ProgramStateCache.h"
@ -165,8 +165,9 @@ struct VKTraits
info.renderPass = pipelineProperties.render_pass;
CHECK_RESULT(vkCreateGraphicsPipelines(dev, nullptr, 1, &info, NULL, &pipeline));
pipeline_storage_type result = std::make_unique<vk::glsl::program>(dev, pipeline, vertexProgramData.uniforms, fragmentProgramData.uniforms);
pipeline_storage_type result = std::make_unique<vk::glsl::program>(dev, pipeline, vertexProgramData.uniforms, fragmentProgramData.uniforms);
result->link();
return result;
}
};

View File

@ -1,6 +1,8 @@
#include "stdafx.h"
#include "VKHelpers.h"
#include <string>
namespace vk
{
namespace glsl
@ -10,10 +12,16 @@ namespace vk
program::program(VkDevice dev, VkPipeline p, const std::vector<program_input> &vertex_input, const std::vector<program_input>& fragment_inputs)
: m_device(dev), pipeline(p)
{
linked = false;
load_uniforms(program_domain::glsl_vertex_program, vertex_input);
load_uniforms(program_domain::glsl_vertex_program, fragment_inputs);
attribute_location_mask = 0;
vertex_attributes_mask = 0;
fs_texture_bindings.fill(~0u);
fs_texture_mirror_bindings.fill(~0u);
vs_texture_bindings.fill(~0u);
}
program::~program()
@ -23,6 +31,8 @@ namespace vk
program& program::load_uniforms(program_domain domain, const std::vector<program_input>& inputs)
{
verify("Cannot change uniforms in already linked program!" HERE), !linked;
for (auto &item : inputs)
{
uniforms[item.type].push_back(item);
@ -31,6 +41,46 @@ namespace vk
return *this;
}
program& program::link()
{
// Preprocess texture bindings
// Link step is only useful for rasterizer programs, compute programs do not need this
for (const auto &uniform : uniforms[program_input_type::input_type_texture])
{
if (const auto name_start = uniform.name.find("tex"); name_start != std::string::npos)
{
const auto name_end = uniform.name.find("_stencil");
const auto index_start = name_start + 3; // Skip 'tex' part
const auto index_length = (name_end != std::string::npos) ? name_end - index_start : name_end;
const auto index_part = uniform.name.substr(index_start, index_length);
const auto index = std::stoi(index_part);
if (name_start == 0)
{
// Fragment texture (tex...)
if (name_end == std::string::npos)
{
// Normal texture
fs_texture_bindings[index] = uniform.location;
}
else
{
// Stencil mirror
fs_texture_mirror_bindings[index] = uniform.location;
}
}
else
{
// Vertex texture (vtex...)
vs_texture_bindings[index] = uniform.location;
}
}
}
linked = true;
return *this;
}
bool program::has_uniform(program_input_type type, const std::string &uniform_name)
{
for (const auto &uniform : uniforms[type])
@ -71,6 +121,44 @@ namespace vk
LOG_NOTICE(RSX, "texture not found in program: %s", uniform_name.c_str());
}
void program::bind_uniform(const VkDescriptorImageInfo & image_descriptor, int texture_unit, ::glsl::program_domain domain, VkDescriptorSet &descriptor_set, bool is_stencil_mirror)
{
verify("Unsupported program domain" HERE, domain != ::glsl::program_domain::glsl_compute_program);
u32 binding;
if (domain == ::glsl::program_domain::glsl_fragment_program)
{
binding = (is_stencil_mirror) ? fs_texture_mirror_bindings[texture_unit] : fs_texture_bindings[texture_unit];
}
else
{
binding = vs_texture_bindings[texture_unit];
}
if (binding != ~0u)
{
const VkWriteDescriptorSet descriptor_writer =
{
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
nullptr, // pNext
descriptor_set, // dstSet
binding, // dstBinding
0, // dstArrayElement
1, // descriptorCount
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // descriptorType
&image_descriptor, // pImageInfo
nullptr, // pBufferInfo
nullptr // pTexelBufferView
};
vkUpdateDescriptorSets(m_device, 1, &descriptor_writer, 0, nullptr);
attribute_location_mask |= (1ull << binding);
return;
}
LOG_NOTICE(RSX, "texture not found in program: %stex%u", (domain == ::glsl::program_domain::glsl_vertex_program)? "v" : "", texture_unit);
}
void program::bind_uniform(const VkDescriptorBufferInfo &buffer_descriptor, uint32_t binding_point, VkDescriptorSet &descriptor_set)
{
bind_buffer(buffer_descriptor, binding_point, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptor_set);

View File

@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "stdafx.h"
#include "VKHelpers.h"
@ -21,24 +21,9 @@ namespace vk
VkImageAspectFlags attachment_aspect_flag = VK_IMAGE_ASPECT_COLOR_BIT;
std::unordered_multimap<u32, std::unique_ptr<vk::image_view>> views;
u64 frame_tag = 0; //frame id when invalidated, 0 if not invalid
u64 frame_tag = 0; // frame id when invalidated, 0 if not invalid
render_target(vk::render_device &dev,
uint32_t memory_type_index,
uint32_t access_flags,
VkImageType image_type,
VkFormat format,
uint32_t width, uint32_t height, uint32_t depth,
uint32_t mipmaps, uint32_t layers,
VkSampleCountFlagBits samples,
VkImageLayout initial_layout,
VkImageTiling tiling,
VkImageUsageFlags usage,
VkImageCreateFlags image_flags)
: viewable_image(dev, memory_type_index, access_flags, image_type, format, width, height, depth,
mipmaps, layers, samples, initial_layout, tiling, usage, image_flags)
{}
using viewable_image::viewable_image;
vk::image* get_surface() override
{

View File

@ -516,7 +516,7 @@ namespace vk
image_flags = (view_type == VK_IMAGE_VIEW_TYPE_CUBE)? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
}
image.reset(new vk::image(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
image.reset(new vk::viewable_image(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
image_type,
dst_format,
w, h, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
@ -543,7 +543,7 @@ namespace vk
view_swizzle = vk::apply_swizzle_remap({view_swizzle.a, view_swizzle.r, view_swizzle.g, view_swizzle.b}, remap_vector);
VkImageSubresourceRange view_range = { aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 1 };
view.reset(new vk::image_view(*vk::get_current_renderer(), image->value, view_type, dst_format, view_swizzle, view_range));
view.reset(new vk::image_view(*vk::get_current_renderer(), image.get(), view_swizzle, view_range));
if (copy)
{
@ -595,14 +595,14 @@ namespace vk
VkFormat dst_format = vk::get_compatible_sampler_format(m_formats_support, gcm_format);
VkImageAspectFlags dst_aspect = vk::get_aspect_flags(dst_format);
image.reset(new vk::image(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
image.reset(new vk::viewable_image(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_2D,
dst_format,
size, size, 1, 1, 6, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT));
VkImageSubresourceRange view_range = { dst_aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 6 };
view.reset(new vk::image_view(*vk::get_current_renderer(), image->value, VK_IMAGE_VIEW_TYPE_CUBE, image->info.format, image->native_component_map, view_range));
view.reset(new vk::image_view(*vk::get_current_renderer(), image.get(), image->native_component_map, view_range));
VkImageSubresourceRange dst_range = { dst_aspect, 0, 1, 0, 6 };
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);
@ -658,14 +658,14 @@ namespace vk
VkFormat dst_format = vk::get_compatible_sampler_format(m_formats_support, gcm_format);
VkImageAspectFlags dst_aspect = vk::get_aspect_flags(dst_format);
image.reset(new vk::image(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
image.reset(new vk::viewable_image(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_3D,
dst_format,
width, height, depth, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0));
VkImageSubresourceRange view_range = { dst_aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 1 };
view.reset(new vk::image_view(*vk::get_current_renderer(), image->value, VK_IMAGE_VIEW_TYPE_3D, image->info.format, image->native_component_map, view_range));
view.reset(new vk::image_view(*vk::get_current_renderer(), image.get(), image->native_component_map, view_range));
VkImageSubresourceRange dst_range = { dst_aspect, 0, 1, 0, 1 };
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);