Skip to content

Use short for parameter count in effect binary#5995

Merged
harry-cpp merged 5 commits intoMonoGame:developfrom
Jjagg:param-count-short
Mar 27, 2020
Merged

Use short for parameter count in effect binary#5995
harry-cpp merged 5 commits intoMonoGame:developfrom
Jjagg:param-count-short

Conversation

@Jjagg
Copy link
Copy Markdown
Contributor

@Jjagg Jjagg commented Oct 8, 2017

A byte was used for the parameter count previously, this limited arrays to 255 elements. Fixes #5994.

private static void WriteParameters(BinaryWriter writer, d3dx_parameter[] parameters, int count)
{
writer.Write((byte)count);
writer.Write((short) count);
Copy link
Copy Markdown
Contributor

@nkast nkast Oct 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about writer.Write7BitEncodedInt(count)?

"If value will fit in seven bits, it takes only one byte of space. If value will not fit in seven bits, the high bit is set on the first byte and written out. value is then shifted by seven bits and the next byte is written. This process is repeated until the entire integer has been written."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'll change that. It might save a couple bytes since most of the time count will fit in one byte. Thanks for the heads up, I didn't know about that function :)

@nkast
Copy link
Copy Markdown
Contributor

nkast commented Oct 8, 2017

@Jjagg
Copy link
Copy Markdown
Contributor Author

Jjagg commented Oct 8, 2017

That's not necessary, row and column are never more than 4 (we could even encode them in a single byte actually).

@nkast
Copy link
Copy Markdown
Contributor

nkast commented Oct 8, 2017

Oh, I see. you are right.

@Jjagg
Copy link
Copy Markdown
Contributor Author

Jjagg commented Oct 14, 2017

Read7BitEncodedInt and Write7BitEncodedInt are protected, so I had to create subclasses to use them in a proper way. Not sure why they're protected, I couldn't find a good explanation anywhere. Anyway, just subclassing seemed like a good solution to me. This is good to go as far as I'm concerned.

@nkast
Copy link
Copy Markdown
Contributor

nkast commented Oct 14, 2017

Interesting, I didn't know that. The 7BitEncodedInt is used in the ContentWriter for some parts of XNB.
In the XNB Format documentation:

This format matches the .NET BinaryReader.Read7BitEncodedInt method. It is a variable size encoding of a 32 bit integer value. C implementation:

int Read7BitEncodedInt()
{
    int result = 0;
    int bitsRead = 0;
    int value;

    do
    {
        value = ReadByte();
        result |= (value & 0x7f) << bitsRead;
        bitsRead += 7;
    }
    while (value & 0x80);

    return result;
}

@Jjagg
Copy link
Copy Markdown
Contributor Author

Jjagg commented Oct 14, 2017

Oh, cool! I could just implement it like that if that's preferable.

@nkast
Copy link
Copy Markdown
Contributor

nkast commented Oct 15, 2017

Well, it doesn't give the implementation of Write7BitEncodedInt(), something that you need to figure out.
Anyway will work IMO.

@Jjagg
Copy link
Copy Markdown
Contributor Author

Jjagg commented Oct 15, 2017

Yeah, I think this is fine as is. MG also uses the 7 bit encoded int methods in the ContentReader and ContentWriter classes, but they extend BinaryReader and BinaryWriter, so they also use the .NET implementation.

@Jjagg
Copy link
Copy Markdown
Contributor Author

Jjagg commented Apr 12, 2018

@tomspilman @cra0zy This is still good to go :) Heads up, it updates the MGFX version. That's important for release notes.

@ThomasFOG
Copy link
Copy Markdown
Contributor

Will the mgfxo be up-to-date, no rebase needed? (I haven't been following much the repo history lately, just a safe check. :) )

@Jjagg
Copy link
Copy Markdown
Contributor Author

Jjagg commented Apr 13, 2018

@mrhelmut Yes, the MGFX version has not been updated by another PR (it's still 8 in develop) which means the binary format has not changed since this branch was created. I recompiled all effects in my last commit, so the .xnb files are up to date :)

@PumpkinPudding
Copy link
Copy Markdown

@Kosmonaut3d
Copy link
Copy Markdown

Kosmonaut3d commented Dec 6, 2018

A checked out version of this will still crash when using arrays with size > 1541

ShaderCode (crash)
#define SIZE 1542
float indexList[SIZE ];

ShaderCode (will work)
#define SIZE 1541
float indexList[SIZE ];

It will crash at Ln49 of ConstantBuffers.cs with an System.OverflowException: 'Arithmetic operation resulted in an overflow.' because the sizeInBytes is negative.

The real problem seems to result from ln244 of Effect.cs where var sizeInBytes = (int)reader.ReadInt16 (); results in a negative number.

@sevenstreak
Copy link
Copy Markdown

Looks like Jjagg's commits are effective refactoring. I'd support pushing to base.

@Jjagg
Copy link
Copy Markdown
Contributor Author

Jjagg commented Apr 22, 2019

Yes, I don't remember looking into the 1541 limit for arrays mentioned above, but this still at least improves the limit. This PR is old, but still good to go.

@Jjagg Jjagg force-pushed the param-count-short branch from 0c416a9 to 078a67c Compare March 27, 2020 19:46
@Jjagg
Copy link
Copy Markdown
Contributor Author

Jjagg commented Mar 27, 2020

@harry-cpp This one is good to go!
Need to put in the release notes for 3.8 that people should recompile their effects after upgrading because the format changed.

@harry-cpp harry-cpp merged commit 477ee10 into MonoGame:develop Mar 27, 2020
@tomspilman tomspilman added this to the 3.8 Release milestone Aug 1, 2020
@Jjagg Jjagg mentioned this pull request Aug 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HLSL array size limited to 255

8 participants