mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-14 18:37:27 +00:00
Added WIP vertex textures support
This commit is contained in:
parent
4d88296485
commit
989f954432
@ -120,7 +120,8 @@ u32 get_row_pitch_in_block(u16 width_in_block, size_t multiple_constraints_in_by
|
||||
* Since rsx ignore unused dimensionnality some app set them to 0.
|
||||
* Use 1 value instead to be more general.
|
||||
*/
|
||||
std::tuple<u16, u16, u8> get_height_depth_layer(const rsx::texture &tex)
|
||||
template<typename RsxTextureType>
|
||||
std::tuple<u16, u16, u8> get_height_depth_layer(const RsxTextureType &tex)
|
||||
{
|
||||
switch (tex.get_extended_texture_dimension())
|
||||
{
|
||||
@ -133,7 +134,8 @@ std::tuple<u16, u16, u8> get_height_depth_layer(const rsx::texture &tex)
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::texture &texture)
|
||||
template<typename RsxTextureType>
|
||||
std::vector<rsx_subresource_layout> get_subresources_layout_impl(const RsxTextureType &texture)
|
||||
{
|
||||
u16 w = texture.width();
|
||||
u16 h;
|
||||
@ -184,6 +186,16 @@ std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::texture &
|
||||
throw EXCEPTION("Wrong format 0x%x", format);
|
||||
}
|
||||
|
||||
std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::texture &texture)
|
||||
{
|
||||
return get_subresources_layout_impl(texture);
|
||||
}
|
||||
|
||||
std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::vertex_texture &texture)
|
||||
{
|
||||
return get_subresources_layout_impl(texture);
|
||||
}
|
||||
|
||||
void upload_texture_subresource(gsl::span<gsl::byte> dst_buffer, const rsx_subresource_layout &src_layout, int format, bool is_swizzled, size_t dst_row_pitch_multiple_of)
|
||||
{
|
||||
u16 w = src_layout.width_in_block;
|
||||
@ -339,36 +351,48 @@ u8 get_format_block_size_in_texel(int format)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPitchAlignement, size_t mipmapAlignment)
|
||||
static size_t get_placed_texture_storage_size(u16 width, u16 height, u32 depth, u8 format, u16 mipmap, bool cubemap, size_t row_pitch_alignement, size_t mipmap_alignment)
|
||||
{
|
||||
size_t w = texture.width(), h = texture.height(), d = std::max<u16>(texture.depth(), 1);
|
||||
size_t w = width;
|
||||
size_t h = std::max<u16>(height, 1);
|
||||
size_t d = std::max<u16>(depth, 1);
|
||||
|
||||
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
size_t blockEdge = get_format_block_size_in_texel(format);
|
||||
size_t blockSizeInByte = get_format_block_size_in_bytes(format);
|
||||
format &= ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
size_t block_edge = get_format_block_size_in_texel(format);
|
||||
size_t block_size_in_byte = get_format_block_size_in_bytes(format);
|
||||
|
||||
size_t heightInBlocks = (h + blockEdge - 1) / blockEdge;
|
||||
size_t widthInBlocks = (w + blockEdge - 1) / blockEdge;
|
||||
size_t height_in_blocks = (h + block_edge - 1) / block_edge;
|
||||
size_t width_in_blocks = (w + block_edge - 1) / block_edge;
|
||||
|
||||
size_t result = 0;
|
||||
for (unsigned mipmap = 0; mipmap < texture.mipmap(); ++mipmap)
|
||||
for (u16 i = 0; i < mipmap; ++i)
|
||||
{
|
||||
size_t rowPitch = align(blockSizeInByte * widthInBlocks, rowPitchAlignement);
|
||||
result += align(rowPitch * heightInBlocks * d, mipmapAlignment);
|
||||
heightInBlocks = std::max<size_t>(heightInBlocks / 2, 1);
|
||||
widthInBlocks = std::max<size_t>(widthInBlocks / 2, 1);
|
||||
size_t rowPitch = align(block_size_in_byte * width_in_blocks, row_pitch_alignement);
|
||||
result += align(rowPitch * height_in_blocks * d, mipmap_alignment);
|
||||
height_in_blocks = std::max<size_t>(height_in_blocks / 2, 1);
|
||||
width_in_blocks = std::max<size_t>(width_in_blocks / 2, 1);
|
||||
}
|
||||
|
||||
return result * (texture.cubemap() ? 6 : 1);
|
||||
return result * (cubemap ? 6 : 1);
|
||||
}
|
||||
|
||||
size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t row_pitch_alignement, size_t mipmap_alignment)
|
||||
{
|
||||
return get_placed_texture_storage_size(texture.width(), texture.height(), texture.depth(), texture.format(), texture.mipmap(), texture.cubemap(),
|
||||
row_pitch_alignement, mipmap_alignment);
|
||||
}
|
||||
|
||||
size_t get_placed_texture_storage_size(const rsx::vertex_texture &texture, size_t row_pitch_alignement, size_t mipmap_alignment)
|
||||
{
|
||||
return get_placed_texture_storage_size(texture.width(), texture.height(), texture.depth(), texture.format(), texture.mipmap(), texture.cubemap(),
|
||||
row_pitch_alignement, mipmap_alignment);
|
||||
}
|
||||
|
||||
|
||||
size_t get_texture_size(const rsx::texture &texture)
|
||||
static size_t get_texture_size(u32 w, u32 h, u8 format)
|
||||
{
|
||||
size_t w = texture.width(), h = texture.height();
|
||||
format &= ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
|
||||
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
// TODO: Take mipmaps into account
|
||||
switch (format)
|
||||
{
|
||||
@ -434,3 +458,13 @@ size_t get_texture_size(const rsx::texture &texture)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_texture_size(const rsx::texture &texture)
|
||||
{
|
||||
return get_texture_size(texture.width(), texture.height(), texture.format());
|
||||
}
|
||||
|
||||
size_t get_texture_size(const rsx::vertex_texture &texture)
|
||||
{
|
||||
return get_texture_size(texture.width(), texture.height(), texture.format());
|
||||
}
|
||||
|
@ -18,13 +18,15 @@ struct rsx_subresource_layout
|
||||
* Get size to store texture in a linear fashion.
|
||||
* Storage is assumed to use a rowPitchAlignement boundary for every row of texture.
|
||||
*/
|
||||
size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPitchAlignement, size_t mipmapAlignment=512);
|
||||
size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t row_pitch_alignement, size_t mipmap_alignment = 0x200);
|
||||
size_t get_placed_texture_storage_size(const rsx::vertex_texture &texture, size_t row_pitch_alignement, size_t mipmap_alignment = 0x200);
|
||||
|
||||
/**
|
||||
* get all rsx_subresource_layout for texture.
|
||||
* The subresources are ordered per layer then per mipmap level (as in rsx memory).
|
||||
*/
|
||||
std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::texture &texture);
|
||||
std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::vertex_texture &texture);
|
||||
|
||||
void upload_texture_subresource(gsl::span<gsl::byte> dst_buffer, const rsx_subresource_layout &src_layout, int format, bool is_swizzled, size_t dst_row_pitch_multiple_of);
|
||||
|
||||
@ -35,3 +37,4 @@ u8 get_format_block_size_in_texel(int format);
|
||||
* Get number of bytes occupied by texture in RSX mem
|
||||
*/
|
||||
size_t get_texture_size(const rsx::texture &texture);
|
||||
size_t get_texture_size(const rsx::vertex_texture &texture);
|
||||
|
@ -235,6 +235,18 @@ namespace
|
||||
}
|
||||
throw EXCEPTION("Unknow texture target");
|
||||
}
|
||||
|
||||
GLenum get_gl_target_for_texture(const rsx::vertex_texture& tex)
|
||||
{
|
||||
switch (tex.get_extended_texture_dimension())
|
||||
{
|
||||
case rsx::texture_dimension_extended::texture_dimension_1d: return GL_TEXTURE_1D;
|
||||
case rsx::texture_dimension_extended::texture_dimension_2d: return GL_TEXTURE_2D;
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap: return GL_TEXTURE_CUBE_MAP;
|
||||
case rsx::texture_dimension_extended::texture_dimension_3d: return GL_TEXTURE_3D;
|
||||
}
|
||||
throw EXCEPTION("Unknow texture target");
|
||||
}
|
||||
}
|
||||
|
||||
void GLGSRender::end()
|
||||
@ -295,7 +307,6 @@ void GLGSRender::end()
|
||||
|
||||
//setup textures
|
||||
{
|
||||
//int texture_index = 0;
|
||||
for (int i = 0; i < rsx::limits::textures_count; ++i)
|
||||
{
|
||||
int location;
|
||||
@ -311,12 +322,9 @@ void GLGSRender::end()
|
||||
}
|
||||
|
||||
m_gl_textures[i].set_target(get_gl_target_for_texture(textures[i]));
|
||||
|
||||
__glcheck m_gl_texture_cache.upload_texture(i, textures[i], m_gl_textures[i], m_rtts);
|
||||
|
||||
__glcheck glProgramUniform1i(m_program->id(), location, i);
|
||||
//__glcheck m_gl_textures[i].init(i, textures[i]);
|
||||
|
||||
//texture_index++;
|
||||
|
||||
if (m_program->uniforms.has_location("ftexture" + std::to_string(i) + "_cm", &location))
|
||||
{
|
||||
@ -331,21 +339,39 @@ void GLGSRender::end()
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
|
||||
{
|
||||
if (vertex_textures[i].enabled())
|
||||
int location;
|
||||
if (m_program->uniforms.has_location("vtexture" + std::to_string(i), &location))
|
||||
{
|
||||
int location;
|
||||
if (m_program->uniforms.has_location("vtexture" + std::to_string(i), &location))
|
||||
if (!textures[i].enabled())
|
||||
{
|
||||
glProgramUniform1i(m_program->id(), location, texture_index);
|
||||
m_gl_vertex_textures[i].init(texture_index, vertex_textures[i]);
|
||||
texture_index++;
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glProgramUniform1i(m_program->id(), location, i);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
m_gl_vertex_textures[i].set_target(get_gl_target_for_texture(vertex_textures[i]));
|
||||
|
||||
__glcheck m_gl_texture_cache.upload_texture(i, vertex_textures[i], m_gl_vertex_textures[i], m_rtts);
|
||||
__glcheck glProgramUniform1i(m_program->id(), location, i);
|
||||
|
||||
if (m_program->uniforms.has_location("vtexture" + std::to_string(i) + "_cm", &location))
|
||||
{
|
||||
if (textures[i].format() & CELL_GCM_TEXTURE_UN)
|
||||
{
|
||||
u32 width = std::max<u32>(textures[i].width(), 1);
|
||||
u32 height = std::max<u32>(textures[i].height(), 1);
|
||||
u32 depth = std::max<u32>(textures[i].depth(), 1);
|
||||
|
||||
glProgramUniform4f(m_program->id(), location, 1.f / width, 1.f / height, 1.f / depth, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
u32 offset_in_index_buffer = set_vertex_buffer();
|
||||
|
@ -424,7 +424,8 @@ namespace gl
|
||||
}
|
||||
}
|
||||
|
||||
void upload_texture(int index, rsx::texture &tex, rsx::gl::texture &gl_texture, gl_render_targets &m_rtts)
|
||||
template<typename RsxTextureType>
|
||||
void upload_texture(int index, RsxTextureType &tex, rsx::gl::texture &gl_texture, gl_render_targets &m_rtts)
|
||||
{
|
||||
const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
|
||||
const u32 range = (u32)get_texture_size(tex);
|
||||
|
@ -127,7 +127,6 @@ static void insert_texture_lod_fetch_function(std::string &dst, const rsx::decom
|
||||
dst += "}\n";
|
||||
}
|
||||
|
||||
|
||||
static void insert_texture_proj_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||
{
|
||||
if (shader.textures.empty())
|
||||
@ -237,26 +236,6 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
|
||||
result.code += "\n";
|
||||
|
||||
for (const rsx::texture_info& texture : shader.textures)
|
||||
{
|
||||
result.code += "uniform vec4 " + texture.name + "_cm = vec4(1.0);\n";
|
||||
|
||||
rsx::texture_target target = state.textures[texture.id];
|
||||
|
||||
|
||||
result.code += "uniform sampler";
|
||||
|
||||
switch (target)
|
||||
{
|
||||
default:
|
||||
case rsx::texture_target::_1: result.code += "1D"; break;
|
||||
case rsx::texture_target::_2: result.code += "2D"; break;
|
||||
case rsx::texture_target::_3: result.code += "3D"; break;
|
||||
case rsx::texture_target::cube: result.code += "Cube"; break;
|
||||
}
|
||||
result.code += " " + texture.name + ";\n";
|
||||
}
|
||||
|
||||
std::string prepare;
|
||||
std::string finalize;
|
||||
int location = 1;
|
||||
@ -264,6 +243,24 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
switch (shader.raw->type)
|
||||
{
|
||||
case rsx::program_type::fragment:
|
||||
for (const rsx::texture_info& texture : shader.textures)
|
||||
{
|
||||
result.code += "uniform vec4 " + texture.name + "_cm = vec4(1.0);\n";
|
||||
rsx::texture_target target = state.textures[texture.id];
|
||||
|
||||
result.code += "uniform sampler";
|
||||
|
||||
switch (target)
|
||||
{
|
||||
default:
|
||||
case rsx::texture_target::_1: result.code += "1D"; break;
|
||||
case rsx::texture_target::_2: result.code += "2D"; break;
|
||||
case rsx::texture_target::_3: result.code += "3D"; break;
|
||||
case rsx::texture_target::cube: result.code += "Cube"; break;
|
||||
}
|
||||
result.code += " " + texture.name + ";\n";
|
||||
}
|
||||
|
||||
insert_texture_fetch_function(result.code, shader, state);
|
||||
insert_texture_bias_fetch_function(result.code, shader, state);
|
||||
insert_texture_grad_fetch_function(result.code, shader, state);
|
||||
@ -524,20 +521,33 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
break;
|
||||
|
||||
case rsx::program_type::vertex:
|
||||
for (const rsx::texture_info& texture : shader.textures)
|
||||
{
|
||||
result.code += "uniform vec4 " + texture.name + "_cm = vec4(1.0);\n";
|
||||
|
||||
rsx::texture_target target = state.vertex_textures[texture.id];
|
||||
|
||||
result.code += "uniform sampler";
|
||||
|
||||
switch (target)
|
||||
{
|
||||
default:
|
||||
case rsx::texture_target::_1: result.code += "1D"; break;
|
||||
case rsx::texture_target::_2: result.code += "2D"; break;
|
||||
case rsx::texture_target::_3: result.code += "3D"; break;
|
||||
case rsx::texture_target::cube: result.code += "Cube"; break;
|
||||
}
|
||||
result.code += " " + texture.name + ";\n";
|
||||
}
|
||||
|
||||
insert_texture_lod_fetch_function(result.code, shader, state);
|
||||
|
||||
result.code += "out vec4 wpos;\n";
|
||||
|
||||
// TODO
|
||||
if (0)
|
||||
{
|
||||
finalize += "\tgl_Position = o0;\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
finalize +=
|
||||
" wpos = window_matrix * viewport_matrix * vec4(o0.xyz, 1.0);\n"
|
||||
" gl_Position = normalize_matrix * vec4(wpos.xyz, 1.0);\n"
|
||||
" gl_Position.w = o0.w;\n";
|
||||
}
|
||||
finalize +=
|
||||
" wpos = window_matrix * viewport_matrix * vec4(o0.xyz, 1.0);\n"
|
||||
" gl_Position = normalize_matrix * vec4(wpos.xyz, 1.0);\n"
|
||||
" gl_Position.w = o0.w;\n";
|
||||
|
||||
{
|
||||
std::string code_end;
|
||||
|
@ -536,6 +536,111 @@ namespace rsx
|
||||
__glcheck glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
|
||||
}
|
||||
|
||||
void texture::init(int index, rsx::vertex_texture& tex)
|
||||
{
|
||||
switch (tex.dimension())
|
||||
{
|
||||
case rsx::texture_dimension::dimension3d:
|
||||
if (!tex.depth())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
case rsx::texture_dimension::dimension2d:
|
||||
if (!tex.height())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
case rsx::texture_dimension::dimension1d:
|
||||
if (!tex.width())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
|
||||
|
||||
//We can't re-use texture handles if using immutable storage
|
||||
if (m_id)
|
||||
{
|
||||
__glcheck remove();
|
||||
}
|
||||
__glcheck create();
|
||||
|
||||
__glcheck glActiveTexture(GL_TEXTURE0 + index);
|
||||
bind();
|
||||
|
||||
u32 full_format = tex.format();
|
||||
|
||||
u32 format = full_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
bool is_swizzled = !!(~full_format & CELL_GCM_TEXTURE_LN);
|
||||
|
||||
__glcheck::gl::pixel_pack_settings().apply();
|
||||
__glcheck::gl::pixel_unpack_settings().apply();
|
||||
|
||||
u32 aligned_pitch = tex.pitch();
|
||||
|
||||
size_t texture_data_sz = get_placed_texture_storage_size(tex, 256);
|
||||
std::vector<gsl::byte> data_upload_buf(texture_data_sz);
|
||||
u32 block_sz = get_pitch_modifier(format);
|
||||
|
||||
__glcheck glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
|
||||
__glcheck create_and_fill_texture(tex.get_extended_texture_dimension(), tex.get_exact_mipmap_count(), format, tex.width(), tex.height(), tex.depth(), get_subresources_layout(tex), is_swizzled, data_upload_buf);
|
||||
|
||||
const std::array<GLenum, 4>& glRemap = get_swizzle_remap(format);
|
||||
|
||||
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[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_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()));
|
||||
}
|
||||
|
||||
void texture::bind()
|
||||
{
|
||||
glBindTexture(m_target, m_id);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
class vertex_texture;
|
||||
class texture;
|
||||
|
||||
namespace gl
|
||||
@ -38,6 +39,7 @@ namespace rsx
|
||||
}
|
||||
|
||||
void init(int index, rsx::texture& tex);
|
||||
void init(int index, rsx::vertex_texture& tex);
|
||||
|
||||
/**
|
||||
* If a format is marked as mandating expansion, any request to have the data uploaded to the GPU shall require that the pixel data
|
||||
|
@ -299,9 +299,21 @@ namespace rsx
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 3) & 0x1);
|
||||
}
|
||||
|
||||
u8 vertex_texture::dimension() const
|
||||
rsx::texture_dimension vertex_texture::dimension() const
|
||||
{
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf);
|
||||
return rsx::to_texture_dimension((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf);
|
||||
}
|
||||
|
||||
rsx::texture_dimension_extended vertex_texture::get_extended_texture_dimension() const
|
||||
{
|
||||
switch (dimension())
|
||||
{
|
||||
case rsx::texture_dimension::dimension1d: return rsx::texture_dimension_extended::texture_dimension_1d;
|
||||
case rsx::texture_dimension::dimension3d: return rsx::texture_dimension_extended::texture_dimension_2d;
|
||||
case rsx::texture_dimension::dimension2d: return cubemap() ? rsx::texture_dimension_extended::texture_dimension_cubemap : rsx::texture_dimension_extended::texture_dimension_2d;
|
||||
|
||||
default: ASSUME(0);
|
||||
}
|
||||
}
|
||||
|
||||
u8 vertex_texture::format() const
|
||||
@ -314,6 +326,12 @@ namespace rsx
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff);
|
||||
}
|
||||
|
||||
u16 vertex_texture::get_exact_mipmap_count() const
|
||||
{
|
||||
u16 max_mipmap_count = static_cast<u16>(floor(log2(std::max(width(), height()))) + 1);
|
||||
return std::min(mipmap(), max_mipmap_count);
|
||||
}
|
||||
|
||||
u8 vertex_texture::unsigned_remap() const
|
||||
{
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 12) & 0xf);
|
||||
@ -341,7 +359,7 @@ namespace rsx
|
||||
|
||||
bool vertex_texture::enabled() const
|
||||
{
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1);
|
||||
return location() <= 1 && ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1);
|
||||
}
|
||||
|
||||
u16 vertex_texture::min_lod() const
|
||||
@ -354,9 +372,9 @@ namespace rsx
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff);
|
||||
}
|
||||
|
||||
u8 vertex_texture::max_aniso() const
|
||||
rsx::texture_max_anisotropy vertex_texture::max_aniso() const
|
||||
{
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7);
|
||||
return rsx::to_texture_max_anisotropy((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7);
|
||||
}
|
||||
|
||||
bool vertex_texture::alpha_kill_enabled() const
|
||||
@ -369,14 +387,14 @@ namespace rsx
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff);
|
||||
}
|
||||
|
||||
u8 vertex_texture::min_filter() const
|
||||
rsx::texture_minify_filter vertex_texture::min_filter() const
|
||||
{
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7);
|
||||
return rsx::to_texture_minify_filter((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7);
|
||||
}
|
||||
|
||||
u8 vertex_texture::mag_filter() const
|
||||
rsx::texture_magnify_filter vertex_texture::mag_filter() const
|
||||
{
|
||||
return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7);
|
||||
return rsx::to_texture_magnify_filter((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7);
|
||||
}
|
||||
|
||||
u8 vertex_texture::convolution_filter() const
|
||||
|
@ -84,9 +84,6 @@ namespace rsx
|
||||
u32 border_color() const;
|
||||
u16 depth() const;
|
||||
u32 pitch() const;
|
||||
|
||||
//custom info
|
||||
u8 index() const;
|
||||
};
|
||||
|
||||
class vertex_texture
|
||||
@ -102,12 +99,12 @@ namespace rsx
|
||||
u32 offset() const;
|
||||
|
||||
// Format
|
||||
u8 location() const;
|
||||
u8 location() const;
|
||||
bool cubemap() const;
|
||||
u8 border_type() const;
|
||||
u8 dimension() const;
|
||||
u8 format() const;
|
||||
u16 mipmap() const;
|
||||
u8 border_type() const;
|
||||
rsx::texture_dimension dimension() const;
|
||||
u8 format() const;
|
||||
u16 mipmap() const;
|
||||
|
||||
// Address
|
||||
u8 unsigned_remap() const;
|
||||
@ -118,16 +115,16 @@ namespace rsx
|
||||
|
||||
// Control0
|
||||
bool enabled() const;
|
||||
u16 min_lod() const;
|
||||
u16 max_lod() const;
|
||||
u8 max_aniso() 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;
|
||||
u8 min_filter() const;
|
||||
u8 mag_filter() const;
|
||||
u8 convolution_filter() 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;
|
||||
@ -142,7 +139,7 @@ namespace rsx
|
||||
u16 depth() const;
|
||||
u32 pitch() const;
|
||||
|
||||
//custom info
|
||||
u8 index() const;
|
||||
rsx::texture_dimension_extended get_extended_texture_dimension() const;
|
||||
u16 get_exact_mipmap_count() const;
|
||||
};
|
||||
}
|
||||
|
@ -351,14 +351,14 @@ namespace rsx
|
||||
|
||||
void thread::end()
|
||||
{
|
||||
transform_constants.clear();
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
register_vertex_info[index].size = 0;
|
||||
register_vertex_data[index].clear();
|
||||
}
|
||||
|
||||
transform_constants.clear();
|
||||
|
||||
if (capture_current_frame)
|
||||
{
|
||||
for (const auto &first_count : first_count_commands)
|
||||
@ -468,14 +468,19 @@ namespace rsx
|
||||
u32 reg = cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT ? first_cmd : first_cmd + i;
|
||||
u32 value = args[i];
|
||||
|
||||
LOG_TRACE(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value);
|
||||
//LOG_NOTICE(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value);
|
||||
|
||||
method_registers[reg] = value;
|
||||
|
||||
if (capture_current_frame)
|
||||
{
|
||||
frame_debug.command_queue.push_back(std::make_pair(reg, value));
|
||||
}
|
||||
|
||||
if (auto method = methods[reg])
|
||||
{
|
||||
method(this, value);
|
||||
}
|
||||
}
|
||||
|
||||
ctrl->get = get + (count + 1) * 4;
|
||||
@ -822,6 +827,27 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::vertex_textures_count; ++index)
|
||||
{
|
||||
if (!textures[index].enabled())
|
||||
{
|
||||
result.state.vertex_textures[index] = rsx::texture_target::none;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (textures[index].get_extended_texture_dimension())
|
||||
{
|
||||
case rsx::texture_dimension_extended::texture_dimension_1d: result.state.vertex_textures[index] = rsx::texture_target::_1; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_2d: result.state.vertex_textures[index] = rsx::texture_target::_2; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_3d: result.state.vertex_textures[index] = rsx::texture_target::_3; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap: result.state.vertex_textures[index] = rsx::texture_target::cube; break;
|
||||
|
||||
default:
|
||||
result.state.vertex_textures[index] = rsx::texture_target::none;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result.vertex_shader.ucode_ptr = transform_program;
|
||||
result.vertex_shader.offset = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];
|
||||
|
||||
|
@ -268,7 +268,7 @@ namespace rsx
|
||||
|
||||
u32 tiles_addr;
|
||||
u32 zculls_addr;
|
||||
vm::ps3::ptr<CellGcmDisplayInfo> gcm_buffers;
|
||||
vm::ps3::ptr<CellGcmDisplayInfo> gcm_buffers = vm::null;
|
||||
u32 gcm_buffers_count;
|
||||
u32 gcm_current_buffer;
|
||||
u32 ctxt_addr;
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit aa6bcbc58961356733ae1fc0742a37a0a6190f31
|
||||
Subproject commit 3b1e7b0e5080ec9cb43616422b0e286c61b88c87
|
Loading…
Reference in New Issue
Block a user