mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 13:07:26 +01:00
Compare commits
3 Commits
7aa253218a
...
59fd2cc683
Author | SHA1 | Date | |
---|---|---|---|
|
59fd2cc683 | ||
|
b8cf4ea82f | ||
|
cf6cdac8a6 |
@ -16,6 +16,7 @@ package graphics
|
||||
|
||||
const (
|
||||
ShaderSrcImageCount = 4
|
||||
ShaderDstImageCount = 1
|
||||
|
||||
// PreservedUniformVariablesCount represents the number of preserved uniform variables.
|
||||
// Any shaders in Ebitengine must have these uniform variables.
|
||||
|
@ -61,7 +61,7 @@ func (p *drawTrianglesCommandPool) put(v *drawTrianglesCommand) {
|
||||
|
||||
// drawTrianglesCommand represents a drawing command to draw an image on another image.
|
||||
type drawTrianglesCommand struct {
|
||||
dst *Image
|
||||
dsts [graphics.ShaderDstImageCount]*Image
|
||||
srcs [graphics.ShaderSrcImageCount]*Image
|
||||
vertices []float32
|
||||
blend graphicsdriver.Blend
|
||||
@ -81,9 +81,16 @@ func (c *drawTrianglesCommand) String() string {
|
||||
c.blend.BlendOperationRGB,
|
||||
c.blend.BlendOperationAlpha)
|
||||
|
||||
dst := fmt.Sprintf("%d", c.dst.id)
|
||||
if c.dst.screen {
|
||||
dst += " (screen)"
|
||||
var dststrs [graphics.ShaderDstImageCount]string
|
||||
for i, dst := range c.dsts {
|
||||
if dst == nil {
|
||||
dststrs[i] = "(nil)"
|
||||
continue
|
||||
}
|
||||
dststrs[i] = fmt.Sprintf("%d", dst.id)
|
||||
if dst.screen {
|
||||
dststrs[i] += " (screen)"
|
||||
}
|
||||
}
|
||||
|
||||
var srcstrs [graphics.ShaderSrcImageCount]string
|
||||
@ -98,7 +105,7 @@ func (c *drawTrianglesCommand) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("draw-triangles: dst: %s <- src: [%s], num of dst regions: %d, num of indices: %d, blend: %s, fill rule: %s, shader id: %d", dst, strings.Join(srcstrs[:], ", "), len(c.dstRegions), c.numIndices(), blend, c.fillRule, c.shader.id)
|
||||
return fmt.Sprintf("draw-triangles: dst: [%s] <- src: [%s], num of dst regions: %d, num of indices: %d, blend: %s, fill rule: %s, shader id: %d", strings.Join(dststrs[:], ", "), strings.Join(srcstrs[:], ", "), len(c.dstRegions), c.numIndices(), blend, c.fillRule, c.shader.id)
|
||||
}
|
||||
|
||||
// Exec executes the drawTrianglesCommand.
|
||||
@ -108,16 +115,25 @@ func (c *drawTrianglesCommand) Exec(commandQueue *commandQueue, graphicsDriver g
|
||||
return nil
|
||||
}
|
||||
|
||||
var imgs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID
|
||||
for i, src := range c.srcs {
|
||||
if src == nil {
|
||||
imgs[i] = graphicsdriver.InvalidImageID
|
||||
var dsts [graphics.ShaderDstImageCount]graphicsdriver.ImageID
|
||||
for i, dst := range c.dsts {
|
||||
if dst == nil {
|
||||
dsts[i] = graphicsdriver.InvalidImageID
|
||||
continue
|
||||
}
|
||||
imgs[i] = src.image.ID()
|
||||
dsts[i] = dst.image.ID()
|
||||
}
|
||||
|
||||
return graphicsDriver.DrawTriangles(c.dst.image.ID(), imgs, c.shader.shader.ID(), c.dstRegions, indexOffset, c.blend, c.uniforms, c.fillRule)
|
||||
var srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID
|
||||
for i, src := range c.srcs {
|
||||
if src == nil {
|
||||
srcs[i] = graphicsdriver.InvalidImageID
|
||||
continue
|
||||
}
|
||||
srcs[i] = src.image.ID()
|
||||
}
|
||||
|
||||
return graphicsDriver.DrawTriangles(dsts, srcs, c.shader.shader.ID(), c.dstRegions, indexOffset, c.blend, c.uniforms, c.fillRule)
|
||||
}
|
||||
|
||||
func (c *drawTrianglesCommand) NeedsSync() bool {
|
||||
@ -142,7 +158,7 @@ func (c *drawTrianglesCommand) setVertices(vertices []float32) {
|
||||
|
||||
// CanMergeWithDrawTrianglesCommand returns a boolean value indicating whether the other drawTrianglesCommand can be merged
|
||||
// with the drawTrianglesCommand c.
|
||||
func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderSrcImageCount]*Image, vertices []float32, blend graphicsdriver.Blend, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) bool {
|
||||
func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dsts [graphics.ShaderDstImageCount]*Image, srcs [graphics.ShaderSrcImageCount]*Image, vertices []float32, blend graphicsdriver.Blend, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) bool {
|
||||
if c.shader != shader {
|
||||
return false
|
||||
}
|
||||
@ -154,7 +170,7 @@ func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs
|
||||
return false
|
||||
}
|
||||
}
|
||||
if c.dst != dst {
|
||||
if c.dsts != dsts {
|
||||
return false
|
||||
}
|
||||
if c.srcs != srcs {
|
||||
|
@ -105,7 +105,7 @@ func mustUseDifferentVertexBuffer(nextNumVertexFloats int) bool {
|
||||
}
|
||||
|
||||
// EnqueueDrawTrianglesCommand enqueues a drawing-image command.
|
||||
func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderSrcImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
|
||||
func (q *commandQueue) EnqueueDrawTrianglesCommand(dsts [graphics.ShaderDstImageCount]*Image, srcs [graphics.ShaderSrcImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
|
||||
if len(vertices) > maxVertexFloatCount {
|
||||
panic(fmt.Sprintf("graphicscommand: len(vertices) must equal to or less than %d but was %d", maxVertexFloatCount, len(vertices)))
|
||||
}
|
||||
@ -125,7 +125,7 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
|
||||
// prependPreservedUniforms not only prepends values to the given slice but also creates a new slice.
|
||||
// Allocating a new slice is necessary to make EnqueueDrawTrianglesCommand safe so far.
|
||||
// TODO: This might cause a performance issue (#2601).
|
||||
uniforms = q.prependPreservedUniforms(uniforms, shader, dst, srcs, dstRegion, srcRegions)
|
||||
uniforms = q.prependPreservedUniforms(uniforms, shader, dsts, srcs, dstRegion, srcRegions)
|
||||
|
||||
// Remove unused uniform variables so that more commands can be merged.
|
||||
shader.ir.FilterUniformVariables(uniforms)
|
||||
@ -133,7 +133,7 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
|
||||
// TODO: If dst is the screen, reorder the command to be the last.
|
||||
if !split && 0 < len(q.commands) {
|
||||
if last, ok := q.commands[len(q.commands)-1].(*drawTrianglesCommand); ok {
|
||||
if last.CanMergeWithDrawTrianglesCommand(dst, srcs, vertices, blend, shader, uniforms, fillRule) {
|
||||
if last.CanMergeWithDrawTrianglesCommand(dsts, srcs, vertices, blend, shader, uniforms, fillRule) {
|
||||
last.setVertices(q.lastVertices(len(vertices) + last.numVertices()))
|
||||
if last.dstRegions[len(last.dstRegions)-1].Region == dstRegion {
|
||||
last.dstRegions[len(last.dstRegions)-1].IndexCount += len(indices)
|
||||
@ -149,7 +149,7 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
|
||||
}
|
||||
|
||||
c := q.drawTrianglesCommandPool.get()
|
||||
c.dst = dst
|
||||
c.dsts = dsts
|
||||
c.srcs = srcs
|
||||
c.vertices = q.lastVertices(len(vertices))
|
||||
c.blend = blend
|
||||
@ -324,13 +324,19 @@ func imageRectangleToRectangleF32(r image.Rectangle) rectangleF32 {
|
||||
}
|
||||
}
|
||||
|
||||
func (q *commandQueue) prependPreservedUniforms(uniforms []uint32, shader *Shader, dst *Image, srcs [graphics.ShaderSrcImageCount]*Image, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle) []uint32 {
|
||||
func (q *commandQueue) prependPreservedUniforms(uniforms []uint32, shader *Shader, dsts [graphics.ShaderDstImageCount]*Image, srcs [graphics.ShaderSrcImageCount]*Image, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle) []uint32 {
|
||||
origUniforms := uniforms
|
||||
uniforms = q.uint32sBuffer.alloc(len(origUniforms) + graphics.PreservedUniformUint32Count)
|
||||
copy(uniforms[graphics.PreservedUniformUint32Count:], origUniforms)
|
||||
|
||||
// Set the destination texture size.
|
||||
dw, dh := dst.InternalSize()
|
||||
var dw, dh int
|
||||
for _, dst := range dsts {
|
||||
if dst != nil {
|
||||
dw, dh = dst.InternalSize()
|
||||
break
|
||||
}
|
||||
}
|
||||
uniforms[0] = math.Float32bits(float32(dw))
|
||||
uniforms[1] = math.Float32bits(float32(dh))
|
||||
uniformIndex := 2
|
||||
@ -469,11 +475,11 @@ func (c *commandQueueManager) putCommandQueue(commandQueue *commandQueue) {
|
||||
c.pool.put(commandQueue)
|
||||
}
|
||||
|
||||
func (c *commandQueueManager) enqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderSrcImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
|
||||
func (c *commandQueueManager) enqueueDrawTrianglesCommand(dsts [graphics.ShaderDstImageCount]*Image, srcs [graphics.ShaderSrcImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
|
||||
if c.current == nil {
|
||||
c.current, _ = c.pool.get()
|
||||
}
|
||||
c.current.EnqueueDrawTrianglesCommand(dst, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
|
||||
c.current.EnqueueDrawTrianglesCommand(dsts, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
|
||||
}
|
||||
|
||||
func (c *commandQueueManager) flush(graphicsDriver graphicsdriver.Graphics, endFrame bool) error {
|
||||
|
@ -142,7 +142,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderSrcImageCount]*Image, vertice
|
||||
}
|
||||
i.flushBufferedWritePixels()
|
||||
|
||||
theCommandQueueManager.enqueueDrawTrianglesCommand(i, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
|
||||
theCommandQueueManager.enqueueDrawTrianglesCommand([graphics.ShaderDstImageCount]*Image{i}, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
|
||||
}
|
||||
|
||||
// ReadPixels reads the image's pixels.
|
||||
|
@ -514,13 +514,13 @@ func (g *graphics11) removeShader(s *shader11) {
|
||||
delete(g.shaders, s.id)
|
||||
}
|
||||
|
||||
func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
// Remove bound textures first. This is needed to avoid warnings on the debugger.
|
||||
g.deviceContext.OMSetRenderTargets([]*_ID3D11RenderTargetView{nil}, nil)
|
||||
srvs := [graphics.ShaderSrcImageCount]*_ID3D11ShaderResourceView{}
|
||||
g.deviceContext.PSSetShaderResources(0, srvs[:])
|
||||
|
||||
dst := g.images[dstID]
|
||||
dst := g.images[dstIDs[0]]
|
||||
var srcs [graphics.ShaderSrcImageCount]*image11
|
||||
for i, id := range srcIDs {
|
||||
img := g.images[id]
|
||||
|
@ -1081,7 +1081,7 @@ func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphicsdriver.ImageID, srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
if shaderID == graphicsdriver.InvalidShaderID {
|
||||
return fmt.Errorf("directx: shader ID is invalid")
|
||||
}
|
||||
@ -1102,7 +1102,7 @@ func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.
|
||||
g.pipelineStates.releaseConstantBuffers(g.frameIndex)
|
||||
}
|
||||
|
||||
dst := g.images[dstID]
|
||||
dst := g.images[dstIDs[0]]
|
||||
var resourceBarriers []_D3D12_RESOURCE_BARRIER_Transition
|
||||
if rb, ok := dst.transiteState(_D3D12_RESOURCE_STATE_RENDER_TARGET); ok {
|
||||
resourceBarriers = append(resourceBarriers, rb)
|
||||
|
@ -68,7 +68,7 @@ type Graphics interface {
|
||||
NewShader(program *shaderir.Program) (Shader, error)
|
||||
|
||||
// DrawTriangles draws an image onto another image with the given parameters.
|
||||
DrawTriangles(dst ImageID, srcs [graphics.ShaderSrcImageCount]ImageID, shader ShaderID, dstRegions []DstRegion, indexOffset int, blend Blend, uniforms []uint32, fillRule FillRule) error
|
||||
DrawTriangles(dsts [graphics.ShaderDstImageCount]ImageID, srcs [graphics.ShaderSrcImageCount]ImageID, shader ShaderID, dstRegions []DstRegion, indexOffset int, blend Blend, uniforms []uint32, fillRule FillRule) error
|
||||
}
|
||||
|
||||
type Resetter interface {
|
||||
|
@ -605,12 +605,12 @@ func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
func (g *Graphics) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
if shaderID == graphicsdriver.InvalidShaderID {
|
||||
return fmt.Errorf("metal: shader ID is invalid")
|
||||
}
|
||||
|
||||
dst := g.images[dstID]
|
||||
dst := g.images[dstIDs[0]]
|
||||
|
||||
if dst.screen {
|
||||
g.view.update()
|
||||
|
@ -198,12 +198,12 @@ func (g *Graphics) uniformVariableName(idx int) string {
|
||||
return name
|
||||
}
|
||||
|
||||
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
func (g *Graphics) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
if shaderID == graphicsdriver.InvalidShaderID {
|
||||
return fmt.Errorf("opengl: shader ID is invalid")
|
||||
}
|
||||
|
||||
destination := g.images[dstID]
|
||||
destination := g.images[dstIDs[0]]
|
||||
|
||||
g.drawCalled = true
|
||||
|
||||
|
@ -116,7 +116,7 @@ func (g *Graphics) NewShader(program *shaderir.Program) (graphicsdriver.Shader,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (g *Graphics) DrawTriangles(dst graphicsdriver.ImageID, srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shader graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
func (g *Graphics) DrawTriangles(dsts [graphics.ShaderDstImageCount]graphicsdriver.ImageID, srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shader graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user