Extracting dest coords in copies; still not right.
This commit is contained in:
parent
fe7de2c0ba
commit
b406f49ae4
|
@ -51,7 +51,8 @@ struct VertexData { \n\
|
||||||
";
|
";
|
||||||
const std::string vs_source = header +
|
const std::string vs_source = header +
|
||||||
"\n\
|
"\n\
|
||||||
layout(location = 0) uniform vec4 src_uv_params; \n\
|
layout(location = 0) uniform vec4 src_uv; \n\
|
||||||
|
layout(location = 1) uniform vec4 dest_rect; \n\
|
||||||
out gl_PerVertex { \n\
|
out gl_PerVertex { \n\
|
||||||
vec4 gl_Position; \n\
|
vec4 gl_Position; \n\
|
||||||
float gl_PointSize; \n\
|
float gl_PointSize; \n\
|
||||||
|
@ -64,7 +65,7 @@ layout(location = 0) in VertexFetch vfetch; \n\
|
||||||
layout(location = 0) out VertexData vtx; \n\
|
layout(location = 0) out VertexData vtx; \n\
|
||||||
void main() { \n\
|
void main() { \n\
|
||||||
gl_Position = vec4(vfetch.pos.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0), 0.0, 1.0); \n\
|
gl_Position = vec4(vfetch.pos.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0), 0.0, 1.0); \n\
|
||||||
vtx.uv = vfetch.pos.xy * src_uv_params.zw + src_uv_params.xy; \n\
|
vtx.uv = vfetch.pos.xy * src_uv.zw + src_uv.xy; \n\
|
||||||
} \n\
|
} \n\
|
||||||
";
|
";
|
||||||
const std::string color_fs_source = header +
|
const std::string color_fs_source = header +
|
||||||
|
@ -207,8 +208,8 @@ struct SavedState {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Blitter::Draw(GLuint src_texture, int32_t src_x, int32_t src_y,
|
void Blitter::Draw(GLuint src_texture, Rect2D src_rect, Rect2D dest_rect,
|
||||||
int32_t src_width, int32_t src_height, GLenum filter) {
|
GLenum filter) {
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
glDisablei(GL_BLEND, 0);
|
glDisablei(GL_BLEND, 0);
|
||||||
|
@ -228,6 +229,8 @@ void Blitter::Draw(GLuint src_texture, int32_t src_x, int32_t src_y,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glViewport(0, 0, dest_rect.width, dest_rect.height);
|
||||||
|
|
||||||
// TODO(benvanik): avoid this?
|
// TODO(benvanik): avoid this?
|
||||||
GLint src_texture_width;
|
GLint src_texture_width;
|
||||||
glGetTextureLevelParameteriv(src_texture, 0, GL_TEXTURE_WIDTH,
|
glGetTextureLevelParameteriv(src_texture, 0, GL_TEXTURE_WIDTH,
|
||||||
|
@ -235,10 +238,12 @@ void Blitter::Draw(GLuint src_texture, int32_t src_x, int32_t src_y,
|
||||||
GLint src_texture_height;
|
GLint src_texture_height;
|
||||||
glGetTextureLevelParameteriv(src_texture, 0, GL_TEXTURE_HEIGHT,
|
glGetTextureLevelParameteriv(src_texture, 0, GL_TEXTURE_HEIGHT,
|
||||||
&src_texture_height);
|
&src_texture_height);
|
||||||
glProgramUniform4f(vertex_program_, 0, src_x / float(src_texture_width),
|
glProgramUniform4f(vertex_program_, 0, src_rect.x / float(src_texture_width),
|
||||||
src_y / float(src_texture_height),
|
src_rect.y / float(src_texture_height),
|
||||||
src_width / float(src_texture_width),
|
src_rect.width / float(src_texture_width),
|
||||||
src_height / float(src_texture_height));
|
src_rect.height / float(src_texture_height));
|
||||||
|
glProgramUniform4f(vertex_program_, 1, float(dest_rect.x), float(dest_rect.y),
|
||||||
|
float(dest_rect.width), float(dest_rect.height));
|
||||||
|
|
||||||
// Useful for seeing the entire framebuffer/etc:
|
// Useful for seeing the entire framebuffer/etc:
|
||||||
// glProgramUniform4f(vertex_program_, 0, 0.0f, 0.0f, 1.0f, 1.0f);
|
// glProgramUniform4f(vertex_program_, 0, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
@ -246,34 +251,27 @@ void Blitter::Draw(GLuint src_texture, int32_t src_x, int32_t src_y,
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Blitter::BlitTexture2D(GLuint src_texture, int32_t src_x, int32_t src_y,
|
void Blitter::BlitTexture2D(GLuint src_texture, Rect2D src_rect,
|
||||||
int32_t src_width, int32_t src_height,
|
Rect2D dest_rect, GLenum filter) {
|
||||||
int32_t dest_x, int32_t dest_y, int32_t dest_width,
|
|
||||||
int32_t dest_height, GLenum filter) {
|
|
||||||
SavedState state;
|
SavedState state;
|
||||||
state.Save();
|
state.Save();
|
||||||
|
|
||||||
glViewport(dest_x, dest_y, dest_width, dest_height);
|
|
||||||
glColorMaski(0, true, true, true, true);
|
glColorMaski(0, true, true, true, true);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
glBindProgramPipeline(color_pipeline_);
|
glBindProgramPipeline(color_pipeline_);
|
||||||
|
|
||||||
Draw(src_texture, src_x, src_y, src_width, src_height, filter);
|
Draw(src_texture, src_rect, dest_rect, filter);
|
||||||
|
|
||||||
state.Restore();
|
state.Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Blitter::CopyColorTexture2D(GLuint src_texture, int32_t src_x,
|
void Blitter::CopyColorTexture2D(GLuint src_texture, Rect2D src_rect,
|
||||||
int32_t src_y, int32_t src_width,
|
GLuint dest_texture, Rect2D dest_rect,
|
||||||
int32_t src_height, GLuint dest_texture,
|
|
||||||
int32_t dest_x, int32_t dest_y,
|
|
||||||
int32_t dest_width, int32_t dest_height,
|
|
||||||
GLenum filter) {
|
GLenum filter) {
|
||||||
SavedState state;
|
SavedState state;
|
||||||
state.Save();
|
state.Save();
|
||||||
|
|
||||||
glViewport(dest_x, dest_y, dest_width, dest_height);
|
|
||||||
glColorMaski(0, true, true, true, true);
|
glColorMaski(0, true, true, true, true);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
|
@ -283,7 +281,7 @@ void Blitter::CopyColorTexture2D(GLuint src_texture, int32_t src_x,
|
||||||
dest_texture, 0);
|
dest_texture, 0);
|
||||||
glNamedFramebufferDrawBuffer(scratch_framebuffer_, GL_COLOR_ATTACHMENT0);
|
glNamedFramebufferDrawBuffer(scratch_framebuffer_, GL_COLOR_ATTACHMENT0);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, scratch_framebuffer_);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, scratch_framebuffer_);
|
||||||
Draw(src_texture, src_x, src_y, src_width, src_height, filter);
|
Draw(src_texture, src_rect, dest_rect, filter);
|
||||||
glNamedFramebufferDrawBuffer(scratch_framebuffer_, GL_NONE);
|
glNamedFramebufferDrawBuffer(scratch_framebuffer_, GL_NONE);
|
||||||
glNamedFramebufferTexture(scratch_framebuffer_, GL_COLOR_ATTACHMENT0, GL_NONE,
|
glNamedFramebufferTexture(scratch_framebuffer_, GL_COLOR_ATTACHMENT0, GL_NONE,
|
||||||
0);
|
0);
|
||||||
|
@ -291,15 +289,11 @@ void Blitter::CopyColorTexture2D(GLuint src_texture, int32_t src_x,
|
||||||
state.Restore();
|
state.Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Blitter::CopyDepthTexture(GLuint src_texture, int32_t src_x, int32_t src_y,
|
void Blitter::CopyDepthTexture(GLuint src_texture, Rect2D src_rect,
|
||||||
int32_t src_width, int32_t src_height,
|
GLuint dest_texture, Rect2D dest_rect) {
|
||||||
GLuint dest_texture, int32_t dest_x,
|
|
||||||
int32_t dest_y, int32_t dest_width,
|
|
||||||
int32_t dest_height) {
|
|
||||||
SavedState state;
|
SavedState state;
|
||||||
state.Save();
|
state.Save();
|
||||||
|
|
||||||
glViewport(dest_x, dest_y, dest_width, dest_height);
|
|
||||||
glColorMaski(0, false, false, false, false);
|
glColorMaski(0, false, false, false, false);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthFunc(GL_ALWAYS);
|
glDepthFunc(GL_ALWAYS);
|
||||||
|
@ -309,7 +303,7 @@ void Blitter::CopyDepthTexture(GLuint src_texture, int32_t src_x, int32_t src_y,
|
||||||
glNamedFramebufferTexture(scratch_framebuffer_, GL_DEPTH_STENCIL_ATTACHMENT,
|
glNamedFramebufferTexture(scratch_framebuffer_, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||||
dest_texture, 0);
|
dest_texture, 0);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, scratch_framebuffer_);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, scratch_framebuffer_);
|
||||||
Draw(src_texture, src_x, src_y, src_width, src_height, GL_NEAREST);
|
Draw(src_texture, src_rect, dest_rect, GL_NEAREST);
|
||||||
glNamedFramebufferTexture(scratch_framebuffer_, GL_DEPTH_STENCIL_ATTACHMENT,
|
glNamedFramebufferTexture(scratch_framebuffer_, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||||
GL_NONE, 0);
|
GL_NONE, 0);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,18 @@ namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
namespace gl4 {
|
namespace gl4 {
|
||||||
|
|
||||||
|
struct Rect2D {
|
||||||
|
int32_t x;
|
||||||
|
int32_t y;
|
||||||
|
int32_t width;
|
||||||
|
int32_t height;
|
||||||
|
Rect2D() : x(0), y(0), width(0), height(0) {}
|
||||||
|
Rect2D(int32_t x_, int32_t y_, int32_t width_, int32_t height_)
|
||||||
|
: x(x_), y(y_), width(width_), height(height_) {}
|
||||||
|
int32_t right() const { return x + width; }
|
||||||
|
int32_t bottom() const { return y + height; }
|
||||||
|
};
|
||||||
|
|
||||||
class Blitter {
|
class Blitter {
|
||||||
public:
|
public:
|
||||||
Blitter();
|
Blitter();
|
||||||
|
@ -27,24 +39,16 @@ class Blitter {
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void BlitTexture2D(GLuint src_texture, int32_t src_x, int32_t src_y,
|
void BlitTexture2D(GLuint src_texture, Rect2D src_rect, Rect2D dest_rect,
|
||||||
int32_t src_width, int32_t src_height, int32_t dest_x,
|
|
||||||
int32_t dest_y, int32_t dest_width, int32_t dest_height,
|
|
||||||
GLenum filter);
|
GLenum filter);
|
||||||
|
|
||||||
void CopyColorTexture2D(GLuint src_texture, int32_t src_x, int32_t src_y,
|
void CopyColorTexture2D(GLuint src_texture, Rect2D src_rect,
|
||||||
int32_t src_width, int32_t src_height,
|
GLuint dest_texture, Rect2D dest_rect, GLenum filter);
|
||||||
GLuint dest_texture, int32_t dest_x, int32_t dest_y,
|
void CopyDepthTexture(GLuint src_texture, Rect2D src_rect,
|
||||||
int32_t dest_width, int32_t dest_height,
|
GLuint dest_texture, Rect2D dest_rect);
|
||||||
GLenum filter);
|
|
||||||
void CopyDepthTexture(GLuint src_texture, int32_t src_x, int32_t src_y,
|
|
||||||
int32_t src_width, int32_t src_height,
|
|
||||||
GLuint dest_texture, int32_t dest_x, int32_t dest_y,
|
|
||||||
int32_t dest_width, int32_t dest_height);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Draw(GLuint src_texture, int32_t src_x, int32_t src_y, int32_t src_width,
|
void Draw(GLuint src_texture, Rect2D src_rect, Rect2D dest_rect, GLenum filter);
|
||||||
int32_t src_height, GLenum filter);
|
|
||||||
|
|
||||||
GLuint vertex_program_;
|
GLuint vertex_program_;
|
||||||
GLuint color_fragment_program_;
|
GLuint color_fragment_program_;
|
||||||
|
|
|
@ -578,12 +578,16 @@ 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);
|
||||||
|
@ -2636,11 +2640,8 @@ bool CommandProcessor::IssueCopy() {
|
||||||
// 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.
|
||||||
// Maybe scissor rect/window offset?
|
uint32_t width = copy_dest_pitch;
|
||||||
uint32_t x = 0;
|
uint32_t height = copy_dest_height;
|
||||||
uint32_t y = 0;
|
|
||||||
uint32_t w = copy_dest_pitch;
|
|
||||||
uint32_t h = copy_dest_height;
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -2651,8 +2652,52 @@ bool CommandProcessor::IssueCopy() {
|
||||||
if (window_offset_y & 0x4000) {
|
if (window_offset_y & 0x4000) {
|
||||||
window_offset_y |= 0x8000;
|
window_offset_y |= 0x8000;
|
||||||
}
|
}
|
||||||
// x = window_offset_x;
|
|
||||||
// y = window_offset_y;
|
// HACK: vertices to use are always in vf0.
|
||||||
|
int copy_vertex_fetch_slot = 0;
|
||||||
|
int r =
|
||||||
|
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + (copy_vertex_fetch_slot / 3) * 6;
|
||||||
|
const auto group = reinterpret_cast<xe_gpu_fetch_group_t*>(®s.values[r]);
|
||||||
|
const xe_gpu_vertex_fetch_t* fetch = nullptr;
|
||||||
|
switch (copy_vertex_fetch_slot % 3) {
|
||||||
|
case 0:
|
||||||
|
fetch = &group->vertex_fetch_0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fetch = &group->vertex_fetch_1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
fetch = &group->vertex_fetch_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert_true(fetch->type == 3);
|
||||||
|
assert_true(fetch->endian == 2);
|
||||||
|
assert_true(fetch->size == 6);
|
||||||
|
const uint8_t* vertex_addr = membase_ + (fetch->address << 2);
|
||||||
|
trace_writer_.WriteMemoryRead(fetch->address << 2, fetch->size * 4);
|
||||||
|
int32_t dest_min_x = int32_t(std::ceilf(std::min(
|
||||||
|
std::min(
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 0), Endian(fetch->endian)),
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 8), Endian(fetch->endian))),
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 16), Endian(fetch->endian)))));
|
||||||
|
int32_t dest_max_x = int32_t(std::ceilf(std::max(
|
||||||
|
std::max(
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 0), Endian(fetch->endian)),
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 8), Endian(fetch->endian))),
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 16), Endian(fetch->endian)))));
|
||||||
|
int32_t dest_min_y = int32_t(std::ceilf(std::min(
|
||||||
|
std::min(
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 4), Endian(fetch->endian)),
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 12), Endian(fetch->endian))),
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 20), Endian(fetch->endian)))));
|
||||||
|
int32_t dest_max_y = int32_t(std::ceilf(std::max(
|
||||||
|
std::max(
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 4), Endian(fetch->endian)),
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 12), Endian(fetch->endian))),
|
||||||
|
GpuSwap(poly::load<float>(vertex_addr + 20), Endian(fetch->endian)))));
|
||||||
|
Rect2D dest_rect(dest_min_x, dest_min_y, dest_max_x - dest_min_x,
|
||||||
|
dest_max_y - dest_min_y);
|
||||||
|
Rect2D src_rect(0, 0, dest_rect.width, dest_rect.height);
|
||||||
|
|
||||||
// Make active so glReadPixels reads from us.
|
// Make active so glReadPixels reads from us.
|
||||||
switch (copy_command) {
|
switch (copy_command) {
|
||||||
|
@ -2663,18 +2708,19 @@ 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, x, y, w, h,
|
context_->blitter(), copy_dest_base, width, 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);
|
||||||
if (!FLAGS_disable_framebuffer_readback) {
|
if (!FLAGS_disable_framebuffer_readback) {
|
||||||
// glReadPixels(x, y, w, h, read_format, read_type, ptr);
|
// glReadPixels(x, y, w, h, read_format, read_type, ptr);
|
||||||
}
|
}
|
||||||
} 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(context_->blitter(), copy_dest_base, x, y, w,
|
texture_cache_.CopyTexture(
|
||||||
h, src_format, copy_dest_swap ? true : false,
|
context_->blitter(), copy_dest_base, width, height, src_format,
|
||||||
depth_target);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -2687,17 +2733,18 @@ 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, x, y, w, h,
|
context_->blitter(), copy_dest_base, width, 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);
|
||||||
if (!FLAGS_disable_framebuffer_readback) {
|
if (!FLAGS_disable_framebuffer_readback) {
|
||||||
// glReadPixels(x, y, w, h, read_format, read_type, ptr);
|
// glReadPixels(x, y, w, h, read_format, read_type, ptr);
|
||||||
}
|
}
|
||||||
} 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, x, y, w, h, src_format,
|
context_->blitter(), copy_dest_base, width, height, src_format,
|
||||||
copy_dest_swap ? true : false, depth_target);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,10 +262,11 @@ void GL4GraphicsSystem::SwapHandler(const SwapParameters& swap_params) {
|
||||||
// no-op.
|
// no-op.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Rect2D src_rect(swap_params.x, swap_params.y, swap_params.width,
|
||||||
|
swap_params.height);
|
||||||
|
Rect2D dest_rect(0, 0, control_->width(), control_->height());
|
||||||
control_->context()->blitter()->BlitTexture2D(
|
control_->context()->blitter()->BlitTexture2D(
|
||||||
swap_params.framebuffer_texture, swap_params.x, swap_params.y,
|
swap_params.framebuffer_texture, src_rect, dest_rect, GL_LINEAR);
|
||||||
swap_params.width, swap_params.height, 0, 0, control_->width(),
|
|
||||||
control_->height(), GL_LINEAR);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -524,17 +524,19 @@ 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,
|
||||||
int32_t x, int32_t y, int32_t width,
|
uint32_t width, uint32_t height,
|
||||||
int32_t height, TextureFormat format,
|
TextureFormat format, bool swap_channels,
|
||||||
bool swap_channels, GLuint src_texture) {
|
GLuint src_texture, Rect2D src_rect,
|
||||||
return ConvertTexture(blitter, guest_address, x, y, width, height, format,
|
Rect2D dest_rect) {
|
||||||
swap_channels, src_texture);
|
return ConvertTexture(blitter, guest_address, width, 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,
|
||||||
int32_t x, int32_t y, int32_t width,
|
uint32_t width, uint32_t height,
|
||||||
int32_t height, TextureFormat format,
|
TextureFormat format, bool swap_channels,
|
||||||
bool swap_channels, GLuint src_texture) {
|
GLuint src_texture, Rect2D src_rect,
|
||||||
|
Rect2D dest_rect) {
|
||||||
const auto& config = texture_configs[uint32_t(format)];
|
const auto& config = texture_configs[uint32_t(format)];
|
||||||
if (config.format == GL_INVALID_ENUM) {
|
if (config.format == GL_INVALID_ENUM) {
|
||||||
assert_always("Unhandled destination texture format");
|
assert_always("Unhandled destination texture format");
|
||||||
|
@ -549,12 +551,11 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
// Have existing texture.
|
// Have existing texture.
|
||||||
assert_false(texture_entry->pending_invalidation);
|
assert_false(texture_entry->pending_invalidation);
|
||||||
if (config.format == GL_DEPTH_STENCIL) {
|
if (config.format == GL_DEPTH_STENCIL) {
|
||||||
blitter->CopyDepthTexture(src_texture, x, y, width, height,
|
blitter->CopyDepthTexture(src_texture, src_rect, texture_entry->handle,
|
||||||
texture_entry->handle, 0, 0, width, height);
|
dest_rect);
|
||||||
} else {
|
} else {
|
||||||
blitter->CopyColorTexture2D(src_texture, x, y, width, height,
|
blitter->CopyColorTexture2D(src_texture, src_rect, texture_entry->handle,
|
||||||
texture_entry->handle, 0, 0, width, height,
|
dest_rect, GL_LINEAR);
|
||||||
GL_LINEAR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: remove texture from write watch list so readback won't kill us.
|
// HACK: remove texture from write watch list so readback won't kill us.
|
||||||
|
@ -574,12 +575,11 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
entry->height == height && entry->format == format) {
|
entry->height == 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, x, y, width, height,
|
blitter->CopyDepthTexture(src_texture, src_rect, entry->handle,
|
||||||
entry->handle, 0, 0, width, height);
|
dest_rect);
|
||||||
} else {
|
} else {
|
||||||
blitter->CopyColorTexture2D(src_texture, x, y, width, height,
|
blitter->CopyColorTexture2D(src_texture, src_rect, entry->handle,
|
||||||
entry->handle, 0, 0, width, height,
|
dest_rect, GL_LINEAR);
|
||||||
GL_LINEAR);
|
|
||||||
}
|
}
|
||||||
return entry->handle;
|
return entry->handle;
|
||||||
}
|
}
|
||||||
|
@ -600,11 +600,10 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
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, width, height);
|
||||||
if (config.format == GL_DEPTH_STENCIL) {
|
if (config.format == GL_DEPTH_STENCIL) {
|
||||||
blitter->CopyDepthTexture(src_texture, x, y, width, height, entry->handle,
|
blitter->CopyDepthTexture(src_texture, src_rect, entry->handle, dest_rect);
|
||||||
0, 0, width, height);
|
|
||||||
} else {
|
} else {
|
||||||
blitter->CopyColorTexture2D(src_texture, x, y, width, height, entry->handle,
|
blitter->CopyColorTexture2D(src_texture, src_rect, entry->handle, dest_rect,
|
||||||
0, 0, width, height, GL_LINEAR);
|
GL_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint handle = entry->handle;
|
GLuint handle = entry->handle;
|
||||||
|
|
|
@ -59,14 +59,13 @@ 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, int32_t x,
|
GLuint CopyTexture(Blitter* blitter, uint32_t guest_address, uint32_t width,
|
||||||
int32_t y, int32_t width, int32_t height,
|
uint32_t height, TextureFormat format, bool swap_channels,
|
||||||
TextureFormat format, bool swap_channels,
|
GLuint src_texture, Rect2D src_rect, Rect2D dest_rect);
|
||||||
GLuint src_texture);
|
GLuint ConvertTexture(Blitter* blitter, uint32_t guest_address,
|
||||||
GLuint ConvertTexture(Blitter* blitter, uint32_t guest_address, int32_t x,
|
uint32_t width, uint32_t height, TextureFormat format,
|
||||||
int32_t y, int32_t width, int32_t height,
|
bool swap_channels, GLuint src_texture, Rect2D src_rect,
|
||||||
TextureFormat format, bool swap_channels,
|
Rect2D dest_rect);
|
||||||
GLuint src_texture);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ReadBufferTexture {
|
struct ReadBufferTexture {
|
||||||
|
|
Loading…
Reference in New Issue