mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[impeller] implement GetPositionUVBuffer (flutter/engine#40248)
[impeller] implement GetPositionUVBuffer
This commit is contained in:
parent
828f3deb86
commit
ff292da861
@ -86,13 +86,6 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
if (texture_ == nullptr) {
|
||||
return true;
|
||||
}
|
||||
// TODO(jonahwilliams): this is a special case for VerticesGeometry which
|
||||
// implements GetPositionUVBuffer. The general geometry case does not use
|
||||
// this method (see note below).
|
||||
auto geometry = GetGeometry();
|
||||
if (geometry->GetVertexType() == GeometryVertexType::kUV) {
|
||||
return RenderVertices(renderer, entity, pass);
|
||||
}
|
||||
|
||||
using VS = TiledTextureFillVertexShader;
|
||||
using FS = TiledTextureFillFragmentShader;
|
||||
@ -104,21 +97,14 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
|
||||
auto& host_buffer = pass.GetTransientsBuffer();
|
||||
|
||||
auto geometry_result =
|
||||
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
|
||||
|
||||
// TODO(bdero): The geometry should be fetched from GetPositionUVBuffer and
|
||||
// contain coverage-mapped UVs, and this should use
|
||||
// position_uv.vert.
|
||||
// https://github.com/flutter/flutter/issues/118553
|
||||
auto bounds_origin = GetGeometry()->GetCoverage(Matrix())->origin;
|
||||
auto geometry_result = GetGeometry()->GetPositionUVBuffer(
|
||||
Rect(bounds_origin, Size(texture_size)), GetInverseMatrix(), renderer,
|
||||
entity, pass);
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp = geometry_result.transform;
|
||||
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
|
||||
frame_info.effect_transform = GetInverseMatrix();
|
||||
frame_info.bounds_origin = geometry->GetCoverage(Matrix())->origin;
|
||||
frame_info.texture_size = Vector2(static_cast<Scalar>(texture_size.width),
|
||||
static_cast<Scalar>(texture_size.height));
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
|
||||
@ -169,73 +155,4 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TiledTextureContents::RenderVertices(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = PositionUVPipeline::VertexShader;
|
||||
using FS = PositionUVPipeline::FragmentShader;
|
||||
|
||||
const auto texture_size = texture_->GetSize();
|
||||
if (texture_size.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& host_buffer = pass.GetTransientsBuffer();
|
||||
|
||||
auto geometry_result = GetGeometry()->GetPositionUVBuffer(
|
||||
Rect::MakeSize(texture_size), GetInverseMatrix(), renderer, entity, pass);
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp = geometry_result.transform;
|
||||
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
|
||||
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
|
||||
frag_info.alpha = GetAlpha();
|
||||
|
||||
Command cmd;
|
||||
cmd.label = "PositionUV";
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
options.stencil_compare = CompareFunction::kEqual;
|
||||
options.stencil_operation = StencilOperation::kIncrementClamp;
|
||||
}
|
||||
options.primitive_type = geometry_result.type;
|
||||
cmd.pipeline = renderer.GetPositionUVPipeline(options);
|
||||
|
||||
cmd.BindVertices(geometry_result.vertex_buffer);
|
||||
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
|
||||
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
|
||||
|
||||
if (color_filter_.has_value()) {
|
||||
auto filtered_texture = CreateFilterTexture(renderer);
|
||||
if (!filtered_texture.has_value()) {
|
||||
return false;
|
||||
}
|
||||
FS::BindTextureSampler(
|
||||
cmd, filtered_texture.value(),
|
||||
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
|
||||
CreateDescriptor()));
|
||||
} else {
|
||||
FS::BindTextureSampler(
|
||||
cmd, texture_,
|
||||
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
|
||||
CreateDescriptor()));
|
||||
}
|
||||
|
||||
if (!pass.AddCommand(std::move(cmd))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -53,10 +53,6 @@ class TiledTextureContents final : public ColorSourceContents {
|
||||
std::optional<std::shared_ptr<Texture>> CreateFilterTexture(
|
||||
const ContentContext& renderer) const;
|
||||
|
||||
bool RenderVertices(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
SamplerDescriptor CreateDescriptor() const;
|
||||
|
||||
std::shared_ptr<Texture> texture_;
|
||||
|
||||
@ -246,6 +246,27 @@ TEST_P(EntityTest, ThreeStrokesInOnePath) {
|
||||
ASSERT_TRUE(OpenPlaygroundHere(entity));
|
||||
}
|
||||
|
||||
TEST_P(EntityTest, StrokeWithTextureContents) {
|
||||
auto bridge = CreateTextureForFixture("bay_bridge.jpg");
|
||||
Path path = PathBuilder{}
|
||||
.MoveTo({100, 100})
|
||||
.LineTo({100, 200})
|
||||
.MoveTo({100, 300})
|
||||
.LineTo({100, 400})
|
||||
.MoveTo({100, 500})
|
||||
.LineTo({100, 600})
|
||||
.TakePath();
|
||||
|
||||
Entity entity;
|
||||
entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
|
||||
auto contents = std::make_unique<TiledTextureContents>();
|
||||
contents->SetGeometry(Geometry::MakeStrokePath(path, 100.0));
|
||||
contents->SetTexture(bridge);
|
||||
contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
|
||||
entity.SetContents(std::move(contents));
|
||||
ASSERT_TRUE(OpenPlaygroundHere(entity));
|
||||
}
|
||||
|
||||
TEST_P(EntityTest, TriangleInsideASquare) {
|
||||
auto callback = [&](ContentContext& context, RenderPass& pass) {
|
||||
Point offset(100, 100);
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "impeller/entity/contents/content_context.h"
|
||||
#include "impeller/entity/entity.h"
|
||||
#include "impeller/entity/position_color.vert.h"
|
||||
#include "impeller/entity/texture_fill.vert.h"
|
||||
#include "impeller/geometry/matrix.h"
|
||||
#include "impeller/geometry/path_builder.h"
|
||||
#include "impeller/renderer/device_buffer.h"
|
||||
@ -52,6 +53,40 @@ std::unique_ptr<Geometry> Geometry::MakeRect(Rect rect) {
|
||||
return std::make_unique<RectGeometry>(rect);
|
||||
}
|
||||
|
||||
static GeometryResult ComputeUVGeometryForRect(Rect source_rect,
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) {
|
||||
constexpr uint16_t kRectIndicies[4] = {0, 1, 2, 3};
|
||||
auto& host_buffer = pass.GetTransientsBuffer();
|
||||
|
||||
std::vector<Point> data(8);
|
||||
auto points = source_rect.GetPoints();
|
||||
for (auto i = 0u, j = 0u; i < 8; i += 2, j++) {
|
||||
data[i] = points[j];
|
||||
data[i + 1] = effect_transform * ((points[j] - texture_coverage.origin) /
|
||||
texture_coverage.size);
|
||||
}
|
||||
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangleStrip,
|
||||
.vertex_buffer =
|
||||
{
|
||||
.vertex_buffer = host_buffer.Emplace(
|
||||
data.data(), 16 * sizeof(float), alignof(float)),
|
||||
.index_buffer = host_buffer.Emplace(
|
||||
kRectIndicies, 4 * sizeof(uint16_t), alignof(uint16_t)),
|
||||
.index_count = 4,
|
||||
.index_type = IndexType::k16bit,
|
||||
},
|
||||
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
entity.GetTransformation(),
|
||||
.prevent_overdraw = false,
|
||||
};
|
||||
}
|
||||
|
||||
/////// Path Geometry ///////
|
||||
|
||||
FillPathGeometry::FillPathGeometry(const Path& path) : path_(path) {}
|
||||
@ -90,6 +125,51 @@ GeometryResult FillPathGeometry::GetPositionBuffer(
|
||||
};
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult FillPathGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) {
|
||||
using VS = TextureFillVertexShader;
|
||||
|
||||
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
|
||||
auto tesselation_result = renderer.GetTessellator()->Tessellate(
|
||||
path_.GetFillType(),
|
||||
path_.CreatePolyline(entity.GetTransformation().GetMaxBasisLength()),
|
||||
[&vertex_builder, &texture_coverage, &effect_transform](
|
||||
const float* vertices, size_t vertices_count, const uint16_t* indices,
|
||||
size_t indices_count) {
|
||||
for (auto i = 0u; i < vertices_count; i += 2) {
|
||||
VS::PerVertexData data;
|
||||
Point vtx = {vertices[i], vertices[i + 1]};
|
||||
data.position = vtx;
|
||||
auto coverage_coords =
|
||||
((vtx - texture_coverage.origin) / texture_coverage.size) /
|
||||
texture_coverage.size;
|
||||
data.texture_coords = effect_transform * coverage_coords;
|
||||
vertex_builder.AppendVertex(data);
|
||||
}
|
||||
FML_DCHECK(vertex_builder.GetVertexCount() == vertices_count / 2);
|
||||
for (auto i = 0u; i < indices_count; i++) {
|
||||
vertex_builder.AppendIndex(indices[i]);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (tesselation_result != Tessellator::Result::kSuccess) {
|
||||
return {};
|
||||
}
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangle,
|
||||
.vertex_buffer =
|
||||
vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer()),
|
||||
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
entity.GetTransformation(),
|
||||
.prevent_overdraw = false,
|
||||
};
|
||||
}
|
||||
|
||||
GeometryVertexType FillPathGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
@ -301,9 +381,9 @@ StrokePathGeometry::CapProc StrokePathGeometry::GetCapProc(Cap stroke_cap) {
|
||||
}
|
||||
|
||||
// static
|
||||
VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
|
||||
VertexBufferBuilder<SolidFillVertexShader::PerVertexData>
|
||||
StrokePathGeometry::CreateSolidStrokeVertices(
|
||||
const Path& path,
|
||||
HostBuffer& buffer,
|
||||
Scalar stroke_width,
|
||||
Scalar scaled_miter_limit,
|
||||
Cap cap,
|
||||
@ -423,7 +503,7 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
|
||||
}
|
||||
}
|
||||
|
||||
return vtx_builder.CreateVertexBuffer(buffer);
|
||||
return vtx_builder;
|
||||
}
|
||||
|
||||
GeometryResult StrokePathGeometry::GetPositionBuffer(
|
||||
@ -442,14 +522,58 @@ GeometryResult StrokePathGeometry::GetPositionBuffer(
|
||||
Scalar stroke_width = std::max(stroke_width_, min_size);
|
||||
|
||||
auto& host_buffer = pass.GetTransientsBuffer();
|
||||
auto vertex_buffer = CreateSolidStrokeVertices(
|
||||
path_, host_buffer, stroke_width, miter_limit_ * stroke_width_ * 0.5,
|
||||
stroke_cap_, GetJoinProc(stroke_join_), GetCapProc(stroke_cap_),
|
||||
auto vertex_builder = CreateSolidStrokeVertices(
|
||||
path_, stroke_width, miter_limit_ * stroke_width_ * 0.5, stroke_cap_,
|
||||
GetJoinProc(stroke_join_), GetCapProc(stroke_cap_),
|
||||
entity.GetTransformation().GetMaxBasisLength());
|
||||
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangleStrip,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.vertex_buffer = vertex_builder.CreateVertexBuffer(host_buffer),
|
||||
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
entity.GetTransformation(),
|
||||
.prevent_overdraw = true,
|
||||
};
|
||||
}
|
||||
|
||||
GeometryResult StrokePathGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) {
|
||||
if (stroke_width_ < 0.0) {
|
||||
return {};
|
||||
}
|
||||
auto determinant = entity.GetTransformation().GetDeterminant();
|
||||
if (determinant == 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
|
||||
Scalar stroke_width = std::max(stroke_width_, min_size);
|
||||
|
||||
auto& host_buffer = pass.GetTransientsBuffer();
|
||||
auto stroke_builder = CreateSolidStrokeVertices(
|
||||
path_, stroke_width, miter_limit_ * stroke_width_ * 0.5, stroke_cap_,
|
||||
GetJoinProc(stroke_join_), GetCapProc(stroke_cap_),
|
||||
entity.GetTransformation().GetMaxBasisLength());
|
||||
|
||||
VertexBufferBuilder<TextureFillVertexShader::PerVertexData> vertex_builder;
|
||||
stroke_builder.IterateVertices(
|
||||
[&vertex_builder, &texture_coverage,
|
||||
&effect_transform](SolidFillVertexShader::PerVertexData old_vtx) {
|
||||
TextureFillVertexShader::PerVertexData data;
|
||||
data.position = old_vtx.position;
|
||||
auto coverage_coords = (old_vtx.position - texture_coverage.origin) /
|
||||
texture_coverage.size;
|
||||
data.texture_coords = effect_transform * coverage_coords;
|
||||
vertex_builder.AppendVertex(data);
|
||||
});
|
||||
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangleStrip,
|
||||
.vertex_buffer = vertex_builder.CreateVertexBuffer(host_buffer),
|
||||
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
entity.GetTransformation(),
|
||||
.prevent_overdraw = true,
|
||||
@ -516,6 +640,18 @@ GeometryResult CoverGeometry::GetPositionBuffer(const ContentContext& renderer,
|
||||
};
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult CoverGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) {
|
||||
auto rect = Rect(Size(pass.GetRenderTargetSize()));
|
||||
return ComputeUVGeometryForRect(rect, texture_coverage, effect_transform,
|
||||
renderer, entity, pass);
|
||||
}
|
||||
|
||||
GeometryVertexType CoverGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
@ -552,6 +688,16 @@ GeometryResult RectGeometry::GetPositionBuffer(const ContentContext& renderer,
|
||||
};
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult RectGeometry::GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) {
|
||||
return ComputeUVGeometryForRect(rect_, texture_coverage, effect_transform,
|
||||
renderer, entity, pass);
|
||||
}
|
||||
|
||||
GeometryVertexType RectGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
|
||||
@ -109,6 +109,13 @@ class FillPathGeometry : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) override;
|
||||
|
||||
Path path_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(FillPathGeometry);
|
||||
@ -154,26 +161,35 @@ class StrokePathGeometry : public Geometry {
|
||||
const Entity& entity,
|
||||
RenderPass& pass) override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryVertexType GetVertexType() const override;
|
||||
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
bool SkipRendering() const;
|
||||
|
||||
static Scalar CreateBevelAndGetDirection(
|
||||
VertexBufferBuilder<SolidFillVertexShader::PerVertexData>& vtx_builder,
|
||||
const Point& position,
|
||||
const Point& start_offset,
|
||||
const Point& end_offset);
|
||||
|
||||
static VertexBuffer CreateSolidStrokeVertices(const Path& path,
|
||||
HostBuffer& buffer,
|
||||
Scalar stroke_width,
|
||||
Scalar scaled_miter_limit,
|
||||
Cap cap,
|
||||
const JoinProc& join_proc,
|
||||
const CapProc& cap_proc,
|
||||
Scalar scale);
|
||||
static VertexBufferBuilder<SolidFillVertexShader::PerVertexData>
|
||||
CreateSolidStrokeVertices(const Path& path,
|
||||
Scalar stroke_width,
|
||||
Scalar scaled_miter_limit,
|
||||
Cap cap,
|
||||
const JoinProc& join_proc,
|
||||
const CapProc& cap_proc,
|
||||
Scalar scale);
|
||||
|
||||
static StrokePathGeometry::JoinProc GetJoinProc(Join stroke_join);
|
||||
|
||||
@ -208,6 +224,13 @@ class CoverGeometry : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) override;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(CoverGeometry);
|
||||
};
|
||||
|
||||
@ -229,6 +252,13 @@ class RectGeometry : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) override;
|
||||
|
||||
Rect rect_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(RectGeometry);
|
||||
|
||||
@ -3,27 +3,21 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/transform.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
uniform FrameInfo {
|
||||
mat4 mvp;
|
||||
mat4 effect_transform;
|
||||
vec2 bounds_origin;
|
||||
vec2 texture_size;
|
||||
float texture_sampler_y_coord_scale;
|
||||
}
|
||||
frame_info;
|
||||
|
||||
in vec2 position;
|
||||
in vec2 texture_coords;
|
||||
|
||||
out vec2 v_texture_coords;
|
||||
|
||||
void main() {
|
||||
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
|
||||
v_texture_coords = IPRemapCoords(
|
||||
IPVec2TransformPosition(
|
||||
frame_info.effect_transform,
|
||||
(position - frame_info.bounds_origin) / frame_info.texture_size),
|
||||
frame_info.texture_sampler_y_coord_scale);
|
||||
v_texture_coords =
|
||||
IPRemapCoords(texture_coords, frame_info.texture_sampler_y_coord_scale);
|
||||
}
|
||||
|
||||
@ -91,6 +91,12 @@ class VertexBufferBuilder {
|
||||
return buffer;
|
||||
};
|
||||
|
||||
void IterateVertices(const std::function<void(VertexType&)>& iterator) {
|
||||
for (auto& vertex : vertices_) {
|
||||
iterator(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<VertexType> vertices_;
|
||||
std::vector<IndexType> indices_;
|
||||
|
||||
@ -10030,7 +10030,7 @@
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 22,
|
||||
"uniform_registers_used": 16,
|
||||
"work_registers_used": 32
|
||||
},
|
||||
"Varying": {
|
||||
@ -10041,10 +10041,10 @@
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.03125,
|
||||
0.0625,
|
||||
0.015625,
|
||||
0.03125,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
],
|
||||
@ -10060,10 +10060,10 @@
|
||||
"load_store"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.03125,
|
||||
0.0625,
|
||||
0.015625,
|
||||
0.03125,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
],
|
||||
@ -10071,18 +10071,18 @@
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.03125,
|
||||
0.0625,
|
||||
0.015625,
|
||||
0.03125,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 16,
|
||||
"work_registers_used": 8
|
||||
"uniform_registers_used": 10,
|
||||
"work_registers_used": 7
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -10099,8 +10099,8 @@
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
3.9600000381469727,
|
||||
4.0,
|
||||
2.9700000286102295,
|
||||
5.0,
|
||||
0.0
|
||||
],
|
||||
"pipelines": [
|
||||
@ -10112,23 +10112,22 @@
|
||||
"load_store"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
3.9600000381469727,
|
||||
4.0,
|
||||
2.9700000286102295,
|
||||
5.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"arithmetic",
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
4.0,
|
||||
4.0,
|
||||
3.0,
|
||||
5.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 6,
|
||||
"work_registers_used": 3
|
||||
"uniform_registers_used": 4,
|
||||
"work_registers_used": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12955,7 +12954,7 @@
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 28,
|
||||
"uniform_registers_used": 20,
|
||||
"work_registers_used": 32
|
||||
},
|
||||
"Varying": {
|
||||
@ -12966,10 +12965,10 @@
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.03125,
|
||||
0.0625,
|
||||
0.015625,
|
||||
0.03125,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
],
|
||||
@ -12985,10 +12984,10 @@
|
||||
"load_store"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.03125,
|
||||
0.0625,
|
||||
0.015625,
|
||||
0.03125,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
],
|
||||
@ -12996,18 +12995,18 @@
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.03125,
|
||||
0.0625,
|
||||
0.015625,
|
||||
0.03125,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 24,
|
||||
"work_registers_used": 8
|
||||
"uniform_registers_used": 16,
|
||||
"work_registers_used": 7
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user