Partial success on predicated tiling (depth buffer still bad).
This commit is contained in:
parent
7c3225ee41
commit
fa58eaa317
|
@ -229,7 +229,7 @@ void Blitter::Draw(GLuint src_texture, Rect2D src_rect, Rect2D dest_rect,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
glViewport(0, 0, dest_rect.width, dest_rect.height);
|
glViewport(dest_rect.x, dest_rect.y, dest_rect.width, dest_rect.height);
|
||||||
|
|
||||||
// TODO(benvanik): avoid this?
|
// TODO(benvanik): avoid this?
|
||||||
GLint src_texture_width;
|
GLint src_texture_width;
|
||||||
|
|
|
@ -578,16 +578,12 @@ void CommandProcessor::IssueSwap() {
|
||||||
|
|
||||||
// Guess frontbuffer dimensions.
|
// Guess frontbuffer dimensions.
|
||||||
// Command buffer seems to set these right before the XE_SWAP.
|
// Command buffer seems to set these right before the XE_SWAP.
|
||||||
// uint32_t window_scissor_tl = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32;
|
uint32_t window_scissor_tl = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32;
|
||||||
// uint32_t window_scissor_br = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR].u32;
|
uint32_t window_scissor_br = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR].u32;
|
||||||
// swap_params.x = window_scissor_tl & 0x7FFF;
|
swap_params.x = window_scissor_tl & 0x7FFF;
|
||||||
// swap_params.y = (window_scissor_tl >> 16) & 0x7FFF;
|
swap_params.y = (window_scissor_tl >> 16) & 0x7FFF;
|
||||||
// swap_params.width = window_scissor_br & 0x7FFF - swap_params.x;
|
swap_params.width = window_scissor_br & 0x7FFF - swap_params.x;
|
||||||
// swap_params.height = (window_scissor_br >> 16) & 0x7FFF - swap_params.y;
|
swap_params.height = (window_scissor_br >> 16) & 0x7FFF - swap_params.y;
|
||||||
swap_params.x = 0;
|
|
||||||
swap_params.y = 0;
|
|
||||||
swap_params.width = 1280;
|
|
||||||
swap_params.height = 720;
|
|
||||||
|
|
||||||
PrepareForWait();
|
PrepareForWait();
|
||||||
swap_handler_(swap_params);
|
swap_handler_(swap_params);
|
||||||
|
@ -2208,6 +2204,7 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateDepthStencilState() {
|
||||||
} else {
|
} else {
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
// glDisable(GL_DEPTH_TEST);
|
||||||
// A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE
|
// A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE
|
||||||
glDepthMask((regs.rb_depthcontrol & 0x00000004) ? GL_TRUE : GL_FALSE);
|
glDepthMask((regs.rb_depthcontrol & 0x00000004) ? GL_TRUE : GL_FALSE);
|
||||||
// A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE
|
// A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE
|
||||||
|
@ -2631,17 +2628,14 @@ bool CommandProcessor::IssueCopy() {
|
||||||
// glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
// glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||||
// glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
|
// glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
|
||||||
|
|
||||||
// Destination pointer in guest memory.
|
|
||||||
// We have GL throw bytes directly into it.
|
|
||||||
// TODO(benvanik): copy to staging texture then PBO back?
|
|
||||||
void* ptr = membase_ + GpuToCpu(copy_dest_base);
|
|
||||||
|
|
||||||
// TODO(benvanik): any way to scissor this? a200 has:
|
// TODO(benvanik): any way to scissor this? a200 has:
|
||||||
// REG_A2XX_RB_COPY_DEST_OFFSET = A2XX_RB_COPY_DEST_OFFSET_X(tile->xoff) |
|
// REG_A2XX_RB_COPY_DEST_OFFSET = A2XX_RB_COPY_DEST_OFFSET_X(tile->xoff) |
|
||||||
// A2XX_RB_COPY_DEST_OFFSET_Y(tile->yoff);
|
// A2XX_RB_COPY_DEST_OFFSET_Y(tile->yoff);
|
||||||
// but I can't seem to find something similar.
|
// but I can't seem to find something similar.
|
||||||
uint32_t width = copy_dest_pitch;
|
uint32_t dest_logical_width = copy_dest_pitch;
|
||||||
uint32_t height = copy_dest_height;
|
uint32_t dest_logical_height = copy_dest_height;
|
||||||
|
uint32_t dest_block_width = poly::round_up(dest_logical_width, 32);
|
||||||
|
uint32_t dest_block_height = poly::round_up(dest_logical_height, 32);
|
||||||
|
|
||||||
uint32_t window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32;
|
uint32_t window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32;
|
||||||
int16_t window_offset_x = window_offset & 0x7FFF;
|
int16_t window_offset_x = window_offset & 0x7FFF;
|
||||||
|
@ -2699,6 +2693,19 @@ bool CommandProcessor::IssueCopy() {
|
||||||
dest_max_y - dest_min_y);
|
dest_max_y - dest_min_y);
|
||||||
Rect2D src_rect(0, 0, dest_rect.width, dest_rect.height);
|
Rect2D src_rect(0, 0, dest_rect.width, dest_rect.height);
|
||||||
|
|
||||||
|
// The dest base address passed in has already been offset by the window
|
||||||
|
// offset, so to ensure texture lookup works we need to offset it.
|
||||||
|
// TODO(benvanik): allow texture cache to lookup partial textures.
|
||||||
|
// TODO(benvanik): change based on format.
|
||||||
|
int32_t dest_offset = window_offset_y * copy_dest_pitch * 4;
|
||||||
|
dest_offset += window_offset_x * 32 * 4;
|
||||||
|
copy_dest_base += dest_offset;
|
||||||
|
|
||||||
|
// Destination pointer in guest memory.
|
||||||
|
// We have GL throw bytes directly into it.
|
||||||
|
// TODO(benvanik): copy to staging texture then PBO back?
|
||||||
|
void* ptr = membase_ + GpuToCpu(copy_dest_base);
|
||||||
|
|
||||||
// Make active so glReadPixels reads from us.
|
// Make active so glReadPixels reads from us.
|
||||||
switch (copy_command) {
|
switch (copy_command) {
|
||||||
case CopyCommand::kRaw: {
|
case CopyCommand::kRaw: {
|
||||||
|
@ -2708,7 +2715,8 @@ bool CommandProcessor::IssueCopy() {
|
||||||
// Source from a bound render target.
|
// Source from a bound render target.
|
||||||
// TODO(benvanik): RAW copy.
|
// TODO(benvanik): RAW copy.
|
||||||
last_framebuffer_texture_ = texture_cache_.CopyTexture(
|
last_framebuffer_texture_ = texture_cache_.CopyTexture(
|
||||||
context_->blitter(), copy_dest_base, width, height,
|
context_->blitter(), copy_dest_base, dest_logical_width,
|
||||||
|
dest_logical_height, dest_block_width, dest_block_height,
|
||||||
ColorFormatToTextureFormat(copy_dest_format),
|
ColorFormatToTextureFormat(copy_dest_format),
|
||||||
copy_dest_swap ? true : false, color_targets[copy_src_select],
|
copy_dest_swap ? true : false, color_targets[copy_src_select],
|
||||||
src_rect, dest_rect);
|
src_rect, dest_rect);
|
||||||
|
@ -2718,9 +2726,11 @@ bool CommandProcessor::IssueCopy() {
|
||||||
} else {
|
} else {
|
||||||
// Source from the bound depth/stencil target.
|
// Source from the bound depth/stencil target.
|
||||||
// TODO(benvanik): RAW copy.
|
// TODO(benvanik): RAW copy.
|
||||||
texture_cache_.CopyTexture(
|
texture_cache_.CopyTexture(context_->blitter(), copy_dest_base,
|
||||||
context_->blitter(), copy_dest_base, width, height, src_format,
|
dest_logical_width, dest_logical_height,
|
||||||
copy_dest_swap ? true : false, depth_target, src_rect, dest_rect);
|
dest_block_width, dest_block_height,
|
||||||
|
src_format, copy_dest_swap ? true : false,
|
||||||
|
depth_target, src_rect, dest_rect);
|
||||||
if (!FLAGS_disable_framebuffer_readback) {
|
if (!FLAGS_disable_framebuffer_readback) {
|
||||||
// glReadPixels(x, y, w, h, GL_DEPTH_STENCIL, read_type, ptr);
|
// glReadPixels(x, y, w, h, GL_DEPTH_STENCIL, read_type, ptr);
|
||||||
}
|
}
|
||||||
|
@ -2733,7 +2743,8 @@ bool CommandProcessor::IssueCopy() {
|
||||||
// Either copy the readbuffer into an existing texture or create a new
|
// Either copy the readbuffer into an existing texture or create a new
|
||||||
// one in the cache so we can service future upload requests.
|
// one in the cache so we can service future upload requests.
|
||||||
last_framebuffer_texture_ = texture_cache_.ConvertTexture(
|
last_framebuffer_texture_ = texture_cache_.ConvertTexture(
|
||||||
context_->blitter(), copy_dest_base, width, height,
|
context_->blitter(), copy_dest_base, dest_logical_width,
|
||||||
|
dest_logical_height, dest_block_width, dest_block_height,
|
||||||
ColorFormatToTextureFormat(copy_dest_format),
|
ColorFormatToTextureFormat(copy_dest_format),
|
||||||
copy_dest_swap ? true : false, color_targets[copy_src_select],
|
copy_dest_swap ? true : false, color_targets[copy_src_select],
|
||||||
src_rect, dest_rect);
|
src_rect, dest_rect);
|
||||||
|
@ -2742,9 +2753,11 @@ bool CommandProcessor::IssueCopy() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Source from the bound depth/stencil target.
|
// Source from the bound depth/stencil target.
|
||||||
texture_cache_.ConvertTexture(
|
texture_cache_.ConvertTexture(context_->blitter(), copy_dest_base,
|
||||||
context_->blitter(), copy_dest_base, width, height, src_format,
|
dest_logical_width, dest_logical_height,
|
||||||
copy_dest_swap ? true : false, depth_target, src_rect, dest_rect);
|
dest_block_width, dest_block_height,
|
||||||
|
src_format, copy_dest_swap ? true : false,
|
||||||
|
depth_target, src_rect, dest_rect);
|
||||||
if (!FLAGS_disable_framebuffer_readback) {
|
if (!FLAGS_disable_framebuffer_readback) {
|
||||||
// glReadPixels(x, y, w, h, GL_DEPTH_STENCIL, read_type, ptr);
|
// glReadPixels(x, y, w, h, GL_DEPTH_STENCIL, read_type, ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,8 +409,8 @@ TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture(
|
||||||
it != read_buffer_textures_.end(); ++it) {
|
it != read_buffer_textures_.end(); ++it) {
|
||||||
auto read_buffer_entry = *it;
|
auto read_buffer_entry = *it;
|
||||||
if (read_buffer_entry->guest_address == texture_info.guest_address &&
|
if (read_buffer_entry->guest_address == texture_info.guest_address &&
|
||||||
read_buffer_entry->width == texture_info.size_2d.logical_width &&
|
read_buffer_entry->block_width == texture_info.size_2d.block_width &&
|
||||||
read_buffer_entry->height == texture_info.size_2d.logical_height) {
|
read_buffer_entry->block_height == texture_info.size_2d.block_height) {
|
||||||
// Found! Acquire the handle and remove the readbuffer entry.
|
// Found! Acquire the handle and remove the readbuffer entry.
|
||||||
read_buffer_textures_.erase(it);
|
read_buffer_textures_.erase(it);
|
||||||
entry->handle = read_buffer_entry->handle;
|
entry->handle = read_buffer_entry->handle;
|
||||||
|
@ -515,8 +515,8 @@ TextureCache::TextureEntry* TextureCache::LookupAddress(uint32_t guest_address,
|
||||||
const auto& texture_info = it->second->texture_info;
|
const auto& texture_info = it->second->texture_info;
|
||||||
if (texture_info.guest_address == guest_address &&
|
if (texture_info.guest_address == guest_address &&
|
||||||
texture_info.dimension == Dimension::k2D &&
|
texture_info.dimension == Dimension::k2D &&
|
||||||
texture_info.size_2d.logical_width == width &&
|
texture_info.size_2d.input_width == width &&
|
||||||
texture_info.size_2d.logical_height == height) {
|
texture_info.size_2d.input_height == height) {
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,16 +524,20 @@ TextureCache::TextureEntry* TextureCache::LookupAddress(uint32_t guest_address,
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint TextureCache::CopyTexture(Blitter* blitter, uint32_t guest_address,
|
GLuint TextureCache::CopyTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
uint32_t width, uint32_t height,
|
uint32_t logical_width,
|
||||||
TextureFormat format, bool swap_channels,
|
uint32_t logical_height, uint32_t block_width,
|
||||||
GLuint src_texture, Rect2D src_rect,
|
uint32_t block_height, TextureFormat format,
|
||||||
Rect2D dest_rect) {
|
bool swap_channels, GLuint src_texture,
|
||||||
return ConvertTexture(blitter, guest_address, width, height, format,
|
Rect2D src_rect, Rect2D dest_rect) {
|
||||||
swap_channels, src_texture, src_rect, dest_rect);
|
return ConvertTexture(blitter, guest_address, logical_width, logical_height,
|
||||||
|
block_width, block_height, format, swap_channels,
|
||||||
|
src_texture, src_rect, dest_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
uint32_t width, uint32_t height,
|
uint32_t logical_width,
|
||||||
|
uint32_t logical_height,
|
||||||
|
uint32_t block_width, uint32_t block_height,
|
||||||
TextureFormat format, bool swap_channels,
|
TextureFormat format, bool swap_channels,
|
||||||
GLuint src_texture, Rect2D src_rect,
|
GLuint src_texture, Rect2D src_rect,
|
||||||
Rect2D dest_rect) {
|
Rect2D dest_rect) {
|
||||||
|
@ -546,7 +550,8 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
// See if we have used a texture at this address before. If we have, we can
|
// See if we have used a texture at this address before. If we have, we can
|
||||||
// reuse it.
|
// reuse it.
|
||||||
// TODO(benvanik): better lookup matching format/etc?
|
// TODO(benvanik): better lookup matching format/etc?
|
||||||
auto texture_entry = LookupAddress(guest_address, width, height, format);
|
auto texture_entry =
|
||||||
|
LookupAddress(guest_address, block_width, block_height, format);
|
||||||
if (texture_entry) {
|
if (texture_entry) {
|
||||||
// Have existing texture.
|
// Have existing texture.
|
||||||
assert_false(texture_entry->pending_invalidation);
|
assert_false(texture_entry->pending_invalidation);
|
||||||
|
@ -571,8 +576,9 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
for (auto it = read_buffer_textures_.begin();
|
for (auto it = read_buffer_textures_.begin();
|
||||||
it != read_buffer_textures_.end(); ++it) {
|
it != read_buffer_textures_.end(); ++it) {
|
||||||
const auto& entry = *it;
|
const auto& entry = *it;
|
||||||
if (entry->guest_address == guest_address && entry->width == width &&
|
if (entry->guest_address == guest_address &&
|
||||||
entry->height == height && entry->format == format) {
|
entry->logical_width == logical_width &&
|
||||||
|
entry->logical_height == logical_height && entry->format == format) {
|
||||||
// Found an existing entry - just reupload.
|
// Found an existing entry - just reupload.
|
||||||
if (config.format == GL_DEPTH_STENCIL) {
|
if (config.format == GL_DEPTH_STENCIL) {
|
||||||
blitter->CopyDepthTexture(src_texture, src_rect, entry->handle,
|
blitter->CopyDepthTexture(src_texture, src_rect, entry->handle,
|
||||||
|
@ -591,14 +597,17 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
// of time we'll dump it.
|
// of time we'll dump it.
|
||||||
auto entry = std::make_unique<ReadBufferTexture>();
|
auto entry = std::make_unique<ReadBufferTexture>();
|
||||||
entry->guest_address = guest_address;
|
entry->guest_address = guest_address;
|
||||||
entry->width = width;
|
entry->logical_width = logical_width;
|
||||||
entry->height = height;
|
entry->logical_height = logical_height;
|
||||||
|
entry->block_width = block_width;
|
||||||
|
entry->block_height = block_height;
|
||||||
entry->format = format;
|
entry->format = format;
|
||||||
|
|
||||||
glCreateTextures(GL_TEXTURE_2D, 1, &entry->handle);
|
glCreateTextures(GL_TEXTURE_2D, 1, &entry->handle);
|
||||||
glTextureParameteri(entry->handle, GL_TEXTURE_BASE_LEVEL, 0);
|
glTextureParameteri(entry->handle, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTextureParameteri(entry->handle, GL_TEXTURE_MAX_LEVEL, 1);
|
glTextureParameteri(entry->handle, GL_TEXTURE_MAX_LEVEL, 1);
|
||||||
glTextureStorage2D(entry->handle, 1, config.internal_format, width, height);
|
glTextureStorage2D(entry->handle, 1, config.internal_format, logical_width,
|
||||||
|
logical_height);
|
||||||
if (config.format == GL_DEPTH_STENCIL) {
|
if (config.format == GL_DEPTH_STENCIL) {
|
||||||
blitter->CopyDepthTexture(src_texture, src_rect, entry->handle, dest_rect);
|
blitter->CopyDepthTexture(src_texture, src_rect, entry->handle, dest_rect);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -59,19 +59,24 @@ class TextureCache {
|
||||||
TextureEntryView* Demand(const TextureInfo& texture_info,
|
TextureEntryView* Demand(const TextureInfo& texture_info,
|
||||||
const SamplerInfo& sampler_info);
|
const SamplerInfo& sampler_info);
|
||||||
|
|
||||||
GLuint CopyTexture(Blitter* blitter, uint32_t guest_address, uint32_t width,
|
GLuint CopyTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
uint32_t height, TextureFormat format, bool swap_channels,
|
uint32_t logical_width, uint32_t logical_height,
|
||||||
|
uint32_t block_width, uint32_t block_height,
|
||||||
|
TextureFormat format, bool swap_channels,
|
||||||
GLuint src_texture, Rect2D src_rect, Rect2D dest_rect);
|
GLuint src_texture, Rect2D src_rect, Rect2D dest_rect);
|
||||||
GLuint ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
GLuint ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
uint32_t width, uint32_t height, TextureFormat format,
|
uint32_t logical_width, uint32_t logical_height,
|
||||||
bool swap_channels, GLuint src_texture, Rect2D src_rect,
|
uint32_t block_width, uint32_t block_height,
|
||||||
Rect2D dest_rect);
|
TextureFormat format, bool swap_channels,
|
||||||
|
GLuint src_texture, Rect2D src_rect, Rect2D dest_rect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ReadBufferTexture {
|
struct ReadBufferTexture {
|
||||||
uint32_t guest_address;
|
uint32_t guest_address;
|
||||||
uint32_t width;
|
uint32_t logical_width;
|
||||||
uint32_t height;
|
uint32_t logical_height;
|
||||||
|
uint32_t block_width;
|
||||||
|
uint32_t block_height;
|
||||||
TextureFormat format;
|
TextureFormat format;
|
||||||
GLuint handle;
|
GLuint handle;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue