RenderCache::ClearEDRAMColor/ClearEDRAMDepthStencil
This commit is contained in:
parent
635d095b87
commit
5ba04b9e55
|
@ -531,6 +531,7 @@ const RenderState* RenderCache::BeginRenderPass(VkCommandBuffer command_buffer,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Speculatively see if targets are actually used so we can skip copies
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
config->color[i].used = pixel_shader->writes_color_target(i);
|
config->color[i].used = pixel_shader->writes_color_target(i);
|
||||||
}
|
}
|
||||||
|
@ -646,7 +647,6 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) {
|
||||||
// RB_SURFACE_INFO
|
// RB_SURFACE_INFO
|
||||||
// http://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html
|
// http://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html
|
||||||
config->surface_pitch_px = regs.rb_surface_info & 0x3FFF;
|
config->surface_pitch_px = regs.rb_surface_info & 0x3FFF;
|
||||||
// config->surface_height_px = (regs.rb_surface_info >> 18) & 0x3FFF;
|
|
||||||
config->surface_msaa =
|
config->surface_msaa =
|
||||||
static_cast<MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
|
static_cast<MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
|
||||||
|
|
||||||
|
@ -814,6 +814,11 @@ void RenderCache::EndRenderPass() {
|
||||||
// Don't bother waiting on this command to complete, as next render pass may
|
// Don't bother waiting on this command to complete, as next render pass may
|
||||||
// reuse previous framebuffer attachments. If they need this, they will wait.
|
// reuse previous framebuffer attachments. If they need this, they will wait.
|
||||||
// TODO: Should we bother re-tiling the images on copy back?
|
// TODO: Should we bother re-tiling the images on copy back?
|
||||||
|
//
|
||||||
|
// FIXME: There's a case where we may have a really big render target (as we
|
||||||
|
// can't get the correct height atm) and we may end up overwriting the valid
|
||||||
|
// contents of another render target by mistake! Need to reorder copy commands
|
||||||
|
// to avoid this.
|
||||||
VkBufferImageCopy region;
|
VkBufferImageCopy region;
|
||||||
region.bufferRowLength = 0;
|
region.bufferRowLength = 0;
|
||||||
region.bufferImageHeight = 0;
|
region.bufferImageHeight = 0;
|
||||||
|
@ -918,6 +923,83 @@ void RenderCache::RawCopyToImage(VkCommandBuffer command_buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderCache::ClearEDRAMColor(VkCommandBuffer command_buffer,
|
||||||
|
uint32_t edram_base,
|
||||||
|
ColorRenderTargetFormat format,
|
||||||
|
uint32_t pitch, uint32_t height,
|
||||||
|
float* color) {
|
||||||
|
// Grab a tile view (as we need to clear an image first)
|
||||||
|
TileViewKey key;
|
||||||
|
key.color_or_depth = 1;
|
||||||
|
key.edram_format = static_cast<uint16_t>(format);
|
||||||
|
key.tile_offset = edram_base;
|
||||||
|
key.tile_width = pitch / 80;
|
||||||
|
key.tile_height = height / 16;
|
||||||
|
auto tile_view = FindOrCreateTileView(command_buffer, key);
|
||||||
|
assert_not_null(tile_view);
|
||||||
|
|
||||||
|
VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
||||||
|
VkClearColorValue clear_value;
|
||||||
|
std::memcpy(clear_value.float32, color, sizeof(float) * 4);
|
||||||
|
|
||||||
|
// Issue a clear command
|
||||||
|
vkCmdClearColorImage(command_buffer, tile_view->image,
|
||||||
|
VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range);
|
||||||
|
|
||||||
|
// Copy image back into EDRAM buffer
|
||||||
|
VkBufferImageCopy copy_range;
|
||||||
|
copy_range.bufferOffset = edram_base * 5120;
|
||||||
|
copy_range.bufferImageHeight = 0;
|
||||||
|
copy_range.bufferRowLength = 0;
|
||||||
|
copy_range.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
|
||||||
|
copy_range.imageExtent = {key.tile_width * 80u, key.tile_height * 16u, 1u};
|
||||||
|
copy_range.imageOffset = {0, 0, 0};
|
||||||
|
vkCmdCopyImageToBuffer(command_buffer, tile_view->image,
|
||||||
|
VK_IMAGE_LAYOUT_GENERAL, edram_buffer_, 1,
|
||||||
|
©_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderCache::ClearEDRAMDepthStencil(VkCommandBuffer command_buffer,
|
||||||
|
uint32_t edram_base,
|
||||||
|
DepthRenderTargetFormat format,
|
||||||
|
uint32_t pitch, uint32_t height,
|
||||||
|
float depth, uint32_t stencil) {
|
||||||
|
// Grab a tile view (as we need to clear an image first)
|
||||||
|
TileViewKey key;
|
||||||
|
key.color_or_depth = 0;
|
||||||
|
key.edram_format = static_cast<uint16_t>(format);
|
||||||
|
key.tile_offset = edram_base;
|
||||||
|
key.tile_width = pitch / 80;
|
||||||
|
key.tile_height = height / 16;
|
||||||
|
auto tile_view = FindOrCreateTileView(command_buffer, key);
|
||||||
|
assert_not_null(tile_view);
|
||||||
|
|
||||||
|
VkImageSubresourceRange range = {
|
||||||
|
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1,
|
||||||
|
};
|
||||||
|
VkClearDepthStencilValue clear_value;
|
||||||
|
clear_value.depth = depth;
|
||||||
|
clear_value.stencil = stencil;
|
||||||
|
|
||||||
|
// Issue a clear command
|
||||||
|
vkCmdClearDepthStencilImage(command_buffer, tile_view->image,
|
||||||
|
VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range);
|
||||||
|
|
||||||
|
// Copy image back into EDRAM buffer
|
||||||
|
VkBufferImageCopy copy_range;
|
||||||
|
copy_range.bufferOffset = edram_base * 5120;
|
||||||
|
copy_range.bufferImageHeight = 0;
|
||||||
|
copy_range.bufferRowLength = 0;
|
||||||
|
copy_range.imageSubresource = {
|
||||||
|
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1,
|
||||||
|
};
|
||||||
|
copy_range.imageExtent = {key.tile_width * 80u, key.tile_height * 16u, 1u};
|
||||||
|
copy_range.imageOffset = {0, 0, 0};
|
||||||
|
vkCmdCopyImageToBuffer(command_buffer, tile_view->image,
|
||||||
|
VK_IMAGE_LAYOUT_GENERAL, edram_buffer_, 1,
|
||||||
|
©_range);
|
||||||
|
}
|
||||||
|
|
||||||
bool RenderCache::SetShadowRegister(uint32_t* dest, uint32_t register_name) {
|
bool RenderCache::SetShadowRegister(uint32_t* dest, uint32_t register_name) {
|
||||||
uint32_t value = register_file_->values[register_name].u32;
|
uint32_t value = register_file_->values[register_name].u32;
|
||||||
if (*dest == value) {
|
if (*dest == value) {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "xenia/gpu/register_file.h"
|
#include "xenia/gpu/register_file.h"
|
||||||
#include "xenia/gpu/shader.h"
|
#include "xenia/gpu/shader.h"
|
||||||
|
#include "xenia/gpu/texture_info.h"
|
||||||
#include "xenia/gpu/vulkan/vulkan_shader.h"
|
#include "xenia/gpu/vulkan/vulkan_shader.h"
|
||||||
#include "xenia/gpu/xenos.h"
|
#include "xenia/gpu/xenos.h"
|
||||||
#include "xenia/ui/vulkan/vulkan.h"
|
#include "xenia/ui/vulkan/vulkan.h"
|
||||||
|
@ -267,6 +268,16 @@ class RenderCache {
|
||||||
bool color_or_depth, VkOffset3D offset,
|
bool color_or_depth, VkOffset3D offset,
|
||||||
VkExtent3D extents);
|
VkExtent3D extents);
|
||||||
|
|
||||||
|
// Queues commands to clear EDRAM contents with a solid color
|
||||||
|
void ClearEDRAMColor(VkCommandBuffer command_buffer, uint32_t edram_base,
|
||||||
|
ColorRenderTargetFormat format, uint32_t pitch,
|
||||||
|
uint32_t height, float* color);
|
||||||
|
// Queues commands to clear EDRAM contents with depth/stencil values.
|
||||||
|
void ClearEDRAMDepthStencil(VkCommandBuffer command_buffer,
|
||||||
|
uint32_t edram_base,
|
||||||
|
DepthRenderTargetFormat format, uint32_t pitch,
|
||||||
|
uint32_t height, float depth, uint32_t stencil);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Parses the current state into a configuration object.
|
// Parses the current state into a configuration object.
|
||||||
bool ParseConfiguration(RenderConfiguration* config);
|
bool ParseConfiguration(RenderConfiguration* config);
|
||||||
|
|
Loading…
Reference in New Issue